From: Shinya Kuribayashi Date: Thu, 17 May 2012 11:11:06 +0000 (+0900) Subject: USB: gpio_vbus: wakeup support on GPIO VBUS interrupts X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=7cbb062ade87b987a24aa834bbde32ad8374a4cf;p=~shefty%2Frdma-dev.git USB: gpio_vbus: wakeup support on GPIO VBUS interrupts We'd like to see the system waking up from the system-wide suspend when it gets plugged-in, or the USB cable is pulled out. Also makes it configurable via platform data 'wakeup'. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- 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; };