Skip to content

Commit 5a4de7d

Browse files
committed
Merge tag 'i2c-for-6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "A set of I2C driver fixes. Mostly fixing resource leaks or sanity checks" * tag 'i2c-for-6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: xiic: Correct return value check for xiic_reinit() i2c: mux: gpio: Add missing fwnode_handle_put() i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() i2c: designware: fix __i2c_dw_disable() in case master is holding SCL low i2c: i801: unregister tco_pdev in i801_probe() error path
2 parents eb72d52 + 59851fb commit 5a4de7d

File tree

6 files changed

+29
-2
lines changed

6 files changed

+29
-2
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,25 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
441441

442442
void __i2c_dw_disable(struct dw_i2c_dev *dev)
443443
{
444+
unsigned int raw_intr_stats;
445+
unsigned int enable;
444446
int timeout = 100;
447+
bool abort_needed;
445448
unsigned int status;
449+
int ret;
450+
451+
regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats);
452+
regmap_read(dev->map, DW_IC_ENABLE, &enable);
453+
454+
abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD;
455+
if (abort_needed) {
456+
regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT);
457+
ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable,
458+
!(enable & DW_IC_ENABLE_ABORT), 10,
459+
100);
460+
if (ret)
461+
dev_err(dev->dev, "timeout while trying to abort current transfer\n");
462+
}
446463

447464
do {
448465
__i2c_dw_disable_nowait(dev);

drivers/i2c/busses/i2c-designware-core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
#define DW_IC_INTR_START_DET BIT(10)
9999
#define DW_IC_INTR_GEN_CALL BIT(11)
100100
#define DW_IC_INTR_RESTART_DET BIT(12)
101+
#define DW_IC_INTR_MST_ON_HOLD BIT(13)
101102

102103
#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
103104
DW_IC_INTR_TX_ABRT | \
@@ -108,6 +109,8 @@
108109
DW_IC_INTR_RX_UNDER | \
109110
DW_IC_INTR_RD_REQ)
110111

112+
#define DW_IC_ENABLE_ABORT BIT(1)
113+
111114
#define DW_IC_STATUS_ACTIVITY BIT(0)
112115
#define DW_IC_STATUS_TFE BIT(2)
113116
#define DW_IC_STATUS_RFNE BIT(3)

drivers/i2c/busses/i2c-i801.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
17541754
"SMBus I801 adapter at %04lx", priv->smba);
17551755
err = i2c_add_adapter(&priv->adapter);
17561756
if (err) {
1757+
platform_device_unregister(priv->tco_pdev);
17571758
i801_acpi_remove(priv);
17581759
return err;
17591760
}

drivers/i2c/busses/i2c-xiic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
710710
* reset the IP instead of just flush fifos
711711
*/
712712
ret = xiic_reinit(i2c);
713-
if (!ret)
713+
if (ret < 0)
714714
dev_dbg(i2c->adap.dev.parent, "reinit failed\n");
715715

716716
if (i2c->rx_msg) {

drivers/i2c/muxes/i2c-demux-pinctrl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
243243

244244
props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
245245
props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
246+
if (!props[i].name || !props[i].value) {
247+
err = -ENOMEM;
248+
goto err_rollback;
249+
}
246250
props[i].length = 3;
247251

248252
of_changeset_init(&priv->chan[i].chgset);

drivers/i2c/muxes/i2c-mux-gpio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
105105

106106
} else if (is_acpi_node(child)) {
107107
rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i);
108-
if (rc)
108+
if (rc) {
109+
fwnode_handle_put(child);
109110
return dev_err_probe(dev, rc, "Cannot get address\n");
111+
}
110112
}
111113

112114
i++;

0 commit comments

Comments
 (0)