diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 02:08:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 02:08:32 -0400 |
commit | f549953c15deab4c54708b39af86d4edecc6cddc (patch) | |
tree | f0412f989b77cdceab34c18aa85a8a25d5942a1f /drivers/usb/otg/twl6030-usb.c | |
parent | f0deb97ab13ad1f89cd0993f7339655d59788405 (diff) | |
parent | e04f5f7e423018bcec84c11af2058cdce87816f3 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (115 commits)
EHCI: fix direction handling for interrupt data toggles
USB: serial: add IDs for WinChipHead USB->RS232 adapter
USB: OHCI: fix another regression for NVIDIA controllers
usb: gadget: m66592-udc: add pullup function
usb: gadget: m66592-udc: add function for external controller
usb: gadget: r8a66597-udc: add pullup function
usb: renesas_usbhs: support multi driver
usb: renesas_usbhs: inaccessible pipe is not an error
usb: renesas_usbhs: care buff alignment when dma handler
USB: PL2303: correctly handle baudrates above 115200
usb: r8a66597-hcd: fixup USB_PORT_STAT_C_SUSPEND shift
usb: renesas_usbhs: compile/config are rescued
usb: renesas_usbhs: fixup comment-out
usb: update email address in ohci-sh and r8a66597-hcd
usb: r8a66597-hcd: add function for external controller
EHCI: only power off port if over-current is active
USB: mon: Allow to use usbmon without debugfs
USB: EHCI: go back to using the system clock for QH unlinks
ehci: add pci quirk for Ordissimo and RM Slate 100 too
ehci: refactor pci quirk to use standard dmi_check_system method
...
Fix up trivial conflicts in Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/usb/otg/twl6030-usb.c')
-rw-r--r-- | drivers/usb/otg/twl6030-usb.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index cfb5aa72b196..b4d2c0972b3d 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c | |||
@@ -95,11 +95,15 @@ struct twl6030_usb { | |||
95 | 95 | ||
96 | struct regulator *usb3v3; | 96 | struct regulator *usb3v3; |
97 | 97 | ||
98 | /* used to set vbus, in atomic path */ | ||
99 | struct work_struct set_vbus_work; | ||
100 | |||
98 | int irq1; | 101 | int irq1; |
99 | int irq2; | 102 | int irq2; |
100 | u8 linkstat; | 103 | u8 linkstat; |
101 | u8 asleep; | 104 | u8 asleep; |
102 | bool irq_enabled; | 105 | bool irq_enabled; |
106 | bool vbus_enable; | ||
103 | unsigned long features; | 107 | unsigned long features; |
104 | }; | 108 | }; |
105 | 109 | ||
@@ -370,20 +374,31 @@ static int twl6030_enable_irq(struct otg_transceiver *x) | |||
370 | return 0; | 374 | return 0; |
371 | } | 375 | } |
372 | 376 | ||
373 | static int twl6030_set_vbus(struct otg_transceiver *x, bool enabled) | 377 | static void otg_set_vbus_work(struct work_struct *data) |
374 | { | 378 | { |
375 | struct twl6030_usb *twl = xceiv_to_twl(x); | 379 | struct twl6030_usb *twl = container_of(data, struct twl6030_usb, |
380 | set_vbus_work); | ||
376 | 381 | ||
377 | /* | 382 | /* |
378 | * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 | 383 | * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 |
379 | * register. This enables boost mode. | 384 | * register. This enables boost mode. |
380 | */ | 385 | */ |
381 | if (enabled) | 386 | |
387 | if (twl->vbus_enable) | ||
382 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, | 388 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, |
383 | CHARGERUSB_CTRL1); | 389 | CHARGERUSB_CTRL1); |
384 | else | 390 | else |
385 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, | 391 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, |
386 | CHARGERUSB_CTRL1); | 392 | CHARGERUSB_CTRL1); |
393 | } | ||
394 | |||
395 | static int twl6030_set_vbus(struct otg_transceiver *x, bool enabled) | ||
396 | { | ||
397 | struct twl6030_usb *twl = xceiv_to_twl(x); | ||
398 | |||
399 | twl->vbus_enable = enabled; | ||
400 | schedule_work(&twl->set_vbus_work); | ||
401 | |||
387 | return 0; | 402 | return 0; |
388 | } | 403 | } |
389 | 404 | ||
@@ -444,6 +459,8 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) | |||
444 | 459 | ||
445 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | 460 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); |
446 | 461 | ||
462 | INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); | ||
463 | |||
447 | twl->irq_enabled = true; | 464 | twl->irq_enabled = true; |
448 | status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, | 465 | status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, |
449 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 466 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
@@ -494,6 +511,7 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev) | |||
494 | regulator_put(twl->usb3v3); | 511 | regulator_put(twl->usb3v3); |
495 | pdata->phy_exit(twl->dev); | 512 | pdata->phy_exit(twl->dev); |
496 | device_remove_file(twl->dev, &dev_attr_vbus); | 513 | device_remove_file(twl->dev, &dev_attr_vbus); |
514 | cancel_work_sync(&twl->set_vbus_work); | ||
497 | kfree(twl); | 515 | kfree(twl); |
498 | 516 | ||
499 | return 0; | 517 | return 0; |