usb: dwc3: core: memory ordering fix in close
[pandora-kernel.git] / drivers / usb / dwc3 / core.c
index 1040bdb..08a5738 100644 (file)
@@ -99,6 +99,7 @@ void dwc3_put_device_id(int id)
 
        ret = test_bit(id, dwc3_devs);
        WARN(!ret, "dwc3: ID %d not in use\n", id);
+       smp_mb__before_clear_bit();
        clear_bit(id, dwc3_devs);
 }
 EXPORT_SYMBOL_GPL(dwc3_put_device_id);
@@ -148,6 +149,8 @@ static void dwc3_core_soft_reset(struct dwc3 *dwc)
        reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
+       mdelay(100);
+
        /* After PHYs are stable we can take Core out of reset state */
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
        reg &= ~DWC3_GCTL_CORESOFTRESET;
@@ -255,7 +258,7 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
  *
  * Returns 0 on success otherwise negative errno.
  */
-static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
+static int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
        struct dwc3_event_buffer        *evt;
        int                             n;
@@ -266,6 +269,8 @@ static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
                                evt->buf, (unsigned long long) evt->dma,
                                evt->length);
 
+               evt->lpos = 0;
+
                dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
                                lower_32_bits(evt->dma));
                dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
@@ -285,6 +290,9 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 
        for (n = 0; n < dwc->num_event_buffers; n++) {
                evt = dwc->ev_buffs[n];
+
+               evt->lpos = 0;
+
                dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
                dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
                dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);
@@ -328,8 +336,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
        }
        dwc->revision = reg;
 
-       dwc3_core_soft_reset(dwc);
-
        /* issue device SoftReset too */
        timeout = jiffies + msecs_to_jiffies(500);
        dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
@@ -347,6 +353,8 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
                cpu_relax();
        } while (true);
 
+       dwc3_core_soft_reset(dwc);
+
        dwc3_cache_hwparams(dwc);
 
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
@@ -452,7 +460,7 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       regs = devm_ioremap(dev, res->start, resource_size(res));
+       regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
        if (!regs) {
                dev_err(dev, "ioremap failed\n");
                return -ENOMEM;