summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-22 09:30:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-22 09:30:31 -0700
commit1dc18801be29bc54709aa355b8acd80e183b03cd (patch)
treea67e9e860efc688419511e9abe9934687ac1d4a1 /drivers
parent9f333cb6b57c3f72073bf058f984b180cc00bf7b (diff)
parentac930b80c1e0eba283d7843180964e6d2a87369d (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.c5
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-davinci.c4
-rw-r--r--drivers/i2c/busses/i2c-imx-lpi2c.c15
-rw-r--r--drivers/i2c/busses/i2c-ls2x-v2.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c10
-rw-r--r--drivers/i2c/busses/i2c-qcom-cci.c48
-rw-r--r--drivers/i2c/busses/i2c-stm32f7.c9
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;