Commit 1f5de42d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fixes from Wolfram Sang:
 "I2C has some bugfixes for you: mainly Jarkko fixed up a few things in
  the designware driver regarding the new slave mode. But Ulf also fixed
  a long-standing and now agreed suspend problem. Plus, some simple
  stuff which nonetheless needs fixing"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: designware: Fix runtime PM for I2C slave mode
  i2c: designware: Remove needless pm_runtime_put_noidle() call
  i2c: aspeed: fixed potential null pointer dereference
  i2c: simtec: use release_mem_region instead of release_resource
  i2c: core: Make comment about I2C table requirement to reflect the code
  i2c: designware: Fix standard mode speed when configuring the slave mode
  i2c: designware: Fix oops from i2c_dw_irq_handler_slave
  i2c: designware: Fix system suspend
parents 299c4608 2a86cdd2
...@@ -410,10 +410,11 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus) ...@@ -410,10 +410,11 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
} }
/* We are in an invalid state; reset bus to a known state. */ /* We are in an invalid state; reset bus to a known state. */
if (!bus->msgs && bus->master_state != ASPEED_I2C_MASTER_STOP) { if (!bus->msgs) {
dev_err(bus->dev, "bus in unknown state"); dev_err(bus->dev, "bus in unknown state");
bus->cmd_err = -EIO; bus->cmd_err = -EIO;
aspeed_i2c_do_stop(bus); if (bus->master_state != ASPEED_I2C_MASTER_STOP)
aspeed_i2c_do_stop(bus);
goto out_no_complete; goto out_no_complete;
} }
msg = &bus->msgs[bus->msgs_index]; msg = &bus->msgs[bus->msgs_index];
......
...@@ -198,8 +198,7 @@ static void i2c_dw_configure_slave(struct dw_i2c_dev *dev) ...@@ -198,8 +198,7 @@ static void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY; dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL | dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED | DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
DW_IC_CON_SPEED_FAST;
dev->mode = DW_IC_SLAVE; dev->mode = DW_IC_SLAVE;
...@@ -430,7 +429,7 @@ static void dw_i2c_plat_complete(struct device *dev) ...@@ -430,7 +429,7 @@ static void dw_i2c_plat_complete(struct device *dev)
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int dw_i2c_plat_suspend(struct device *dev) static int dw_i2c_plat_runtime_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
...@@ -452,11 +451,21 @@ static int dw_i2c_plat_resume(struct device *dev) ...@@ -452,11 +451,21 @@ static int dw_i2c_plat_resume(struct device *dev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int dw_i2c_plat_suspend(struct device *dev)
{
pm_runtime_resume(dev);
return dw_i2c_plat_runtime_suspend(dev);
}
#endif
static const struct dev_pm_ops dw_i2c_dev_pm_ops = { static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
.prepare = dw_i2c_plat_prepare, .prepare = dw_i2c_plat_prepare,
.complete = dw_i2c_plat_complete, .complete = dw_i2c_plat_complete,
SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume) SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL) SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
dw_i2c_plat_resume,
NULL)
}; };
#define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops) #define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops)
......
...@@ -177,6 +177,8 @@ static int i2c_dw_reg_slave(struct i2c_client *slave) ...@@ -177,6 +177,8 @@ static int i2c_dw_reg_slave(struct i2c_client *slave)
return -EBUSY; return -EBUSY;
if (slave->flags & I2C_CLIENT_TEN) if (slave->flags & I2C_CLIENT_TEN)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
pm_runtime_get_sync(dev->dev);
/* /*
* Set slave address in the IC_SAR register, * Set slave address in the IC_SAR register,
* the address to which the DW_apb_i2c responds. * the address to which the DW_apb_i2c responds.
...@@ -205,6 +207,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) ...@@ -205,6 +207,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)
dev->disable_int(dev); dev->disable_int(dev);
dev->disable(dev); dev->disable(dev);
dev->slave = NULL; dev->slave = NULL;
pm_runtime_put(dev->dev);
return 0; return 0;
} }
...@@ -272,7 +275,7 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev) ...@@ -272,7 +275,7 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
slave_activity = ((dw_readl(dev, DW_IC_STATUS) & slave_activity = ((dw_readl(dev, DW_IC_STATUS) &
DW_IC_STATUS_SLAVE_ACTIVITY) >> 6); DW_IC_STATUS_SLAVE_ACTIVITY) >> 6);
if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY)) if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave)
return 0; return 0;
dev_dbg(dev->dev, dev_dbg(dev->dev,
...@@ -382,7 +385,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev) ...@@ -382,7 +385,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
ret = i2c_add_numbered_adapter(adap); ret = i2c_add_numbered_adapter(adap);
if (ret) if (ret)
dev_err(dev->dev, "failure adding adapter: %d\n", ret); dev_err(dev->dev, "failure adding adapter: %d\n", ret);
pm_runtime_put_noidle(dev->dev);
return ret; return ret;
} }
......
...@@ -127,8 +127,7 @@ static int simtec_i2c_probe(struct platform_device *dev) ...@@ -127,8 +127,7 @@ static int simtec_i2c_probe(struct platform_device *dev)
iounmap(pd->reg); iounmap(pd->reg);
err_res: err_res:
release_resource(pd->ioarea); release_mem_region(pd->ioarea->start, size);
kfree(pd->ioarea);
err: err:
kfree(pd); kfree(pd);
...@@ -142,8 +141,7 @@ static int simtec_i2c_remove(struct platform_device *dev) ...@@ -142,8 +141,7 @@ static int simtec_i2c_remove(struct platform_device *dev)
i2c_del_adapter(&pd->adap); i2c_del_adapter(&pd->adap);
iounmap(pd->reg); iounmap(pd->reg);
release_resource(pd->ioarea); release_mem_region(pd->ioarea->start, resource_size(pd->ioarea));
kfree(pd->ioarea);
kfree(pd); kfree(pd);
return 0; return 0;
......
...@@ -353,8 +353,8 @@ static int i2c_device_probe(struct device *dev) ...@@ -353,8 +353,8 @@ static int i2c_device_probe(struct device *dev)
} }
/* /*
* An I2C ID table is not mandatory, if and only if, a suitable Device * An I2C ID table is not mandatory, if and only if, a suitable OF
* Tree match table entry is supplied for the probing device. * or ACPI ID table is supplied for the probing device.
*/ */
if (!driver->id_table && if (!driver->id_table &&
!i2c_acpi_match_device(dev->driver->acpi_match_table, client) && !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment