PM / Sleep: introduce dpm_for_each_dev
authorMing Lei <ming.lei@canonical.com>
Fri, 17 Aug 2012 14:06:59 +0000 (22:06 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Aug 2012 14:37:35 +0000 (07:37 -0700)
dpm_list and its pm lock provide a good way to iterate all
devices in system. Except this way, there is no other easy
way to iterate devices in system.

firmware loader need to cache firmware images for devices
before system sleep, so introduce the function to meet its
demand.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/power/main.c
include/linux/pm.h

index 0113adc310dccc4a62a325cccde4221f34c5ce7e..b0b072a88f5fdaf8447ae6fb9133a613be8fac06 100644 (file)
@@ -1324,3 +1324,25 @@ int device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
        return async_error;
 }
 EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
+
+/**
+ * dpm_for_each_dev - device iterator.
+ * @data: data for the callback.
+ * @fn: function to be called for each device.
+ *
+ * Iterate over devices in dpm_list, and call @fn for each device,
+ * passing it @data.
+ */
+void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
+{
+       struct device *dev;
+
+       if (!fn)
+               return;
+
+       device_pm_lock();
+       list_for_each_entry(dev, &dpm_list, power.entry)
+               fn(dev, data);
+       device_pm_unlock();
+}
+EXPORT_SYMBOL_GPL(dpm_for_each_dev);
index f067e60a38322fa3a935249cc75c185a8bf522af..88f034a23f2c6a04d56c9cc07743d1e7148824b5 100644 (file)
@@ -638,6 +638,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
        } while (0)
 
 extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);
+extern void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *));
 
 extern int pm_generic_prepare(struct device *dev);
 extern int pm_generic_suspend_late(struct device *dev);
@@ -677,6 +678,10 @@ static inline int device_pm_wait_for_dev(struct device *a, struct device *b)
        return 0;
 }
 
+static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
+{
+}
+
 #define pm_generic_prepare     NULL
 #define pm_generic_suspend     NULL
 #define pm_generic_resume      NULL