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@xxxxxxxxxxxxxx> --- drivers/usb/dwc3/core.c | 31 ++++++++++++++++++------------- drivers/usb/dwc3/core.h | 15 ++++++++++++--- drivers/usb/dwc3/dwc3-omap.c | 32 +++++++++++++++++++++----------- drivers/usb/dwc3/host.c | 19 ++----------------- drivers/usb/dwc3/io.h | 16 ++++++++++++++-- 5 files changed, 67 insertions(+), 46 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 99b58d8..1040bdb 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -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; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 3061a8b..e9e6e86 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -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 @@ -75,6 +76,16 @@ #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 @@ -582,7 +593,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]; @@ -593,8 +604,6 @@ struct dwc3 { void __iomem *regs; size_t regs_size; - int irq; - u32 num_event_buffers; u32 u1u2; u32 maximum_speed; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index d7d9c0e..479dc04 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -49,7 +49,6 @@ #include <linux/of.h> #include "core.h" -#include "io.h" /* * All these registers belong to OMAP's Wrapper around the @@ -143,6 +142,17 @@ struct dwc3_omap { u32 dma_status:1; }; +static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset) +{ + return readl(base + offset); +} + +static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) +{ + writel(value, base + offset); +} + + static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) { struct dwc3_omap *omap = _omap; @@ -150,7 +160,7 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) spin_lock(&omap->lock); - reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1); + reg = dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_1); if (reg & USBOTGSS_IRQ1_DMADISABLECLR) { dev_dbg(omap->dev, "DMA Disable was Cleared\n"); @@ -184,10 +194,10 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL) dev_dbg(omap->dev, "IDPULLUP Fall\n"); - dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg); + dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg); - reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0); - dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg); + reg = dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_0); + dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg); spin_unlock(&omap->lock); @@ -270,7 +280,7 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) omap->base = base; omap->dwc3 = dwc3; - reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); + reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); utmi_mode = of_get_property(node, "utmi-mode", &size); if (utmi_mode && size == sizeof(*utmi_mode)) { @@ -293,10 +303,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) } } - dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg); + dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg); /* check the DMA Status */ - reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG); + reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE); /* Set No-Idle and No-Standby */ @@ -306,7 +316,7 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY) | USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE)); - dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg); + dwc3_omap_writel(omap->base, USBOTGSS_SYSCONFIG, reg); ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0, "dwc3-omap", omap); @@ -318,7 +328,7 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) /* enable all IRQs */ reg = USBOTGSS_IRQO_COREIRQ_ST; - dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg); + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg); reg = (USBOTGSS_IRQ1_OEVT | USBOTGSS_IRQ1_DRVVBUS_RISE | @@ -330,7 +340,7 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) USBOTGSS_IRQ1_DISCHRGVBUS_FALL | USBOTGSS_IRQ1_IDPULLUP_FALL); - dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); + dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg); ret = platform_device_add_resources(dwc3, pdev->resource, pdev->num_resources); diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index b108d18..56a6234 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -39,15 +39,6 @@ #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; diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h index 071d561..a50f76b 100644 --- a/drivers/usb/dwc3/io.h +++ b/drivers/usb/dwc3/io.h @@ -41,14 +41,26 @@ #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 */ -- 1.7.6 -- Consultant for Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html