USB: Add DT probing support to ehci-spear and ohci-spear
authorStefan Roese <sr@denx.de>
Mon, 16 Apr 2012 03:38:08 +0000 (09:08 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Apr 2012 20:55:01 +0000 (13:55 -0700)
This patch adds support to configure the SPEAr EHCI & OHCI driver via
device-tree instead of platform_data.

Signed-off-by: Stefan Roese <sr@denx.de>
Acked-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/devicetree/bindings/usb/spear-usb.txt [new file with mode: 0644]
drivers/usb/host/ehci-spear.c
drivers/usb/host/ohci-spear.c

diff --git a/Documentation/devicetree/bindings/usb/spear-usb.txt b/Documentation/devicetree/bindings/usb/spear-usb.txt
new file mode 100644 (file)
index 0000000..f8a464a
--- /dev/null
@@ -0,0 +1,39 @@
+ST SPEAr SoC USB controllers:
+-----------------------------
+
+EHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ehci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the EHCI interrupt
+
+Example:
+
+       ehci@e1800000 {
+               compatible = "st,spear600-ehci", "usb-ehci";
+               reg = <0xe1800000 0x1000>;
+               interrupt-parent = <&vic1>;
+               interrupts = <27>;
+       };
+
+
+OHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ohci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the OHCI interrupt
+
+Example:
+
+       ohci@e1900000 {
+               compatible = "st,spear600-ohci", "usb-ohci";
+               reg = <0xe1800000 0x1000>;
+               interrupt-parent = <&vic1>;
+               interrupts = <26>;
+       };
index 6e92855..2e3c89a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/jiffies.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 
@@ -168,6 +169,8 @@ static int ehci_spear_drv_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
                ehci_spear_drv_resume);
 
+static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd ;
@@ -175,12 +178,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
        struct resource *res;
        struct clk *usbh_clk;
        const struct hc_driver *driver = &ehci_spear_hc_driver;
-       int *pdata = pdev->dev.platform_data;
        int irq, retval;
        char clk_name[20] = "usbh_clk";
-
-       if (pdata == NULL)
-               return -EFAULT;
+       static int instance = -1;
 
        if (usb_disabled())
                return -ENODEV;
@@ -191,8 +191,22 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
                goto fail_irq_get;
        }
 
-       if (*pdata >= 0)
-               sprintf(clk_name, "usbh.%01d_clk", *pdata);
+       /*
+        * 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 = &spear_ehci_dma_mask;
+
+       /*
+        * Increment the device instance, when probing via device-tree
+        */
+       if (pdev->id < 0)
+               instance++;
+       else
+               instance = pdev->id;
+       sprintf(clk_name, "usbh.%01d_clk", instance);
 
        usbh_clk = clk_get(NULL, clk_name);
        if (IS_ERR(usbh_clk)) {
@@ -277,6 +291,11 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
        return 0;
 }
 
+static struct of_device_id spear_ehci_id_table[] __devinitdata = {
+       { .compatible = "st,spear600-ehci", },
+       { },
+};
+
 static struct platform_driver spear_ehci_hcd_driver = {
        .probe          = spear_ehci_hcd_drv_probe,
        .remove         = spear_ehci_hcd_drv_remove,
@@ -285,6 +304,7 @@ static struct platform_driver spear_ehci_hcd_driver = {
                .name = "spear-ehci",
                .bus = &platform_bus_type,
                .pm = &ehci_spear_pm_ops,
+               .of_match_table = of_match_ptr(spear_ehci_id_table),
        }
 };
 
index 95c1648..eb4640b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/signal.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 
 struct spear_ohci {
        struct ohci_hcd ohci;
@@ -90,6 +91,8 @@ static const struct hc_driver ohci_spear_hc_driver = {
        .start_port_reset       = ohci_start_port_reset,
 };
 
+static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
        const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -98,11 +101,8 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
        struct spear_ohci *ohci_p;
        struct resource *res;
        int retval, irq;
-       int *pdata = pdev->dev.platform_data;
        char clk_name[20] = "usbh_clk";
-
-       if (pdata == NULL)
-               return -EFAULT;
+       static int instance = -1;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -110,8 +110,22 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
                goto fail_irq_get;
        }
 
-       if (*pdata >= 0)
-               sprintf(clk_name, "usbh.%01d_clk", *pdata);
+       /*
+        * 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 = &spear_ohci_dma_mask;
+
+       /*
+        * Increment the device instance, when probing via device-tree
+        */
+       if (pdev->id < 0)
+               instance++;
+       else
+               instance = pdev->id;
+       sprintf(clk_name, "usbh.%01d_clk", instance);
 
        usbh_clk = clk_get(NULL, clk_name);
        if (IS_ERR(usbh_clk)) {
@@ -222,6 +236,11 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 }
 #endif
 
+static struct of_device_id spear_ohci_id_table[] __devinitdata = {
+       { .compatible = "st,spear600-ohci", },
+       { },
+};
+
 /* Driver definition to register with the platform bus */
 static struct platform_driver spear_ohci_hcd_driver = {
        .probe =        spear_ohci_hcd_drv_probe,
@@ -233,6 +252,7 @@ static struct platform_driver spear_ohci_hcd_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "spear-ohci",
+               .of_match_table = of_match_ptr(spear_ohci_id_table),
        },
 };