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
This commit is contained in:
commit
21f35d2ca8
|
@ -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 @@ put_sync_adapter:
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue