diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2013-09-04 11:25:44 -0600 |
---|---|---|
committer | Alex Williamson <alex.williamson@redhat.com> | 2013-09-04 11:25:44 -0600 |
commit | 3bc4f3993b93dbf1f6402e2034a2e20eb07db807 (patch) | |
tree | 592283e59e121b76355836295d6016fe33cfc5d1 /drivers/usb/host/ehci-tegra.c | |
parent | 17638db1b88184d8895f3f4551c936d7480a1d3f (diff) | |
parent | cb3e4330e697dffaf3d9cefebc9c7e7d39c89f2e (diff) |
Merge remote branch 'origin/master' into next-merge
Diffstat (limited to 'drivers/usb/host/ehci-tegra.c')
-rw-r--r-- | drivers/usb/host/ehci-tegra.c | 95 |
1 files changed, 31 insertions, 64 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 6ee7ef79b4f..78fa76da332 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -25,9 +25,9 @@ #include <linux/irq.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> -#include <linux/platform_data/tegra_usb.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/usb/ehci_def.h> @@ -51,6 +51,10 @@ static struct hc_driver __read_mostly tegra_ehci_hc_driver; +struct tegra_ehci_soc_config { + bool has_hostpc; +}; + static int (*orig_hub_control)(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); @@ -58,7 +62,6 @@ static int (*orig_hub_control)(struct usb_hcd *hcd, struct tegra_ehci_hcd { struct tegra_usb_phy *phy; struct clk *clk; - struct usb_phy *transceiver; int port_resuming; bool needs_double_reset; enum tegra_usb_phy_port_speed port_speed; @@ -322,50 +325,38 @@ static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) free_dma_aligned_buffer(urb); } -static int setup_vbus_gpio(struct platform_device *pdev, - struct tegra_ehci_platform_data *pdata) -{ - int err = 0; - int gpio; - - gpio = pdata->vbus_gpio; - if (!gpio_is_valid(gpio)) - gpio = of_get_named_gpio(pdev->dev.of_node, - "nvidia,vbus-gpio", 0); - if (!gpio_is_valid(gpio)) - return 0; +static const struct tegra_ehci_soc_config tegra30_soc_config = { + .has_hostpc = true, +}; - err = gpio_request(gpio, "vbus_gpio"); - if (err) { - dev_err(&pdev->dev, "can't request vbus gpio %d", gpio); - return err; - } - err = gpio_direction_output(gpio, 1); - if (err) { - dev_err(&pdev->dev, "can't enable vbus\n"); - return err; - } +static const struct tegra_ehci_soc_config tegra20_soc_config = { + .has_hostpc = false, +}; - return err; -} +static struct of_device_id tegra_ehci_of_match[] = { + { .compatible = "nvidia,tegra30-ehci", .data = &tegra30_soc_config }, + { .compatible = "nvidia,tegra20-ehci", .data = &tegra20_soc_config }, + { }, +}; static int tegra_ehci_probe(struct platform_device *pdev) { + const struct of_device_id *match; + const struct tegra_ehci_soc_config *soc_config; struct resource *res; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct tegra_ehci_hcd *tegra; - struct tegra_ehci_platform_data *pdata; int err = 0; int irq; - struct device_node *np_phy; struct usb_phy *u_phy; - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "Platform data missing\n"); - return -EINVAL; + match = of_match_device(tegra_ehci_of_match, &pdev->dev); + if (!match) { + dev_err(&pdev->dev, "Error: No device match found\n"); + return -ENODEV; } + soc_config = match->data; /* Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. @@ -376,14 +367,11 @@ static int tegra_ehci_probe(struct platform_device *pdev) if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - setup_vbus_gpio(pdev, pdata); - hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); - err = -ENOMEM; - goto cleanup_vbus_gpio; + return -ENOMEM; } platform_set_drvdata(pdev, hcd); ehci = hcd_to_ehci(hcd); @@ -406,13 +394,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) udelay(1); tegra_periph_reset_deassert(tegra->clk); - np_phy = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0); - if (!np_phy) { - err = -ENODEV; - goto cleanup_clk_en; - } - - u_phy = tegra_usb_get_phy(np_phy); + u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); if (IS_ERR(u_phy)) { err = PTR_ERR(u_phy); goto cleanup_clk_en; @@ -437,6 +419,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto cleanup_clk_en; } ehci->caps = hcd->regs + 0x100; + ehci->has_hostpc = soc_config->has_hostpc; err = usb_phy_init(hcd->phy); if (err) { @@ -466,26 +449,18 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto cleanup_phy; } - if (pdata->operating_mode == TEGRA_USB_OTG) { - tegra->transceiver = - devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); - if (!IS_ERR(tegra->transceiver)) - otg_set_host(tegra->transceiver->otg, &hcd->self); - } else { - tegra->transceiver = ERR_PTR(-ENODEV); - } + otg_set_host(u_phy->otg, &hcd->self); err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD\n"); - goto cleanup_transceiver; + goto cleanup_otg_set_host; } return err; -cleanup_transceiver: - if (!IS_ERR(tegra->transceiver)) - otg_set_host(tegra->transceiver->otg, NULL); +cleanup_otg_set_host: + otg_set_host(u_phy->otg, NULL); cleanup_phy: usb_phy_shutdown(hcd->phy); cleanup_clk_en: @@ -494,8 +469,6 @@ cleanup_clk_get: clk_put(tegra->clk); cleanup_hcd_create: usb_put_hcd(hcd); -cleanup_vbus_gpio: - /* FIXME: Undo setup_vbus_gpio() here */ return err; } @@ -505,8 +478,7 @@ static int tegra_ehci_remove(struct platform_device *pdev) struct tegra_ehci_hcd *tegra = (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; - if (!IS_ERR(tegra->transceiver)) - otg_set_host(tegra->transceiver->otg, NULL); + otg_set_host(hcd->phy->otg, NULL); usb_phy_shutdown(hcd->phy); usb_remove_hcd(hcd); @@ -525,11 +497,6 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } -static struct of_device_id tegra_ehci_of_match[] = { - { .compatible = "nvidia,tegra20-ehci", }, - { }, -}; - static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, .remove = tegra_ehci_remove, |