diff options
author | Andrey Konovalov <andrey.konovalov@linaro.org> | 2012-07-16 20:24:10 +0400 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2012-07-16 20:24:10 +0400 |
commit | b3768db6f4d8407882c02d560389543c972d4748 (patch) | |
tree | f1a1632e87232ae67e2c0e59197a26c62e1d6b26 /drivers | |
parent | c98c5ee0ecac183b83b12ea12c760640cf50cfee (diff) | |
parent | 6af8da9c55bf34b0089db8296c0e55470b8a7b27 (diff) |
Merge branch 'tracking-unsorted' into merge-linux-linaro
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/of/platform.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 18 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 17 |
3 files changed, 42 insertions, 0 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e44f8c2d239d..4150b9427047 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -348,6 +348,7 @@ static int of_platform_bus_create(struct device_node *bus, struct platform_device *dev; const char *bus_id = NULL; void *platform_data = NULL; + int id = -1; int rc = 0; /* Make sure it has a compatible property */ @@ -360,6 +361,7 @@ static int of_platform_bus_create(struct device_node *bus, auxdata = of_dev_lookup(lookup, bus); if (auxdata) { bus_id = auxdata->name; + id = auxdata->id; platform_data = auxdata->platform_data; } @@ -369,6 +371,11 @@ static int of_platform_bus_create(struct device_node *bus, } dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent); + + /* override the id if auxdata gives an id */ + if (id != -1) + dev->id = id; + if (!dev || !of_match_node(matches, bus)) return 0; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4378bf72bbac..a878ab1f6b99 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1003,6 +1003,12 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) head->qh_next.qh = qh; head->hw->hw_next = dma; + /* + * flush qh descriptor into memory immediately, + * see comments in qh_append_tds. + */ + ehci_sync_mem(); + qh_get(qh); qh->xacterrs = 0; qh->qh_state = QH_STATE_LINKED; @@ -1090,6 +1096,18 @@ static struct ehci_qh *qh_append_tds ( wmb (); dummy->hw_token = token; + /* + * Writing to dma coherent buffer on ARM may + * be delayed to reach memory, so HC may not see + * hw_token of dummy qtd in time, which can cause + * the qtd transaction to be executed very late, + * and degrade performance a lot. ehci_sync_mem + * is added to flush 'token' immediatelly into + * memory, so that ehci can execute the transaction + * ASAP. + */ + ehci_sync_mem(); + urb->hcpriv = qh_get (qh); } } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2694ed6558d2..b44c37d59ef0 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -748,6 +748,23 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) #endif +/* + * Writing to dma coherent memory on ARM may be delayed via L2 + * writing buffer, so introduce the helper which can flush L2 writing + * buffer into memory immediately, especially used to flush ehci + * descriptor to memory. + */ +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +static inline void ehci_sync_mem() +{ + mb(); +} +#else +static inline void ehci_sync_mem() +{ +} +#endif + /*-------------------------------------------------------------------------*/ #ifdef CONFIG_PCI |