b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From: Russell King <rmk+kernel@armlinux.org.uk> |
| 2 | Bcc: linux@mail.armlinux.org.uk |
| 3 | Subject: [PATCH 7/7] i2c: pxa: implement generic i2c bus recovery |
| 4 | MIME-Version: 1.0 |
| 5 | Content-Disposition: inline |
| 6 | Content-Transfer-Encoding: 8bit |
| 7 | Content-Type: text/plain; charset="utf-8" |
| 8 | |
| 9 | Implement generic GPIO-based I2C bus recovery for the PXA I2C driver. |
| 10 | |
| 11 | Reviewed-by: Andrew Lunn <andrew@lunn.ch> |
| 12 | Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> |
| 13 | --- |
| 14 | drivers/i2c/busses/i2c-pxa.c | 176 +++++++++++++++++++++++++++++++---- |
| 15 | 1 file changed, 159 insertions(+), 17 deletions(-) |
| 16 | |
| 17 | --- a/drivers/i2c/busses/i2c-pxa.c |
| 18 | +++ b/drivers/i2c/busses/i2c-pxa.c |
| 19 | @@ -20,6 +20,7 @@ |
| 20 | #include <linux/delay.h> |
| 21 | #include <linux/err.h> |
| 22 | #include <linux/errno.h> |
| 23 | +#include <linux/gpio/consumer.h> |
| 24 | #include <linux/i2c.h> |
| 25 | #include <linux/i2c-pxa.h> |
| 26 | #include <linux/init.h> |
| 27 | @@ -29,6 +30,7 @@ |
| 28 | #include <linux/module.h> |
| 29 | #include <linux/of.h> |
| 30 | #include <linux/of_device.h> |
| 31 | +#include <linux/pinctrl/consumer.h> |
| 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/platform_data/i2c-pxa.h> |
| 34 | #include <linux/slab.h> |
| 35 | @@ -261,6 +263,11 @@ struct pxa_i2c { |
| 36 | bool highmode_enter; |
| 37 | u32 fm_mask; |
| 38 | u32 hs_mask; |
| 39 | + |
| 40 | + struct i2c_bus_recovery_info recovery; |
| 41 | + struct pinctrl *pinctrl; |
| 42 | + struct pinctrl_state *pinctrl_default; |
| 43 | + struct pinctrl_state *pinctrl_recovery; |
| 44 | }; |
| 45 | |
| 46 | #define _IBMR(i2c) ((i2c)->reg_ibmr) |
| 47 | @@ -560,13 +567,8 @@ static void i2c_pxa_set_slave(struct pxa |
| 48 | #define i2c_pxa_set_slave(i2c, err) do { } while (0) |
| 49 | #endif |
| 50 | |
| 51 | -static void i2c_pxa_reset(struct pxa_i2c *i2c) |
| 52 | +static void i2c_pxa_do_reset(struct pxa_i2c *i2c) |
| 53 | { |
| 54 | - pr_debug("Resetting I2C Controller Unit\n"); |
| 55 | - |
| 56 | - /* abort any transfer currently under way */ |
| 57 | - i2c_pxa_abort(i2c); |
| 58 | - |
| 59 | /* reset according to 9.8 */ |
| 60 | writel(ICR_UR, _ICR(i2c)); |
| 61 | writel(I2C_ISR_INIT, _ISR(i2c)); |
| 62 | @@ -585,12 +587,25 @@ static void i2c_pxa_reset(struct pxa_i2c |
| 63 | #endif |
| 64 | |
| 65 | i2c_pxa_set_slave(i2c, 0); |
| 66 | +} |
| 67 | |
| 68 | +static void i2c_pxa_enable(struct pxa_i2c *i2c) |
| 69 | +{ |
| 70 | /* enable unit */ |
| 71 | writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c)); |
| 72 | udelay(100); |
| 73 | } |
| 74 | |
| 75 | +static void i2c_pxa_reset(struct pxa_i2c *i2c) |
| 76 | +{ |
| 77 | + pr_debug("Resetting I2C Controller Unit\n"); |
| 78 | + |
| 79 | + /* abort any transfer currently under way */ |
| 80 | + i2c_pxa_abort(i2c); |
| 81 | + i2c_pxa_do_reset(i2c); |
| 82 | + i2c_pxa_enable(i2c); |
| 83 | +} |
| 84 | + |
| 85 | |
| 86 | #ifdef CONFIG_I2C_PXA_SLAVE |
| 87 | /* |
| 88 | @@ -1002,6 +1017,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2 |
| 89 | ret = i2c_pxa_wait_bus_not_busy(i2c); |
| 90 | if (ret) { |
| 91 | dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n"); |
| 92 | + i2c_recover_bus(&i2c->adap); |
| 93 | goto out; |
| 94 | } |
| 95 | |
| 96 | @@ -1047,6 +1063,7 @@ static int i2c_pxa_do_xfer(struct pxa_i2 |
| 97 | |
| 98 | if (!timeout && i2c->msg_num) { |
| 99 | i2c_pxa_scream_blue_murder(i2c, "timeout with active message"); |
| 100 | + i2c_recover_bus(&i2c->adap); |
| 101 | ret = I2C_RETRY; |
| 102 | } |
| 103 | |
| 104 | @@ -1228,6 +1245,129 @@ static int i2c_pxa_probe_pdata(struct pl |
| 105 | return 0; |
| 106 | } |
| 107 | |
| 108 | +static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap) |
| 109 | +{ |
| 110 | + struct pxa_i2c *i2c = adap->algo_data; |
| 111 | + u32 ibmr = readl(_IBMR(i2c)); |
| 112 | + |
| 113 | + /* |
| 114 | + * Program the GPIOs to reflect the current I2C bus state while |
| 115 | + * we transition to recovery; this avoids glitching the bus. |
| 116 | + */ |
| 117 | + gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS); |
| 118 | + gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS); |
| 119 | + |
| 120 | + WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery)); |
| 121 | +} |
| 122 | + |
| 123 | +static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) |
| 124 | +{ |
| 125 | + struct pxa_i2c *i2c = adap->algo_data; |
| 126 | + u32 isr; |
| 127 | + |
| 128 | + /* |
| 129 | + * The bus should now be free. Clear up the I2C controller before |
| 130 | + * handing control of the bus back to avoid the bus changing state. |
| 131 | + */ |
| 132 | + isr = readl(_ISR(i2c)); |
| 133 | + if (isr & (ISR_UB | ISR_IBB)) { |
| 134 | + dev_dbg(&i2c->adap.dev, |
| 135 | + "recovery: resetting controller, ISR=0x%08x\n", isr); |
| 136 | + i2c_pxa_do_reset(i2c); |
| 137 | + } |
| 138 | + |
| 139 | + WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default)); |
| 140 | + |
| 141 | + dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n", |
| 142 | + readl(_IBMR(i2c)), readl(_ISR(i2c))); |
| 143 | + |
| 144 | + i2c_pxa_enable(i2c); |
| 145 | +} |
| 146 | + |
| 147 | +static int i2c_pxa_init_recovery(struct pxa_i2c *i2c) |
| 148 | +{ |
| 149 | + struct i2c_bus_recovery_info *bri = &i2c->recovery; |
| 150 | + struct device *dev = i2c->adap.dev.parent; |
| 151 | + |
| 152 | + /* |
| 153 | + * When slave mode is enabled, we are not the only master on the bus. |
| 154 | + * Bus recovery can only be performed when we are the master, which |
| 155 | + * we can't be certain of. Therefore, when slave mode is enabled, do |
| 156 | + * not configure bus recovery. |
| 157 | + */ |
| 158 | + if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE)) |
| 159 | + return 0; |
| 160 | + |
| 161 | + i2c->pinctrl = devm_pinctrl_get(dev); |
| 162 | + if (IS_ERR(i2c->pinctrl)) |
| 163 | + return PTR_ERR(i2c->pinctrl); |
| 164 | + |
| 165 | + if (!i2c->pinctrl) |
| 166 | + return 0; |
| 167 | + |
| 168 | + i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl, |
| 169 | + PINCTRL_STATE_DEFAULT); |
| 170 | + i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery"); |
| 171 | + |
| 172 | + if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) { |
| 173 | + dev_info(dev, "missing pinmux recovery information: %ld %ld\n", |
| 174 | + PTR_ERR(i2c->pinctrl_default), |
| 175 | + PTR_ERR(i2c->pinctrl_recovery)); |
| 176 | + return 0; |
| 177 | + } |
| 178 | + |
| 179 | + /* |
| 180 | + * Claiming GPIOs can influence the pinmux state, and may glitch the |
| 181 | + * I2C bus. Do this carefully. |
| 182 | + */ |
| 183 | + bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN); |
| 184 | + if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER)) |
| 185 | + return -EPROBE_DEFER; |
| 186 | + if (IS_ERR(bri->scl_gpiod)) { |
| 187 | + dev_info(dev, "missing scl gpio recovery information: %pe\n", |
| 188 | + bri->scl_gpiod); |
| 189 | + return 0; |
| 190 | + } |
| 191 | + |
| 192 | + /* |
| 193 | + * We have SCL. Pull SCL low and wait a bit so that SDA glitches |
| 194 | + * have no effect. |
| 195 | + */ |
| 196 | + gpiod_direction_output(bri->scl_gpiod, 0); |
| 197 | + udelay(10); |
| 198 | + bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN); |
| 199 | + |
| 200 | + /* Wait a bit in case of a SDA glitch, and then release SCL. */ |
| 201 | + udelay(10); |
| 202 | + gpiod_direction_output(bri->scl_gpiod, 1); |
| 203 | + |
| 204 | + if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER)) |
| 205 | + return -EPROBE_DEFER; |
| 206 | + |
| 207 | + if (IS_ERR(bri->sda_gpiod)) { |
| 208 | + dev_info(dev, "missing sda gpio recovery information: %pe\n", |
| 209 | + bri->sda_gpiod); |
| 210 | + return 0; |
| 211 | + } |
| 212 | + |
| 213 | + bri->prepare_recovery = i2c_pxa_prepare_recovery; |
| 214 | + bri->unprepare_recovery = i2c_pxa_unprepare_recovery; |
| 215 | + bri->recover_bus = i2c_generic_scl_recovery; |
| 216 | + |
| 217 | + i2c->adap.bus_recovery_info = bri; |
| 218 | + |
| 219 | + /* |
| 220 | + * Claiming GPIOs can change the pinmux state, which confuses the |
| 221 | + * pinctrl since pinctrl's idea of the current setting is unaffected |
| 222 | + * by the pinmux change caused by claiming the GPIO. Work around that |
| 223 | + * by switching pinctrl to the GPIO state here. We do it this way to |
| 224 | + * avoid glitching the I2C bus. |
| 225 | + */ |
| 226 | + pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery); |
| 227 | + |
| 228 | + return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default); |
| 229 | +} |
| 230 | + |
| 231 | static int i2c_pxa_probe(struct platform_device *dev) |
| 232 | { |
| 233 | struct i2c_pxa_platform_data *plat = dev_get_platdata(&dev->dev); |
| 234 | @@ -1240,6 +1380,16 @@ static int i2c_pxa_probe(struct platform |
| 235 | if (!i2c) |
| 236 | return -ENOMEM; |
| 237 | |
| 238 | + /* Default adapter num to device id; i2c_pxa_probe_dt can override. */ |
| 239 | + i2c->adap.nr = dev->id; |
| 240 | + i2c->adap.owner = THIS_MODULE; |
| 241 | + i2c->adap.retries = 5; |
| 242 | + i2c->adap.algo_data = i2c; |
| 243 | + i2c->adap.dev.parent = &dev->dev; |
| 244 | +#ifdef CONFIG_OF |
| 245 | + i2c->adap.dev.of_node = dev->dev.of_node; |
| 246 | +#endif |
| 247 | + |
| 248 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
| 249 | i2c->reg_base = devm_ioremap_resource(&dev->dev, res); |
| 250 | if (IS_ERR(i2c->reg_base)) |
| 251 | @@ -1251,8 +1401,9 @@ static int i2c_pxa_probe(struct platform |
| 252 | return irq; |
| 253 | } |
| 254 | |
| 255 | - /* Default adapter num to device id; i2c_pxa_probe_dt can override. */ |
| 256 | - i2c->adap.nr = dev->id; |
| 257 | + ret = i2c_pxa_init_recovery(i2c); |
| 258 | + if (ret) |
| 259 | + return ret; |
| 260 | |
| 261 | ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type); |
| 262 | if (ret > 0) |
| 263 | @@ -1260,9 +1411,6 @@ static int i2c_pxa_probe(struct platform |
| 264 | if (ret < 0) |
| 265 | return ret; |
| 266 | |
| 267 | - i2c->adap.owner = THIS_MODULE; |
| 268 | - i2c->adap.retries = 5; |
| 269 | - |
| 270 | spin_lock_init(&i2c->lock); |
| 271 | init_waitqueue_head(&i2c->wait); |
| 272 | |
| 273 | @@ -1332,12 +1480,6 @@ static int i2c_pxa_probe(struct platform |
| 274 | |
| 275 | i2c_pxa_reset(i2c); |
| 276 | |
| 277 | - i2c->adap.algo_data = i2c; |
| 278 | - i2c->adap.dev.parent = &dev->dev; |
| 279 | -#ifdef CONFIG_OF |
| 280 | - i2c->adap.dev.of_node = dev->dev.of_node; |
| 281 | -#endif |
| 282 | - |
| 283 | ret = i2c_add_numbered_adapter(&i2c->adap); |
| 284 | if (ret < 0) |
| 285 | goto ereqirq; |