usb: dwc3: core: split host address space
authorIdo Shayevitz <idos@codeaurora.org>
Tue, 24 Apr 2012 11:18:39 +0000 (14:18 +0300)
committerFelipe Balbi <balbi@ti.com>
Tue, 24 Apr 2012 12:37:04 +0000 (15:37 +0300)
This fix prevents a problem with dwc3 and host mode where
we were requesting the entire memory region in dwc3/core.c,
thus preventing xhci-plat from ever ioremapping its own address space.

Signed-off-by: Ido Shayevitz <idos@codeaurora.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/host.c
drivers/usb/dwc3/io.h

index 7bd815a507e8c3c94f9faaf0545b465f7ed3a781..b2b4172236941b5ff45b9acd99c0a1cbad97e728 100644 (file)
@@ -410,7 +410,6 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
        struct device           *dev = &pdev->dev;
 
        int                     ret = -ENOMEM;
-       int                     irq;
 
        void __iomem            *regs;
        void                    *mem;
@@ -425,15 +424,28 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
        dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
        dwc->mem = mem;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!res) {
-               dev_err(dev, "missing resource\n");
+               dev_err(dev, "missing IRQ\n");
                return -ENODEV;
        }
+       dwc->xhci_resources[1] = *res;
 
-       dwc->res = res;
-
-       res = devm_request_mem_region(dev, res->start, resource_size(res),
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "missing memory resource\n");
+               return -ENODEV;
+       }
+       dwc->xhci_resources[0] = *res;
+       dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
+                                       DWC3_XHCI_REGS_END;
+
+        /*
+         * Request memory region but exclude xHCI regs,
+         * since it will be requested by the xhci-plat driver.
+         */
+       res = devm_request_mem_region(dev, res->start + DWC3_GLOBALS_REGS_START,
+                       resource_size(res) - DWC3_GLOBALS_REGS_START,
                        dev_name(dev));
        if (!res) {
                dev_err(dev, "can't request mem region\n");
@@ -446,19 +458,12 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "missing IRQ\n");
-               return -ENODEV;
-       }
-
        spin_lock_init(&dwc->lock);
        platform_set_drvdata(pdev, dwc);
 
        dwc->regs       = regs;
        dwc->regs_size  = resource_size(res);
        dwc->dev        = dev;
-       dwc->irq        = irq;
 
        if (!strncmp("super", maximum_speed, 5))
                dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
index a32c2b503fe1bb0993df32739ae29da25e34889f..c7b3ca037bbc205019ba8f7ba432435b3f8b6de9 100644 (file)
@@ -52,6 +52,7 @@
 
 /* Global constants */
 #define DWC3_ENDPOINTS_NUM     32
+#define DWC3_XHCI_RESOURCES_NUM        2
 
 #define DWC3_EVENT_BUFFERS_SIZE        PAGE_SIZE
 #define DWC3_EVENT_TYPE_MASK   0xfe
 #define DWC3_GSNPSID_MASK      0xffff0000
 #define DWC3_GSNPSREV_MASK     0xffff
 
+/* DWC3 registers memory space boundries */
+#define DWC3_XHCI_REGS_START           0x0
+#define DWC3_XHCI_REGS_END             0x7fff
+#define DWC3_GLOBALS_REGS_START                0xc100
+#define DWC3_GLOBALS_REGS_END          0xc6ff
+#define DWC3_DEVICE_REGS_START         0xc700
+#define DWC3_DEVICE_REGS_END           0xcbff
+#define DWC3_OTG_REGS_START            0xcc00
+#define DWC3_OTG_REGS_END              0xccff
+
 /* Global Registers */
 #define DWC3_GSBUSCFG0         0xc100
 #define DWC3_GSBUSCFG1         0xc104
@@ -583,7 +594,7 @@ struct dwc3 {
        struct device           *dev;
 
        struct platform_device  *xhci;
-       struct resource         *res;
+       struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];
 
        struct dwc3_event_buffer **ev_buffs;
        struct dwc3_ep          *eps[DWC3_ENDPOINTS_NUM];
@@ -594,8 +605,6 @@ struct dwc3 {
        void __iomem            *regs;
        size_t                  regs_size;
 
-       int                     irq;
-
        u32                     num_event_buffers;
        u32                     u1u2;
        u32                     maximum_speed;
index b108d18fd40d543a25915f8d72ee20cbd3a6fe6c..56a62342884d713bfeef36c289169505ef8b0a25 100644 (file)
 
 #include "core.h"
 
-static struct resource generic_resources[] = {
-       {
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .flags = IORESOURCE_MEM,
-       },
-};
-
 int dwc3_host_init(struct dwc3 *dwc)
 {
        struct platform_device  *xhci;
@@ -68,14 +59,8 @@ int dwc3_host_init(struct dwc3 *dwc)
 
        dwc->xhci = xhci;
 
-       /* setup resources */
-       generic_resources[0].start = dwc->irq;
-
-       generic_resources[1].start = dwc->res->start;
-       generic_resources[1].end = dwc->res->start + 0x7fff;
-
-       ret = platform_device_add_resources(xhci, generic_resources,
-                       ARRAY_SIZE(generic_resources));
+       ret = platform_device_add_resources(xhci, dwc->xhci_resources,
+                                               DWC3_XHCI_RESOURCES_NUM);
        if (ret) {
                dev_err(dwc->dev, "couldn't add resources to xHCI device\n");
                goto err1;
index 071d561f3e68f21af7eff20a1df954a9bff075cf..a50f76b9d19b5107c2f93f1192b6408504b112a4 100644 (file)
 
 #include <linux/io.h>
 
+#include "core.h"
+
 static inline u32 dwc3_readl(void __iomem *base, u32 offset)
 {
-       return readl(base + offset);
+       /*
+        * We requested the mem region starting from the Globals address
+        * space, see dwc3_probe in core.c.
+        * However, the offsets are given starting from xHCI address space.
+        */
+       return readl(base + (offset - DWC3_GLOBALS_REGS_START));
 }
 
 static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
 {
-       writel(value, base + offset);
+       /*
+        * We requested the mem region starting from the Globals address
+        * space, see dwc3_probe in core.c.
+        * However, the offsets are given starting from xHCI address space.
+        */
+       writel(value, base + (offset - DWC3_GLOBALS_REGS_START));
 }
 
 #endif /* __DRIVERS_USB_DWC3_IO_H */