Commit 5a4de7dc authored by Linus Torvalds's avatar Linus Torvalds

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
parents eb72d520 59851fb0
...@@ -441,8 +441,25 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) ...@@ -441,8 +441,25 @@ int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
void __i2c_dw_disable(struct dw_i2c_dev *dev) void __i2c_dw_disable(struct dw_i2c_dev *dev)
{ {
unsigned int raw_intr_stats;
unsigned int enable;
int timeout = 100; int timeout = 100;
bool abort_needed;
unsigned int status; unsigned int status;
int ret;
regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats);
regmap_read(dev->map, DW_IC_ENABLE, &enable);
abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD;
if (abort_needed) {
regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT);
ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable,
!(enable & DW_IC_ENABLE_ABORT), 10,
100);
if (ret)
dev_err(dev->dev, "timeout while trying to abort current transfer\n");
}
do { do {
__i2c_dw_disable_nowait(dev); __i2c_dw_disable_nowait(dev);
......
...@@ -98,6 +98,7 @@ ...@@ -98,6 +98,7 @@
#define DW_IC_INTR_START_DET BIT(10) #define DW_IC_INTR_START_DET BIT(10)
#define DW_IC_INTR_GEN_CALL BIT(11) #define DW_IC_INTR_GEN_CALL BIT(11)
#define DW_IC_INTR_RESTART_DET BIT(12) #define DW_IC_INTR_RESTART_DET BIT(12)
#define DW_IC_INTR_MST_ON_HOLD BIT(13)
#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
DW_IC_INTR_TX_ABRT | \ DW_IC_INTR_TX_ABRT | \
...@@ -108,6 +109,8 @@ ...@@ -108,6 +109,8 @@
DW_IC_INTR_RX_UNDER | \ DW_IC_INTR_RX_UNDER | \
DW_IC_INTR_RD_REQ) DW_IC_INTR_RD_REQ)
#define DW_IC_ENABLE_ABORT BIT(1)
#define DW_IC_STATUS_ACTIVITY BIT(0) #define DW_IC_STATUS_ACTIVITY BIT(0)
#define DW_IC_STATUS_TFE BIT(2) #define DW_IC_STATUS_TFE BIT(2)
#define DW_IC_STATUS_RFNE BIT(3) #define DW_IC_STATUS_RFNE BIT(3)
......
...@@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
"SMBus I801 adapter at %04lx", priv->smba); "SMBus I801 adapter at %04lx", priv->smba);
err = i2c_add_adapter(&priv->adapter); err = i2c_add_adapter(&priv->adapter);
if (err) { if (err) {
platform_device_unregister(priv->tco_pdev);
i801_acpi_remove(priv); i801_acpi_remove(priv);
return err; return err;
} }
......
...@@ -710,7 +710,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) ...@@ -710,7 +710,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
* reset the IP instead of just flush fifos * reset the IP instead of just flush fifos
*/ */
ret = xiic_reinit(i2c); ret = xiic_reinit(i2c);
if (!ret) if (ret < 0)
dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); dev_dbg(i2c->adap.dev.parent, "reinit failed\n");
if (i2c->rx_msg) { if (i2c->rx_msg) {
......
...@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) ...@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
if (!props[i].name || !props[i].value) {
err = -ENOMEM;
goto err_rollback;
}
props[i].length = 3; props[i].length = 3;
of_changeset_init(&priv->chan[i].chgset); of_changeset_init(&priv->chan[i].chgset);
......
...@@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, ...@@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux,
} else if (is_acpi_node(child)) { } else if (is_acpi_node(child)) {
rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i);
if (rc) if (rc) {
fwnode_handle_put(child);
return dev_err_probe(dev, rc, "Cannot get address\n"); return dev_err_probe(dev, rc, "Cannot get address\n");
}
} }
i++; i++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment