| From de71e6b71ed340378ff5fcb868da68bd4c9f65de Mon Sep 17 00:00:00 2001 |
| From: Tony Lindgren <tony@atomide.com> |
| Date: Thu, 10 Jan 2019 07:59:16 -0800 |
| Subject: i2c: omap: Use noirq system sleep pm ops to idle device for suspend |
| |
| [ Upstream commit c6e2bd956936d925748581e4d0294f10f1d92f2c ] |
| |
| We currently get the following error with pixcir_ts driver during a |
| suspend resume cycle: |
| |
| omap_i2c 4802a000.i2c: controller timed out |
| pixcir_ts 1-005c: pixcir_int_enable: can't read reg 0x34 : -110 |
| pixcir_ts 1-005c: Failed to disable interrupt generation: -110 |
| pixcir_ts 1-005c: Failed to stop |
| dpm_run_callback(): pixcir_i2c_ts_resume+0x0/0x98 |
| [pixcir_i2c_ts] returns -110 |
| PM: Device 1-005c failed to resume: error -110 |
| |
| And at least am437x based devices with pixcir_ts will fail to resume |
| to a touchscreen that is configured as the wakeup-source in device |
| tree for these devices. |
| |
| This is because pixcir_ts tries to reconfigure it's registers for |
| noirq suspend which fails. This also leaves i2c-omap in enabled state |
| for suspend. |
| |
| Let's fix the pixcir_ts issue and make sure i2c-omap is suspended by |
| adding SET_NOIRQ_SYSTEM_SLEEP_PM_OPS. |
| |
| Let's also get rid of some ifdefs while at it and replace them with |
| __maybe_unused as SET_RUNTIME_PM_OPS and SET_NOIRQ_SYSTEM_SLEEP_PM_OPS |
| already deal with the various PM Kconfig options. |
| |
| Reported-by: Keerthy <j-keerthy@ti.com> |
| Signed-off-by: Tony Lindgren <tony@atomide.com> |
| Acked-by: Vignesh R <vigneshr@ti.com> |
| Signed-off-by: Wolfram Sang <wsa@the-dreams.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/i2c/busses/i2c-omap.c | 13 +++++-------- |
| 1 file changed, 5 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c |
| index 65d06a819307..2ac86096ddd9 100644 |
| --- a/drivers/i2c/busses/i2c-omap.c |
| +++ b/drivers/i2c/busses/i2c-omap.c |
| @@ -1498,8 +1498,7 @@ static int omap_i2c_remove(struct platform_device *pdev) |
| return 0; |
| } |
| |
| -#ifdef CONFIG_PM |
| -static int omap_i2c_runtime_suspend(struct device *dev) |
| +static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev) |
| { |
| struct omap_i2c_dev *omap = dev_get_drvdata(dev); |
| |
| @@ -1525,7 +1524,7 @@ static int omap_i2c_runtime_suspend(struct device *dev) |
| return 0; |
| } |
| |
| -static int omap_i2c_runtime_resume(struct device *dev) |
| +static int __maybe_unused omap_i2c_runtime_resume(struct device *dev) |
| { |
| struct omap_i2c_dev *omap = dev_get_drvdata(dev); |
| |
| @@ -1540,20 +1539,18 @@ static int omap_i2c_runtime_resume(struct device *dev) |
| } |
| |
| static const struct dev_pm_ops omap_i2c_pm_ops = { |
| + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| + pm_runtime_force_resume) |
| SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend, |
| omap_i2c_runtime_resume, NULL) |
| }; |
| -#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) |
| -#else |
| -#define OMAP_I2C_PM_OPS NULL |
| -#endif /* CONFIG_PM */ |
| |
| static struct platform_driver omap_i2c_driver = { |
| .probe = omap_i2c_probe, |
| .remove = omap_i2c_remove, |
| .driver = { |
| .name = "omap_i2c", |
| - .pm = OMAP_I2C_PM_OPS, |
| + .pm = &omap_i2c_pm_ops, |
| .of_match_table = of_match_ptr(omap_i2c_of_match), |
| }, |
| }; |
| -- |
| 2.19.1 |
| |