diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 11:45:33 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-01 11:45:33 -0500 |
commit | 8062d94a545457a83d5291bd62c3bfd14200bba0 (patch) | |
tree | a6a7aaaea5dff00f7415a93189720a1164ae30dd /drivers/usb/otg/twl4030-usb.c | |
parent | 15e68a803573974409972e761d8f08f03fce5bdb (diff) | |
parent | 6e13c6505cdff9766d5268ffb8c972c1a2f996e6 (diff) |
Merge tag 'xceiv-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB: transceiver changes for 3.4
Here we have a big rework done by Heikki Krogerus (thanks) which
splits OTG functionality away from transceivers.
We have known for quite a long time that struct otg_transceiver was
a bad name for the structure, considering transceiver is far from
being OTG-specific (see 4e67185).
Diffstat (limited to 'drivers/usb/otg/twl4030-usb.c')
-rw-r--r-- | drivers/usb/otg/twl4030-usb.c | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 14f66c35862..c4a86da858e 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -144,7 +144,7 @@ | |||
144 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) | 144 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) |
145 | 145 | ||
146 | struct twl4030_usb { | 146 | struct twl4030_usb { |
147 | struct otg_transceiver otg; | 147 | struct usb_phy phy; |
148 | struct device *dev; | 148 | struct device *dev; |
149 | 149 | ||
150 | /* TWL4030 internal USB regulator supplies */ | 150 | /* TWL4030 internal USB regulator supplies */ |
@@ -166,7 +166,7 @@ struct twl4030_usb { | |||
166 | }; | 166 | }; |
167 | 167 | ||
168 | /* internal define on top of container_of */ | 168 | /* internal define on top of container_of */ |
169 | #define xceiv_to_twl(x) container_of((x), struct twl4030_usb, otg) | 169 | #define phy_to_twl(x) container_of((x), struct twl4030_usb, phy) |
170 | 170 | ||
171 | /*-------------------------------------------------------------------------*/ | 171 | /*-------------------------------------------------------------------------*/ |
172 | 172 | ||
@@ -246,10 +246,11 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) | |||
246 | 246 | ||
247 | /*-------------------------------------------------------------------------*/ | 247 | /*-------------------------------------------------------------------------*/ |
248 | 248 | ||
249 | static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | 249 | static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl) |
250 | { | 250 | { |
251 | int status; | 251 | int status; |
252 | int linkstat = USB_EVENT_NONE; | 252 | int linkstat = USB_EVENT_NONE; |
253 | struct usb_otg *otg = twl->phy.otg; | ||
253 | 254 | ||
254 | twl->vbus_supplied = false; | 255 | twl->vbus_supplied = false; |
255 | 256 | ||
@@ -281,7 +282,7 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
281 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 282 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
282 | status, status, linkstat); | 283 | status, status, linkstat); |
283 | 284 | ||
284 | twl->otg.last_event = linkstat; | 285 | twl->phy.last_event = linkstat; |
285 | 286 | ||
286 | /* REVISIT this assumes host and peripheral controllers | 287 | /* REVISIT this assumes host and peripheral controllers |
287 | * are registered, and that both are active... | 288 | * are registered, and that both are active... |
@@ -290,11 +291,11 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
290 | spin_lock_irq(&twl->lock); | 291 | spin_lock_irq(&twl->lock); |
291 | twl->linkstat = linkstat; | 292 | twl->linkstat = linkstat; |
292 | if (linkstat == USB_EVENT_ID) { | 293 | if (linkstat == USB_EVENT_ID) { |
293 | twl->otg.default_a = true; | 294 | otg->default_a = true; |
294 | twl->otg.state = OTG_STATE_A_IDLE; | 295 | twl->phy.state = OTG_STATE_A_IDLE; |
295 | } else { | 296 | } else { |
296 | twl->otg.default_a = false; | 297 | otg->default_a = false; |
297 | twl->otg.state = OTG_STATE_B_IDLE; | 298 | twl->phy.state = OTG_STATE_B_IDLE; |
298 | } | 299 | } |
299 | spin_unlock_irq(&twl->lock); | 300 | spin_unlock_irq(&twl->lock); |
300 | 301 | ||
@@ -520,8 +521,8 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
520 | else | 521 | else |
521 | twl4030_phy_resume(twl); | 522 | twl4030_phy_resume(twl); |
522 | 523 | ||
523 | atomic_notifier_call_chain(&twl->otg.notifier, status, | 524 | atomic_notifier_call_chain(&twl->phy.notifier, status, |
524 | twl->otg.gadget); | 525 | twl->phy.otg->gadget); |
525 | } | 526 | } |
526 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 527 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
527 | 528 | ||
@@ -542,15 +543,15 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) | |||
542 | twl->asleep = 0; | 543 | twl->asleep = 0; |
543 | } | 544 | } |
544 | 545 | ||
545 | atomic_notifier_call_chain(&twl->otg.notifier, status, | 546 | atomic_notifier_call_chain(&twl->phy.notifier, status, |
546 | twl->otg.gadget); | 547 | twl->phy.otg->gadget); |
547 | } | 548 | } |
548 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 549 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
549 | } | 550 | } |
550 | 551 | ||
551 | static int twl4030_set_suspend(struct otg_transceiver *x, int suspend) | 552 | static int twl4030_set_suspend(struct usb_phy *x, int suspend) |
552 | { | 553 | { |
553 | struct twl4030_usb *twl = xceiv_to_twl(x); | 554 | struct twl4030_usb *twl = phy_to_twl(x); |
554 | 555 | ||
555 | if (suspend) | 556 | if (suspend) |
556 | twl4030_phy_suspend(twl, 1); | 557 | twl4030_phy_suspend(twl, 1); |
@@ -560,33 +561,27 @@ static int twl4030_set_suspend(struct otg_transceiver *x, int suspend) | |||
560 | return 0; | 561 | return 0; |
561 | } | 562 | } |
562 | 563 | ||
563 | static int twl4030_set_peripheral(struct otg_transceiver *x, | 564 | static int twl4030_set_peripheral(struct usb_otg *otg, |
564 | struct usb_gadget *gadget) | 565 | struct usb_gadget *gadget) |
565 | { | 566 | { |
566 | struct twl4030_usb *twl; | 567 | if (!otg) |
567 | |||
568 | if (!x) | ||
569 | return -ENODEV; | 568 | return -ENODEV; |
570 | 569 | ||
571 | twl = xceiv_to_twl(x); | 570 | otg->gadget = gadget; |
572 | twl->otg.gadget = gadget; | ||
573 | if (!gadget) | 571 | if (!gadget) |
574 | twl->otg.state = OTG_STATE_UNDEFINED; | 572 | otg->phy->state = OTG_STATE_UNDEFINED; |
575 | 573 | ||
576 | return 0; | 574 | return 0; |
577 | } | 575 | } |
578 | 576 | ||
579 | static int twl4030_set_host(struct otg_transceiver *x, struct usb_bus *host) | 577 | static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) |
580 | { | 578 | { |
581 | struct twl4030_usb *twl; | 579 | if (!otg) |
582 | |||
583 | if (!x) | ||
584 | return -ENODEV; | 580 | return -ENODEV; |
585 | 581 | ||
586 | twl = xceiv_to_twl(x); | 582 | otg->host = host; |
587 | twl->otg.host = host; | ||
588 | if (!host) | 583 | if (!host) |
589 | twl->otg.state = OTG_STATE_UNDEFINED; | 584 | otg->phy->state = OTG_STATE_UNDEFINED; |
590 | 585 | ||
591 | return 0; | 586 | return 0; |
592 | } | 587 | } |
@@ -596,6 +591,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
596 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; | 591 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; |
597 | struct twl4030_usb *twl; | 592 | struct twl4030_usb *twl; |
598 | int status, err; | 593 | int status, err; |
594 | struct usb_otg *otg; | ||
599 | 595 | ||
600 | if (!pdata) { | 596 | if (!pdata) { |
601 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 597 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
@@ -606,16 +602,26 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
606 | if (!twl) | 602 | if (!twl) |
607 | return -ENOMEM; | 603 | return -ENOMEM; |
608 | 604 | ||
605 | otg = kzalloc(sizeof *otg, GFP_KERNEL); | ||
606 | if (!otg) { | ||
607 | kfree(twl); | ||
608 | return -ENOMEM; | ||
609 | } | ||
610 | |||
609 | twl->dev = &pdev->dev; | 611 | twl->dev = &pdev->dev; |
610 | twl->irq = platform_get_irq(pdev, 0); | 612 | twl->irq = platform_get_irq(pdev, 0); |
611 | twl->otg.dev = twl->dev; | ||
612 | twl->otg.label = "twl4030"; | ||
613 | twl->otg.set_host = twl4030_set_host; | ||
614 | twl->otg.set_peripheral = twl4030_set_peripheral; | ||
615 | twl->otg.set_suspend = twl4030_set_suspend; | ||
616 | twl->usb_mode = pdata->usb_mode; | 613 | twl->usb_mode = pdata->usb_mode; |
617 | twl->vbus_supplied = false; | 614 | twl->vbus_supplied = false; |
618 | twl->asleep = 1; | 615 | twl->asleep = 1; |
616 | |||
617 | twl->phy.dev = twl->dev; | ||
618 | twl->phy.label = "twl4030"; | ||
619 | twl->phy.otg = otg; | ||
620 | twl->phy.set_suspend = twl4030_set_suspend; | ||
621 | |||
622 | otg->phy = &twl->phy; | ||
623 | otg->set_host = twl4030_set_host; | ||
624 | otg->set_peripheral = twl4030_set_peripheral; | ||
619 | 625 | ||
620 | /* init spinlock for workqueue */ | 626 | /* init spinlock for workqueue */ |
621 | spin_lock_init(&twl->lock); | 627 | spin_lock_init(&twl->lock); |
@@ -623,16 +629,17 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
623 | err = twl4030_usb_ldo_init(twl); | 629 | err = twl4030_usb_ldo_init(twl); |
624 | if (err) { | 630 | if (err) { |
625 | dev_err(&pdev->dev, "ldo init failed\n"); | 631 | dev_err(&pdev->dev, "ldo init failed\n"); |
632 | kfree(otg); | ||
626 | kfree(twl); | 633 | kfree(twl); |
627 | return err; | 634 | return err; |
628 | } | 635 | } |
629 | otg_set_transceiver(&twl->otg); | 636 | usb_set_transceiver(&twl->phy); |
630 | 637 | ||
631 | platform_set_drvdata(pdev, twl); | 638 | platform_set_drvdata(pdev, twl); |
632 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 639 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
633 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 640 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
634 | 641 | ||
635 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | 642 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); |
636 | 643 | ||
637 | /* Our job is to use irqs and status from the power module | 644 | /* Our job is to use irqs and status from the power module |
638 | * to keep the transceiver disabled when nothing's connected. | 645 | * to keep the transceiver disabled when nothing's connected. |
@@ -649,6 +656,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
649 | if (status < 0) { | 656 | if (status < 0) { |
650 | dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", | 657 | dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", |
651 | twl->irq, status); | 658 | twl->irq, status); |
659 | kfree(otg); | ||
652 | kfree(twl); | 660 | kfree(twl); |
653 | return status; | 661 | return status; |
654 | } | 662 | } |
@@ -693,6 +701,7 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
693 | regulator_put(twl->usb1v8); | 701 | regulator_put(twl->usb1v8); |
694 | regulator_put(twl->usb3v1); | 702 | regulator_put(twl->usb3v1); |
695 | 703 | ||
704 | kfree(twl->phy.otg); | ||
696 | kfree(twl); | 705 | kfree(twl); |
697 | 706 | ||
698 | return 0; | 707 | return 0; |