Skip to content

Commit 78a6ee1

Browse files
juhosgAndi Shyti
authored andcommitted
i2c: pxa: defer reset on Armada 3700 when recovery is used
The I2C communication is completely broken on the Armada 3700 platform since commit 0b01392 ("i2c: pxa: move to generic GPIO recovery"). For example, on the Methode uDPU board, probing of the two onboard temperature sensors fails ... [ 7.271713] i2c i2c-0: using pinctrl states for GPIO recovery [ 7.277503] i2c i2c-0: PXA I2C adapter [ 7.282199] i2c i2c-1: using pinctrl states for GPIO recovery [ 7.288241] i2c i2c-1: PXA I2C adapter [ 7.292947] sfp sfp-eth1: Host maximum power 3.0W [ 7.299614] sfp sfp-eth0: Host maximum power 3.0W [ 7.308178] lm75 1-0048: supply vs not found, using dummy regulator [ 32.489631] lm75 1-0048: probe with driver lm75 failed with error -121 [ 32.496833] lm75 1-0049: supply vs not found, using dummy regulator [ 82.890614] lm75 1-0049: probe with driver lm75 failed with error -121 ... and accessing the plugged-in SFP modules also does not work: [ 511.298537] sfp sfp-eth1: please wait, module slow to respond [ 536.488530] sfp sfp-eth0: please wait, module slow to respond ... [ 1065.688536] sfp sfp-eth1: failed to read EEPROM: -EREMOTEIO [ 1090.888532] sfp sfp-eth0: failed to read EEPROM: -EREMOTEIO After a discussion [1], there was an attempt to fix the problem by reverting the offending change by commit 7b211c7 ("Revert "i2c: pxa: move to generic GPIO recovery""), but that only helped to fix the issue in the 6.1.y stable tree. The reason behind the partial succes is that there was another change in commit 20cb3fc ("i2c: Set i2c pinctrl recovery info from it's device pinctrl") in the 6.3-rc1 cycle which broke things further. The cause of the problem is the same in case of both offending commits mentioned above. Namely, the I2C core code changes the pinctrl state to GPIO while running the recovery initialization code. Although the PXA specific initialization also does this, but the key difference is that it happens before the controller is getting enabled in i2c_pxa_reset(), whereas in the case of the generic initialization it happens after that. Change the code to reset the controller only before the first transfer instead of before registering the controller. This ensures that the controller is not enabled at the time when the generic recovery code performs the pinctrl state changes, thus avoids the problem described above. As the result this change restores the original behaviour, which in turn makes the I2C communication to work again as it can be seen from the following log: [ 7.363250] i2c i2c-0: using pinctrl states for GPIO recovery [ 7.369041] i2c i2c-0: PXA I2C adapter [ 7.373673] i2c i2c-1: using pinctrl states for GPIO recovery [ 7.379742] i2c i2c-1: PXA I2C adapter [ 7.384506] sfp sfp-eth1: Host maximum power 3.0W [ 7.393013] sfp sfp-eth0: Host maximum power 3.0W [ 7.399266] lm75 1-0048: supply vs not found, using dummy regulator [ 7.407257] hwmon hwmon0: temp1_input not attached to any thermal zone [ 7.413863] lm75 1-0048: hwmon0: sensor 'tmp75c' [ 7.418746] lm75 1-0049: supply vs not found, using dummy regulator [ 7.426371] hwmon hwmon1: temp1_input not attached to any thermal zone [ 7.432972] lm75 1-0049: hwmon1: sensor 'tmp75c' [ 7.755092] sfp sfp-eth1: module MENTECHOPTO POS22-LDCC-KR rev 1.0 sn MNC208U90009 dc 200828 [ 7.764997] mvneta d0040000.ethernet eth1: unsupported SFP module: no common interface modes [ 7.785362] sfp sfp-eth0: module Mikrotik S-RJ01 rev 1.0 sn 61B103C55C58 dc 201022 [ 7.803426] hwmon hwmon2: temp1_input not attached to any thermal zone Link: https://lore.kernel.org/r/[email protected] #1 Cc: [email protected] # 6.3+ Fixes: 20cb3fc ("i2c: Set i2c pinctrl recovery info from it's device pinctrl") Signed-off-by: Gabor Juhos <[email protected]> Tested-by: Robert Marko <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Andi Shyti <[email protected]> Link: https://lore.kernel.org/r/20260226-i2c-pxa-fix-i2c-communication-v4-1-797a091dae87@gmail.com
1 parent be627ab commit 78a6ee1

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

drivers/i2c/busses/i2c-pxa.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ struct pxa_i2c {
268268
struct pinctrl *pinctrl;
269269
struct pinctrl_state *pinctrl_default;
270270
struct pinctrl_state *pinctrl_recovery;
271+
bool reset_before_xfer;
271272
};
272273

273274
#define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -1144,6 +1145,11 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap,
11441145
{
11451146
struct pxa_i2c *i2c = adap->algo_data;
11461147

1148+
if (i2c->reset_before_xfer) {
1149+
i2c_pxa_reset(i2c);
1150+
i2c->reset_before_xfer = false;
1151+
}
1152+
11471153
return i2c_pxa_internal_xfer(i2c, msgs, num, i2c_pxa_do_xfer);
11481154
}
11491155

@@ -1521,7 +1527,16 @@ static int i2c_pxa_probe(struct platform_device *dev)
15211527
}
15221528
}
15231529

1524-
i2c_pxa_reset(i2c);
1530+
/*
1531+
* Skip reset on Armada 3700 when recovery is used to avoid
1532+
* controller hang due to the pinctrl state changes done by
1533+
* the generic recovery initialization code. The reset will
1534+
* be performed later, prior to the first transfer.
1535+
*/
1536+
if (i2c_type == REGS_A3700 && i2c->adap.bus_recovery_info)
1537+
i2c->reset_before_xfer = true;
1538+
else
1539+
i2c_pxa_reset(i2c);
15251540

15261541
ret = i2c_add_numbered_adapter(&i2c->adap);
15271542
if (ret < 0)

0 commit comments

Comments
 (0)