Merge tag 'i2c-7.3-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux

Pull more i2c updates from Andi Shyti:
 "Fixes and cleanups around probe error handling, resource management
  and a minor Rust cleanup.

  Drivers:
   - several drivers: drop duplicate IRQ error reporting
   - imx-lpi2c: improve probe initialization and error cleanup
   - mxs: fix DMA channel leak on probe failure
   - ocores: fix clock cleanup on resume failure
   - rcar: handle reset controllers without status support

  Muxes:
   - demux-pinctrl: fix OF node leak on allocation failure

  Rust:
   - mark trivial I2cAdapter reference-counting methods inline"

* tag 'i2c-7.3-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux:
  i2c: rust: mark I2cAdapter methods as inline
  i2c: rcar: fix reset handling for Gen5
  i2c: mxs: fix DMA channel leak on probe error
  i2c: mux: demux-pinctrl: fix OF node leak on kstrdup failure
  i2c: ocores: Disable clock on failed resume
  i2c: imx-lpi2c: reset controller in probe stage
  i2c: imx-lpi2c: properly unwind resources on probe failure
  i2c: busses: drop redundant dev_err_probe() around irq helpers
This commit is contained in:
Linus Torvalds
2026-08-24 09:07:15 -07:00
30 changed files with 78 additions and 74 deletions

View File

@@ -337,11 +337,11 @@ static int amd_asf_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return dev_err_probe(dev, irq, "missing IRQ resources\n");
return irq;
ret = devm_request_irq(dev, irq, amd_asf_irq_handler, IRQF_SHARED, "amd_asf", asf_dev);
if (ret)
return dev_err_probe(dev, ret, "Unable to request irq: %d for use\n", irq);
return ret;
asf_dev->adap.owner = THIS_MODULE;
asf_dev->adap.algo = &amd_asf_smbus_algorithm;

View File

@@ -1147,8 +1147,7 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
bcm_iproc_i2c_isr, 0, pdev->name,
iproc_i2c);
if (ret < 0)
return dev_err_probe(iproc_i2c->device, ret,
"unable to request irq %i\n", irq);
return ret;
iproc_i2c->irq = irq;
} else {

View File

@@ -551,7 +551,7 @@ static int gxp_i2c_probe(struct platform_device *pdev)
rc = devm_request_irq(&pdev->dev, drvdata->irq, gxp_i2c_irq_handler,
IRQF_SHARED, gxp_i2c_name[drvdata->engine], drvdata);
if (rc < 0)
return dev_err_probe(&pdev->dev, rc, "irq request failed\n");
return rc;
i2c_parse_fw_timings(&pdev->dev, &drvdata->t, true);

View File

@@ -481,7 +481,7 @@ static int hisi_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, ctlr->irq, hisi_i2c_irq, 0, "hisi-i2c", ctlr);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq handler\n");
return ret;
ctlr->clk = devm_clk_get_optional_enabled(&pdev->dev, NULL);
if (IS_ERR_OR_NULL(ctlr->clk)) {

View File

@@ -1510,11 +1510,6 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (ret)
lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ;
ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
pdev->name, lpi2c_imx);
if (ret)
return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq);
i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);
platform_set_drvdata(pdev, lpi2c_imx);
@@ -1527,14 +1522,18 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
* each transfer
*/
ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"can't lock I2C peripheral clock rate\n");
if (ret) {
ret = dev_err_probe(&pdev->dev, ret,
"can't lock I2C peripheral clock rate\n");
goto clk_disable;
}
lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
if (!lpi2c_imx->rate_per)
return dev_err_probe(&pdev->dev, -EINVAL,
"can't get I2C peripheral clock rate\n");
if (!lpi2c_imx->rate_per) {
ret = dev_err_probe(&pdev->dev, -EINVAL,
"can't get I2C peripheral clock rate\n");
goto clk_disable;
}
if (lpi2c_imx->hwdata->need_prepare_unprepare_clk)
pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_LONG_TIMEOUT_MS);
@@ -1546,6 +1545,20 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
/*
* Reset all internal controller registers of both Master and Target
* to avoid effects of previous status.
*/
writel(MCR_RST, lpi2c_imx->base + LPI2C_MCR);
writel(SCR_RST, lpi2c_imx->base + LPI2C_SCR);
writel(0, lpi2c_imx->base + LPI2C_MCR);
writel(0, lpi2c_imx->base + LPI2C_SCR);
ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
pdev->name, lpi2c_imx);
if (ret)
goto rpm_disable;
temp = readl(lpi2c_imx->base + LPI2C_PARAM);
lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
@@ -1576,8 +1589,11 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
rpm_disable:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
clk_disable:
clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks);
return ret;
}

View File

@@ -1753,7 +1753,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return dev_err_probe(&pdev->dev, irq, "can't get IRQ\n");
return irq;
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(base))

View File

@@ -852,7 +852,7 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
i2c->irq = platform_get_irq(pdev, 0);
if (i2c->irq < 0)
return dev_err_probe(dev, i2c->irq, "failed to get irq resource");
return i2c->irq;
clk = devm_clk_get_enabled(dev, "func");
if (IS_ERR(clk))
@@ -906,7 +906,7 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
IRQF_NO_SUSPEND, dev_name(i2c->dev), i2c);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq");
return ret;
platform_set_drvdata(pdev, i2c);

View File

@@ -323,7 +323,7 @@ static int ls2x_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, ls2x_i2c_isr, IRQF_SHARED, "ls2x-i2c",
priv);
if (ret < 0)
return dev_err_probe(dev, ret, "Unable to request irq %d\n", irq);
return ret;
return devm_i2c_add_adapter(dev, adap);
}

View File

@@ -581,8 +581,7 @@ static int mchp_corei2c_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq, mchp_corei2c_isr, IRQF_SHARED,
pdev->name, idev);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"failed to claim irq %d\n", irq);
return ret;
ret = clk_prepare_enable(idev->i2c_clk);
if (ret)

View File

@@ -2350,7 +2350,7 @@ static int mlxbf_i2c_probe(struct platform_device *pdev)
IRQF_SHARED | IRQF_PROBE_SHARED,
dev_name(dev), priv);
if (ret < 0)
return dev_err_probe(dev, ret, "Cannot get irq %d\n", irq);
return ret;
priv->irq = irq;

View File

@@ -839,7 +839,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
}
/* Setup the DMA */
i2c->dmach = dma_request_chan(dev, "rx-tx");
i2c->dmach = devm_dma_request_chan(dev, "rx-tx");
if (IS_ERR(i2c->dmach)) {
return dev_err_probe(dev, PTR_ERR(i2c->dmach),
"Failed to request dma\n");
@@ -877,9 +877,6 @@ static void mxs_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&i2c->adapter);
if (i2c->dmach)
dma_release_channel(i2c->dmach);
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
}

View File

@@ -1137,8 +1137,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
ret = devm_request_irq(dev, priv->irq, i2c_irq_handler, 0,
DRIVER_NAME, priv);
if (ret)
return dev_err_probe(dev, ret,
"cannot claim the irq %d\n", priv->irq);
return ret;
priv->clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(priv->clk))

View File

@@ -755,7 +755,11 @@ static int ocores_i2c_resume(struct device *dev)
rate = clk_get_rate(i2c->clk) / 1000;
if (rate)
i2c->ip_clock_khz = rate;
return ocores_init(dev, i2c);
ret = ocores_init(dev, i2c);
if (ret)
clk_disable_unprepare(i2c->clk);
return ret;
}
static DEFINE_NOIRQ_DEV_PM_OPS(ocores_i2c_pm,

View File

@@ -1169,8 +1169,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, IRQF_NO_AUTOEN,
dev_name(dev), gi2c);
if (ret)
return dev_err_probe(dev, ret,
"Request_irq failed: %d\n", gi2c->irq);
return ret;
i2c_set_adapdata(&gi2c->adap, gi2c);
gi2c->adap.dev.parent = dev;

View File

@@ -123,12 +123,13 @@
#define ID_NACK BIT(4)
#define ID_EPROTO BIT(5)
/* persistent flags */
#define ID_P_NO_RST_STAT BIT(26)
#define ID_P_FMPLUS BIT(27)
#define ID_P_NOT_ATOMIC BIT(28)
#define ID_P_HOST_NOTIFY BIT(29)
#define ID_P_NO_RXDMA BIT(30) /* HW forbids RXDMA sometimes */
#define ID_P_PM_BLOCKED BIT(31)
#define ID_P_MASK GENMASK(31, 27)
#define ID_P_MASK GENMASK(31, 26)
#define ID_SLAVE_NACK BIT(0)
@@ -901,12 +902,11 @@ static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
if (ret)
return ret;
/* SCMI based resets don't need to poll for success */
if (priv->devtype < I2C_RCAR_GEN5)
return read_poll_timeout_atomic(reset_control_status, ret, ret == 0,
1, 100, false, priv->rstc);
if (priv->flags & ID_P_NO_RST_STAT)
return 0;
return 0;
return read_poll_timeout_atomic(reset_control_status, ret, ret == 0,
1, 100, false, priv->rstc);
}
static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
@@ -1200,15 +1200,12 @@ static int rcar_i2c_probe(struct platform_device *pdev)
goto out_pm_put;
}
/*
* Gen5+ uses SCMI based reset which cannot report status.
* Firmware has to ensure proper reset
*/
if (priv->devtype < I2C_RCAR_GEN5) {
ret = reset_control_status(priv->rstc);
if (ret < 0)
goto out_pm_put;
}
ret = reset_control_status(priv->rstc);
/* Some SCMI firmware does not support reading reset status */
if (ret == -ENOTSUPP)
priv->flags |= ID_P_NO_RST_STAT;
else if (ret < 0)
goto out_pm_put;
/* hard reset disturbs HostNotify local target, so disable it */
priv->flags &= ~ID_P_HOST_NOTIFY;

View File

@@ -554,8 +554,7 @@ static int riic_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, irq_desc->isr, 0, irq_desc->name, riic);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq %s\n",
irq_desc->name);
return ret;
}

View File

@@ -442,7 +442,7 @@ static int rzv2m_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, rzv2m_i2c_tia_irq_handler, 0,
dev_name(dev), priv);
if (ret < 0)
return dev_err_probe(dev, ret, "Unable to request irq %d\n", irq);
return ret;
adap = &priv->adap;
adap->nr = pdev->id;

View File

@@ -546,10 +546,8 @@ static int sprd_i2c_probe(struct platform_device *pdev)
sprd_i2c_isr, sprd_i2c_isr_thread,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret) {
dev_err_probe(&pdev->dev, ret, "failed to request irq %d\n", i2c_dev->irq);
if (ret)
goto err_rpm_put;
}
ret = i2c_add_numbered_adapter(&i2c_dev->adap);
if (ret) {

View File

@@ -825,8 +825,7 @@ static int st_i2c_probe(struct platform_device *pdev)
NULL, st_i2c_isr_thread,
IRQF_ONESHOT, pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to request irq %i\n", i2c_dev->irq);
return ret;
pinctrl_pm_select_default_state(i2c_dev->dev);
/* In case idle state available, select it */

View File

@@ -801,14 +801,12 @@ static int stm32f4_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, irq_event, stm32f4_i2c_isr_event, 0,
pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to request irq event %i\n", irq_event);
return ret;
ret = devm_request_irq(&pdev->dev, irq_error, stm32f4_i2c_isr_error, 0,
pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to request irq error %i\n", irq_error);
return ret;
ret = stm32f4_i2c_hw_config(i2c_dev);
if (ret)

View File

@@ -2204,7 +2204,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret, "Failed to request irq event\n");
return ret;
if (!i2c_dev->setup.single_it_line) {
irq_error = platform_get_irq(pdev, 1);
@@ -2217,7 +2217,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret, "Failed to request irq error\n");
return ret;
}
ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup);

View File

@@ -261,10 +261,8 @@ static int p2wi_probe(struct platform_device *pdev)
i2c_set_adapdata(&p2wi->adapter, p2wi);
ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi);
if (ret) {
dev_err_probe(dev, ret, "can't register interrupt handler irq%d\n", irq);
if (ret)
goto err_reset_assert;
}
writel(P2WI_CTRL_SOFT_RST, p2wi->regs + P2WI_CTRL);

View File

@@ -576,7 +576,7 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, i2c->irq, synquacer_i2c_isr,
0, dev_name(&pdev->dev), i2c);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "cannot claim IRQ %d\n", i2c->irq);
return ret;
i2c->state = STATE_IDLE;
i2c->dev = &pdev->dev;

View File

@@ -560,7 +560,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, uniphier_fi2c_interrupt, 0,
pdev->name, priv);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq %d\n", irq);
return ret;
return i2c_add_adapter(&priv->adap);
}

View File

@@ -354,7 +354,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, uniphier_i2c_interrupt, 0, pdev->name,
priv);
if (ret)
return dev_err_probe(dev, ret, "failed to request irq %d\n", irq);
return ret;
return i2c_add_adapter(&priv->adap);
}

View File

@@ -114,8 +114,7 @@ static int wmt_i2c_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr,
0, pdev->name, i2c);
if (err)
return dev_err_probe(&pdev->dev, err,
"failed to request irq %i\n", i2c->irq);
return err;
i2c->clk = of_clk_get(np, 0);
if (IS_ERR(i2c->clk))

View File

@@ -305,8 +305,7 @@ static int zxi2c_probe(struct platform_device *pdev)
error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr,
IRQF_SHARED, pdev->name, i2c);
if (error)
return dev_err_probe(&pdev->dev, error,
"failed to request irq %i\n", i2c->irq);
return error;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)

View File

@@ -530,7 +530,7 @@ static int xlp9xx_i2c_probe(struct platform_device *pdev)
err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0,
pdev->name, priv);
if (err)
return dev_err_probe(&pdev->dev, err, "IRQ request failed!\n");
return err;
init_completion(&priv->msg_complete);
priv->adapter.dev.parent = &pdev->dev;

View File

@@ -247,6 +247,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
if (!props[i].name || !props[i].value) {
err = -ENOMEM;
of_node_put(adap_np);
goto err_rollback;
}
props[i].length = 3;

View File

@@ -394,6 +394,7 @@ pub fn index(&self) -> i32 {
}
/// Gets pointer to an `i2c_adapter` by index.
#[inline]
pub fn get(index: i32) -> Result<ARef<Self>> {
// SAFETY: `index` must refer to a valid I2C adapter; the kernel
// guarantees that `i2c_get_adapter(index)` returns either a valid
@@ -415,11 +416,13 @@ pub fn get(index: i32) -> Result<ARef<Self>> {
// SAFETY: Instances of `I2cAdapter` are always reference-counted.
unsafe impl AlwaysRefCounted for I2cAdapter {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::i2c_get_adapter(self.index()) };
}
#[inline]
unsafe fn dec_ref(obj: NonNull<Self>) {
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
unsafe { bindings::i2c_put_adapter(obj.as_ref().as_raw()) }