Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51249dca authored by Ido Shayevitz's avatar Ido Shayevitz Committed by Felipe Balbi
Browse files

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: default avatarIdo Shayevitz <idos@codeaurora.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent ab5e59db
Loading
Loading
Loading
Loading
+18 −13
Original line number Original line Diff line number Diff line
@@ -410,7 +410,6 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
	struct device		*dev = &pdev->dev;
	struct device		*dev = &pdev->dev;


	int			ret = -ENOMEM;
	int			ret = -ENOMEM;
	int			irq;


	void __iomem		*regs;
	void __iomem		*regs;
	void			*mem;
	void			*mem;
@@ -425,15 +424,28 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
	dwc->mem = mem;
	dwc->mem = mem;


	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
	if (!res) {
		dev_err(dev, "missing resource\n");
		dev_err(dev, "missing IRQ\n");
		return -ENODEV;
		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));
			dev_name(dev));
	if (!res) {
	if (!res) {
		dev_err(dev, "can't request mem region\n");
		dev_err(dev, "can't request mem region\n");
@@ -446,19 +458,12 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
		return -ENOMEM;
		return -ENOMEM;
	}
	}


	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "missing IRQ\n");
		return -ENODEV;
	}

	spin_lock_init(&dwc->lock);
	spin_lock_init(&dwc->lock);
	platform_set_drvdata(pdev, dwc);
	platform_set_drvdata(pdev, dwc);


	dwc->regs	= regs;
	dwc->regs	= regs;
	dwc->regs_size	= resource_size(res);
	dwc->regs_size	= resource_size(res);
	dwc->dev	= dev;
	dwc->dev	= dev;
	dwc->irq	= irq;


	if (!strncmp("super", maximum_speed, 5))
	if (!strncmp("super", maximum_speed, 5))
		dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
		dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
+12 −3
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@


/* Global constants */
/* Global constants */
#define DWC3_ENDPOINTS_NUM	32
#define DWC3_ENDPOINTS_NUM	32
#define DWC3_XHCI_RESOURCES_NUM	2


#define DWC3_EVENT_BUFFERS_SIZE	PAGE_SIZE
#define DWC3_EVENT_BUFFERS_SIZE	PAGE_SIZE
#define DWC3_EVENT_TYPE_MASK	0xfe
#define DWC3_EVENT_TYPE_MASK	0xfe
@@ -75,6 +76,16 @@
#define DWC3_GSNPSID_MASK	0xffff0000
#define DWC3_GSNPSID_MASK	0xffff0000
#define DWC3_GSNPSREV_MASK	0xffff
#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 */
/* Global Registers */
#define DWC3_GSBUSCFG0		0xc100
#define DWC3_GSBUSCFG0		0xc100
#define DWC3_GSBUSCFG1		0xc104
#define DWC3_GSBUSCFG1		0xc104
@@ -583,7 +594,7 @@ struct dwc3 {
	struct device		*dev;
	struct device		*dev;


	struct platform_device	*xhci;
	struct platform_device	*xhci;
	struct resource		*res;
	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];


	struct dwc3_event_buffer **ev_buffs;
	struct dwc3_event_buffer **ev_buffs;
	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
@@ -594,8 +605,6 @@ struct dwc3 {
	void __iomem		*regs;
	void __iomem		*regs;
	size_t			regs_size;
	size_t			regs_size;


	int			irq;

	u32			num_event_buffers;
	u32			num_event_buffers;
	u32			u1u2;
	u32			u1u2;
	u32			maximum_speed;
	u32			maximum_speed;
+2 −17
Original line number Original line Diff line number Diff line
@@ -39,15 +39,6 @@


#include "core.h"
#include "core.h"


static struct resource generic_resources[] = {
	{
		.flags = IORESOURCE_IRQ,
	},
	{
		.flags = IORESOURCE_MEM,
	},
};

int dwc3_host_init(struct dwc3 *dwc)
int dwc3_host_init(struct dwc3 *dwc)
{
{
	struct platform_device	*xhci;
	struct platform_device	*xhci;
@@ -68,14 +59,8 @@ int dwc3_host_init(struct dwc3 *dwc)


	dwc->xhci = xhci;
	dwc->xhci = xhci;


	/* setup resources */
	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
	generic_resources[0].start = dwc->irq;
						DWC3_XHCI_RESOURCES_NUM);

	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));
	if (ret) {
	if (ret) {
		dev_err(dwc->dev, "couldn't add resources to xHCI device\n");
		dev_err(dwc->dev, "couldn't add resources to xHCI device\n");
		goto err1;
		goto err1;
+14 −2
Original line number Original line Diff line number Diff line
@@ -41,14 +41,26 @@


#include <linux/io.h>
#include <linux/io.h>


#include "core.h"

static inline u32 dwc3_readl(void __iomem *base, u32 offset)
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)
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 */
#endif /* __DRIVERS_USB_DWC3_IO_H */