]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/usb/host/ehci-tegra.c
DMA-API: usb: use dma_set_coherent_mask()
[karo-tx-linux.git] / drivers / usb / host / ehci-tegra.c
index 6ee7ef79b4f86a5c802e33245592d40ec27127a5..3d9ee43ef2d77743c6d54481414234be25e9f20f 100644 (file)
@@ -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>
 
 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.
@@ -373,17 +364,15 @@ static int tegra_ehci_probe(struct platform_device *pdev)
         */
        if (!pdev->dev.dma_mask)
                pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-       if (!pdev->dev.coherent_dma_mask)
-               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-
-       setup_vbus_gpio(pdev, pdata);
+       err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+       if (err)
+               return err;
 
        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 +395,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 +420,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 +450,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 +470,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 +479,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 +498,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,