Commit 21f35d2c 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:
 "Fix the regression with AMD GPU suspend by reverting the
  handling of bus regulators in the I2C core.

  Also, there is a fix for the MPC driver to prevent an
  out-of-bound-access"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  Revert "i2c: core: support bus regulator controlling in adapter"
  i2c: mpc: Avoid out of bounds memory access
parents d445d649 a19f75de
...@@ -492,7 +492,7 @@ static void mpc_i2c_finish(struct mpc_i2c *i2c, int rc) ...@@ -492,7 +492,7 @@ static void mpc_i2c_finish(struct mpc_i2c *i2c, int rc)
static void mpc_i2c_do_action(struct mpc_i2c *i2c) static void mpc_i2c_do_action(struct mpc_i2c *i2c)
{ {
struct i2c_msg *msg = &i2c->msgs[i2c->curr_msg]; struct i2c_msg *msg = NULL;
int dir = 0; int dir = 0;
int recv_len = 0; int recv_len = 0;
u8 byte; u8 byte;
...@@ -501,10 +501,13 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c) ...@@ -501,10 +501,13 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c)
i2c->cntl_bits &= ~(CCR_RSTA | CCR_MTX | CCR_TXAK); i2c->cntl_bits &= ~(CCR_RSTA | CCR_MTX | CCR_TXAK);
if (msg->flags & I2C_M_RD) if (i2c->action != MPC_I2C_ACTION_STOP) {
dir = 1; msg = &i2c->msgs[i2c->curr_msg];
if (msg->flags & I2C_M_RECV_LEN) if (msg->flags & I2C_M_RD)
recv_len = 1; dir = 1;
if (msg->flags & I2C_M_RECV_LEN)
recv_len = 1;
}
switch (i2c->action) { switch (i2c->action) {
case MPC_I2C_ACTION_RESTART: case MPC_I2C_ACTION_RESTART:
...@@ -581,7 +584,7 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c) ...@@ -581,7 +584,7 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c)
break; break;
} }
if (msg->len == i2c->byte_posn) { if (msg && msg->len == i2c->byte_posn) {
i2c->curr_msg++; i2c->curr_msg++;
i2c->byte_posn = 0; i2c->byte_posn = 0;
......
...@@ -466,14 +466,12 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client) ...@@ -466,14 +466,12 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
static int i2c_device_probe(struct device *dev) static int i2c_device_probe(struct device *dev)
{ {
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver; struct i2c_driver *driver;
int status; int status;
if (!client) if (!client)
return 0; return 0;
adap = client->adapter;
client->irq = client->init_irq; client->irq = client->init_irq;
if (!client->irq) { if (!client->irq) {
...@@ -539,14 +537,6 @@ static int i2c_device_probe(struct device *dev) ...@@ -539,14 +537,6 @@ static int i2c_device_probe(struct device *dev)
dev_dbg(dev, "probe\n"); dev_dbg(dev, "probe\n");
if (adap->bus_regulator) {
status = regulator_enable(adap->bus_regulator);
if (status < 0) {
dev_err(&adap->dev, "Failed to enable bus regulator\n");
goto err_clear_wakeup_irq;
}
}
status = of_clk_set_defaults(dev->of_node, false); status = of_clk_set_defaults(dev->of_node, false);
if (status < 0) if (status < 0)
goto err_clear_wakeup_irq; goto err_clear_wakeup_irq;
...@@ -605,10 +595,8 @@ static int i2c_device_probe(struct device *dev) ...@@ -605,10 +595,8 @@ static int i2c_device_probe(struct device *dev)
static void i2c_device_remove(struct device *dev) static void i2c_device_remove(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver; struct i2c_driver *driver;
adap = client->adapter;
driver = to_i2c_driver(dev->driver); driver = to_i2c_driver(dev->driver);
if (driver->remove) { if (driver->remove) {
int status; int status;
...@@ -623,8 +611,6 @@ static void i2c_device_remove(struct device *dev) ...@@ -623,8 +611,6 @@ static void i2c_device_remove(struct device *dev)
devres_release_group(&client->dev, client->devres_group_id); devres_release_group(&client->dev, client->devres_group_id);
dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator)
regulator_disable(adap->bus_regulator);
dev_pm_clear_wake_irq(&client->dev); dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false); device_init_wakeup(&client->dev, false);
...@@ -634,86 +620,6 @@ static void i2c_device_remove(struct device *dev) ...@@ -634,86 +620,6 @@ static void i2c_device_remove(struct device *dev)
pm_runtime_put(&client->adapter->dev); pm_runtime_put(&client->adapter->dev);
} }
#ifdef CONFIG_PM_SLEEP
static int i2c_resume_early(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
if (pm_runtime_status_suspended(&client->dev) &&
client->adapter->bus_regulator) {
err = regulator_enable(client->adapter->bus_regulator);
if (err)
return err;
}
return pm_generic_resume_early(&client->dev);
}
static int i2c_suspend_late(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
err = pm_generic_suspend_late(&client->dev);
if (err)
return err;
if (!pm_runtime_status_suspended(&client->dev) &&
client->adapter->bus_regulator)
return regulator_disable(client->adapter->bus_regulator);
return 0;
}
#endif
#ifdef CONFIG_PM
static int i2c_runtime_resume(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
if (client->adapter->bus_regulator) {
err = regulator_enable(client->adapter->bus_regulator);
if (err)
return err;
}
return pm_generic_runtime_resume(&client->dev);
}
static int i2c_runtime_suspend(struct device *dev)
{
struct i2c_client *client = i2c_verify_client(dev);
int err;
if (!client)
return 0;
err = pm_generic_runtime_suspend(&client->dev);
if (err)
return err;
if (client->adapter->bus_regulator)
return regulator_disable(client->adapter->bus_regulator);
return 0;
}
#endif
static const struct dev_pm_ops i2c_device_pm = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(i2c_suspend_late, i2c_resume_early)
SET_RUNTIME_PM_OPS(i2c_runtime_suspend, i2c_runtime_resume, NULL)
};
static void i2c_device_shutdown(struct device *dev) static void i2c_device_shutdown(struct device *dev)
{ {
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);
...@@ -773,7 +679,6 @@ struct bus_type i2c_bus_type = { ...@@ -773,7 +679,6 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe, .probe = i2c_device_probe,
.remove = i2c_device_remove, .remove = i2c_device_remove,
.shutdown = i2c_device_shutdown, .shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm,
}; };
EXPORT_SYMBOL_GPL(i2c_bus_type); EXPORT_SYMBOL_GPL(i2c_bus_type);
......
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