diff options
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 2460f0d82990..17e4ceb5014d 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/gpio.h> | 39 | #include <linux/gpio.h> |
40 | #include <linux/regulator/consumer.h> | ||
40 | #include <plat/usb.h> | 41 | #include <plat/usb.h> |
41 | 42 | ||
42 | /* | 43 | /* |
@@ -178,6 +179,11 @@ struct ehci_hcd_omap { | |||
178 | void __iomem *uhh_base; | 179 | void __iomem *uhh_base; |
179 | void __iomem *tll_base; | 180 | void __iomem *tll_base; |
180 | void __iomem *ehci_base; | 181 | void __iomem *ehci_base; |
182 | |||
183 | /* Regulators for USB PHYs. | ||
184 | * Each PHY can have a seperate regulator. | ||
185 | */ | ||
186 | struct regulator *regulator[OMAP3_HS_USB_PORTS]; | ||
181 | }; | 187 | }; |
182 | 188 | ||
183 | /*-------------------------------------------------------------------------*/ | 189 | /*-------------------------------------------------------------------------*/ |
@@ -546,6 +552,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
546 | 552 | ||
547 | int irq = platform_get_irq(pdev, 0); | 553 | int irq = platform_get_irq(pdev, 0); |
548 | int ret = -ENODEV; | 554 | int ret = -ENODEV; |
555 | int i; | ||
556 | char supply[7]; | ||
549 | 557 | ||
550 | if (!pdata) { | 558 | if (!pdata) { |
551 | dev_dbg(&pdev->dev, "missing platform_data\n"); | 559 | dev_dbg(&pdev->dev, "missing platform_data\n"); |
@@ -613,6 +621,21 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
613 | goto err_tll_ioremap; | 621 | goto err_tll_ioremap; |
614 | } | 622 | } |
615 | 623 | ||
624 | /* get ehci regulator and enable */ | ||
625 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
626 | if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) { | ||
627 | omap->regulator[i] = NULL; | ||
628 | continue; | ||
629 | } | ||
630 | snprintf(supply, sizeof(supply), "hsusb%d", i); | ||
631 | omap->regulator[i] = regulator_get(omap->dev, supply); | ||
632 | if (IS_ERR(omap->regulator[i])) | ||
633 | dev_dbg(&pdev->dev, | ||
634 | "failed to get ehci port%d regulator\n", i); | ||
635 | else | ||
636 | regulator_enable(omap->regulator[i]); | ||
637 | } | ||
638 | |||
616 | ret = omap_start_ehc(omap, hcd); | 639 | ret = omap_start_ehc(omap, hcd); |
617 | if (ret) { | 640 | if (ret) { |
618 | dev_dbg(&pdev->dev, "failed to start ehci\n"); | 641 | dev_dbg(&pdev->dev, "failed to start ehci\n"); |
@@ -641,6 +664,12 @@ err_add_hcd: | |||
641 | omap_stop_ehc(omap, hcd); | 664 | omap_stop_ehc(omap, hcd); |
642 | 665 | ||
643 | err_start: | 666 | err_start: |
667 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
668 | if (omap->regulator[i]) { | ||
669 | regulator_disable(omap->regulator[i]); | ||
670 | regulator_put(omap->regulator[i]); | ||
671 | } | ||
672 | } | ||
644 | iounmap(omap->tll_base); | 673 | iounmap(omap->tll_base); |
645 | 674 | ||
646 | err_tll_ioremap: | 675 | err_tll_ioremap: |
@@ -674,10 +703,17 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
674 | { | 703 | { |
675 | struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); | 704 | struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); |
676 | struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); | 705 | struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); |
706 | int i; | ||
677 | 707 | ||
678 | usb_remove_hcd(hcd); | 708 | usb_remove_hcd(hcd); |
679 | omap_stop_ehc(omap, hcd); | 709 | omap_stop_ehc(omap, hcd); |
680 | iounmap(hcd->regs); | 710 | iounmap(hcd->regs); |
711 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
712 | if (omap->regulator[i]) { | ||
713 | regulator_disable(omap->regulator[i]); | ||
714 | regulator_put(omap->regulator[i]); | ||
715 | } | ||
716 | } | ||
681 | iounmap(omap->tll_base); | 717 | iounmap(omap->tll_base); |
682 | iounmap(omap->uhh_base); | 718 | iounmap(omap->uhh_base); |
683 | usb_put_hcd(hcd); | 719 | usb_put_hcd(hcd); |