diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-18 16:53:38 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-18 16:53:38 +0200 |
| commit | 5895db67c12464003afd16c08049b73aa09e58ea (patch) | |
| tree | c3855a7ab889dffc2a02460f65abbbe6b800b6e6 /drivers/i2c | |
| parent | 1c5f3df9481bb6275aeb079a8312d037da69715b (diff) | |
| parent | f89c296854b755a66657065c35b05406fc18264d (diff) | |
Merge v6.18.39linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-imx-lpi2c.c | 15 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f7.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core-base.c | 81 |
6 files changed, 77 insertions, 36 deletions
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-i801.c b/drivers/i2c/busses/i2c-i801.c index 506d69b156f7..217dea2743e8 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -927,13 +927,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, */ if (hwpec) iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv)); -out: /* * Unlock the SMBus device for use by BIOS/ACPI, * and clear status flags if not done already. */ iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv)); +out: pm_runtime_put_autosuspend(&priv->pci_dev->dev); mutex_unlock(&priv->acpi_lock); return ret; diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 3bf138eba04c..24c70ea371bb 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -1588,7 +1588,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) @@ -1608,6 +1619,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-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 28c5c5c1fb7a..a21fa45bd64c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -844,7 +844,7 @@ static int fsl_i2c_probe(struct platform_device *op) "fsl,timeout", &mpc_ops.timeout); if (!result) { - mpc_ops.timeout *= HZ / 1000000; + mpc_ops.timeout = mpc_ops.timeout * HZ / 1000000; if (mpc_ops.timeout < 5) mpc_ops.timeout = 5; } else { diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 905aa9ab64e1..c57dda9866cf 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; diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 05b315405639..e049fa908231 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -63,6 +63,7 @@ static DEFINE_MUTEX(core_lock); static DEFINE_IDR(i2c_adapter_idr); +static void i2c_deregister_clients(struct i2c_adapter *adap); static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key); @@ -1556,11 +1557,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - dev_set_name(&adap->dev, "i2c-%d", adap->nr); + res = dev_set_name(&adap->dev, "i2c-%d", adap->nr); + if (res) + goto err_remove_irq_domain; + adap->dev.bus = &i2c_bus_type; adap->dev.type = &i2c_adapter_type; device_initialize(&adap->dev); + res = i2c_init_recovery(adap); + if (res == -EPROBE_DEFER) + goto err_put_adap; + /* * This adapter can be used as a parent immediately after device_add(), * setup runtime-pm (especially ignore-children) before hand. @@ -1574,23 +1582,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap) idr_replace(&i2c_adapter_idr, adap, adap->nr); mutex_unlock(&core_lock); + adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root); + res = device_add(&adap->dev); if (res) { pr_err("adapter '%s': can't register device (%d)\n", adap->name, res); - put_device(&adap->dev); - goto out_list; + goto err_replace_id; } - adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root); - res = i2c_setup_smbus_alert(adap); if (res) goto out_reg; - res = i2c_init_recovery(adap); - if (res == -EPROBE_DEFER) - goto out_reg; - dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); /* create pre-declared device nodes */ @@ -1609,10 +1612,19 @@ static int i2c_register_adapter(struct i2c_adapter *adap) return 0; out_reg: + i2c_deregister_clients(adap); + device_del(&adap->dev); +err_replace_id: + mutex_lock(&core_lock); + idr_replace(&i2c_adapter_idr, NULL, adap->nr); + mutex_unlock(&core_lock); debugfs_remove_recursive(adap->debugfs); +err_put_adap: init_completion(&adap->dev_released); - device_unregister(&adap->dev); + put_device(&adap->dev); wait_for_completion(&adap->dev_released); +err_remove_irq_domain: + i2c_host_notify_irq_teardown(adap); out_list: mutex_lock(&core_lock); idr_remove(&i2c_adapter_idr, adap->nr); @@ -1748,29 +1760,10 @@ static int __process_removed_adapter(struct device_driver *d, void *data) return 0; } -/** - * i2c_del_adapter - unregister I2C adapter - * @adap: the adapter being unregistered - * Context: can sleep - * - * This unregisters an I2C adapter which was previously registered - * by @i2c_add_adapter or @i2c_add_numbered_adapter. - */ -void i2c_del_adapter(struct i2c_adapter *adap) +static void i2c_deregister_clients(struct i2c_adapter *adap) { - struct i2c_adapter *found; struct i2c_client *client, *next; - /* First make sure that this adapter was ever added */ - mutex_lock(&core_lock); - found = idr_find(&i2c_adapter_idr, adap->nr); - mutex_unlock(&core_lock); - if (found != adap) { - pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name); - return; - } - - i2c_acpi_remove_space_handler(adap); /* Tell drivers about this removal */ mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, @@ -1796,6 +1789,34 @@ void i2c_del_adapter(struct i2c_adapter *adap) * them up properly, so we give them a chance to do that first. */ device_for_each_child(&adap->dev, NULL, __unregister_client); device_for_each_child(&adap->dev, NULL, __unregister_dummy); +} + +/** + * i2c_del_adapter - unregister I2C adapter + * @adap: the adapter being unregistered + * Context: can sleep + * + * This unregisters an I2C adapter which was previously registered + * by @i2c_add_adapter or @i2c_add_numbered_adapter. + */ +void i2c_del_adapter(struct i2c_adapter *adap) +{ + struct i2c_adapter *found; + + /* First make sure that this adapter was ever added */ + mutex_lock(&core_lock); + found = idr_find(&i2c_adapter_idr, adap->nr); + if (found == adap) + idr_replace(&i2c_adapter_idr, NULL, adap->nr); + mutex_unlock(&core_lock); + if (found != adap) { + pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name); + return; + } + + i2c_acpi_remove_space_handler(adap); + + i2c_deregister_clients(adap); /* device name is gone after device_unregister */ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); |
