diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 6d6e81242f74..447af5523c2e 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -272,7 +272,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { { "HISI02A1", 0 }, { "HISI02A2", 0 }, { "HISI02A3", 0 }, - { "HJMC3001", 0 }, + { "HJMC3001", ACCESS_INTR_MASK }, { "HYGO0010", ACCESS_INTR_MASK }, { "INT33C2", 0 }, { "INT33C3", 0 }, diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index e1a4338bc51e..1cfd7a4c8237 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -29,6 +29,7 @@ #define DRIVER_NAME "imx-lpi2c" +#define LPI2C_VERID 0x00 /* i2c version ID */ #define LPI2C_PARAM 0x04 /* i2c RX/TX FIFO size */ #define LPI2C_MCR 0x10 /* i2c contrl register */ #define LPI2C_MSR 0x14 /* i2c status register */ @@ -136,6 +137,9 @@ #define I2C_PM_LONG_TIMEOUT_MS 1000 /* Avoid dead lock caused by big clock prepare lock */ #define I2C_DMA_THRESHOLD 8 /* bytes */ +/* Bit 0 indicates the presence of the target feature */ +#define VERID_FEATURE_TARGET_PRESENT BIT(0) + enum lpi2c_imx_mode { STANDARD, /* 100+Kbps */ FAST, /* 400+Kbps */ @@ -194,6 +198,7 @@ struct lpi2c_imx_struct { bool can_use_dma; struct lpi2c_imx_dma *dma; struct i2c_client *target; + bool target_supported; int irq; const struct imx_lpi2c_hwdata *hwdata; }; @@ -1330,6 +1335,10 @@ static int lpi2c_imx_register_target(struct i2c_client *client) struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(client->adapter); int ret; + /* Reject target-mode registration on controllers that don't support it. */ + if (!lpi2c_imx->target_supported) + return -EOPNOTSUPP; + if (lpi2c_imx->target) return -EBUSY; @@ -1546,13 +1555,23 @@ static int lpi2c_imx_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); /* - * Reset all internal controller registers of both Master and Target - * to avoid effects of previous status. + * Reset all internal controller registers to avoid effects of any + * state left over from a previous stage (e.g. the bootloader). + * + * The Master block (MCR) is present on every controller, so reset it + * unconditionally. VERID shows whether the target feature is supported. + * Do not touch the Target block (SCR) on a master-only controller to + * avoid an asynchronous SError. */ 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); + + lpi2c_imx->target_supported = !!(readl(lpi2c_imx->base + LPI2C_VERID) & + VERID_FEATURE_TARGET_PRESENT); + if (lpi2c_imx->target_supported) { + writel(SCR_RST, lpi2c_imx->base + LPI2C_SCR); + 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); diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index bdeda3979c48..25b6e4e9e3fa 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -595,9 +595,11 @@ static int cci_probe(struct platform_device *pdev) goto disable_clocks; pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); + ret = devm_pm_runtime_set_active_enabled(dev); + if (ret) + goto disable_clocks; + pm_runtime_use_autosuspend(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); for (i = 0; i < cci->data->num_masters; i++) { if (!cci->master[i].cci) @@ -613,8 +615,6 @@ static int cci_probe(struct platform_device *pdev) return 0; error_i2c: - pm_runtime_disable(dev); - pm_runtime_dont_use_autosuspend(dev); for (--i ; i >= 0; i--) { if (cci->master[i].cci) { @@ -640,9 +640,6 @@ static void cci_remove(struct platform_device *pdev) cci_halt(cci, i); } } - - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); } static const struct cci_data cci_v1_data = { diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 658636c1ee0e..00013b41a6f5 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -188,8 +188,8 @@ static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = { /* source_clock = 32 MHz */ static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = { - { I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38 }, - { I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 19 }, + { I2C_MAX_STANDARD_MODE_FREQ, 12, 9, 10, 26 }, + { I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 19 }, { I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 5, 15 }, {} }; diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index fb25704219c7..ddaacf876dad 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1816,6 +1816,12 @@ void i2c_del_adapter(struct i2c_adapter *adap) return; } + /* + * This drains any in-flight writers, so all + * clients will be caught by i2c_deregister_clients(). + */ + device_remove_file(&adap->dev, &dev_attr_new_device); + i2c_acpi_remove_space_handler(adap); i2c_deregister_clients(adap); diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 681a201c239b..68a4c34b5987 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -408,6 +408,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, return 0; err_free_priv: + of_node_put(priv->adap.dev.of_node); kfree(priv); return ret; }