aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/otg/gpio_vbus.c33
-rw-r--r--include/linux/usb/gpio_vbus.h2
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 1e6bd0347af..bde6298a969 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -327,6 +327,8 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
goto err_otg;
}
+ device_init_wakeup(&pdev->dev, pdata->wakeup);
+
return 0;
err_otg:
regulator_put(gpio_vbus->vbus_draw);
@@ -348,6 +350,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)
struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
int gpio = pdata->gpio_vbus;
+ device_init_wakeup(&pdev->dev, 0);
cancel_delayed_work_sync(&gpio_vbus->work);
regulator_put(gpio_vbus->vbus_draw);
@@ -364,6 +367,33 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int gpio_vbus_pm_suspend(struct device *dev)
+{
+ struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(gpio_vbus->irq);
+
+ return 0;
+}
+
+static int gpio_vbus_pm_resume(struct device *dev)
+{
+ struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(gpio_vbus->irq);
+
+ return 0;
+}
+
+static const struct dev_pm_ops gpio_vbus_dev_pm_ops = {
+ .suspend = gpio_vbus_pm_suspend,
+ .resume = gpio_vbus_pm_resume,
+};
+#endif
+
/* NOTE: the gpio-vbus device may *NOT* be hotplugged */
MODULE_ALIAS("platform:gpio-vbus");
@@ -372,6 +402,9 @@ static struct platform_driver gpio_vbus_driver = {
.driver = {
.name = "gpio-vbus",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &gpio_vbus_dev_pm_ops,
+#endif
},
.remove = __exit_p(gpio_vbus_remove),
};
diff --git a/include/linux/usb/gpio_vbus.h b/include/linux/usb/gpio_vbus.h
index d9f03ccc2d6..837bba604a0 100644
--- a/include/linux/usb/gpio_vbus.h
+++ b/include/linux/usb/gpio_vbus.h
@@ -17,6 +17,7 @@
* @gpio_pullup: optional D+ or D- pullup GPIO (else negative/invalid)
* @gpio_vbus_inverted: true if gpio_vbus is active low
* @gpio_pullup_inverted: true if gpio_pullup is active low
+ * @wakeup: configure gpio_vbus as a wake-up source
*
* The VBUS sensing GPIO should have a pulldown, which will normally be
* part of a resistor ladder turning a 4.0V-5.25V level on VBUS into a
@@ -27,4 +28,5 @@ struct gpio_vbus_mach_info {
int gpio_pullup;
bool gpio_vbus_inverted;
bool gpio_pullup_inverted;
+ bool wakeup;
};