PM: Do not use the syscore flag for runtime PM
authorRafael J. Wysocki <rjw@sisk.pl>
Mon, 13 Aug 2012 12:00:25 +0000 (14:00 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Mon, 3 Sep 2012 23:36:05 +0000 (01:36 +0200)
The syscore device PM flag used to mark the devices (belonging to
PM domains) that should never be turned off, except for the system
core (syscore) suspend/hibernation and resume stages, need not be
accessed by the runtime PM core functions, because all of the devices
it is set for need to be marked as "irq safe" anyway and are
protected from being turned off by runtime PM by ensuring that their
usage counters are always set.

For this reason, make the syscore flag system-wide PM-specific
and simplify the code used for manipulating it, because it need not
acquire the device's power.lock any more.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
drivers/base/power/common.c
drivers/base/power/domain.c
drivers/base/power/runtime.c
include/linux/device.h
include/linux/pm.h

index cf7a85134730d579074808d0c42174ab04a1e9c7..39c32529b83374c36eda18188c393930732ad99f 100644 (file)
@@ -83,18 +83,3 @@ int dev_pm_put_subsys_data(struct device *dev)
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_put_subsys_data);
-
-/**
- * dev_pm_syscore_device - Set/unset the given device's power.syscore flag.
- * @dev: Device whose flag is to be modified.
- * @val: New value of the flag.
- */
-void dev_pm_syscore_device(struct device *dev, bool val)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev->power.lock, flags);
-       dev->power.syscore = val;
-       spin_unlock_irqrestore(&dev->power.lock, flags);
-}
-EXPORT_SYMBOL_GPL(dev_pm_syscore_device);
index d7e71b5b080ea6b29a88caa8249cb4afe8d6463a..5f4606f13be6922f2c56987fd7089e2cd4b82d5f 100644 (file)
@@ -442,7 +442,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
        not_suspended = 0;
        list_for_each_entry(pdd, &genpd->dev_list, list_node)
                if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
-                   || pdd->dev->power.irq_safe || pdd->dev->power.syscore))
+                   || pdd->dev->power.irq_safe))
                        not_suspended++;
 
        if (not_suspended > genpd->in_progress)
index bd1de3980919ca8dfa7670e15145b1ce796f9c1a..7d9c1cb1c39a7760081bae4d518efd8acf835902 100644 (file)
@@ -134,7 +134,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
 
        if (dev->power.runtime_error)
                retval = -EINVAL;
-       else if (dev->power.disable_depth > 0 || dev->power.syscore)
+       else if (dev->power.disable_depth > 0)
                retval = -EACCES;
        else if (atomic_read(&dev->power.usage_count) > 0)
                retval = -EAGAIN;
index 52a5f15a2223ecb916391138ca9cb44f5d5d108a..86529e642d6c047ac2399ba0c21c69e229adf755 100644 (file)
@@ -772,6 +772,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
        dev->power.ignore_children = enable;
 }
 
+static inline void dev_pm_syscore_device(struct device *dev, bool val)
+{
+#ifdef CONFIG_PM_SLEEP
+       dev->power.syscore = val;
+#endif
+}
+
 static inline void device_lock(struct device *dev)
 {
        mutex_lock(&dev->mutex);
index b79a0dd3bc6dcf8032dbc33f06bbbd54b35f71bb..44d1f2307dbc3a9d21ed0bb6a0e1948e91415b1a 100644 (file)
@@ -43,12 +43,8 @@ struct device;
 
 #ifdef CONFIG_PM
 extern const char power_group_name[];          /* = "power" */
-
-extern void dev_pm_syscore_device(struct device *dev, bool val);
 #else
 #define power_group_name       NULL
-
-static inline void dev_pm_syscore_device(struct device *dev, bool val) {}
 #endif
 
 typedef struct pm_message {
@@ -515,13 +511,13 @@ struct dev_pm_info {
        bool                    is_suspended:1; /* Ditto */
        bool                    ignore_children:1;
        bool                    early_init:1;   /* Owned by the PM core */
-       bool                    syscore:1;
        spinlock_t              lock;
 #ifdef CONFIG_PM_SLEEP
        struct list_head        entry;
        struct completion       completion;
        struct wakeup_source    *wakeup;
        bool                    wakeup_path:1;
+       bool                    syscore:1;
 #else
        unsigned int            should_wakeup:1;
 #endif