diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-22 09:30:31 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-06-22 09:30:31 -0700 |
| commit | 1dc18801be29bc54709aa355b8acd80e183b03cd (patch) | |
| tree | a67e9e860efc688419511e9abe9934687ac1d4a1 /drivers | |
| parent | 9f333cb6b57c3f72073bf058f984b180cc00bf7b (diff) | |
| parent | ac930b80c1e0eba283d7843180964e6d2a87369d (diff) | |
Merge tag 'i2c-7.2-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux
Pull more i2c updates from Andi Shyti:
"Cleanups:
- generic cleanups in qcom, qcom-cci and pxa, plus core cleanups in
algo-bit and atr
Fixes:
- davinci: clean up cpufreq notifier on probe failure
- imx-lpi2c: suspend the adapter while hardware is powered down
- ls2x-v2: return IRQ_HANDLED after servicing error interrupts
- stm32f7: fix timing calculation accuracy
DT bindings:
- microchip: permit resets
- i2c-mux-pinctrl: update maintainer entry
- i2c-mux-reg: convert bindings to DT schema"
* tag 'i2c-7.2-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux:
i2c: pxa: Use named initializers for the platform_device_id array
i2c: imx-lpi2c: mark I2C adapter when hardware is powered down
i2c: stm32f7: truncate clock period instead of rounding it
dt-bindings: i2c: microchip,corei2c: permit resets
i2c: qcom: Unify user-visible "Qualcomm" name
i2c: ls2x-v2: return IRQ_HANDLED after servicing an error
i2c: atr: annotate i2c_atr_adap_desc->aliases with __counted_by_ptr
i2c: algo: bit: use str_plural helper in bit_xfer
dt-bindings: i2c: i2c-mux-pinctrl: change maintainer
dt-bindings: i2c: convert i2c-mux-reg to DT schema
i2c: davinci: Unregister cpufreq notifier on probe failure
i2c: qcom-cci: Remove overcautious disable_irq() calls
i2c: qcom-cci: Move cci_init() under cci_reset() function
i2c: qcom-cci: Do not check return value of cci_init()
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-imx-lpi2c.c | 15 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ls2x-v2.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 10 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-qcom-cci.c | 48 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f7.c | 9 |
8 files changed, 54 insertions, 41 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 6544d27e4419..d1d9a6c1a1e2 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/errno.h> #include <linux/sched.h> +#include <linux/string_choices.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> @@ -562,7 +563,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ret = readbytes(i2c_adap, pmsg); if (ret >= 1) bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", - ret, ret == 1 ? "" : "s"); + ret, str_plural(ret)); if (ret < pmsg->len) { if (ret >= 0) ret = -EIO; @@ -573,7 +574,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ret = sendbytes(i2c_adap, pmsg); if (ret >= 1) bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", - ret, ret == 1 ? "" : "s"); + ret, str_plural(ret)); if (ret < pmsg->len) { if (ret >= 0) ret = -EIO; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3123ab75600b..d35456994280 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1058,7 +1058,7 @@ config I2C_QCOM_CCI will be called i2c-qcom-cci. config I2C_QCOM_GENI - tristate "Qualcomm Technologies Inc.'s GENI based I2C controller" + tristate "Qualcomm GENI based I2C controller" depends on ARCH_QCOM || COMPILE_TEST depends on QCOM_GENI_SE help diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 66c23535656b..0617f416cb0b 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -818,12 +818,14 @@ static int davinci_i2c_probe(struct platform_device *pdev) adap->nr = pdev->id; r = i2c_add_numbered_adapter(adap); if (r) - goto err_unuse_clocks; + goto err_cpufreq; pm_runtime_put_autosuspend(dev->dev); return 0; +err_cpufreq: + i2c_davinci_cpufreq_deregister(dev); err_unuse_clocks: pm_runtime_dont_use_autosuspend(dev->dev); pm_runtime_put_sync(dev->dev); diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index cd4da50c4dd9..e6c24a9d934d 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -1646,7 +1646,18 @@ static int __maybe_unused lpi2c_runtime_resume(struct device *dev) static int __maybe_unused lpi2c_suspend_noirq(struct device *dev) { - return pm_runtime_force_suspend(dev); + struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); + int ret; + + i2c_mark_adapter_suspended(&lpi2c_imx->adapter); + + ret = pm_runtime_force_suspend(dev); + if (ret) { + i2c_mark_adapter_resumed(&lpi2c_imx->adapter); + return ret; + } + + return 0; } static int __maybe_unused lpi2c_resume_noirq(struct device *dev) @@ -1666,6 +1677,8 @@ static int __maybe_unused lpi2c_resume_noirq(struct device *dev) if (lpi2c_imx->target) lpi2c_imx_target_init(lpi2c_imx); + i2c_mark_adapter_resumed(&lpi2c_imx->adapter); + return 0; } diff --git a/drivers/i2c/busses/i2c-ls2x-v2.c b/drivers/i2c/busses/i2c-ls2x-v2.c index 517760d70169..9df73557ecc4 100644 --- a/drivers/i2c/busses/i2c-ls2x-v2.c +++ b/drivers/i2c/busses/i2c-ls2x-v2.c @@ -304,7 +304,7 @@ static irqreturn_t loongson2_i2c_isr_event(int irq, void *data) regmap_read(priv->regmap, LOONGSON2_I2C_SR1, &status); if (status & LOONGSON2_I2C_SR1_ITERREN_MASK) { loongson2_i2c_isr_error(status, data); - return IRQ_NONE; + return IRQ_HANDLED; } regmap_read(priv->regmap, LOONGSON2_I2C_CR2, &cr2); diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 9a8b154ab69e..c9927a389aaf 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -214,11 +214,11 @@ static const struct of_device_id i2c_pxa_dt_ids[] = { MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids); static const struct platform_device_id i2c_pxa_id_table[] = { - { "pxa2xx-i2c", REGS_PXA2XX }, - { "pxa3xx-pwri2c", REGS_PXA3XX }, - { "ce4100-i2c", REGS_CE4100 }, - { "pxa910-i2c", REGS_PXA910 }, - { "armada-3700-i2c", REGS_A3700 }, + { .name = "pxa2xx-i2c", .driver_data = REGS_PXA2XX }, + { .name = "pxa3xx-pwri2c", .driver_data = REGS_PXA3XX }, + { .name = "ce4100-i2c", .driver_data = REGS_CE4100 }, + { .name = "pxa910-i2c", .driver_data = REGS_PXA910 }, + { .name = "armada-3700-i2c", .driver_data = REGS_A3700 }, { } }; MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index 01e440b6585d..4d64895a9e9e 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -225,25 +225,7 @@ static int cci_halt(struct cci *cci, u8 master_num) return 0; } -static int cci_reset(struct cci *cci) -{ - /* - * we reset the whole controller, here and for implicity use - * master[0].xxx for waiting on it. - */ - reinit_completion(&cci->master[0].irq_complete); - writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD); - - if (!wait_for_completion_timeout(&cci->master[0].irq_complete, - CCI_TIMEOUT)) { - dev_err(cci->dev, "CCI reset timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -static int cci_init(struct cci *cci) +static void cci_init(struct cci *cci) { u32 val = CCI_IRQ_MASK_0_I2C_M0_RD_DONE | CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT | @@ -284,6 +266,24 @@ static int cci_init(struct cci *cci) val = hw->scl_stretch_en << 8 | hw->trdhld << 4 | hw->tsp; writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i)); } +} + +static int cci_reset(struct cci *cci) +{ + /* + * we reset the whole controller, here and for implicity use + * master[0].xxx for waiting on it. + */ + reinit_completion(&cci->master[0].irq_complete); + writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD); + + if (!wait_for_completion_timeout(&cci->master[0].irq_complete, + CCI_TIMEOUT)) { + dev_err(cci->dev, "CCI reset timeout\n"); + return -ETIMEDOUT; + } + + cci_init(cci); return 0; } @@ -304,7 +304,6 @@ static int cci_run_queue(struct cci *cci, u8 master, u8 queue) dev_err(cci->dev, "master %d queue %d timeout\n", master, queue); cci_reset(cci); - cci_init(cci); return -ETIMEDOUT; } @@ -609,11 +608,7 @@ static int cci_probe(struct platform_device *pdev) ret = cci_reset(cci); if (ret < 0) - goto error; - - ret = cci_init(cci); - if (ret < 0) - goto error; + goto disable_clocks; pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(dev); @@ -643,8 +638,6 @@ error_i2c: of_node_put(cci->master[i].adap.dev.of_node); } } -error: - disable_irq(cci->irq); disable_clocks: cci_disable_clocks(cci); @@ -664,7 +657,6 @@ static void cci_remove(struct platform_device *pdev) } } - disable_irq(cci->irq); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); } diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 16c6e61c7e11..d6d993b436cb 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -464,8 +464,13 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, { struct stm32f7_i2c_spec *specs; u32 p_prev = STM32F7_PRESC_MAX; - u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, - setup->clock_src); + /* + * Truncate instead of rounding to closest: if the clock period is + * overestimated, the computed SCL timings will come out shorter on + * the wire, which can push the bus above the target rate and below + * the spec's tLOW/tHIGH minimums. + */ + u32 i2cclk = NSEC_PER_SEC / setup->clock_src; u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC, setup->speed_freq); u32 clk_error_prev = i2cbus; |
