linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Add bus recovery to i2c-pxa
@ 2020-05-06  9:40 Russell King - ARM Linux admin
  2020-05-06  9:40 ` [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery Russell King
  2020-05-06  9:40 ` [PATCH 2/2] arm64: dts: add uDPU " Russell King
  0 siblings, 2 replies; 7+ messages in thread
From: Russell King - ARM Linux admin @ 2020-05-06  9:40 UTC (permalink / raw)
  To: linux-i2c

Hi,

This series adds bus recovery to i2c-pxa, using GPIOs to manually
recover the bus. This has been proven to work on Armada 3720 with
various SFP modules that appear to misbehave.

I am only expecting patch 1 to be applied to the i2c tree; patch 2
should be applied through normal routes via the arm-soc tree, but
are included in this series since it is part of the same change.

 arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts |  22 ++-
 drivers/i2c/busses/i2c-pxa.c                     | 176 ++++++++++++++++++++---
 2 files changed, 179 insertions(+), 19 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery
  2020-05-06  9:40 [PATCH 0/2] Add bus recovery to i2c-pxa Russell King - ARM Linux admin
@ 2020-05-06  9:40 ` Russell King
  2020-05-06 14:00   ` Andrew Lunn
  2020-05-06  9:40 ` [PATCH 2/2] arm64: dts: add uDPU " Russell King
  1 sibling, 1 reply; 7+ messages in thread
From: Russell King @ 2020-05-06  9:40 UTC (permalink / raw)
  To: linux-i2c
  Cc: Andrew Lunn, devicetree, Gregory Clement, Jason Cooper,
	linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
	Vladimir Vid

Implement generic GPIO-based I2C bus recovery for the PXA I2C driver.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/i2c/busses/i2c-pxa.c | 176 +++++++++++++++++++++++++++++++----
 1 file changed, 159 insertions(+), 17 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 0e194d6cd1b5..da15ab2a519e 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -28,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/i2c-pxa.h>
 #include <linux/slab.h>
@@ -260,6 +262,11 @@ struct pxa_i2c {
 	bool			highmode_enter;
 	u32			fm_mask;
 	u32			hs_mask;
+
+	struct i2c_bus_recovery_info recovery;
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*pinctrl_default;
+	struct pinctrl_state	*pinctrl_recovery;
 };
 
 #define _IBMR(i2c)	((i2c)->reg_ibmr)
@@ -559,13 +566,8 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
 #define i2c_pxa_set_slave(i2c, err)	do { } while (0)
 #endif
 
-static void i2c_pxa_reset(struct pxa_i2c *i2c)
+static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
 {
-	pr_debug("Resetting I2C Controller Unit\n");
-
-	/* abort any transfer currently under way */
-	i2c_pxa_abort(i2c);
-
 	/* reset according to 9.8 */
 	writel(ICR_UR, _ICR(i2c));
 	writel(I2C_ISR_INIT, _ISR(i2c));
@@ -584,12 +586,25 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 #endif
 
 	i2c_pxa_set_slave(i2c, 0);
+}
 
+static void i2c_pxa_enable(struct pxa_i2c *i2c)
+{
 	/* enable unit */
 	writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
 	udelay(100);
 }
 
+static void i2c_pxa_reset(struct pxa_i2c *i2c)
+{
+	pr_debug("Resetting I2C Controller Unit\n");
+
+	/* abort any transfer currently under way */
+	i2c_pxa_abort(i2c);
+	i2c_pxa_do_reset(i2c);
+	i2c_pxa_enable(i2c);
+}
+
 
 #ifdef CONFIG_I2C_PXA_SLAVE
 /*
@@ -1043,6 +1058,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 	ret = i2c_pxa_wait_bus_not_busy(i2c);
 	if (ret) {
 		dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
+		i2c_recover_bus(&i2c->adap);
 		goto out;
 	}
 
@@ -1088,6 +1104,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 
 	if (!timeout && i2c->msg_num) {
 		i2c_pxa_scream_blue_murder(i2c, "timeout with active message");
+		i2c_recover_bus(&i2c->adap);
 		ret = I2C_RETRY;
 	}
 
@@ -1277,6 +1294,129 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
 	return 0;
 }
 
+static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap)
+{
+	struct pxa_i2c *i2c = adap->algo_data;
+	u32 ibmr = readl(_IBMR(i2c));
+
+	/*
+	 * Program the GPIOs to reflect the current I2C bus state while
+	 * we transition to recovery; this avoids glitching the bus.
+	 */
+	gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS);
+	gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS);
+
+	WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery));
+}
+
+static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
+{
+	struct pxa_i2c *i2c = adap->algo_data;
+	u32 isr;
+
+	/*
+	 * The bus should now be free. Clear up the I2C controller before
+	 * handing control of the bus back to avoid the bus changing state.
+	 */
+	isr = readl(_ISR(i2c));
+	if (isr & (ISR_UB | ISR_IBB)) {
+		dev_dbg(&i2c->adap.dev,
+			"recovery: resetting controller, ISR=0x%08x\n", isr);
+		i2c_pxa_do_reset(i2c);
+	}
+
+	WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default));
+
+	dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n",
+	        readl(_IBMR(i2c)), readl(_ISR(i2c)));
+
+	i2c_pxa_enable(i2c);
+}
+
+static int i2c_pxa_init_recovery(struct pxa_i2c *i2c)
+{
+	struct i2c_bus_recovery_info *bri = &i2c->recovery;
+	struct device *dev = i2c->adap.dev.parent;
+
+	/*
+	 * When slave mode is enabled, we are not the only master on the bus.
+	 * Bus recovery can only be performed when we are the master, which
+	 * we can't be certain of. Therefore, when slave mode is enabled, do
+	 * not configure bus recovery.
+	 */
+	if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE))
+		return 0;
+
+	i2c->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(i2c->pinctrl))
+		return PTR_ERR(i2c->pinctrl);
+
+	if (!i2c->pinctrl)
+		return 0;
+
+	i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl,
+						    PINCTRL_STATE_DEFAULT);
+	i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery");
+
+	if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) {
+		dev_info(dev, "missing pinmux recovery information: %ld %ld\n",
+			 PTR_ERR(i2c->pinctrl_default),
+			 PTR_ERR(i2c->pinctrl_recovery));
+		return 0;
+	}
+
+	/*
+	 * Claiming GPIOs can influence the pinmux state, and may glitch the
+	 * I2C bus. Do this carefully.
+	 */
+	bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
+	if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER))
+		return -EPROBE_DEFER;
+	if (IS_ERR(bri->scl_gpiod)) {
+		dev_info(dev, "missing scl gpio recovery information: %pe\n",
+			 bri->scl_gpiod);
+		return 0;
+	}
+
+	/*
+	 * We have SCL. Pull SCL low and wait a bit so that SDA glitches
+	 * have no effect.
+	 */
+	gpiod_direction_output(bri->scl_gpiod, 0);
+	udelay(10);
+	bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN);
+
+	/* Wait a bit in case of a SDA glitch, and then release SCL. */
+	udelay(10);
+	gpiod_direction_output(bri->scl_gpiod, 1);
+
+	if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER))
+		return -EPROBE_DEFER;
+
+	if (IS_ERR(bri->sda_gpiod)) {
+		dev_info(dev, "missing sda gpio recovery information: %pe\n",
+			 bri->sda_gpiod);
+		return 0;
+	}
+
+	bri->prepare_recovery = i2c_pxa_prepare_recovery;
+	bri->unprepare_recovery = i2c_pxa_unprepare_recovery;
+	bri->recover_bus = i2c_generic_scl_recovery;
+
+	i2c->adap.bus_recovery_info = bri;
+
+	/*
+	 * Claiming GPIOs can change the pinmux state, which confuses the
+	 * pinctrl since since pinctrl's idea of the current setting is
+	 * unaffected by the pinmux change caused by claiming the GPIO.
+	 * Work around that by switching pinctrl to the GPIO state here.
+	 * We do it this way to avoid glitching the I2C bus.
+	 */
+	pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery);
+
+	return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default);
+}
+
 static int i2c_pxa_probe(struct platform_device *dev)
 {
 	struct i2c_pxa_platform_data *plat = dev_get_platdata(&dev->dev);
@@ -1289,6 +1429,16 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	if (!i2c)
 		return -ENOMEM;
 
+	/* Default adapter num to device id; i2c_pxa_probe_dt can override. */
+	i2c->adap.nr = dev->id;
+	i2c->adap.owner   = THIS_MODULE;
+	i2c->adap.retries = 5;
+	i2c->adap.algo_data = i2c;
+	i2c->adap.dev.parent = &dev->dev;
+#ifdef CONFIG_OF
+	i2c->adap.dev.of_node = dev->dev.of_node;
+#endif
+
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	i2c->reg_base = devm_ioremap_resource(&dev->dev, res);
 	if (IS_ERR(i2c->reg_base))
@@ -1298,8 +1448,9 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	if (irq < 0)
 		return irq;
 
-	/* Default adapter num to device id; i2c_pxa_probe_dt can override. */
-	i2c->adap.nr = dev->id;
+	ret = i2c_pxa_init_recovery(i2c);
+	if (ret)
+		return ret;
 
 	ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
 	if (ret > 0)
@@ -1307,9 +1458,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	if (ret < 0)
 		return ret;
 
-	i2c->adap.owner   = THIS_MODULE;
-	i2c->adap.retries = 5;
-
 	spin_lock_init(&i2c->lock);
 	init_waitqueue_head(&i2c->wait);
 
@@ -1375,12 +1523,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
 	i2c_pxa_reset(i2c);
 
-	i2c->adap.algo_data = i2c;
-	i2c->adap.dev.parent = &dev->dev;
-#ifdef CONFIG_OF
-	i2c->adap.dev.of_node = dev->dev.of_node;
-#endif
-
 	ret = i2c_add_numbered_adapter(&i2c->adap);
 	if (ret < 0)
 		goto ereqirq;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] arm64: dts: add uDPU i2c bus recovery
  2020-05-06  9:40 [PATCH 0/2] Add bus recovery to i2c-pxa Russell King - ARM Linux admin
  2020-05-06  9:40 ` [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery Russell King
@ 2020-05-06  9:40 ` Russell King
  2020-05-06 13:48   ` Andrew Lunn
  2020-05-17 16:10   ` Gregory CLEMENT
  1 sibling, 2 replies; 7+ messages in thread
From: Russell King @ 2020-05-06  9:40 UTC (permalink / raw)
  To: linux-i2c
  Cc: Andrew Lunn, devicetree, Gregory Clement, Jason Cooper,
	linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
	Vladimir Vid

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 .../boot/dts/marvell/armada-3720-uDPU.dts     | 22 +++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
index 7eb6c1796cef..95d46e8d081c 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
@@ -117,18 +117,36 @@
 	};
 };
 
+&pinctrl_nb {
+	i2c1_recovery_pins: i2c1-recovery-pins {
+		groups = "i2c1";
+		function = "gpio";
+	};
+
+	i2c2_recovery_pins: i2c2-recovery-pins {
+		groups = "i2c2";
+		function = "gpio";
+	};
+};
+
 &i2c0 {
 	status = "okay";
-	pinctrl-names = "default";
+	pinctrl-names = "default", "recovery";
 	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-1 = <&i2c1_recovery_pins>;
 	/delete-property/mrvl,i2c-fast-mode;
+	scl-gpios = <&gpionb 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpionb 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 };
 
 &i2c1 {
 	status = "okay";
-	pinctrl-names = "default";
+	pinctrl-names = "default", "recovery";
 	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_recovery_pins>;
 	/delete-property/mrvl,i2c-fast-mode;
+	scl-gpios = <&gpionb 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpionb 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 
 	lm75@48 {
 		status = "okay";
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] arm64: dts: add uDPU i2c bus recovery
  2020-05-06  9:40 ` [PATCH 2/2] arm64: dts: add uDPU " Russell King
@ 2020-05-06 13:48   ` Andrew Lunn
  2020-05-17 16:10   ` Gregory CLEMENT
  1 sibling, 0 replies; 7+ messages in thread
From: Andrew Lunn @ 2020-05-06 13:48 UTC (permalink / raw)
  To: Russell King
  Cc: linux-i2c, devicetree, Gregory Clement, Jason Cooper,
	linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
	Vladimir Vid

On Wed, May 06, 2020 at 10:40:37AM +0100, Russell King wrote:
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  .../boot/dts/marvell/armada-3720-uDPU.dts     | 22 +++++++++++++++++--

Hi Russell

Interesting that the 3720 uses pxa, not orion i2c. I had not noticed
that before.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery
  2020-05-06  9:40 ` [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery Russell King
@ 2020-05-06 14:00   ` Andrew Lunn
  2020-05-13  9:29     ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Lunn @ 2020-05-06 14:00 UTC (permalink / raw)
  To: Russell King
  Cc: linux-i2c, devicetree, Gregory Clement, Jason Cooper,
	linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
	Vladimir Vid

On Wed, May 06, 2020 at 10:40:31AM +0100, Russell King wrote:
> Implement generic GPIO-based I2C bus recovery for the PXA I2C driver.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/i2c/busses/i2c-pxa.c | 176 +++++++++++++++++++++++++++++++----
>  1 file changed, 159 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
> index 0e194d6cd1b5..da15ab2a519e 100644
> --- a/drivers/i2c/busses/i2c-pxa.c
> +++ b/drivers/i2c/busses/i2c-pxa.c
> @@ -20,6 +20,7 @@
>  #include <linux/delay.h>
>  #include <linux/err.h>
>  #include <linux/errno.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/i2c.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
> @@ -28,6 +29,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/i2c-pxa.h>
>  #include <linux/slab.h>
> @@ -260,6 +262,11 @@ struct pxa_i2c {
>  	bool			highmode_enter;
>  	u32			fm_mask;
>  	u32			hs_mask;
> +
> +	struct i2c_bus_recovery_info recovery;
> +	struct pinctrl		*pinctrl;
> +	struct pinctrl_state	*pinctrl_default;
> +	struct pinctrl_state	*pinctrl_recovery;
>  };
>  
>  #define _IBMR(i2c)	((i2c)->reg_ibmr)
> @@ -559,13 +566,8 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
>  #define i2c_pxa_set_slave(i2c, err)	do { } while (0)
>  #endif
>  
> -static void i2c_pxa_reset(struct pxa_i2c *i2c)
> +static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
>  {
> -	pr_debug("Resetting I2C Controller Unit\n");
> -
> -	/* abort any transfer currently under way */
> -	i2c_pxa_abort(i2c);
> -
>  	/* reset according to 9.8 */
>  	writel(ICR_UR, _ICR(i2c));
>  	writel(I2C_ISR_INIT, _ISR(i2c));
> @@ -584,12 +586,25 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
>  #endif
>  
>  	i2c_pxa_set_slave(i2c, 0);
> +}
>  
> +static void i2c_pxa_enable(struct pxa_i2c *i2c)
> +{
>  	/* enable unit */
>  	writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
>  	udelay(100);
>  }
>  
> +static void i2c_pxa_reset(struct pxa_i2c *i2c)
> +{
> +	pr_debug("Resetting I2C Controller Unit\n");

Hi Russell

I know you are just moving code around, but maybe pr_debug() could be
cleaned up to dev_debug()? 

> +	/*
> +	 * Claiming GPIOs can change the pinmux state, which confuses the
> +	 * pinctrl since since pinctrl's idea of the current setting is

since since

I don't know too much about this hardware, but for what it is worth,

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery
  2020-05-06 14:00   ` Andrew Lunn
@ 2020-05-13  9:29     ` Russell King - ARM Linux admin
  0 siblings, 0 replies; 7+ messages in thread
From: Russell King - ARM Linux admin @ 2020-05-13  9:29 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: linux-i2c, devicetree, Gregory Clement, Jason Cooper,
	linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
	Vladimir Vid

On Wed, May 06, 2020 at 04:00:54PM +0200, Andrew Lunn wrote:
> On Wed, May 06, 2020 at 10:40:31AM +0100, Russell King wrote:
> > Implement generic GPIO-based I2C bus recovery for the PXA I2C driver.
> > 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/i2c/busses/i2c-pxa.c | 176 +++++++++++++++++++++++++++++++----
> >  1 file changed, 159 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
> > index 0e194d6cd1b5..da15ab2a519e 100644
> > --- a/drivers/i2c/busses/i2c-pxa.c
> > +++ b/drivers/i2c/busses/i2c-pxa.c
> > @@ -20,6 +20,7 @@
> >  #include <linux/delay.h>
> >  #include <linux/err.h>
> >  #include <linux/errno.h>
> > +#include <linux/gpio/consumer.h>
> >  #include <linux/i2c.h>
> >  #include <linux/init.h>
> >  #include <linux/interrupt.h>
> > @@ -28,6 +29,7 @@
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> >  #include <linux/of_device.h>
> > +#include <linux/pinctrl/consumer.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/platform_data/i2c-pxa.h>
> >  #include <linux/slab.h>
> > @@ -260,6 +262,11 @@ struct pxa_i2c {
> >  	bool			highmode_enter;
> >  	u32			fm_mask;
> >  	u32			hs_mask;
> > +
> > +	struct i2c_bus_recovery_info recovery;
> > +	struct pinctrl		*pinctrl;
> > +	struct pinctrl_state	*pinctrl_default;
> > +	struct pinctrl_state	*pinctrl_recovery;
> >  };
> >  
> >  #define _IBMR(i2c)	((i2c)->reg_ibmr)
> > @@ -559,13 +566,8 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
> >  #define i2c_pxa_set_slave(i2c, err)	do { } while (0)
> >  #endif
> >  
> > -static void i2c_pxa_reset(struct pxa_i2c *i2c)
> > +static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
> >  {
> > -	pr_debug("Resetting I2C Controller Unit\n");
> > -
> > -	/* abort any transfer currently under way */
> > -	i2c_pxa_abort(i2c);
> > -
> >  	/* reset according to 9.8 */
> >  	writel(ICR_UR, _ICR(i2c));
> >  	writel(I2C_ISR_INIT, _ISR(i2c));
> > @@ -584,12 +586,25 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
> >  #endif
> >  
> >  	i2c_pxa_set_slave(i2c, 0);
> > +}
> >  
> > +static void i2c_pxa_enable(struct pxa_i2c *i2c)
> > +{
> >  	/* enable unit */
> >  	writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
> >  	udelay(100);
> >  }
> >  
> > +static void i2c_pxa_reset(struct pxa_i2c *i2c)
> > +{
> > +	pr_debug("Resetting I2C Controller Unit\n");
> 
> Hi Russell
> 
> I know you are just moving code around, but maybe pr_debug() could be
> cleaned up to dev_debug()? 

Yes, but I don't want to add irrelevant changes into this; changing
the way the driver prints stuff wouldn't be part of adding recovery
support, and would likely get review comments suggesting it should
be a separate patch.

> > +	/*
> > +	 * Claiming GPIOs can change the pinmux state, which confuses the
> > +	 * pinctrl since since pinctrl's idea of the current setting is
> 
> since since
> 
> I don't know too much about this hardware, but for what it is worth,
> 
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] arm64: dts: add uDPU i2c bus recovery
  2020-05-06  9:40 ` [PATCH 2/2] arm64: dts: add uDPU " Russell King
  2020-05-06 13:48   ` Andrew Lunn
@ 2020-05-17 16:10   ` Gregory CLEMENT
  1 sibling, 0 replies; 7+ messages in thread
From: Gregory CLEMENT @ 2020-05-17 16:10 UTC (permalink / raw)
  To: Russell King, linux-i2c
  Cc: Andrew Lunn, devicetree, Jason Cooper, linux-arm-kernel,
	Rob Herring, Sebastian Hesselbarth, Vladimir Vid

Hi Russell,

> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Applied on mvebu/dt64

Thanks,

Gregory


> ---
>  .../boot/dts/marvell/armada-3720-uDPU.dts     | 22 +++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
> index 7eb6c1796cef..95d46e8d081c 100644
> --- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
> +++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
> @@ -117,18 +117,36 @@
>  	};
>  };
>  
> +&pinctrl_nb {
> +	i2c1_recovery_pins: i2c1-recovery-pins {
> +		groups = "i2c1";
> +		function = "gpio";
> +	};
> +
> +	i2c2_recovery_pins: i2c2-recovery-pins {
> +		groups = "i2c2";
> +		function = "gpio";
> +	};
> +};
> +
>  &i2c0 {
>  	status = "okay";
> -	pinctrl-names = "default";
> +	pinctrl-names = "default", "recovery";
>  	pinctrl-0 = <&i2c1_pins>;
> +	pinctrl-1 = <&i2c1_recovery_pins>;
>  	/delete-property/mrvl,i2c-fast-mode;
> +	scl-gpios = <&gpionb 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	sda-gpios = <&gpionb 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>  };
>  
>  &i2c1 {
>  	status = "okay";
> -	pinctrl-names = "default";
> +	pinctrl-names = "default", "recovery";
>  	pinctrl-0 = <&i2c2_pins>;
> +	pinctrl-1 = <&i2c2_recovery_pins>;
>  	/delete-property/mrvl,i2c-fast-mode;
> +	scl-gpios = <&gpionb 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> +	sda-gpios = <&gpionb 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>  
>  	lm75@48 {
>  		status = "okay";
> -- 
> 2.20.1
>

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-05-17 16:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06  9:40 [PATCH 0/2] Add bus recovery to i2c-pxa Russell King - ARM Linux admin
2020-05-06  9:40 ` [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery Russell King
2020-05-06 14:00   ` Andrew Lunn
2020-05-13  9:29     ` Russell King - ARM Linux admin
2020-05-06  9:40 ` [PATCH 2/2] arm64: dts: add uDPU " Russell King
2020-05-06 13:48   ` Andrew Lunn
2020-05-17 16:10   ` Gregory CLEMENT

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).