PM / wakeirq: Avoid setting power.wakeirq too hastily
[linux-2.6-microblaze.git] / drivers / base / power / wakeup.c
index 7726200..15d27d7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/suspend.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/pm_wakeirq.h>
 #include <trace/events/power.h>
 
 #include "power.h"
@@ -238,6 +239,86 @@ int device_wakeup_enable(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(device_wakeup_enable);
 
+/**
+ * device_wakeup_attach_irq - Attach a wakeirq to a wakeup source
+ * @dev: Device to handle
+ * @wakeirq: Device specific wakeirq entry
+ *
+ * Attach a device wakeirq to the wakeup source so the device
+ * wake IRQ can be configured automatically for suspend and
+ * resume.
+ *
+ * Call under the device's power.lock lock.
+ */
+int device_wakeup_attach_irq(struct device *dev,
+                            struct wake_irq *wakeirq)
+{
+       struct wakeup_source *ws;
+
+       ws = dev->power.wakeup;
+       if (!ws) {
+               dev_err(dev, "forgot to call call device_init_wakeup?\n");
+               return -EINVAL;
+       }
+
+       if (ws->wakeirq)
+               return -EEXIST;
+
+       ws->wakeirq = wakeirq;
+       return 0;
+}
+
+/**
+ * device_wakeup_detach_irq - Detach a wakeirq from a wakeup source
+ * @dev: Device to handle
+ *
+ * Removes a device wakeirq from the wakeup source.
+ *
+ * Call under the device's power.lock lock.
+ */
+void device_wakeup_detach_irq(struct device *dev)
+{
+       struct wakeup_source *ws;
+
+       ws = dev->power.wakeup;
+       if (ws)
+               ws->wakeirq = NULL;
+}
+
+/**
+ * device_wakeup_arm_wake_irqs(void)
+ *
+ * Itereates over the list of device wakeirqs to arm them.
+ */
+void device_wakeup_arm_wake_irqs(void)
+{
+       struct wakeup_source *ws;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
+               if (ws->wakeirq)
+                       dev_pm_arm_wake_irq(ws->wakeirq);
+       }
+       rcu_read_unlock();
+}
+
+/**
+ * device_wakeup_disarm_wake_irqs(void)
+ *
+ * Itereates over the list of device wakeirqs to disarm them.
+ */
+void device_wakeup_disarm_wake_irqs(void)
+{
+       struct wakeup_source *ws;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
+               if (ws->wakeirq)
+                       dev_pm_disarm_wake_irq(ws->wakeirq);
+       }
+       rcu_read_unlock();
+}
+
 /**
  * device_wakeup_detach - Detach a device's wakeup source object from it.
  * @dev: Device to detach the wakeup source object from.