diff options
author | Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> | 2012-05-17 07:11:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-17 14:20:34 -0400 |
commit | 7cbb062ade87b987a24aa834bbde32ad8374a4cf (patch) | |
tree | ec7dd2e6d4fb69060a32f4b8ca52cccbad50f3c9 | |
parent | ec1ac6e1690adf4087afdc706770cb6fb732157b (diff) |
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 <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/otg/gpio_vbus.c | 33 | ||||
-rw-r--r-- | include/linux/usb/gpio_vbus.h | 2 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 1e6bd0347aff..bde6298a9693 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) | |||
327 | goto err_otg; | 327 | goto err_otg; |
328 | } | 328 | } |
329 | 329 | ||
330 | device_init_wakeup(&pdev->dev, pdata->wakeup); | ||
331 | |||
330 | return 0; | 332 | return 0; |
331 | err_otg: | 333 | err_otg: |
332 | regulator_put(gpio_vbus->vbus_draw); | 334 | regulator_put(gpio_vbus->vbus_draw); |
@@ -348,6 +350,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) | |||
348 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | 350 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; |
349 | int gpio = pdata->gpio_vbus; | 351 | int gpio = pdata->gpio_vbus; |
350 | 352 | ||
353 | device_init_wakeup(&pdev->dev, 0); | ||
351 | cancel_delayed_work_sync(&gpio_vbus->work); | 354 | cancel_delayed_work_sync(&gpio_vbus->work); |
352 | regulator_put(gpio_vbus->vbus_draw); | 355 | regulator_put(gpio_vbus->vbus_draw); |
353 | 356 | ||
@@ -364,6 +367,33 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) | |||
364 | return 0; | 367 | return 0; |
365 | } | 368 | } |
366 | 369 | ||
370 | #ifdef CONFIG_PM | ||
371 | static int gpio_vbus_pm_suspend(struct device *dev) | ||
372 | { | ||
373 | struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); | ||
374 | |||
375 | if (device_may_wakeup(dev)) | ||
376 | enable_irq_wake(gpio_vbus->irq); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int gpio_vbus_pm_resume(struct device *dev) | ||
382 | { | ||
383 | struct gpio_vbus_data *gpio_vbus = dev_get_drvdata(dev); | ||
384 | |||
385 | if (device_may_wakeup(dev)) | ||
386 | disable_irq_wake(gpio_vbus->irq); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static const struct dev_pm_ops gpio_vbus_dev_pm_ops = { | ||
392 | .suspend = gpio_vbus_pm_suspend, | ||
393 | .resume = gpio_vbus_pm_resume, | ||
394 | }; | ||
395 | #endif | ||
396 | |||
367 | /* NOTE: the gpio-vbus device may *NOT* be hotplugged */ | 397 | /* NOTE: the gpio-vbus device may *NOT* be hotplugged */ |
368 | 398 | ||
369 | MODULE_ALIAS("platform:gpio-vbus"); | 399 | MODULE_ALIAS("platform:gpio-vbus"); |
@@ -372,6 +402,9 @@ static struct platform_driver gpio_vbus_driver = { | |||
372 | .driver = { | 402 | .driver = { |
373 | .name = "gpio-vbus", | 403 | .name = "gpio-vbus", |
374 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
405 | #ifdef CONFIG_PM | ||
406 | .pm = &gpio_vbus_dev_pm_ops, | ||
407 | #endif | ||
375 | }, | 408 | }, |
376 | .remove = __exit_p(gpio_vbus_remove), | 409 | .remove = __exit_p(gpio_vbus_remove), |
377 | }; | 410 | }; |
diff --git a/include/linux/usb/gpio_vbus.h b/include/linux/usb/gpio_vbus.h index d9f03ccc2d60..837bba604a0b 100644 --- a/include/linux/usb/gpio_vbus.h +++ b/include/linux/usb/gpio_vbus.h | |||
@@ -17,6 +17,7 @@ | |||
17 | * @gpio_pullup: optional D+ or D- pullup GPIO (else negative/invalid) | 17 | * @gpio_pullup: optional D+ or D- pullup GPIO (else negative/invalid) |
18 | * @gpio_vbus_inverted: true if gpio_vbus is active low | 18 | * @gpio_vbus_inverted: true if gpio_vbus is active low |
19 | * @gpio_pullup_inverted: true if gpio_pullup is active low | 19 | * @gpio_pullup_inverted: true if gpio_pullup is active low |
20 | * @wakeup: configure gpio_vbus as a wake-up source | ||
20 | * | 21 | * |
21 | * The VBUS sensing GPIO should have a pulldown, which will normally be | 22 | * The VBUS sensing GPIO should have a pulldown, which will normally be |
22 | * part of a resistor ladder turning a 4.0V-5.25V level on VBUS into a | 23 | * 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 { | |||
27 | int gpio_pullup; | 28 | int gpio_pullup; |
28 | bool gpio_vbus_inverted; | 29 | bool gpio_vbus_inverted; |
29 | bool gpio_pullup_inverted; | 30 | bool gpio_pullup_inverted; |
31 | bool wakeup; | ||
30 | }; | 32 | }; |