I2C recovery VF61

I’m trying to use I2C bus recovery, implemented in kernel 4.4 , but have no succeed.
vf610-colibri-eval-v3.dtsi file was modified to enable I2C ports 1, 2 and 3 with the bus recovery properties filled. Bellow the code used for I2C1 port:

	clock-frequency = <400000>;
	pinctrl-names = "default", "gpio";
	pinctrl-0 = <&pinctrl_i2c1>;
	pinctrl-1 = <&pinctrl_i2c1_gpio>;
	scl-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
	sda-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
	status = "okay";

&iomuxc {
	vf610-colibri {

		pinctrl_i2c1: i2c1grp {
			fsl,pins = <
				VF610_PAD_PTB16__I2C1_SCL		0x37ff
				VF610_PAD_PTB17__I2C1_SDA		0x37ff
		pinctrl_i2c1_gpio: i2c1grp_gpio {
			fsl,pins = <
				VF610_PAD_PTB16__GPIO_38 		0x00c2								
				VF610_PAD_PTB17__GPIO_39		0x00c2

After load the new dtb to the VF61 cpu, I’m getting error -517 (EPROBE_DEFER).

of_get_named_gpiod_flags: parsed ‘sda-gpios’ property of node ‘/soc/aips-bus@40000000/i2c@40067000[0]’ - status (-517)

of_get_named_gpiod_flags: parsed ‘scl-gpios’ property of node ‘/soc/aips-bus@40000000/i2c@40067000[0]’ - status (-517)

It appears that the I2C driver was called before the gpios list is filled, because the loop from list_for_each_entry macro gets out in the first run. I tried to debug it till the following point:

(file: i2c.imx) i2c_imx_init_recovery info 
--(file: gpiolib-of.c) of_get_named_gpiod_flags
----(file: gpiolib.c) gpiochip_find
------(file: gpiolib.c) list_for_each_entry

Did anyone tried to use I2C bus recovery with VF61 and succeeded doing that? Any suggestion on how to put it working?

After load the new dtb to the VF61 cpu, I’m getting error -517 (EPROBE_DEFER).

Those can usually be ignored as mere warnings. The kernel will automatically retry once whatever thing that asked for a deferral is ready.

Is I2C not working/not available in the end or what is exactly the issue?

I2C is working well, but when I simulate a fail in SDA PIN, bus recovey isn’t working.

Does the driver ever succeeds in loading? Can you post your kernel log (dmesg)?

Hello Sfetan,

I can’t see any errors at the kernel start up about the I2C issue.

I attached the file with the dmesg prints.link text

Hm, your log does not show the above mentioned -517 error. As far as I can tell this is a debug message from gpiolib-of.c, I guess you used a kernel with debug messages enabled back then?

I will do some further investigations.

Closer investigations unveiled two problems with I2C bus recovery:

First, i2c_imx_init_recovery actually did not handle -517 (EPROBE_DEFER) as it should. This lead to the driver being loaded without GPIO recovery support. This is the output with debug messages enabled in drivers/i2c/busses/i2c-imx.c:

[    0.301957] imx-i2c 40067000.i2c: <i2c_imx_probe>
[    0.304685] imx-i2c 40067000.i2c: recovery information incomplete
[    0.304936] i2c i2c-1: claimed irq 37
[    0.304960] i2c i2c-1: device resources: [mem 0x40067000-0x40067fff]
[    0.304977] i2c i2c-1: adapter name: "40067000.i2c"
[    0.304993] i2c i2c-1: IMX I2C adapter registered
[    0.309606] i2c i2c-1: using dma0chan2 (tx) and dma0chan3 (rx) for DMA transfers

I pushed two patches to our toradex_vf_4.4-next branch which solve this issue.

Second, I2C GPIO recovery seems to disable the GPIO after muxing it back to I2C. This is an issue with Vybrids GPIO driver: On Vybrid, imx_pmx_gpio_disable_free disables the input/output driver on freeing a GPIO… In this particular case this disables the I2C functionality of the pin which is not what we want. This issue is solved with another patch on the same branch.

Furthermore: It is important to enable the input buffer in the GPIO pinmux configuration (this is the first bit, your pinctrl configuration 0x00c2 currently does not enable the input buffer). Otherwise the I2C GPIO recovery framework won’t be able to read the state of the pin. I recommend to use the same pinctrl configuration as used in the I2C pinmux configuration: 0x37ff.

Hello Stefan, I’ve tested the version 4.4-next, and the i2c recovery is working well. Thank you.