USB: EHCI: DT support for generic bus glue
authorArnd Bergmann <arnd@arndb.de>
Wed, 27 Mar 2013 21:44:22 +0000 (21:44 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Mar 2013 18:22:15 +0000 (11:22 -0700)
This lets us use the ehci-platform driver on platforms without special
requirements for their ehci controllers. In particular, this is true
for the vt8500/wm8x50 platforms, which currently have a separate
driver that causes problems with multiplatform configurations.

Tested-by: Tony Prisk <linux@prisktech.co.nz>
Tested-by: Peter Vasil <petervasil@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-platform.c
drivers/usb/host/ehci-vt8500.c [deleted file]

index 037a4729d549af46b15c4b85f461a5fc9fe1af1d..b12b97d2ccafd628db4c0e744c1b4d3202a295cf 100644 (file)
@@ -1269,11 +1269,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER                ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define        PLATFORM_DRIVER         vt8500_ehci_driver
-#endif
-
 #ifdef CONFIG_PLAT_SPEAR
 #include "ehci-spear.c"
 #define PLATFORM_DRIVER                spear_ehci_hcd_driver
index ca7506390542bf0e5c75232724477e4832f68f1c..cda0fa9613e7c633c7f4382ddb0b5b3ee5c71ca9 100644 (file)
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/hrtimer.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -62,22 +64,32 @@ static const struct ehci_driver_overrides platform_overrides __initdata = {
        .reset =        ehci_platform_reset,
 };
 
+static struct usb_ehci_pdata ehci_platform_defaults;
+
 static int ehci_platform_probe(struct platform_device *dev)
 {
        struct usb_hcd *hcd;
        struct resource *res_mem;
-       struct usb_ehci_pdata *pdata = dev->dev.platform_data;
+       struct usb_ehci_pdata *pdata;
        int irq;
        int err = -ENOMEM;
 
-       if (!pdata) {
-               WARN_ON(1);
-               return -ENODEV;
-       }
-
        if (usb_disabled())
                return -ENODEV;
 
+       /*
+        * use reasonable defaults so platforms don't have to provide these.
+        * with DT probing on ARM, none of these are set.
+        */
+       if (!dev->dev.platform_data)
+               dev->dev.platform_data = &ehci_platform_defaults;
+       if (!dev->dev.dma_mask)
+               dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+       if (!dev->dev.coherent_dma_mask)
+               dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+       pdata = dev->dev.platform_data;
+
        irq = platform_get_irq(dev, 0);
        if (irq < 0) {
                dev_err(&dev->dev, "no irq provided");
@@ -139,6 +151,9 @@ static int ehci_platform_remove(struct platform_device *dev)
        if (pdata->power_off)
                pdata->power_off(dev);
 
+       if (pdata == &ehci_platform_defaults)
+               dev->dev.platform_data = NULL;
+
        return 0;
 }
 
@@ -183,6 +198,12 @@ static int ehci_platform_resume(struct device *dev)
 #define ehci_platform_resume   NULL
 #endif /* CONFIG_PM */
 
+static const struct of_device_id vt8500_ehci_ids[] = {
+       { .compatible = "via,vt8500-ehci", },
+       { .compatible = "wm,prizm-ehci", },
+       {}
+};
+
 static const struct platform_device_id ehci_platform_table[] = {
        { "ehci-platform", 0 },
        { }
@@ -203,6 +224,7 @@ static struct platform_driver ehci_platform_driver = {
                .owner  = THIS_MODULE,
                .name   = "ehci-platform",
                .pm     = &ehci_platform_pm_ops,
+               .of_match_table = of_match_ptr(vt8500_ehci_ids),
        }
 };
 
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
deleted file mode 100644 (file)
index 7ecf709..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * drivers/usb/host/ehci-vt8500.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * Based on ehci-au1xxx.c
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-
-static const struct hc_driver vt8500_ehci_hc_driver = {
-       .description            = hcd_name,
-       .product_desc           = "VT8500 EHCI",
-       .hcd_priv_size          = sizeof(struct ehci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq                    = ehci_irq,
-       .flags                  = HCD_MEMORY | HCD_USB2,
-
-       /*
-        * basic lifecycle operations
-        */
-       .reset                  = ehci_setup,
-       .start                  = ehci_run,
-       .stop                   = ehci_stop,
-       .shutdown               = ehci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue            = ehci_urb_enqueue,
-       .urb_dequeue            = ehci_urb_dequeue,
-       .endpoint_disable       = ehci_endpoint_disable,
-       .endpoint_reset         = ehci_endpoint_reset,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number       = ehci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data        = ehci_hub_status_data,
-       .hub_control            = ehci_hub_control,
-       .bus_suspend            = ehci_bus_suspend,
-       .bus_resume             = ehci_bus_resume,
-       .relinquish_port        = ehci_relinquish_port,
-       .port_handed_over       = ehci_port_handed_over,
-
-       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
-};
-
-static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
-
-static int vt8500_ehci_drv_probe(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd;
-       struct ehci_hcd *ehci;
-       struct resource *res;
-       int ret;
-
-       if (usb_disabled())
-               return -ENODEV;
-
-       /*
-        * Right now device-tree probed devices don't get dma_mask set.
-        * Since shared usb code relies on it, set it here for now.
-        * Once we have dma capability bindings this can go away.
-        */
-       if (!pdev->dev.dma_mask)
-               pdev->dev.dma_mask = &vt8500_ehci_dma_mask;
-
-       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
-               pr_debug("resource[1] is not IORESOURCE_IRQ");
-               return -ENOMEM;
-       }
-       hcd = usb_create_hcd(&vt8500_ehci_hc_driver, &pdev->dev, "VT8500");
-       if (!hcd)
-               return -ENOMEM;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hcd->rsrc_start = res->start;
-       hcd->rsrc_len = resource_size(res);
-
-       hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(hcd->regs)) {
-               ret = PTR_ERR(hcd->regs);
-               goto err1;
-       }
-
-       ehci = hcd_to_ehci(hcd);
-       ehci->caps = hcd->regs;
-
-       ret = usb_add_hcd(hcd, pdev->resource[1].start,
-                         IRQF_SHARED);
-       if (ret == 0) {
-               platform_set_drvdata(pdev, hcd);
-               return ret;
-       }
-
-err1:
-       usb_put_hcd(hcd);
-       return ret;
-}
-
-static int vt8500_ehci_drv_remove(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
-       usb_remove_hcd(hcd);
-       usb_put_hcd(hcd);
-       platform_set_drvdata(pdev, NULL);
-
-       return 0;
-}
-
-static const struct of_device_id vt8500_ehci_ids[] = {
-       { .compatible = "via,vt8500-ehci", },
-       { .compatible = "wm,prizm-ehci", },
-       {}
-};
-
-static struct platform_driver vt8500_ehci_driver = {
-       .probe          = vt8500_ehci_drv_probe,
-       .remove         = vt8500_ehci_drv_remove,
-       .shutdown       = usb_hcd_platform_shutdown,
-       .driver = {
-               .name   = "vt8500-ehci",
-               .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(vt8500_ehci_ids),
-       }
-};
-
-MODULE_ALIAS("platform:vt8500-ehci");
-MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);