From: Greg Kroah-Hartman Date: Thu, 21 Feb 2019 12:34:17 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v3.18.136~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=361795e598e45c0b117a0ffc39e6e6540a89c5f0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: mfd-as3722-handle-interrupts-on-suspend.patch mfd-as3722-mark-pm-functions-as-__maybe_unused.patch --- diff --git a/queue-4.4/mfd-as3722-handle-interrupts-on-suspend.patch b/queue-4.4/mfd-as3722-handle-interrupts-on-suspend.patch new file mode 100644 index 00000000000..3d95af1db01 --- /dev/null +++ b/queue-4.4/mfd-as3722-handle-interrupts-on-suspend.patch @@ -0,0 +1,117 @@ +From 35deff7eb212b661b32177b6043f674fde6314d7 Mon Sep 17 00:00:00 2001 +From: Jon Hunter +Date: Fri, 20 Nov 2015 10:51:00 +0000 +Subject: mfd: as3722: Handle interrupts on suspend + +From: Jon Hunter + +commit 35deff7eb212b661b32177b6043f674fde6314d7 upstream. + +The as3722 device is registered as an irqchip and the as3722-rtc interrupt +is one of it's interrupt sources. When using the as3722-rtc as a wake-up +device from suspend, the following is seen: + + PM: Syncing filesystems ... done. + Freezing user space processes ... (elapsed 0.001 seconds) done. + Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. + Suspending console(s) (use no_console_suspend to debug) + PM: suspend of devices complete after 161.119 msecs + PM: late suspend of devices complete after 1.048 msecs + PM: noirq suspend of devices complete after 0.756 msecs + Disabling non-boot CPUs ... + CPU1: shutdown + CPU2: shutdown + CPU3: shutdown + Entering suspend state LP1 + Enabling non-boot CPUs ... + CPU1 is up + CPU2 is up + CPU3 is up + PM: noirq resume of devices complete after 0.487 msecs + as3722 4-0040: Failed to read IRQ status: -16 + as3722 4-0040: Failed to read IRQ status: -16 + as3722 4-0040: Failed to read IRQ status: -16 + as3722 4-0040: Failed to read IRQ status: -16 + ... + +The reason why the as3722 interrupt status cannot be read is because the +as3722 interrupt is not masked during suspend and when the as3722-rtc +interrupt occurs, to wake-up the device, the interrupt is seen before the +i2c controller has been resumed in order to read the as3722 interrupt +status. + +The as3722-rtc driver sets it's interrupt as a wake-up source during +suspend, which gets propagated to the parent as3722 interrupt. However, +the as3722-rtc driver cannot disable it's interrupt during suspend +otherwise we would never be woken up and so the as3722 must disable it's +interrupt instead. + +Fix this by disabling the as3722 interrupt during suspend. To ensure that +a wake-up event from the as3722 is not missing, enable the as3722 interrupt +as a wake-up source before disabling the interrupt on entering suspend. + +Signed-off-by: Jon Hunter +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/as3722.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/mfd/as3722.c ++++ b/drivers/mfd/as3722.c +@@ -405,6 +405,8 @@ static int as3722_i2c_probe(struct i2c_c + goto scrub; + } + ++ device_init_wakeup(as3722->dev, true); ++ + dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); + return 0; + +@@ -422,6 +424,29 @@ static int as3722_i2c_remove(struct i2c_ + return 0; + } + ++static int as3722_i2c_suspend(struct device *dev) ++{ ++ struct as3722 *as3722 = dev_get_drvdata(dev); ++ ++ if (device_may_wakeup(dev)) ++ enable_irq_wake(as3722->chip_irq); ++ disable_irq(as3722->chip_irq); ++ ++ return 0; ++} ++ ++static int as3722_i2c_resume(struct device *dev) ++{ ++ struct as3722 *as3722 = dev_get_drvdata(dev); ++ ++ enable_irq(as3722->chip_irq); ++ ++ if (device_may_wakeup(dev)) ++ disable_irq_wake(as3722->chip_irq); ++ ++ return 0; ++} ++ + static const struct of_device_id as3722_of_match[] = { + { .compatible = "ams,as3722", }, + {}, +@@ -434,10 +459,15 @@ static const struct i2c_device_id as3722 + }; + MODULE_DEVICE_TABLE(i2c, as3722_i2c_id); + ++static const struct dev_pm_ops as3722_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(as3722_i2c_suspend, as3722_i2c_resume) ++}; ++ + static struct i2c_driver as3722_i2c_driver = { + .driver = { + .name = "as3722", + .of_match_table = as3722_of_match, ++ .pm = &as3722_pm_ops, + }, + .probe = as3722_i2c_probe, + .remove = as3722_i2c_remove, diff --git a/queue-4.4/mfd-as3722-mark-pm-functions-as-__maybe_unused.patch b/queue-4.4/mfd-as3722-mark-pm-functions-as-__maybe_unused.patch new file mode 100644 index 00000000000..d18224f4d8a --- /dev/null +++ b/queue-4.4/mfd-as3722-mark-pm-functions-as-__maybe_unused.patch @@ -0,0 +1,50 @@ +From a7b956fd38dd217dd78e3058110929f5ac914df1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Dec 2015 16:21:05 +0100 +Subject: mfd: as3722: Mark PM functions as __maybe_unused + +From: Arnd Bergmann + +commit a7b956fd38dd217dd78e3058110929f5ac914df1 upstream. + +The newly introduced as3722_i2c_suspend/resume functions are built +unconditionally, but only used when power management is enabled, +so we get a warning otherwise: + +drivers/mfd/as3722.c:427:12: warning: 'as3722_i2c_suspend' defined but not used [-Wunused-function] +drivers/mfd/as3722.c:438:12: warning: 'as3722_i2c_resume' defined but not used [-Wunused-function] + +This marks them both as __maybe_unused, which avoids an ugly #ifdef +and gives us best compile-time coverage. When they are unused, the +compiler will silently drop the functions from its output. + +Signed-off-by: Arnd Bergmann +Fixes: 35deff7eb212 ("mfd: as3722: Handle interrupts on suspend") +Signed-off-by: Lee Jones +Cc: Jon Hunter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/as3722.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mfd/as3722.c ++++ b/drivers/mfd/as3722.c +@@ -424,7 +424,7 @@ static int as3722_i2c_remove(struct i2c_ + return 0; + } + +-static int as3722_i2c_suspend(struct device *dev) ++static int __maybe_unused as3722_i2c_suspend(struct device *dev) + { + struct as3722 *as3722 = dev_get_drvdata(dev); + +@@ -435,7 +435,7 @@ static int as3722_i2c_suspend(struct dev + return 0; + } + +-static int as3722_i2c_resume(struct device *dev) ++static int __maybe_unused as3722_i2c_resume(struct device *dev) + { + struct as3722 *as3722 = dev_get_drvdata(dev); + diff --git a/queue-4.4/series b/queue-4.4/series index be6ff282291..debea304899 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -12,3 +12,5 @@ net-stmmac-fix-a-race-in-eee-enable-callback.patch net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirect-packets.patch x86-livepatch-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch kvm-fix-kvm_ioctl_create_device-reference-counting-cve-2019-6974.patch +mfd-as3722-handle-interrupts-on-suspend.patch +mfd-as3722-mark-pm-functions-as-__maybe_unused.patch