Skip to content

Commit 23dfa04

Browse files
committed
Merge tag 'i2c-for-6.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Revert a not-working conversion to generic recovery for PXA, use proper IO accessors for designware, and use proper PM level for ocores to allow accessing interrupt providers late" * tag 'i2c-for-6.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: ocores: Move system PM hooks to the NOIRQ phase i2c: designware: Fix corrupted memory seen in the ISR Revert "i2c: pxa: move to generic GPIO recovery"
2 parents 9ea991a + 382561d commit 23dfa04

File tree

3 files changed

+78
-18
lines changed

3 files changed

+78
-18
lines changed

drivers/i2c/busses/i2c-designware-common.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static int dw_reg_read(void *context, unsigned int reg, unsigned int *val)
6363
{
6464
struct dw_i2c_dev *dev = context;
6565

66-
*val = readl_relaxed(dev->base + reg);
66+
*val = readl(dev->base + reg);
6767

6868
return 0;
6969
}
@@ -72,7 +72,7 @@ static int dw_reg_write(void *context, unsigned int reg, unsigned int val)
7272
{
7373
struct dw_i2c_dev *dev = context;
7474

75-
writel_relaxed(val, dev->base + reg);
75+
writel(val, dev->base + reg);
7676

7777
return 0;
7878
}
@@ -81,7 +81,7 @@ static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val)
8181
{
8282
struct dw_i2c_dev *dev = context;
8383

84-
*val = swab32(readl_relaxed(dev->base + reg));
84+
*val = swab32(readl(dev->base + reg));
8585

8686
return 0;
8787
}
@@ -90,7 +90,7 @@ static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val)
9090
{
9191
struct dw_i2c_dev *dev = context;
9292

93-
writel_relaxed(swab32(val), dev->base + reg);
93+
writel(swab32(val), dev->base + reg);
9494

9595
return 0;
9696
}
@@ -99,8 +99,8 @@ static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val)
9999
{
100100
struct dw_i2c_dev *dev = context;
101101

102-
*val = readw_relaxed(dev->base + reg) |
103-
(readw_relaxed(dev->base + reg + 2) << 16);
102+
*val = readw(dev->base + reg) |
103+
(readw(dev->base + reg + 2) << 16);
104104

105105
return 0;
106106
}
@@ -109,8 +109,8 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val)
109109
{
110110
struct dw_i2c_dev *dev = context;
111111

112-
writew_relaxed(val, dev->base + reg);
113-
writew_relaxed(val >> 16, dev->base + reg + 2);
112+
writew(val, dev->base + reg);
113+
writew(val >> 16, dev->base + reg + 2);
114114

115115
return 0;
116116
}

drivers/i2c/busses/i2c-ocores.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,8 @@ static int ocores_i2c_resume(struct device *dev)
771771
return ocores_init(dev, i2c);
772772
}
773773

774-
static DEFINE_SIMPLE_DEV_PM_OPS(ocores_i2c_pm,
775-
ocores_i2c_suspend, ocores_i2c_resume);
774+
static DEFINE_NOIRQ_DEV_PM_OPS(ocores_i2c_pm,
775+
ocores_i2c_suspend, ocores_i2c_resume);
776776

777777
static struct platform_driver ocores_i2c_driver = {
778778
.probe = ocores_i2c_probe,

drivers/i2c/busses/i2c-pxa.c

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ struct pxa_i2c {
265265
u32 hs_mask;
266266

267267
struct i2c_bus_recovery_info recovery;
268+
struct pinctrl *pinctrl;
269+
struct pinctrl_state *pinctrl_default;
270+
struct pinctrl_state *pinctrl_recovery;
268271
};
269272

270273
#define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -1299,12 +1302,13 @@ static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap)
12991302
*/
13001303
gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS);
13011304
gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS);
1305+
1306+
WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery));
13021307
}
13031308

13041309
static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
13051310
{
13061311
struct pxa_i2c *i2c = adap->algo_data;
1307-
struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
13081312
u32 isr;
13091313

13101314
/*
@@ -1318,7 +1322,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
13181322
i2c_pxa_do_reset(i2c);
13191323
}
13201324

1321-
WARN_ON(pinctrl_select_state(bri->pinctrl, bri->pins_default));
1325+
WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default));
13221326

13231327
dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n",
13241328
readl(_IBMR(i2c)), readl(_ISR(i2c)));
@@ -1340,20 +1344,76 @@ static int i2c_pxa_init_recovery(struct pxa_i2c *i2c)
13401344
if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE))
13411345
return 0;
13421346

1343-
bri->pinctrl = devm_pinctrl_get(dev);
1344-
if (PTR_ERR(bri->pinctrl) == -ENODEV) {
1345-
bri->pinctrl = NULL;
1347+
i2c->pinctrl = devm_pinctrl_get(dev);
1348+
if (PTR_ERR(i2c->pinctrl) == -ENODEV)
1349+
i2c->pinctrl = NULL;
1350+
if (IS_ERR(i2c->pinctrl))
1351+
return PTR_ERR(i2c->pinctrl);
1352+
1353+
if (!i2c->pinctrl)
1354+
return 0;
1355+
1356+
i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl,
1357+
PINCTRL_STATE_DEFAULT);
1358+
i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery");
1359+
1360+
if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) {
1361+
dev_info(dev, "missing pinmux recovery information: %ld %ld\n",
1362+
PTR_ERR(i2c->pinctrl_default),
1363+
PTR_ERR(i2c->pinctrl_recovery));
1364+
return 0;
1365+
}
1366+
1367+
/*
1368+
* Claiming GPIOs can influence the pinmux state, and may glitch the
1369+
* I2C bus. Do this carefully.
1370+
*/
1371+
bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
1372+
if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER))
1373+
return -EPROBE_DEFER;
1374+
if (IS_ERR(bri->scl_gpiod)) {
1375+
dev_info(dev, "missing scl gpio recovery information: %pe\n",
1376+
bri->scl_gpiod);
1377+
return 0;
1378+
}
1379+
1380+
/*
1381+
* We have SCL. Pull SCL low and wait a bit so that SDA glitches
1382+
* have no effect.
1383+
*/
1384+
gpiod_direction_output(bri->scl_gpiod, 0);
1385+
udelay(10);
1386+
bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN);
1387+
1388+
/* Wait a bit in case of a SDA glitch, and then release SCL. */
1389+
udelay(10);
1390+
gpiod_direction_output(bri->scl_gpiod, 1);
1391+
1392+
if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER))
1393+
return -EPROBE_DEFER;
1394+
1395+
if (IS_ERR(bri->sda_gpiod)) {
1396+
dev_info(dev, "missing sda gpio recovery information: %pe\n",
1397+
bri->sda_gpiod);
13461398
return 0;
13471399
}
1348-
if (IS_ERR(bri->pinctrl))
1349-
return PTR_ERR(bri->pinctrl);
13501400

13511401
bri->prepare_recovery = i2c_pxa_prepare_recovery;
13521402
bri->unprepare_recovery = i2c_pxa_unprepare_recovery;
1403+
bri->recover_bus = i2c_generic_scl_recovery;
13531404

13541405
i2c->adap.bus_recovery_info = bri;
13551406

1356-
return 0;
1407+
/*
1408+
* Claiming GPIOs can change the pinmux state, which confuses the
1409+
* pinctrl since pinctrl's idea of the current setting is unaffected
1410+
* by the pinmux change caused by claiming the GPIO. Work around that
1411+
* by switching pinctrl to the GPIO state here. We do it this way to
1412+
* avoid glitching the I2C bus.
1413+
*/
1414+
pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery);
1415+
1416+
return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default);
13571417
}
13581418

13591419
static int i2c_pxa_probe(struct platform_device *dev)

0 commit comments

Comments
 (0)