Hi! > Let's use standard runtime PM functions instead of custom start and stop > functions. This way we can implement runtime idle mode using runtime PM > autosuspend in the following patches. This is not in recent kernel. What needs to be done here? Best regards, Pavel > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c > @@ -21,6 +21,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -2927,58 +2928,27 @@ static const struct attribute_group mxt_attr_group = { > .attrs = mxt_attrs, > }; > > -static void mxt_start(struct mxt_data *data) > +static int mxt_input_open(struct input_dev *input_dev) > { > - switch (data->suspend_mode) { > - case MXT_SUSPEND_T9_CTRL: > - mxt_soft_reset(data); > - > - /* Touch enable */ > - /* 0x83 = SCANEN | RPTEN | ENABLE */ > - mxt_write_object(data, > - MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83); > - break; > - > - case MXT_SUSPEND_DEEP_SLEEP: > - default: > - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); > - > - /* Recalibrate since chip has been in deep sleep */ > - mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); > - break; > - } > -} > - > -static void mxt_stop(struct mxt_data *data) > -{ > - switch (data->suspend_mode) { > - case MXT_SUSPEND_T9_CTRL: > - /* Touch disable */ > - mxt_write_object(data, > - MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0); > - break; > + struct mxt_data *data = input_get_drvdata(input_dev); > + struct device *dev = &data->client->dev; > + int error; > > - case MXT_SUSPEND_DEEP_SLEEP: > - default: > - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); > - break; > + error = pm_runtime_get_sync(dev); > + if (error < 0) { > + pm_runtime_put_noidle(dev); > + return error; > } > -} > - > -static int mxt_input_open(struct input_dev *dev) > -{ > - struct mxt_data *data = input_get_drvdata(dev); > - > - mxt_start(data); > > return 0; > } > > -static void mxt_input_close(struct input_dev *dev) > +static void mxt_input_close(struct input_dev *input_dev) > { > - struct mxt_data *data = input_get_drvdata(dev); > + struct mxt_data *data = input_get_drvdata(input_dev); > + struct device *dev = &data->client->dev; > > - mxt_stop(data); > + pm_runtime_put_sync(dev); > } > > static int mxt_parse_device_properties(struct mxt_data *data) > @@ -3036,6 +3006,7 @@ static const struct dmi_system_id chromebook_T9_suspend_dmi[] = { > static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) > { > struct mxt_data *data; > + struct device *dev; > int error; > > /* > @@ -3070,6 +3041,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) > snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", > client->adapter->nr, client->addr); > > + dev = &client->dev; > data->client = client; > data->irq = client->irq; > i2c_set_clientdata(client, data); > @@ -3109,20 +3081,23 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) > msleep(MXT_RESET_INVALID_CHG); > } > > + pm_runtime_enable(dev); > + > error = mxt_initialize(data); > if (error) > - return error; > + goto err_disable; > > error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); > if (error) { > dev_err(&client->dev, "Failure %d creating sysfs group\n", > error); > - goto err_free_object; > + goto err_disable; > } > > return 0; > > -err_free_object: > +err_disable: > + pm_runtime_disable(dev); > mxt_free_input_device(data); > mxt_free_object_table(data); > return error; > @@ -3131,11 +3106,69 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) > static int mxt_remove(struct i2c_client *client) > { > struct mxt_data *data = i2c_get_clientdata(client); > + struct device *dev = &data->client->dev; > > disable_irq(data->irq); > sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); > mxt_free_input_device(data); > mxt_free_object_table(data); > + pm_runtime_disable(dev); > + > + return 0; > +} > + > +static int __maybe_unused mxt_runtime_suspend(struct device *dev) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct mxt_data *data = i2c_get_clientdata(client); > + struct input_dev *input_dev = data->input_dev; > + > + if (!input_dev) > + return 0; > + > + switch (data->suspend_mode) { > + case MXT_SUSPEND_T9_CTRL: > + /* Touch disable */ > + mxt_write_object(data, > + MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0); > + break; > + > + case MXT_SUSPEND_DEEP_SLEEP: > + default: > + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); > + break; > + } > + > + return 0; > +} > + > +static int __maybe_unused mxt_runtime_resume(struct device *dev) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + struct mxt_data *data = i2c_get_clientdata(client); > + struct input_dev *input_dev = data->input_dev; > + > + if (!input_dev) > + return 0; > + > + switch (data->suspend_mode) { > + case MXT_SUSPEND_T9_CTRL: > + mxt_soft_reset(data); > + > + /* Touch enable */ > + /* 0x83 = SCANEN | RPTEN | ENABLE */ > + mxt_write_object(data, > + MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83); > + break; > + > + case MXT_SUSPEND_DEEP_SLEEP: > + default: > + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); > + > + /* Recalibrate since chip has been in deep sleep */ > + mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); > + break; > + } > > return 0; > } > @@ -3152,7 +3185,7 @@ static int __maybe_unused mxt_suspend(struct device *dev) > mutex_lock(&input_dev->mutex); > > if (input_dev->users) > - mxt_stop(data); > + mxt_runtime_suspend(dev); > > mutex_unlock(&input_dev->mutex); > > @@ -3175,14 +3208,17 @@ static int __maybe_unused mxt_resume(struct device *dev) > mutex_lock(&input_dev->mutex); > > if (input_dev->users) > - mxt_start(data); > + mxt_runtime_resume(dev); > > mutex_unlock(&input_dev->mutex); > > return 0; > } > > -static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); > +const struct dev_pm_ops mxt_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(mxt_suspend, mxt_resume) > + SET_RUNTIME_PM_OPS(mxt_runtime_suspend, mxt_runtime_resume, NULL) > +}; > > static const struct of_device_id mxt_of_match[] = { > { .compatible = "atmel,maxtouch", }, > - -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html