aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/otg/twl6030-usb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 02:08:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 02:08:32 -0400
commitf549953c15deab4c54708b39af86d4edecc6cddc (patch)
treef0412f989b77cdceab34c18aa85a8a25d5942a1f /drivers/usb/otg/twl6030-usb.c
parentf0deb97ab13ad1f89cd0993f7339655d59788405 (diff)
parente04f5f7e423018bcec84c11af2058cdce87816f3 (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.c30
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
373static int twl6030_set_vbus(struct otg_transceiver *x, bool enabled) 377static 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
395static 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;