}
 EXPORT_SYMBOL_GPL(pm_runtime_enable);
 
+/**
+ * pm_runtime_forbid - Block run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Increase the device's usage count and clear its power.runtime_auto flag,
+ * so that it cannot be suspended at run time until pm_runtime_allow() is called
+ * for it.
+ */
+void pm_runtime_forbid(struct device *dev)
+{
+       spin_lock_irq(&dev->power.lock);
+       if (!dev->power.runtime_auto)
+               goto out;
+
+       dev->power.runtime_auto = false;
+       atomic_inc(&dev->power.usage_count);
+       __pm_runtime_resume(dev, false);
+
+ out:
+       spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_forbid);
+
+/**
+ * pm_runtime_allow - Unblock run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Decrease the device's usage count and set its power.runtime_auto flag.
+ */
+void pm_runtime_allow(struct device *dev)
+{
+       spin_lock_irq(&dev->power.lock);
+       if (dev->power.runtime_auto)
+               goto out;
+
+       dev->power.runtime_auto = true;
+       if (atomic_dec_and_test(&dev->power.usage_count))
+               __pm_runtime_idle(dev);
+
+ out:
+       spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_allow);
+
 /**
  * pm_runtime_init - Initialize run-time PM fields in given device object.
  * @dev: Device object to initialize.
 
        atomic_set(&dev->power.child_count, 0);
        pm_suspend_ignore_children(dev, false);
+       dev->power.runtime_auto = true;
 
        dev->power.request_pending = false;
        dev->power.request = RPM_REQ_NONE;
 
 
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/pm_runtime.h>
 #include "power.h"
 
 /*
+ *     control - Report/change current runtime PM setting of the device
+ *
+ *     Runtime power management of a device can be blocked with the help of
+ *     this attribute.  All devices have one of the following two values for
+ *     the power/control file:
+ *
+ *      + "auto\n" to allow the device to be power managed at run time;
+ *      + "on\n" to prevent the device from being power managed at run time;
+ *
+ *     The default for all devices is "auto", which means that devices may be
+ *     subject to automatic power management, depending on their drivers.
+ *     Changing this attribute to "on" prevents the driver from power managing
+ *     the device at run time.  Doing that while the device is suspended causes
+ *     it to be woken up.
+ *
  *     wakeup - Report/change current wakeup option for device
  *
  *     Some devices support "wakeup" events, which are hardware signals
 static const char enabled[] = "enabled";
 static const char disabled[] = "disabled";
 
+#ifdef CONFIG_PM_RUNTIME
+static const char ctrl_auto[] = "auto";
+static const char ctrl_on[] = "on";
+
+static ssize_t control_show(struct device *dev, struct device_attribute *attr,
+                           char *buf)
+{
+       return sprintf(buf, "%s\n",
+                               dev->power.runtime_auto ? ctrl_auto : ctrl_on);
+}
+
+static ssize_t control_store(struct device * dev, struct device_attribute *attr,
+                            const char * buf, size_t n)
+{
+       char *cp;
+       int len = n;
+
+       cp = memchr(buf, '\n', n);
+       if (cp)
+               len = cp - buf;
+       if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
+               pm_runtime_allow(dev);
+       else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
+               pm_runtime_forbid(dev);
+       else
+               return -EINVAL;
+       return n;
+}
+
+static DEVICE_ATTR(control, 0644, control_show, control_store);
+#endif
+
 static ssize_t
 wake_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
 
 
 static struct attribute * power_attrs[] = {
+#ifdef CONFIG_PM_RUNTIME
+       &dev_attr_control.attr,
+#endif
        &dev_attr_wakeup.attr,
        NULL,
 };
 
        unsigned int            request_pending:1;
        unsigned int            deferred_resume:1;
        unsigned int            run_wake:1;
+       unsigned int            runtime_auto:1;
        enum rpm_request        request;
        enum rpm_status         runtime_status;
        int                     runtime_error;
 
 extern int pm_runtime_barrier(struct device *dev);
 extern void pm_runtime_enable(struct device *dev);
 extern void __pm_runtime_disable(struct device *dev, bool check_resume);
+extern void pm_runtime_allow(struct device *dev);
+extern void pm_runtime_forbid(struct device *dev);
 
 static inline bool pm_children_suspended(struct device *dev)
 {
 static inline int pm_runtime_barrier(struct device *dev) { return 0; }
 static inline void pm_runtime_enable(struct device *dev) {}
 static inline void __pm_runtime_disable(struct device *dev, bool c) {}
+static inline void pm_runtime_allow(struct device *dev) {}
+static inline void pm_runtime_forbid(struct device *dev) {}
 
 static inline bool pm_children_suspended(struct device *dev) { return false; }
 static inline void pm_suspend_ignore_children(struct device *dev, bool en) {}