diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-cadence.c | 8 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 45 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-imx-lpi2c.c | 20 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 14 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 19 |
6 files changed, 60 insertions, 47 deletions
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 686971263bef..45d6771fac8c 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -962,10 +962,6 @@ static int cdns_i2c_probe(struct platform_device *pdev) goto err_clk_dis; } - ret = i2c_add_adapter(&id->adap); - if (ret < 0) - goto err_clk_dis; - /* * Cadence I2C controller has a bug wherein it generates * invalid read transaction after HW timeout in master receiver mode. @@ -975,6 +971,10 @@ static int cdns_i2c_probe(struct platform_device *pdev) */ cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET); + ret = i2c_add_adapter(&id->adap); + if (ret < 0) + goto err_clk_dis; + dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n", id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq); diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index a62c14c3b2b7..7a3faa551cf8 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -475,30 +475,28 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; - u32 ic_tar = 0; + u32 ic_con, ic_tar = 0; /* Disable the adapter */ __i2c_dw_enable_and_wait(dev, false); /* if the slave address is ten bit address, enable 10BITADDR */ - if (dev->dynamic_tar_update_enabled) { + ic_con = dw_readl(dev, DW_IC_CON); + if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { + ic_con |= DW_IC_CON_10BITADDR_MASTER; /* * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing - * mode has to be enabled via bit 12 of IC_TAR register, - * otherwise bit 4 of IC_CON is used. + * mode has to be enabled via bit 12 of IC_TAR register. + * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be + * detected from registers. */ - if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) - ic_tar = DW_IC_TAR_10BITADDR_MASTER; + ic_tar = DW_IC_TAR_10BITADDR_MASTER; } else { - u32 ic_con = dw_readl(dev, DW_IC_CON); - - if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) - ic_con |= DW_IC_CON_10BITADDR_MASTER; - else - ic_con &= ~DW_IC_CON_10BITADDR_MASTER; - dw_writel(dev, ic_con, DW_IC_CON); + ic_con &= ~DW_IC_CON_10BITADDR_MASTER; } + dw_writel(dev, ic_con, DW_IC_CON); + /* * Set the slave (target) address and enable 10-bit addressing mode * if applicable. @@ -963,7 +961,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) { struct i2c_adapter *adap = &dev->adapter; int r; - u32 reg; init_completion(&dev->cmd_complete); @@ -971,26 +968,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) if (r) return r; - r = i2c_dw_acquire_lock(dev); - if (r) - return r; - - /* - * Test if dynamic TAR update is enabled in this controller by writing - * to IC_10BITADDR_MASTER field in IC_CON: when it is enabled this - * field is read-only so it should not succeed - */ - reg = dw_readl(dev, DW_IC_CON); - dw_writel(dev, reg ^ DW_IC_CON_10BITADDR_MASTER, DW_IC_CON); - - if ((dw_readl(dev, DW_IC_CON) & DW_IC_CON_10BITADDR_MASTER) == - (reg & DW_IC_CON_10BITADDR_MASTER)) { - dev->dynamic_tar_update_enabled = true; - dev_dbg(dev->dev, "Dynamic TAR update enabled"); - } - - i2c_dw_release_lock(dev); - snprintf(adap->name, sizeof(adap->name), "Synopsys DesignWare I2C adapter"); adap->retries = 3; diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 26250b425e2f..c1db3a5a340f 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -125,7 +125,6 @@ struct dw_i2c_dev { int (*acquire_lock)(struct dw_i2c_dev *dev); void (*release_lock)(struct dw_i2c_dev *dev); bool pm_runtime_disabled; - bool dynamic_tar_update_enabled; }; #define ACCESS_SWAP 0x00000001 diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 934f5485f3c5..e86801a63120 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -28,6 +28,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/sched.h> #include <linux/slab.h> @@ -636,12 +637,31 @@ static int lpi2c_imx_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int lpi2c_imx_suspend(struct device *dev) +{ + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int lpi2c_imx_resume(struct device *dev) +{ + pinctrl_pm_select_default_state(dev); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(imx_lpi2c_pm, lpi2c_imx_suspend, lpi2c_imx_resume); + static struct platform_driver lpi2c_imx_driver = { .probe = lpi2c_imx_probe, .remove = lpi2c_imx_remove, .driver = { .name = DRIVER_NAME, .of_match_table = lpi2c_imx_of_match, + .pm = &imx_lpi2c_pm, }, }; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index e34d82e79b98..c21ca7bf2efe 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -58,7 +58,7 @@ #define SMBSLVDAT (0xC + piix4_smba) /* count for request_region */ -#define SMBIOSIZE 8 +#define SMBIOSIZE 9 /* PCI Address Constants */ #define SMBBA 0x090 @@ -592,6 +592,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, u8 port; int retval; + mutex_lock(&piix4_mutex_sb800); + /* Request the SMBUS semaphore, avoid conflicts with the IMC */ smbslvcnt = inb_p(SMBSLVCNT); do { @@ -605,10 +607,10 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, usleep_range(1000, 2000); } while (--retries); /* SMBus is still owned by the IMC, we give up */ - if (!retries) + if (!retries) { + mutex_unlock(&piix4_mutex_sb800); return -EBUSY; - - mutex_lock(&piix4_mutex_sb800); + } outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); @@ -623,11 +625,11 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); - mutex_unlock(&piix4_mutex_sb800); - /* Release the semaphore */ outb_p(smbslvcnt | 0x20, SMBSLVCNT); + mutex_unlock(&piix4_mutex_sb800); + return retval; } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 408de741fec5..d2402bbf6729 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -221,7 +221,8 @@ static int i2c_acpi_get_info(struct acpi_device *adev, acpi_dev_free_resource_list(&resource_list); - strlcpy(info->type, dev_name(&adev->dev), sizeof(info->type)); + acpi_set_modalias(adev, dev_name(&adev->dev), info->type, + sizeof(info->type)); return 0; } @@ -1335,15 +1336,29 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.fwnode = info->fwnode; i2c_dev_set_name(adap, client); + + if (info->properties) { + status = device_add_properties(&client->dev, info->properties); + if (status) { + dev_err(&adap->dev, + "Failed to add properties to client %s: %d\n", + client->name, status); + goto out_err; + } + } + status = device_register(&client->dev); if (status) - goto out_err; + goto out_free_props; dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", client->name, dev_name(&client->dev)); return client; +out_free_props: + if (info->properties) + device_remove_properties(&client->dev); out_err: dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x (%d)\n", |