usb: dwc3: core: split host address space

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>
This commit is contained in:
Ido Shayevitz 2012-04-24 14:18:39 +03:00 committed by Felipe Balbi
parent ab5e59dbdb
commit 51249dca62
4 changed files with 45 additions and 34 deletions

View 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 = 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;
res = devm_request_mem_region(dev, res->start, resource_size(res),
/*
* 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;

View 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
@ -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
@ -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;

View File

@ -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;

View File

@ -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 */