Skip to content

Commit 7d66976

Browse files
codrin989wsakernel
authored andcommitted
i2c: at91: Fix pinmux after devm_gpiod_get() for bus recovery
devm_gpiod_get() usually calls gpio_request_enable() for non-strict pinmux drivers. These puts the pins in GPIO mode, whithout notifying the pinctrl driver. At this point, the I2C bus no longer owns the pins. To mux the pins back to the I2C bus, we use the pinctrl driver to change the state of the pins to GPIO, before using devm_gpiod_get(). After the pins are received as GPIOs, we switch theer pinctrl state back to the default one, Fixes: d3d3fdc ("i2c: at91: implement i2c bus recovery") Signed-off-by: Codrin Ciubotariu <[email protected]> Acked-by: Ludovic Desroches <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 2f5a55c commit 7d66976

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

drivers/i2c/busses/i2c-at91-master.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,18 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
845845
PINCTRL_STATE_DEFAULT);
846846
dev->pinctrl_pins_gpio = pinctrl_lookup_state(dev->pinctrl,
847847
"gpio");
848+
if (IS_ERR(dev->pinctrl_pins_default) ||
849+
IS_ERR(dev->pinctrl_pins_gpio)) {
850+
dev_info(&pdev->dev, "pinctrl states incomplete for recovery\n");
851+
return -EINVAL;
852+
}
853+
854+
/*
855+
* pins will be taken as GPIO, so we might as well inform pinctrl about
856+
* this and move the state to GPIO
857+
*/
858+
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio);
859+
848860
rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
849861
if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER)
850862
return -EPROBE_DEFER;
@@ -855,9 +867,7 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
855867
return -EPROBE_DEFER;
856868

857869
if (IS_ERR(rinfo->sda_gpiod) ||
858-
IS_ERR(rinfo->scl_gpiod) ||
859-
IS_ERR(dev->pinctrl_pins_default) ||
860-
IS_ERR(dev->pinctrl_pins_gpio)) {
870+
IS_ERR(rinfo->scl_gpiod)) {
861871
dev_info(&pdev->dev, "recovery information incomplete\n");
862872
if (!IS_ERR(rinfo->sda_gpiod)) {
863873
gpiod_put(rinfo->sda_gpiod);
@@ -867,9 +877,13 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
867877
gpiod_put(rinfo->scl_gpiod);
868878
rinfo->scl_gpiod = NULL;
869879
}
880+
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
870881
return -EINVAL;
871882
}
872883

884+
/* change the state of the pins back to their default state */
885+
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
886+
873887
dev_info(&pdev->dev, "using scl, sda for recovery\n");
874888

875889
rinfo->prepare_recovery = at91_prepare_twi_recovery;

0 commit comments

Comments
 (0)