aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-tegra.c')
-rw-r--r--drivers/usb/host/ehci-tegra.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index db9d1b4bfbd..dbc7fe8ca9e 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -21,7 +21,12 @@
21#include <linux/platform_data/tegra_usb.h> 21#include <linux/platform_data/tegra_usb.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/usb/otg.h> 23#include <linux/usb/otg.h>
24#include <linux/gpio.h>
25#include <linux/of.h>
26#include <linux/of_gpio.h>
27
24#include <mach/usb_phy.h> 28#include <mach/usb_phy.h>
29#include <mach/iomap.h>
25 30
26#define TEGRA_USB_DMA_ALIGN 32 31#define TEGRA_USB_DMA_ALIGN 32
27 32
@@ -574,6 +579,35 @@ static const struct hc_driver tegra_ehci_hc_driver = {
574 .port_handed_over = ehci_port_handed_over, 579 .port_handed_over = ehci_port_handed_over,
575}; 580};
576 581
582static int setup_vbus_gpio(struct platform_device *pdev)
583{
584 int err = 0;
585 int gpio;
586
587 if (!pdev->dev.of_node)
588 return 0;
589
590 gpio = of_get_named_gpio(pdev->dev.of_node, "nvidia,vbus-gpio", 0);
591 if (!gpio_is_valid(gpio))
592 return 0;
593
594 err = gpio_request(gpio, "vbus_gpio");
595 if (err) {
596 dev_err(&pdev->dev, "can't request vbus gpio %d", gpio);
597 return err;
598 }
599 err = gpio_direction_output(gpio, 1);
600 if (err) {
601 dev_err(&pdev->dev, "can't enable vbus\n");
602 return err;
603 }
604 gpio_set_value(gpio, 1);
605
606 return err;
607}
608
609static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
610
577static int tegra_ehci_probe(struct platform_device *pdev) 611static int tegra_ehci_probe(struct platform_device *pdev)
578{ 612{
579 struct resource *res; 613 struct resource *res;
@@ -590,6 +624,15 @@ static int tegra_ehci_probe(struct platform_device *pdev)
590 return -EINVAL; 624 return -EINVAL;
591 } 625 }
592 626
627 /* Right now device-tree probed devices don't get dma_mask set.
628 * Since shared usb code relies on it, set it here for now.
629 * Once we have dma capability bindings this can go away.
630 */
631 if (!pdev->dev.dma_mask)
632 pdev->dev.dma_mask = &tegra_ehci_dma_mask;
633
634 setup_vbus_gpio(pdev);
635
593 tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); 636 tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL);
594 if (!tegra) 637 if (!tegra)
595 return -ENOMEM; 638 return -ENOMEM;
@@ -640,6 +683,28 @@ static int tegra_ehci_probe(struct platform_device *pdev)
640 goto fail_io; 683 goto fail_io;
641 } 684 }
642 685
686 /* This is pretty ugly and needs to be fixed when we do only
687 * device-tree probing. Old code relies on the platform_device
688 * numbering that we lack for device-tree-instantiated devices.
689 */
690 if (instance < 0) {
691 switch (res->start) {
692 case TEGRA_USB_BASE:
693 instance = 0;
694 break;
695 case TEGRA_USB2_BASE:
696 instance = 1;
697 break;
698 case TEGRA_USB3_BASE:
699 instance = 2;
700 break;
701 default:
702 err = -ENODEV;
703 dev_err(&pdev->dev, "unknown usb instance\n");
704 goto fail_phy;
705 }
706 }
707
643 tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, 708 tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config,
644 TEGRA_USB_PHY_MODE_HOST); 709 TEGRA_USB_PHY_MODE_HOST);
645 if (IS_ERR(tegra->phy)) { 710 if (IS_ERR(tegra->phy)) {
@@ -773,6 +838,11 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev)
773 hcd->driver->shutdown(hcd); 838 hcd->driver->shutdown(hcd);
774} 839}
775 840
841static struct of_device_id tegra_ehci_of_match[] __devinitdata = {
842 { .compatible = "nvidia,tegra20-ehci", },
843 { },
844};
845
776static struct platform_driver tegra_ehci_driver = { 846static struct platform_driver tegra_ehci_driver = {
777 .probe = tegra_ehci_probe, 847 .probe = tegra_ehci_probe,
778 .remove = tegra_ehci_remove, 848 .remove = tegra_ehci_remove,
@@ -783,5 +853,6 @@ static struct platform_driver tegra_ehci_driver = {
783 .shutdown = tegra_ehci_hcd_shutdown, 853 .shutdown = tegra_ehci_hcd_shutdown,
784 .driver = { 854 .driver = {
785 .name = "tegra-ehci", 855 .name = "tegra-ehci",
856 .of_match_table = tegra_ehci_of_match,
786 } 857 }
787}; 858};