summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>2011-03-11 14:57:36 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:04 +0200
commit364df12e7007e48bfabebd9ecacc5c682964d738 (patch)
tree7eedd67b118ba0d78d1aed6a86a88f0a37d19c5d
parent76e10d158efb6d4516018846f60c2ab5501900bc (diff)
usb: musb: ux500: add ux500 specific code for gadget side
Although U8500 and U5500 platforms use paltform dma, Inventra dma specific code can work for them for the most part. Only difference is for the Rx path where this patch is making use of request->short_not_ok to select dma mode. usb: musb: ux500: add dma name for ux500 usb: musb: ux500: add dma glue layer for ux500 DMA is mainly intended for mass storage class. Unaligned sizes and buffers are not supported. usb: musb: ux500: add configuration and build options for ux500 dma usb: musb: clear AUTOSET while clearing DMAENAB On the completion of tx dma, dma is disabled by clearing MUSB_TXCSR_DMAENAB in TXCSR. If MUSB_TXCSR_AUTOSET was set in txstate() it will remain set although it is not needed in PIO mode. Clear it as soon as it is not needed. usb: musb: ux500: copy dma mask from platform device to musb device musb code checks dma mask before calling dma hooks. usb: musb: do not release dma channel on channel_program failure Musb hcd releases dma channel (hw_ep->tx_channel / hw_ep->rx_channel ) if ->channel_program() fails. A null hw_ep->tx_channel is then used to continue the transfer in pio mode. Next call to musb_ep_program() will try to allocate the dma channel again. This patch allows the transfer to continue in pio mode if ->channel_program() fails without releasing the dma channel. usb: musb: restore rxcsr on channel_program failure Rxcsr is configured for dma transfer before calling ->channel_program(). Restore rxcsr if ->channel_program() fails. usb: musb: ux500: enable host side dma support Host side dma support for ux500 is enabled by piggybacking on Inventra dma support. Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
-rw-r--r--drivers/usb/musb/Kconfig9
-rw-r--r--drivers/usb/musb/musb_core.h1
-rw-r--r--drivers/usb/musb/musb_host.c25
3 files changed, 21 insertions, 14 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index f70cab3beee..1169c42b56e 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -114,4 +114,13 @@ config MUSB_PIO_ONLY
endchoice
+config USB_MUSB_DEBUG
+ depends on USB_MUSB_HDRC
+ bool "Enable debugging messages"
+ default n
+ help
+ This enables musb debugging. To set the logging level use the debug
+ module parameter. Starting at level 3, per-transfer (urb, usb_request,
+ packet, or dma transfer) tracing may kick in.
+
endif # USB_MUSB_HDRC
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f4a40f001c8..f072adba36a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -275,6 +275,7 @@ struct musb_hw_ep {
u8 rx_reinit;
u8 tx_reinit;
+ bool do_tx_pio;
/* peripheral side */
struct musb_ep ep_in; /* TX */
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index ef8d744800a..a0db9917f18 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -290,7 +290,7 @@ start:
dev_dbg(musb->controller, "Start TX%d %s\n", epnum,
hw_ep->tx_channel ? "dma" : "pio");
- if (!hw_ep->tx_channel)
+ if (!hw_ep->tx_channel || hw_ep->do_tx_pio)
musb_h_tx_start(hw_ep);
else if (is_cppi_enabled() || tusb_dma_omap())
musb_h_tx_dma_start(hw_ep);
@@ -615,7 +615,7 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
u16 csr;
u8 mode;
-#ifdef CONFIG_USB_INVENTRA_DMA
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)
if (length > channel->max_len)
length = channel->max_len;
@@ -656,8 +656,6 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
if (!dma->channel_program(channel, pkt_size, mode,
urb->transfer_dma + offset, length)) {
- dma->channel_release(channel);
- hw_ep->tx_channel = NULL;
csr = musb_readw(epio, MUSB_TXCSR);
csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
@@ -796,11 +794,11 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
else
load_count = min((u32) packet_sz, len);
- if (dma_channel && musb_tx_dma_program(dma_controller,
+ if (!dma_channel || !musb_tx_dma_program(dma_controller,
hw_ep, qh, urb, offset, len))
- load_count = 0;
+ hw_ep->do_tx_pio = true;
- if (load_count) {
+ if (hw_ep->do_tx_pio) {
/* PIO to load FIFO */
qh->segsize = load_count;
musb_write_fifo(hw_ep, load_count, buf);
@@ -1104,7 +1102,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
struct urb *urb = next_urb(qh);
u32 status = 0;
void __iomem *mbase = musb->mregs;
- struct dma_channel *dma;
+ struct dma_channel *dma = NULL;
bool transfer_pending = false;
musb_ep_select(mbase, epnum);
@@ -1537,7 +1535,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* FIXME this is _way_ too much in-line logic for Mentor DMA */
-#ifndef CONFIG_USB_INVENTRA_DMA
+#if !defined(CONFIG_USB_INVENTRA_DMA) && !defined(CONFIG_USB_UX500_DMA)
if (rx_csr & MUSB_RXCSR_H_REQPKT) {
/* REVISIT this happened for a while on some short reads...
* the cleanup still needs investigation... looks bad...
@@ -1569,7 +1567,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
| MUSB_RXCSR_RXPKTRDY);
musb_writew(hw_ep->regs, MUSB_RXCSR, val);
-#ifdef CONFIG_USB_INVENTRA_DMA
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)
if (usb_pipeisoc(pipe)) {
struct usb_iso_packet_descriptor *d;
@@ -1625,7 +1623,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
}
/* we are expecting IN packets */
-#ifdef CONFIG_USB_INVENTRA_DMA
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)
if (dma) {
struct dma_controller *c;
u16 rx_count;
@@ -1733,10 +1731,9 @@ void musb_host_rx(struct musb *musb, u8 epnum)
dma->desired_mode, buf, length);
if (!ret) {
- c->channel_release(dma);
- hw_ep->rx_channel = NULL;
dma = NULL;
- /* REVISIT reset CSR */
+ /* Restore CSR */
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
}
}
#endif /* Mentor DMA */