PM / Sleep / Runtime: Fixup some driver's system suspend
Subsystems (10)
v3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
Patch 1 -> 2:
These patches provides two new runtime PM helper functions which intend to be used from system suspend/resume callbacks, to make sure devices are put into low power state during system suspend and brought back to full power at system resume.
The prerequisite is to have all levels of a device's runtime PM callbacks to be defined through the SET_PM_RUNTIME_PM_OPS macro, which means these are available for CONFIG_PM.
By using the new runtime PM helper functions especially the two scenarios below will be addressed.
1) The PM core prevents .runtime_suspend callbacks from being invoked during system suspend. That means even for a runtime PM centric subsystem and driver, the device needs to be put into low power state from a system suspend callback. Otherwise it may very well be left in full power state (runtime resumed) while the system is suspended. By using the new helper functions, we make sure to walk the hierarchy of a device's power domain, subsystem and driver.
2) Subsystems and drivers need to cope with all the combinations of CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME. The two new helper functions smothly addresses this.
Patch 3 -> 4:
Fixup system suspend for spi-pl022 driver, by using the new runtime PM helper functions.
These patches is based upon the latest next-branch for spi-pl022 driver. They will not apply to Rafael's linux-pm tree, but are included in this patchset for reference and to receive comments/acks.
Patch 5:
Fixup system suspend for i2c-nomadik driver, by using the new runtime PM helper functions.
This patch is based upon the latest next-branch for the i2c-nomadik driver. They will not apply to Rafael's linux-pm tree, but are included in this patchset for reference and to receive comments/acks.
Patch 6 -> 8:
Fixup system suspend for mmci driver, by using the new runtime PM helper functions.
A final note, the amba bus has converted to use the SET_PM_RUNTIME_PM_OPS which is needed for these patches to work with only CONFIG_PM_SLEEP and not CONFIG_PM_RUNTIME. Anyway, the patches for the amba bus have recently been applied by Russell and resides in his ARM tree.
Changes in v3:
This is repost of the patchset. Only patch 1 and patch 2 has been updated to v3, the rest are still in v1.
Ulf Hansson (8):
PM / Runtime: Fetch runtime PM callbacks using a macro
PM / Sleep / Runtime: Add pm_runtime_suspend|resume_force functions
spi: pl022: Let runtime PM callbacks be available for CONFIG_PM
spi: pl022: Don't ignore power domain and amba bus at system suspend
i2c: nomadik: Fixup system suspend
mmc: mmci: Mask IRQs for all variants during runtime suspend
mmc: mmci: Let runtime PM callbacks be available for CONFIG_PM
mmc: mmci: Put the device into low power state at system suspend
drivers/base/power/Makefile | 3 +- drivers/base/power/runtime.c | 162 +++++++++++++++++++++++++++++--------- drivers/i2c/busses/i2c-nomadik.c | 14 ++-- drivers/mmc/host/mmci.c | 60 ++++---------- drivers/spi/spi-pl022.c | 58 +++++--------- include/linux/pm_runtime.h | 4 + 6 files changed, 170 insertions(+), 131 deletions(-)
Signature · 1 line
1.7.9.5
PATCH v3 1/8 PM / Runtime: Fetch runtime PM callbacks using a macro
While fetching the proper runtime PM callback, we walk the hierarchy of device's power domains, subsystems and drivers.
This is common for rpm_suspend(), rpm_idle() and rpm_resume(). Let's clean up the code by using a macro that handles this.
---
Changes in v3:
Added functions to return the callbacks, which will be the only users of the macro. According to comments from Alan Stern and Kevin Hilman.
Changes in v2:
Updated the macro to return a callback instead. Suggested by Josh Cartwright.
--- drivers/base/power/runtime.c | 78 +++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 39 deletions(-)
drivers/base/power/runtime.c +39 -39
@@ -13,6 +13,42 @@#include <trace/events/rpm.h> #include "power.h" +#define RPM_GET_CALLBACK (dev, cb) \ +({ \ + int (*__rpm_cb)(struct device *__d); \ + \ + if (dev->pm_domain) \ + __rpm_cb = dev->pm_domain->ops.cb; \ + else if (dev->type && dev->type->pm) \ + __rpm_cb = dev->type->pm->cb; \ + else if (dev->class && dev->class->pm) \ + __rpm_cb = dev->class->pm->cb; \ + else if (dev->bus && dev->bus->pm) \ + __rpm_cb = dev->bus->pm->cb; \ + else \ + __rpm_cb = NULL; \ + \ + if (!__rpm_cb && dev->driver && dev->driver->pm) \ + __rpm_cb = dev->driver->pm->cb; \ + \ + __rpm_cb; \ +}) + +static int (*rpm_get_suspend_cb (struct device *dev))(struct device *) +{ +return RPM_GET_CALLBACK (dev, runtime_suspend); +} + +static int (*rpm_get_resume_cb (struct device *dev))(struct device *) +{ +return RPM_GET_CALLBACK (dev, runtime_resume); +} + +static int (*rpm_get_idle_cb (struct device *dev))(struct device *) +{ +return RPM_GET_CALLBACK (dev, runtime_idle); +} +static int rpm_resume (struct device *dev,int rpmflags);static int rpm_suspend (struct device *dev,int rpmflags);
@@ -310,19 +346,7 @@ static int rpm_idle(struct device *dev, int rpmflags) dev->power.idle_notification = true; -if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_idle; -else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_idle; -else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_idle; -else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_idle; -else - callback =NULL ; - -if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_idle; + callback =rpm_get_idle_cb (dev);if (callback) retval =__rpm_callback (callback, dev);
@@ -492,19 +516,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)__update_runtime_status (dev,RPM_SUSPENDING ); -if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_suspend; -else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_suspend; -else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_suspend; -else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_suspend; -else - callback =NULL ; - -if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_suspend; + callback =rpm_get_suspend_cb (dev); retval =rpm_callback (callback, dev);if (retval)
@@ -724,19 +736,7 @@ static int rpm_resume(struct device *dev, int rpmflags)__update_runtime_status (dev,RPM_RESUMING ); -if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_resume; -else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_resume; -else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_resume; -else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_resume; -else - callback =NULL ; - -if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_resume; + callback =rpm_get_resume_cb (dev); retval =rpm_callback (callback, dev);if (retval) {
Signature · 1 line
1.7.9.5
PATCH v3 2/8 PM / Sleep / Runtime: Add pm_runtime_suspend|resume_force functions
In reply to Ulf HanssonThis patch provides two new runtime PM helper functions which intend to be used from system suspend/resume callbacks, to make sure devices are put into low power state during system suspend and brought back to full power at system resume.
The prerequisite is to have all levels of a device's runtime PM callbacks to be defined through the SET_PM_RUNTIME_PM_OPS macro, which means these are available for CONFIG_PM.
By using the new runtime PM helper functions especially the two scenarios below will be addressed.
1) The PM core prevents .runtime_suspend callbacks from being invoked during system suspend. That means even for a runtime PM centric subsystem and driver, the device needs to be put into low power state from a system suspend callback. Otherwise it may very well be left in full power state (runtime resumed) while the system is suspended. By using the new helper functions, we make sure to walk the hierarchy of a device's power domain, subsystem and driver.
2) Subsystems and drivers need to cope with all the combinations of CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME. The two new helper functions smothly addresses this.
---
Changes in v3:
Use rpm_get_suspend|resume_cb() instead of the macro.
Changes in v2:
Adopt to version 2 of the RPM_GET_CALLBACK macro.
--- drivers/base/power/Makefile | 3 +- drivers/base/power/runtime.c | 84 ++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_runtime.h | 4 ++ 3 files changed, 89 insertions(+), 2 deletions(-)
drivers/base/power/Makefile +1 -2
@@ -1,6 +1,5 @@ -obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o +obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o runtime.o obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o -obj-$(CONFIG_PM_RUNTIME) += runtime.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_PM_OPP) += opp.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o
drivers/base/power/runtime.c +84 -0
93 lines not on this page · raw message
include/linux/pm_runtime.h +4 -0
@@ -26,9 +26,13 @@#ifdef CONFIG_PM extern int pm_generic_runtime_suspend (struct device *dev);extern int pm_generic_runtime_resume (struct device *dev); +extern int pm_runtime_force_suspend (struct device *dev); +extern int pm_runtime_force_resume (struct device *dev);#else static inline int pm_generic_runtime_suspend (struct device *dev) {return 0 ; }static inline int pm_generic_runtime_resume (struct device *dev) {return 0 ; } +static inline int pm_runtime_force_suspend (struct device *dev) {return 0 ; } +static inline int pm_runtime_force_resume (struct device *dev) {return 0 ; }#endif #ifdef CONFIG_PM_RUNTIME
Signature · 1 line
1.7.9.5
PATCH v3 2/8 PM / Sleep / Runtime: Add pm_runtime_suspend|resume_force functions
Quoted 24 lines · Ulf Hansson
This patch provides two new runtime PM helper functions which intend to be used from system suspend/resume callbacks, to make sure devices are put into low power state during system suspend and brought back to full power at system resume.
The prerequisite is to have all levels of a device's runtime PM callbacks to be defined through the
SET_PM_RUNTIME_PM_OPSmacro, which means these are available forCONFIG_PM.By using the new runtime PM helper functions especially the two scenarios below will be addressed.
1) The PM core prevents .runtime_suspend callbacks from being invoked during system suspend. That means even for a runtime PM centric subsystem and driver, the device needs to be put into low power state from a system suspend callback. Otherwise it may very well be left in full power state (runtime resumed) while the system is suspended. By using the new helper functions, we make sure to walk the hierarchy of a device's power domain, subsystem and driver.
2) Subsystems and drivers need to cope with all the combinations of
CONFIG_PM_SLEEPandCONFIG_PM_RUNTIME. The two new helper functions smothly addresses this.
Quoted 9 lines
Cc Kevin Hilman <[email protected]>Cc Alan Stern <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Cc Mark Brown <[email protected]>Cc Russell King <[email protected]>Cc Linus Walleij <[email protected]>Cc Wolfram Sang <[email protected]>Cc Alessandro Rubini <[email protected]>Signed-off-by Ulf Hansson <[email protected]>
FWIW
PATCH v3 3/8 spi: pl022: Let runtime PM callbacks be available for CONFIG_PM
In reply to Ulf HanssonConvert to the SET_PM_RUNTIME_PM macro while defining the runtime PM callbacks. This means the callbacks becomes available for both CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME, which is needed to handle the combinations of these scenarios.
--- drivers/spi/spi-pl022.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/spi/spi-pl022.c +3 -3
@@ -2277,7 +2277,7 @@ pl022_remove(struct amba_device *adev)return 0 ; } -#if defined(CONFIG_SUSPEND ) || defined(CONFIG_PM_RUNTIME ) +#ifdef CONFIG_PM /* * These two functions are used from both suspend/resume and * the runtime counterparts to handle external resources like
@@ -2343,7 +2343,7 @@ static int pl022_resume(struct device *dev) }#endif /* CONFIG_PM */ -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int pl022_runtime_suspend (struct device *dev) {struct pl022 *pl022 =dev_get_drvdata (dev);
@@ -2363,7 +2363,7 @@ static int pl022_runtime_resume(struct device *dev)static const struct dev_pm_ops pl022_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) -SET_RUNTIME_PM_OPS (pl022_runtime_suspend, pl022_runtime_resume,NULL ) +SET_PM_RUNTIME_PM_OPS (pl022_runtime_suspend, pl022_runtime_resume,NULL ) };static struct vendor_data vendor_arm = {
Signature · 1 line
1.7.9.5
Mark Brown
maintainerPATCH v3 3/8 spi: pl022: Let runtime PM callbacks be available for CONFIG_PM
Quoted 4 lines · Ulf Hansson
Convert to the
SET_PM_RUNTIME_PMmacro while defining the runtime PM callbacks. This means the callbacks becomes available for bothCONFIG_PM_SLEEPandCONFIG_PM_RUNTIME, which is needed to handle the combinations of these scenarios.
Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140306/58aee6a0/attachment-0001.sig>
PATCH v3 4/8 spi: pl022: Don't ignore power domain and amba bus at system suspend
In reply to Ulf HanssonPreviously only the resources controlled by the driver were put into low power state at system suspend. Both the amba bus and a potential power domain were ignored.
Moreover, while putting the device into low power state we first brought it back to full power, but for no particular reason.
To handle both issues above, use pm_runtime_force_suspend|resume() from the system suspend|resume callbacks.
--- drivers/spi/spi-pl022.c | 54 ++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-)
drivers/spi/spi-pl022.c +18 -36
@@ -2277,35 +2277,7 @@ pl022_remove(struct amba_device *adev)return 0 ; } -#ifdef CONFIG_PM -/* -* These two functions are used from both suspend/resume and -* the runtime counterparts to handle external resources like -* clocks, pins and regulators when going to sleep. -*/ -static void pl022_suspend_resources (struct pl022 *pl022,bool runtime) -{ -clk_disable_unprepare (pl022->clk); - -if (runtime) -pinctrl_pm_select_idle_state (&pl022->adev->dev); -else -pinctrl_pm_select_sleep_state (&pl022->adev->dev); -} - -static void pl022_resume_resources (struct pl022 *pl022,bool runtime) -{ -/* First go to the default state */ -pinctrl_pm_select_default_state (&pl022->adev->dev); -if (!runtime) -/* Then let's idle the pins until the next transfer happens */ -pinctrl_pm_select_idle_state (&pl022->adev->dev); - -clk_prepare_enable (pl022->clk); -} -#endif - -#ifdef CONFIG_SUSPEND +#ifdef CONFIG_PM_SLEEP static int pl022_suspend (struct device *dev) {struct pl022 *pl022 =dev_get_drvdata (dev);
@@ -2317,8 +2289,13 @@ static int pl022_suspend(struct device *dev)return ret; } -pm_runtime_get_sync (dev); -pl022_suspend_resources (pl022, false); + ret =pm_runtime_force_suspend (dev); +if (ret) { +spi_master_resume (pl022->master); +return ret; + } + +pinctrl_pm_select_sleep_state (dev);dev_dbg (dev,"suspended\n" );return 0 ;
@@ -2329,8 +2306,9 @@ static int pl022_resume(struct device *dev)struct pl022 *pl022 =dev_get_drvdata (dev);int ret; -pl022_resume_resources (pl022, false); -pm_runtime_put (dev); + ret =pm_runtime_force_resume (dev); +if (ret) +dev_err (dev,"problem resuming\n" );/* Start the queue running */ ret =spi_master_resume (pl022->master);
@@ -2341,14 +2319,16 @@ static int pl022_resume(struct device *dev) return ret; } -#endif /* CONFIG_PM */ +#endif #ifdef CONFIG_PM static int pl022_runtime_suspend (struct device *dev) {struct pl022 *pl022 =dev_get_drvdata (dev); -pl022_suspend_resources (pl022, true); +clk_disable_unprepare (pl022->clk); +pinctrl_pm_select_idle_state (dev); +return 0 ; }
@@ -2356,7 +2336,9 @@ static int pl022_runtime_resume(struct device *dev) {struct pl022 *pl022 =dev_get_drvdata (dev); -pl022_resume_resources (pl022, true); +pinctrl_pm_select_default_state (dev); +clk_prepare_enable (pl022->clk); +return 0 ; }#endif
Signature · 1 line
1.7.9.5
Mark Brown
maintainerPATCH v3 4/8 spi: pl022: Don't ignore power domain and amba bus at system suspend
Quoted 3 lines · Ulf Hansson
Previously only the resources controlled by the driver were put into low power state at system suspend. Both the amba bus and a potential power domain were ignored.
Applied, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140306/0960093d/attachment.sig>
PATCH v3 5/8 i2c: nomadik: Fixup system suspend
In reply to Ulf HanssonFor !CONFIG_PM_RUNTIME, the device were never put back into active state while resuming.
For CONFIG_PM_RUNTIME, we blindly trusted the device to be inactive while we were about to handle it at suspend late, which is just too optimistic.
Even if the driver uses pm_runtime_put_sync() after each tranfer to return it's runtime PM resources, there are no guarantees this will actually mean the device will inactivated. The reason is that the PM core will prevent runtime suspend during system suspend, and thus when a transfer occurs during the early phases of system suspend the device will be kept active after the transfer.
To handle both issues above, use pm_runtime_force_suspend|resume() from the system suspend|resume callbacks.
--- drivers/i2c/busses/i2c-nomadik.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/i2c/busses/i2c-nomadik.c +7 -7
@@ -879,19 +879,19 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)#ifdef CONFIG_PM_SLEEP static int nmk_i2c_suspend_late (struct device *dev) { -pinctrl_pm_select_sleep_state (dev); +int ret; + ret =pm_runtime_force_suspend (dev); +if (ret) +return ret; + +pinctrl_pm_select_sleep_state (dev);return 0 ; }static int nmk_i2c_resume_early (struct device *dev) { -/* First go to the default state */ -pinctrl_pm_select_default_state (dev); -/* Then let's idle the pins until the next transfer happens */ -pinctrl_pm_select_idle_state (dev); - -return 0 ; +return pm_runtime_force_resume (dev); }#endif
Signature · 1 line
1.7.9.5
PATCH v3 5/8 i2c: nomadik: Fixup system suspend
Quoted 14 lines · Ulf Hansson
For !CONFIG_PM_RUNTIME, the device were never put back into active state while resuming.
For
CONFIG_PM_RUNTIME, we blindly trusted the device to be inactive while we were about to handle it at suspend late, which is just too optimistic.Even if the driver uses
pm_runtime_put_sync()after each tranfer to return it's runtime PM resources, there are no guarantees this will actually mean the device will inactivated. The reason is that the PM core will prevent runtime suspend during system suspend, and thus when a transfer occurs during the early phases of system suspend the device will be kept active after the transfer.
Quoted 7 lines
To handle both issues above, use pm_runtime_force_suspend|resume() from the system suspend|resume callbacks.
Cc Alessandro Rubini <[email protected]>Cc Linus Walleij <[email protected]>Cc Wolfram Sang <[email protected]>Signed-off-by Ulf Hansson <[email protected]>
Hi Wolfram,
The pm-drivers branch of the linux-pm.git, contains the helper functions this patch depends on.
If you decide to pull that branch to your tree, to be able to apply this patch, please let me know. Otherwise I will repost this patch once 3.15 rc1 is available.
Kind regards
Ulf Hansson
Quoted 38 lines
--- drivers/i2c/busses/i2c-nomadik.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)drivers/i2c/busses/i2c-nomadik.c +7
-8@@ -879,19 +879,19 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)#ifdef CONFIG_PM_SLEEP static int nmk_i2c_suspend_late (struct device *dev) { -pinctrl_pm_select_sleep_state (dev); +int ret; + ret =pm_runtime_force_suspend (dev); +if (ret) +return ret; + +pinctrl_pm_select_sleep_state (dev);return 0 ; }static int nmk_i2c_resume_early (struct device *dev) { -/* First go to the default state */ -pinctrl_pm_select_default_state (dev); -/* Then let's idle the pins until the next transfer happens */ -pinctrl_pm_select_idle_state (dev); - -return 0 ; +return pm_runtime_force_resume (dev); }#endif --1.7.9.5
PATCH v3 6/8 mmc: mmci: Mask IRQs for all variants during runtime suspend
In reply to Ulf HanssonIn runtime suspended state, we are not expecting IRQs and thus we can safely mask them, not only for pwrreg_nopower variants but for all.
Obviously we then also need to make sure we restore the IRQ mask while becoming runtime resumed.
--- drivers/mmc/host/mmci.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
drivers/mmc/host/mmci.c +11 -12
@@ -1758,35 +1758,34 @@ static void mmci_save(struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); -writel (0 , host->base +MMCIMASK0 ); +writel (0 , host->base +MMCIMASK0 ); +if (host->variant->pwrreg_nopower) {writel (0 , host->base +MMCIDATACTRL );writel (0 , host->base +MMCIPOWER );writel (0 , host->base +MMCICLOCK ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +mmci_reg_delay (host); +spin_unlock_irqrestore (&host->lock, flags); }static void mmci_restore (struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); +if (host->variant->pwrreg_nopower) {writel (host->clk_reg, host->base +MMCICLOCK );writel (host->datactrl_reg, host->base +MMCIDATACTRL );writel (host->pwr_reg, host->base +MMCIPOWER ); -writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); +mmci_reg_delay (host); + +spin_unlock_irqrestore (&host->lock, flags); }static int mmci_runtime_suspend (struct device *dev)
Signature · 1 line
1.7.9.5
PATCH v3 6/8 mmc: mmci: Mask IRQs for all variants during runtime suspend
Quoted 8 lines · Ulf Hansson
In runtime suspended state, we are not expecting IRQs and thus we can safely mask them, not only for
pwrreg_nopowervariants but for all.Obviously we then also need to make sure we restore the IRQ mask while becoming runtime resumed.
Cc Russell King <[email protected]>Signed-off-by Ulf Hansson <[email protected]>
Hi Russell,
I suppose we have discussed and sorted out the concerns you had around this patch!?
It's available in your patch tracker, would be nice to get it merged for 3.15, if that's possible.
Kind regards
Uffe
Quoted 58 lines
--- drivers/mmc/host/mmci.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)drivers/mmc/host/mmci.c +11
-13@@ -1758,35 +1758,34 @@ static void mmci_save(struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); -writel (0 , host->base +MMCIMASK0 ); +writel (0 , host->base +MMCIMASK0 ); +if (host->variant->pwrreg_nopower) {writel (0 , host->base +MMCIDATACTRL );writel (0 , host->base +MMCIPOWER );writel (0 , host->base +MMCICLOCK ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +mmci_reg_delay (host); +spin_unlock_irqrestore (&host->lock, flags); }static void mmci_restore (struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); +if (host->variant->pwrreg_nopower) {writel (host->clk_reg, host->base +MMCICLOCK );writel (host->datactrl_reg, host->base +MMCIDATACTRL );writel (host->pwr_reg, host->base +MMCIPOWER ); -writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); +mmci_reg_delay (host); + +spin_unlock_irqrestore (&host->lock, flags); }static int mmci_runtime_suspend (struct device *dev) --1.7.9.5
PATCH v3 6/8 mmc: mmci: Mask IRQs for all variants during runtime suspend
Quoted 12 lines · Ulf Hansson
Quoted 8 lines · Ulf Hansson
In runtime suspended state, we are not expecting IRQs and thus we can safely mask them, not only for
pwrreg_nopowervariants but for all.Obviously we then also need to make sure we restore the IRQ mask while becoming runtime resumed.
Cc Russell King <[email protected]>Signed-off-by Ulf Hansson <[email protected]>Hi Russell,
Quoted 8 lines
I suppose we have discussed and sorted out the concerns you had around this patch!?
It's available in your patch tracker, would be nice to get it merged for 3.15, if that's possible.
Kind regards
Uffe
Sorry for spamming, this went to the wrong addresses. Let's try again.
Kind regards
Uffe
Quoted 59 lines
Quoted 59 lines
--- drivers/mmc/host/mmci.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)drivers/mmc/host/mmci.c +11
-13@@ -1758,35 +1758,34 @@ static void mmci_save(struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); -writel (0 , host->base +MMCIMASK0 ); +writel (0 , host->base +MMCIMASK0 ); +if (host->variant->pwrreg_nopower) {writel (0 , host->base +MMCIDATACTRL );writel (0 , host->base +MMCIPOWER );writel (0 , host->base +MMCICLOCK ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +mmci_reg_delay (host); +spin_unlock_irqrestore (&host->lock, flags); }static void mmci_restore (struct mmci_host *host) {unsigned long flags; -if (host->variant->pwrreg_nopower) { -spin_lock_irqsave (&host->lock, flags); +spin_lock_irqsave (&host->lock, flags); +if (host->variant->pwrreg_nopower) {writel (host->clk_reg, host->base +MMCICLOCK );writel (host->datactrl_reg, host->base +MMCIDATACTRL );writel (host->pwr_reg, host->base +MMCIPOWER ); -writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); -mmci_reg_delay (host); - -spin_unlock_irqrestore (&host->lock, flags); } +writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); +mmci_reg_delay (host); + +spin_unlock_irqrestore (&host->lock, flags); }static int mmci_runtime_suspend (struct device *dev) --1.7.9.5
PATCH v3 7/8 mmc: mmci: Let runtime PM callbacks be available for CONFIG_PM
In reply to Ulf HanssonConvert to the SET_PM_RUNTIME_PM macro while defining the runtime PM callbacks. This means the callbacks becomes available for both CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME, which is needed to handle the combinations of these scenarios.
--- drivers/mmc/host/mmci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/mmci.c +2 -2
@@ -1753,7 +1753,7 @@ static int mmci_resume(struct device *dev) }#endif -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static void mmci_save (struct mmci_host *host) {unsigned long flags;
@@ -1821,7 +1821,7 @@ static int mmci_runtime_resume(struct device *dev)static const struct dev_pm_ops mmci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) -SET_RUNTIME_PM_OPS (mmci_runtime_suspend, mmci_runtime_resume,NULL ) +SET_PM_RUNTIME_PM_OPS (mmci_runtime_suspend, mmci_runtime_resume,NULL ) };static struct amba_id mmci_ids[] = {
Signature · 1 line
1.7.9.5
PATCH v3 8/8 mmc: mmci: Put the device into low power state at system suspend
In reply to Ulf HanssonFor CONFIG_PM_SLEEP, the device were always left in full power state after system suspend.
We solely relied on a power domain to put it into low power state, which is an unreasonable requirement to put on SOCs to implement. Especially for those SOCs not supporting power domains at all.
Use pm_runtime_force_suspend|resume() as the system suspend callbacks, to resolve the issue.
--- drivers/mmc/host/mmci.c | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-)
drivers/mmc/host/mmci.c +2 -31
@@ -1723,36 +1723,6 @@ static int mmci_remove(struct amba_device *dev)return 0 ; } -#ifdef CONFIG_SUSPEND -static int mmci_suspend (struct device *dev) -{ -struct amba_device *adev =to_amba_device (dev); -struct mmc_host *mmc =amba_get_drvdata (adev); - -if (mmc) { -struct mmci_host *host =mmc_priv (mmc); -pm_runtime_get_sync (dev); -writel (0 , host->base +MMCIMASK0 ); - } - -return 0 ; -} - -static int mmci_resume (struct device *dev) -{ -struct amba_device *adev =to_amba_device (dev); -struct mmc_host *mmc =amba_get_drvdata (adev); - -if (mmc) { -struct mmci_host *host =mmc_priv (mmc); -writel (MCI_IRQENABLE , host->base +MMCIMASK0 ); -pm_runtime_put (dev); - } - -return 0 ; -} -#endif -#ifdef CONFIG_PM static void mmci_save (struct mmci_host *host) {
@@ -1820,7 +1790,8 @@ static int mmci_runtime_resume(struct device *dev)#endif static const struct dev_pm_ops mmci_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume)SET_PM_RUNTIME_PM_OPS (mmci_runtime_suspend, mmci_runtime_resume,NULL ) };
Signature · 1 line
1.7.9.5
v3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
In reply to Ulf HanssonQuoted 20 lines · Ulf Hansson
Patch 1 -> 2:
These patches provides two new runtime PM helper functions which intend to be used from system suspend/resume callbacks, to make sure devices are put into low power state during system suspend and brought back to full power at system resume.The prerequisite is to have all levels of a device's runtime PM callbacks to be defined through the
SET_PM_RUNTIME_PM_OPSmacro, which means these are available forCONFIG_PM.By using the new runtime PM helper functions especially the two scenarios below will be addressed.
1) The PM core prevents .runtime_suspend callbacks from being invoked during system suspend. That means even for a runtime PM centric subsystem and driver, the device needs to be put into low power state from a system suspend callback. Otherwise it may very well be left in full power state (runtime resumed) while the system is suspended. By using the new helper functions, we make sure to walk the hierarchy of a device's power domain, subsystem and driver.
Quoted 3 lines
2) Subsystems and drivers need to cope with all the combinations of
CONFIG_PM_SLEEPandCONFIG_PM_RUNTIME. The two new helper functions smothly addresses this.
OK, I've queued up [1-2/8] for 3.15. The rest generally didn't apply for me and I think it'd be better to push them through the respective subsystem trees later anyway.
Thanks!
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
v3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
Quoted 21 lines · Rafael J. Wysocki
Quoted 20 lines · Ulf Hansson
Patch 1 -> 2:
These patches provides two new runtime PM helper functions which intend to be used from system suspend/resume callbacks, to make sure devices are put into low power state during system suspend and brought back to full power at system resume.The prerequisite is to have all levels of a device's runtime PM callbacks to be defined through the
SET_PM_RUNTIME_PM_OPSmacro, which means these are available forCONFIG_PM.By using the new runtime PM helper functions especially the two scenarios below will be addressed.
1) The PM core prevents .runtime_suspend callbacks from being invoked during system suspend. That means even for a runtime PM centric subsystem and driver, the device needs to be put into low power state from a system suspend callback. Otherwise it may very well be left in full power state (runtime resumed) while the system is suspended. By using the new helper functions, we make sure to walk the hierarchy of a device's power domain, subsystem and driver.
Quoted 7 lines
Quoted 3 lines
2) Subsystems and drivers need to cope with all the combinations of
CONFIG_PM_SLEEPandCONFIG_PM_RUNTIME. The two new helper functions smothly addresses this.OK, I've queued up [1-2/8] for 3.15. The rest generally didn't apply for me and I think it'd be better to push them through the respective subsystem trees later anyway.
Thanks Rafael!
Agree, regarding 3->8, they were at this point mostly included for your reference.
Kind regards
Uffe
Quoted 6 lines
Thanks!
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
Mark Brown
maintainerv3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
In reply to Rafael J. WysockiQuoted 3 lines · Rafael J. Wysocki
OK, I've queued up [1-2/8] for 3.15. The rest generally didn't apply for me and I think it'd be better to push them through the respective subsystem trees later anyway.
Is there a tag we can pull to get those patches? The driver changes
depend on the new API introduced in patch 2.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140305/b9b21cb4/attachment.sig>
v3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
Quoted 8 lines · Mark Brown
Quoted 3 lines · Rafael J. Wysocki
OK, I've queued up [1-2/8] for 3.15. The rest generally didn't apply for me and I think it'd be better to push them through the respective subsystem trees later anyway.
Is there a tag we can pull to get those patches? The driver changes depend on the new API introduced in patch 2.
They are in the pm-drivers branch of linux-pm.git.
Thanks!
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Mark Brown
maintainerv3 cover PM / Sleep / Runtime: Fixup some driver's system suspend
Quoted 6 lines · Rafael J. Wysocki
Quoted 2 lines · Mark Brown
Is there a tag we can pull to get those patches? The driver changes depend on the new API introduced in patch 2.
They are in the pm-drivers branch of linux-pm.git.
I've pulled them now, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140306/545f45c6/attachment-0001.sig>