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)
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 recv_len = 0;
u8 byte;
......@@ -501,10 +501,13 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c)
i2c->cntl_bits &= ~(CCR_RSTA | CCR_MTX | CCR_TXAK);
if (msg->flags & I2C_M_RD)
dir = 1;
if (msg->flags & I2C_M_RECV_LEN)
recv_len = 1;
if (i2c->action != MPC_I2C_ACTION_STOP) {
msg = &i2c->msgs[i2c->curr_msg];
if (msg->flags & I2C_M_RD)
dir = 1;
if (msg->flags & I2C_M_RECV_LEN)
recv_len = 1;
}
switch (i2c->action) {
case MPC_I2C_ACTION_RESTART:
......@@ -581,7 +584,7 @@ static void mpc_i2c_do_action(struct mpc_i2c *i2c)
break;
}
if (msg->len == i2c->byte_posn) {
if (msg && msg->len == i2c->byte_posn) {
i2c->curr_msg++;
i2c->byte_posn = 0;
......
......@@ -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)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver;
int status;
if (!client)
return 0;
adap = client->adapter;
client->irq = client->init_irq;
if (!client->irq) {
......@@ -539,14 +537,6 @@ static int i2c_device_probe(struct device *dev)
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);
if (status < 0)
goto err_clear_wakeup_irq;
......@@ -605,10 +595,8 @@ static int i2c_device_probe(struct device *dev)
static void i2c_device_remove(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
struct i2c_driver *driver;
adap = client->adapter;
driver = to_i2c_driver(dev->driver);
if (driver->remove) {
int status;
......@@ -623,8 +611,6 @@ static void i2c_device_remove(struct device *dev)
devres_release_group(&client->dev, client->devres_group_id);
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);
device_init_wakeup(&client->dev, false);
......@@ -634,86 +620,6 @@ static void i2c_device_remove(struct device *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)
{
struct i2c_client *client = i2c_verify_client(dev);
......@@ -773,7 +679,6 @@ struct bus_type i2c_bus_type = {
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm,
};
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