MUSB patches to select all DMA drivers
Subsystems (4)
cover MUSB patches to select all DMA drivers
Hi all,
Here are few patches that allow building in all the MUSB DMA drivers for distros. This also allows us to get rid of most of the ifdefs, and also simplifies the musb_host_rx monster function a bit.
Regards,
Tony
Tony Lindgren (12):
usb: musb: Fix up DMA related macros
usb: musb: Set up function pointers for DMA
usb: musb: Get rid of the DMA ifdefs for musb_core.c
usb: musb: Remove DMA ifdef for musb_gadget.c short_packet
usb: musb: Remove the rest of DMA related ifdefs in musb_gadget.c
usb: musb: Remove ifdefs for TX DMA for musb_host.c
usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part1
usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part2
usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part3
usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part4
usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part5
usb: musb: Allow building in all the DMA code
drivers/usb/musb/Kconfig | 38 ++- drivers/usb/musb/am35x.c | 6 +- drivers/usb/musb/blackfin.c | 5 + drivers/usb/musb/cppi_dma.c | 9 +- drivers/usb/musb/da8xx.c | 6 +- drivers/usb/musb/davinci.c | 7 +- drivers/usb/musb/jz4740.c | 6 +- drivers/usb/musb/musb_core.c | 29 ++- drivers/usb/musb/musb_core.h | 5 + drivers/usb/musb/musb_cppi41.c | 8 +- drivers/usb/musb/musb_dma.h | 67 +++++- drivers/usb/musb/musb_dsps.c | 6 +- drivers/usb/musb/musb_gadget.c | 52 ++-- drivers/usb/musb/musb_host.c | 509 ++++++++++++++++++++++++--------------- drivers/usb/musb/musbhsdma.c | 9 +- drivers/usb/musb/omap2430.c | 5 + drivers/usb/musb/tusb6010.c | 8 +- drivers/usb/musb/tusb6010.h | 6 - drivers/usb/musb/tusb6010_omap.c | 9 +- drivers/usb/musb/ux500.c | 6 +- drivers/usb/musb/ux500_dma.c | 8 +- 21 files changed, 509 insertions(+), 295 deletions(-)
Signature · 6 lines
2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 1430508578-5208-1-git-send-email-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org
PATCH 7/12 usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part1
Remove ifdefs for musb_host_rx to get closer to building in all the DMA drivers.
--- drivers/usb/musb/musb_host.c | 61 ++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-)
drivers/usb/musb/musb_host.c +44 -13
@@ -1533,6 +1533,44 @@ done: MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); } +#ifdef CONFIG_USB_TI_CPPI41_DMA +/* Seems to set up ISO for cppi41 and not advance len. See commit c57c41d */ +static int musb_rx_dma_iso_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len) +{ +struct dma_channel *channel = hw_ep->tx_channel; +void __iomem *epio = hw_ep->regs; +dma_addr_t *buf; +u32 length, res; +u16 val; + + buf = (void *)urb->iso_frame_desc[qh->iso_idx].offset + + (u32 )urb->transfer_dma; + + length = urb->iso_frame_desc[qh->iso_idx].length; + + val =musb_readw (epio,MUSB_RXCSR ); + val |=MUSB_RXCSR_DMAENAB ; +musb_writew (hw_ep->regs,MUSB_RXCSR , val); + + res = dma->channel_program (channel, qh->maxpacket,0 , + (u32 )buf, length); + +return res; +} +#else +static inline int musb_rx_dma_iso_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len) +{ +return false; +} +#endif #ifdef CONFIG_USB_INVENTRA_DMA
@@ -1746,25 +1784,14 @@ void musb_host_rx(struct musb *musb, u8 epnum)if (++qh->iso_idx >= urb->number_of_packets) { done = true; }else { -#if defined(CONFIG_USB_TI_CPPI41_DMA ) -struct dma_controller *c; -dma_addr_t *buf; -u32 length, ret; +struct dma_controller *c = musb->dma_controller; - c = musb->dma_controller; - buf = (void *) - urb->iso_frame_desc[qh->iso_idx].offset - + (u32 )urb->transfer_dma; +/* REVISIT: Why ignore return value here? */ +if (musb_dma_cppi41 (musb)) + done =musb_rx_dma_iso_cppi41 (c, hw_ep, + qh, urb, + xfer_len); - length = - urb->iso_frame_desc[qh->iso_idx].length; - - val |=MUSB_RXCSR_DMAENAB ; -musb_writew (hw_ep->regs,MUSB_RXCSR , val);
PATCH 10/12 usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part4
In reply to a message not in the archiveRemove ifdefs for musb_host_rx to get closer to building in all the DMA drivers.
--- drivers/usb/musb/musb_host.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_host.c +2 -4
@@ -1857,9 +1857,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) }/* we are expecting IN packets */ -#if defined(CONFIG_USB_INVENTRA_DMA ) || defined(CONFIG_USB_UX500_DMA ) || \ - defined(CONFIG_USB_TI_CPPI41_DMA ) -if (dma) { +if ((musb_dma_inventra (musb) ||musb_dma_ux500 (musb) || +musb_dma_cppi41 (musb)) && dma) {struct dma_controller *c;u16 rx_count;int ret, length;
@@ -1976,7 +1975,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)musb_writew (epio,MUSB_RXCSR , val); } } -#endif /* Mentor DMA */ if (!dma) {unsigned int received_len;
Signature · 6 lines
2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/12 usb: musb: Fix up DMA related macros
In reply to Tony LindgrenPass struct musb to tusb_dma_omap() and is_cppi_enabled(), and add macros for the other DMA controllers. Populate the platform specific quirks with the DMA type and use it during runtime.
Note that platform glue layers with no custom DMA code are tagged with MUSB_DMA_INVENTRA which may have a chance of working. Looks like the defconfigs for these use PIO_ONLY, so this should not break existing configs.
--- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/blackfin.c | 1 + drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 3 ++- drivers/usb/musb/jz4740.c | 2 +- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_dma.h | 35 ++++++++++++++++++++++++++++++----- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/musb_gadget.c | 8 ++++---- drivers/usb/musb/musb_host.c | 10 +++++----- drivers/usb/musb/omap2430.c | 1 + drivers/usb/musb/tusb6010.c | 4 ++-- drivers/usb/musb/tusb6010.h | 6 ------ drivers/usb/musb/ux500.c | 2 +- 14 files changed, 51 insertions(+), 29 deletions(-)
drivers/usb/musb/am35x.c +1 -1
@@ -438,7 +438,7 @@ static void am35x_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) }static const struct musb_platform_ops am35x_ops = { - .quirks =MUSB_INDEXED_EP , + .quirks =MUSB_DMA_INVENTRA |MUSB_INDEXED_EP , .init = am35x_musb_init, .exit = am35x_musb_exit,
drivers/usb/musb/blackfin.c +1 -0
@@ -465,6 +465,7 @@ static int bfin_musb_exit(struct musb *musb) }static const struct musb_platform_ops bfin_ops = { + .quirks =MUSB_DMA_INVENTRA , .init = bfin_musb_init, .exit = bfin_musb_exit,
drivers/usb/musb/da8xx.c +1 -1
@@ -458,7 +458,7 @@ static int da8xx_musb_exit(struct musb *musb) }static const struct musb_platform_ops da8xx_ops = { - .quirks =MUSB_INDEXED_EP , + .quirks =MUSB_DMA_CPPI |MUSB_INDEXED_EP , .init = da8xx_musb_init, .exit = da8xx_musb_exit,
drivers/usb/musb/davinci.c +2 -1
@@ -284,7 +284,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)* mask, state, "vector", and EOI registers. */ cppi = container_of(musb->dma_controller, struct cppi, controller); -if (is_cppi_enabled () && musb->dma_controller && !cppi->irq) +if (is_cppi_enabled (musb) && musb->dma_controller && !cppi->irq) retval =cppi_interrupt (irq, __hci);/* ack and handle non-CPPI interrupts */
@@ -491,6 +491,7 @@ static int davinci_musb_exit(struct musb *musb) }static const struct musb_platform_ops davinci_ops = { + .quirks =MUSB_DMA_CPPI , .init = davinci_musb_init, .exit = davinci_musb_exit,
drivers/usb/musb/jz4740.c +1 -1
@@ -106,7 +106,7 @@ static int jz4740_musb_exit(struct musb *musb) }static const struct musb_platform_ops jz4740_musb_ops = { - .quirks =MUSB_INDEXED_EP , + .quirks =MUSB_DMA_INVENTRA |MUSB_INDEXED_EP , .fifo_mode =2 , .init = jz4740_musb_init, .exit = jz4740_musb_exit,
drivers/usb/musb/musb_core.c +1 -1
@@ -1659,7 +1659,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)if (!epnum) {#ifndef CONFIG_USB_TUSB_OMAP_DMA -if (!is_cppi_enabled ()) { +if (!is_cppi_enabled (musb)) {/* endpoint 0 */ if (is_host_active (musb))musb_h_ep0_irq (musb);
drivers/usb/musb/musb_dma.h +30 -5
@@ -68,16 +68,41 @@ struct musb_hw_ep;#define is_dma_capable () (1)#endif -#if defined(CONFIG_USB_TI_CPPI_DMA ) || defined(CONFIG_USB_TI_CPPI41_DMA ) -#define is_cppi_enabled () 1 +#ifdef CONFIG_USB_UX500_DMA +#define musb_dma_ux500 (musb) (musb->io.quirks & MUSB_DMA_UX500) +#else +#define musb_dma_ux500 (musb) 0 +#endif + +#ifdef CONFIG_USB_TI_CPPI41_DMA +#define musb_dma_cppi41 (musb) (musb->io.quirks & MUSB_DMA_CPPI41) +#else +#define musb_dma_cppi41 (musb) 0 +#endif + +#ifdef CONFIG_USB_TI_CPPI_DMA +#define musb_dma_cppi (musb) (musb->io.quirks & MUSB_DMA_CPPI)#else -#define is_cppi_enabled () 0 +#define musb_dma_cppi (musb) 0#endif #ifdef CONFIG_USB_TUSB_OMAP_DMA -#define tusb_dma_omap () 1 +#define tusb_dma_omap (musb) (musb->io.quirks & MUSB_DMA_TUSB_OMAP) +#else +#define tusb_dma_omap (musb) 0 +#endif + +#ifdef CONFIG_USB_INVENTRA_DMA +#define musb_dma_inventra (musb) (musb->io.quirks & MUSB_DMA_INVENTRA) +#else +#define musb_dma_inventra (musb) 0 +#endif + +#if defined(CONFIG_USB_TI_CPPI_DMA ) || defined(CONFIG_USB_TI_CPPI41_DMA ) +#define is_cppi_enabled (musb) \ + (musb_dma_cppi(musb) || musb_dma_cppi41(musb))#else -#define tusb_dma_omap () 0 +#define is_cppi_enabled (musb) 0#endif /* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1
drivers/usb/musb/musb_dsps.c +1 -1
@@ -634,7 +634,7 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) }static struct musb_platform_ops dsps_ops = { - .quirks =MUSB_INDEXED_EP , + .quirks =MUSB_DMA_CPPI41 |MUSB_INDEXED_EP , .init = dsps_musb_init, .exit = dsps_musb_exit,
drivers/usb/musb/musb_gadget.c +4 -4
@@ -366,7 +366,7 @@ static void txstate(struct musb *musb, struct musb_request *req) }#endif -if (is_cppi_enabled ()) { +if (is_cppi_enabled (musb)) {/* program endpoint CSR first, then setup DMA */ csr &= ~(MUSB_TXCSR_P_UNDERRUN |MUSB_TXCSR_TXPKTRDY ); csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
@@ -402,7 +402,7 @@ static void txstate(struct musb *musb, struct musb_request *req)musb_writew (epio,MUSB_TXCSR , csr);/* invariant: prequest->buf is non-null */ } - }else if (tusb_dma_omap ()) + }else if (tusb_dma_omap (musb)) use_dma = use_dma && c->channel_program( musb_ep->dma, musb_ep->packet_sz, request->zero,
@@ -595,7 +595,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)return ; } -if (is_cppi_enabled () &&is_buffer_mapped (req)) { +if (is_cppi_enabled (musb) &&is_buffer_mapped (req)) {struct dma_controller *c = musb->dma_controller;struct dma_channel *channel = musb_ep->dma;
@@ -772,7 +772,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) fifo_count =min_t (unsigned, len, fifo_count);#ifdef CONFIG_USB_TUSB_OMAP_DMA -if (tusb_dma_omap () &&is_buffer_mapped (req)) { +if (tusb_dma_omap (musb) &&is_buffer_mapped (req)) {struct dma_controller *c = musb->dma_controller;struct dma_channel *channel = musb_ep->dma;u32 dma_addr = request->dma + request->actual;
drivers/usb/musb/musb_host.c +5 -5
@@ -181,7 +181,7 @@ static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep)/* NOTE: no locks here; caller should lock and select EP */ txcsr =musb_readw (ep->regs,MUSB_TXCSR ); txcsr |=MUSB_TXCSR_DMAENAB |MUSB_TXCSR_H_WZC_BITS ; -if (is_cppi_enabled ()) +if (is_cppi_enabled (ep->musb)) txcsr |=MUSB_TXCSR_DMAMODE ;musb_writew (ep->regs,MUSB_TXCSR , txcsr); }
@@ -294,7 +294,7 @@ start:if (!hw_ep->tx_channel)musb_h_tx_start (hw_ep); -else if (is_cppi_enabled () ||tusb_dma_omap ()) +else if (is_cppi_enabled (musb) ||tusb_dma_omap (musb))musb_h_tx_dma_start (hw_ep); } }
@@ -656,7 +656,7 @@ static bool musb_tx_dma_program(struct dma_controller *dma, channel->desired_mode = mode;musb_writew (epio,MUSB_TXCSR , csr);#else -if (!is_cppi_enabled () && !tusb_dma_omap ()) +if (!is_cppi_enabled (hw_ep->musb) && !tusb_dma_omap (hw_ep->musb))return false; channel->actual_len =0 ;
@@ -901,7 +901,7 @@ finish:/* kick things off */ -if ((is_cppi_enabled () ||tusb_dma_omap ()) && dma_channel) { +if ((is_cppi_enabled (musb) ||tusb_dma_omap (musb)) && dma_channel) {/* Candidate for DMA */ dma_channel->actual_len =0L ; qh->segsize = len;
@@ -1441,7 +1441,7 @@ done: }else if ((usb_pipeisoc (pipe) || transfer_pending) && dma) {if (musb_tx_dma_program (musb->dma_controller, hw_ep, qh, urb, offset, length)) { -if (is_cppi_enabled () ||tusb_dma_omap ()) +if (is_cppi_enabled (musb) ||tusb_dma_omap (musb))musb_h_tx_dma_start (hw_ep);return ; }
drivers/usb/musb/omap2430.c +1 -0
@@ -493,6 +493,7 @@ static int omap2430_musb_exit(struct musb *musb) }static const struct musb_platform_ops omap2430_ops = { + .quirks =MUSB_DMA_INVENTRA , .init = omap2430_musb_init, .exit = omap2430_musb_exit,
drivers/usb/musb/tusb6010.c +2 -2
@@ -890,7 +890,7 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci)dev_dbg (musb->controller,"DMA IRQ %08x\n" , dma_src); real_dma_src = ~real_dma_src & dma_src; -if (tusb_dma_omap () && real_dma_src) { +if (tusb_dma_omap (musb) && real_dma_src) {int tx_source = (real_dma_src &0xffff );int i;
@@ -1181,7 +1181,7 @@ static int tusb_musb_exit(struct musb *musb) }static const struct musb_platform_ops tusb_ops = { - .quirks =MUSB_IN_TUSB , + .quirks =MUSB_DMA_TUSB_OMAP |MUSB_IN_TUSB , .init = tusb_musb_init, .exit = tusb_musb_exit,
drivers/usb/musb/tusb6010.h +0 -6
@@ -12,12 +12,6 @@#ifndef __TUSB6010_H__#define __TUSB6010_H__ -#ifdef CONFIG_USB_TUSB_OMAP_DMA -#define tusb_dma_omap () 1 -#else -#define tusb_dma_omap () 0 -#endif -/* VLYNQ control register. 32-bit at offset 0x000 */ #define TUSB_VLYNQ_CTRL 0x004
drivers/usb/musb/ux500.c +1 -1
@@ -188,7 +188,7 @@ static int ux500_musb_exit(struct musb *musb) }static const struct musb_platform_ops ux500_ops = { - .quirks =MUSB_INDEXED_EP , + .quirks =MUSB_DMA_UX500 |MUSB_INDEXED_EP , .init = ux500_musb_init, .exit = ux500_musb_exit, .fifo_mode =5 ,
Signature · 1 line
2.1.4
PATCH 2/12 usb: musb: Set up function pointers for DMA
In reply to Tony LindgrenSet up function pointers for DMA so get closer to
being able to build in all the DMA engines.
--- drivers/usb/musb/am35x.c | 4 ++++ drivers/usb/musb/blackfin.c | 4 ++++ drivers/usb/musb/cppi_dma.c | 9 ++++++--- drivers/usb/musb/da8xx.c | 4 ++++ drivers/usb/musb/davinci.c | 4 ++++ drivers/usb/musb/jz4740.c | 4 ++++ drivers/usb/musb/musb_core.c | 25 ++++++++++++++++++++++--- drivers/usb/musb/musb_core.h | 5 +++++ drivers/usb/musb/musb_cppi41.c | 8 +++++--- drivers/usb/musb/musb_dma.h | 32 +++++++++++++++++++++++++++----- drivers/usb/musb/musb_dsps.c | 4 ++++ drivers/usb/musb/musbhsdma.c | 9 ++++++--- drivers/usb/musb/omap2430.c | 4 ++++ drivers/usb/musb/tusb6010.c | 4 ++++ drivers/usb/musb/tusb6010_omap.c | 9 ++++++--- drivers/usb/musb/ux500.c | 4 ++++ drivers/usb/musb/ux500_dma.c | 8 +++++--- 17 files changed, 118 insertions(+), 23 deletions(-)
drivers/usb/musb/am35x.c +4 -0
@@ -443,6 +443,10 @@ static const struct musb_platform_ops am35x_ops = { .exit = am35x_musb_exit, .read_fifo = am35x_read_fifo, +#ifdef CONFIG_USB_INVENTRA_DMA + .dma_init = musbhs_dma_controller_create, + .dma_exit = musbhs_dma_controller_destroy, +#endif .enable = am35x_musb_enable, .disable = am35x_musb_disable,
drivers/usb/musb/blackfin.c +4 -0
@@ -478,6 +478,10 @@ static const struct musb_platform_ops bfin_ops = { .fifo_mode = 2, .read_fifo = bfin_read_fifo, .write_fifo = bfin_write_fifo, +#ifdef CONFIG_USB_INVENTRA_DMA + .dma_init = musbhs_dma_controller_create, + .dma_exit = musbhs_dma_controller_destroy, +#endif .enable = bfin_musb_enable, .disable = bfin_musb_disable,
drivers/usb/musb/cppi_dma.c +6 -3
@@ -1297,7 +1297,8 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)EXPORT_SYMBOL_GPL (cppi_interrupt);/* Instantiate a software object representing a DMA controller. */ -struct dma_controller *dma_controller_create (struct musb *musb,void __iomem *mregs) +struct dma_controller * +cppi_dma_controller_create (struct musb *musb,void __iomem *mregs) {struct cppi *controller;struct device *dev = musb->controller;
@@ -1334,7 +1335,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mrif (irq >0 ) {if (request_irq (irq, cppi_interrupt,0 ,"cppi-dma" , musb)) {dev_err (dev,"request_irq %d failed!\n" , irq); -dma_controller_destroy (&controller->controller); +musb_dma_controller_destroy (&controller->controller);return NULL ; } controller->irq = irq;
@@ -1343,11 +1344,12 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mrcppi_controller_start (controller);return &controller->controller; } +EXPORT_SYMBOL_GPL (cppi_dma_controller_create);/* * Destroy a previously-instantiated DMA controller. */ -void dma_controller_destroy (struct dma_controller *c) +void cppi_dma_controller_destroy (struct dma_controller *c) {struct cppi *cppi;
@@ -1363,6 +1365,7 @@ void dma_controller_destroy(struct dma_controller *c)kfree (cppi); } +EXPORT_SYMBOL_GPL (cppi_dma_controller_destroy);/* * Context: controller irqlocked, endpoint selected
drivers/usb/musb/da8xx.c +4 -0
@@ -463,6 +463,10 @@ static const struct musb_platform_ops da8xx_ops = { .exit = da8xx_musb_exit, .fifo_mode =2 , +#ifdef CONFIG_USB_TI_CPPI_DMA + .dma_init = cppi_dma_controller_create, + .dma_exit = cppi_dma_controller_destroy, +#endif .enable = da8xx_musb_enable, .disable = da8xx_musb_disable,
drivers/usb/musb/davinci.c +4 -0
@@ -495,6 +495,10 @@ static const struct musb_platform_ops davinci_ops = { .init = davinci_musb_init, .exit = davinci_musb_exit, +#ifdef CONFIG_USB_TI_CPPI_DMA + .dma_init = cppi_dma_controller_create, + .dma_exit = cppi_dma_controller_destroy, +#endif .enable = davinci_musb_enable, .disable = davinci_musb_disable,
drivers/usb/musb/jz4740.c +4 -0
@@ -105,6 +105,10 @@ static int jz4740_musb_exit(struct musb *musb)return 0 ; } +/* +* DMA has not been confirmed to work with CONFIG_USB_INVENTRA_DMA, +* so let's not set up the dma function pointers yet. +*/ static const struct musb_platform_ops jz4740_musb_ops = { .quirks =MUSB_DMA_INVENTRA |MUSB_INDEXED_EP , .fifo_mode =2 ,
drivers/usb/musb/musb_core.c +22 -3
@@ -389,6 +389,15 @@ EXPORT_SYMBOL_GPL(musb_readl);void (*musb_writel)(void __iomem *addr,unsigned offset,u32 data);EXPORT_SYMBOL_GPL (musb_writel); +#ifndef CONFIG_MUSB_PIO_ONLY +struct dma_controller * +(*musb_dma_controller_create)(struct musb *musb,void __iomem *base); +EXPORT_SYMBOL (musb_dma_controller_create); + +void (*musb_dma_controller_destroy)(struct dma_controller *c); +EXPORT_SYMBOL (musb_dma_controller_destroy); +#endif +/* * New style IO functions */
@@ -2059,6 +2068,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)if (musb->ops->writel) musb_writel = musb->ops->writel; +#ifndef CONFIG_MUSB_PIO_ONLY +if (!musb->ops->dma_init || !musb->ops->dma_exit) { +dev_err (dev,"DMA controller not set\n" ); + goto fail2; + } + musb_dma_controller_create = musb->ops->dma_init; + musb_dma_controller_destroy = musb->ops->dma_exit; +#endif +if (musb->ops->read_fifo) musb->io.read_fifo = musb->ops->read_fifo;else
@@ -2078,7 +2096,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)pm_runtime_get_sync (musb->controller);if (use_dma && dev->dma_mask) { - musb->dma_controller =dma_controller_create (musb, musb->mregs); + musb->dma_controller = +musb_dma_controller_create (musb, musb->mregs);if (IS_ERR (musb->dma_controller)) { status =PTR_ERR (musb->dma_controller); goto fail2_5;
@@ -2189,7 +2208,7 @@ fail3:cancel_delayed_work_sync (&musb->finish_resume_work);cancel_delayed_work_sync (&musb->deassert_reset_work);if (musb->dma_controller) -dma_controller_destroy (musb->dma_controller); +musb_dma_controller_destroy (musb->dma_controller); fail2_5:pm_runtime_put_sync (musb->controller);
@@ -2248,7 +2267,7 @@ static int musb_remove(struct platform_device *pdev)musb_shutdown (pdev);if (musb->dma_controller) -dma_controller_destroy (musb->dma_controller); +musb_dma_controller_destroy (musb->dma_controller);cancel_work_sync (&musb->irq_work);cancel_delayed_work_sync (&musb->finish_resume_work);
drivers/usb/musb/musb_core.h +5 -0
@@ -157,6 +157,8 @@ struct musb_io;* @writel: write 32 bits * @read_fifo: reads the fifo * @write_fifo: writes to fifo +* @dma_init: platform specific dma init function +* @dma_exit: platform specific dma exit function * @init: turns on clocks, sets up platform-specific registers, etc * @exit: undoes @init * @set_mode: forcefully changes operating mode
@@ -195,6 +197,9 @@ struct musb_platform_ops {void (*writel)(void __iomem *addr,unsigned offset,u32 data);void (*read_fifo)(struct musb_hw_ep *hw_ep,u16 len,u8 *buf);void (*write_fifo)(struct musb_hw_ep *hw_ep,u16 len,const u8 *buf); +struct dma_controller * + (*dma_init) (struct musb *musb,void __iomem *base); +void (*dma_exit)(struct dma_controller *c);int (*set_mode)(struct musb *musb,u8 mode);void (*try_idle)(struct musb *musb,unsigned long timeout);int (*recover)(struct musb *musb);
drivers/usb/musb/musb_cppi41.c +5 -3
@@ -678,7 +678,7 @@ err:return ret; } -void dma_controller_destroy (struct dma_controller *c) +void cppi41_dma_controller_destroy (struct dma_controller *c) {struct cppi41_dma_controller *controller =container_of (c, struct cppi41_dma_controller, controller);
@@ -687,9 +687,10 @@ void dma_controller_destroy(struct dma_controller *c)cppi41_dma_controller_stop (controller);kfree (controller); } +EXPORT_SYMBOL_GPL (cppi41_dma_controller_destroy); -struct dma_controller *dma_controller_create (struct musb *musb, -void __iomem *base) +struct dma_controller * +cppi41_dma_controller_create (struct musb *musb,void __iomem *base) {struct cppi41_dma_controller *controller;int ret =0 ;
@@ -726,3 +727,4 @@ kzalloc_fail:return ERR_PTR (ret);return NULL ; } +EXPORT_SYMBOL_GPL (cppi41_dma_controller_create);
drivers/usb/musb/musb_dma.h +27 -5
@@ -202,19 +202,41 @@ struct dma_controller {extern void musb_dma_completion (struct musb *musb,u8 epnum,u8 transmit);#ifdef CONFIG_MUSB_PIO_ONLY -static inline struct dma_controller *dma_controller_create (struct musb *m, -void __iomem *io) +static inline struct dma_controller * +musb_dma_controller_create (struct musb *m,void __iomem *io) {return NULL ; } -static inline void dma_controller_destroy (struct dma_controller *d) { } +static inline void musb_dma_controller_destroy (struct dma_controller *d) { }#else -extern struct dma_controller *dma_controller_create (struct musb *,void __iomem *); +extern struct dma_controller * +(*musb_dma_controller_create)(struct musb *,void __iomem *); -extern void dma_controller_destroy (struct dma_controller *); +extern void (*musb_dma_controller_destroy)(struct dma_controller *);#endif +/* Platform specific DMA functions */ +extern struct dma_controller * +musbhs_dma_controller_create (struct musb *musb,void __iomem *base); +extern void musbhs_dma_controller_destroy (struct dma_controller *c); + +extern struct dma_controller * +tusb_dma_controller_create (struct musb *musb,void __iomem *base); +extern void tusb_dma_controller_destroy (struct dma_controller *c); + +extern struct dma_controller * +cppi_dma_controller_create (struct musb *musb,void __iomem *base); +extern void cppi_dma_controller_destroy (struct dma_controller *c); + +extern struct dma_controller * +cppi41_dma_controller_create (struct musb *musb,void __iomem *base); +extern void cppi41_dma_controller_destroy (struct dma_controller *c); + +extern struct dma_controller * +ux500_dma_controller_create (struct musb *musb,void __iomem *base); +extern void ux500_dma_controller_destroy (struct dma_controller *c); +#endif /* __MUSB_DMA_H__ */
drivers/usb/musb/musb_dsps.c +4 -0
@@ -638,6 +638,10 @@ static struct musb_platform_ops dsps_ops = { .init = dsps_musb_init, .exit = dsps_musb_exit, +#ifdef CONFIG_USB_TI_CPPI41_DMA + .dma_init = cppi41_dma_controller_create, + .dma_exit = cppi41_dma_controller_destroy, +#endif .enable = dsps_musb_enable, .disable = dsps_musb_disable,
drivers/usb/musb/musbhsdma.c +6 -3
@@ -357,7 +357,7 @@ done:return retval; } -void dma_controller_destroy (struct dma_controller *c) +void musbhs_dma_controller_destroy (struct dma_controller *c) {struct musb_dma_controller *controller =container_of (c, struct musb_dma_controller, controller);
@@ -369,8 +369,10 @@ void dma_controller_destroy(struct dma_controller *c)kfree (controller); } +EXPORT_SYMBOL_GPL (musbhs_dma_controller_destroy); -struct dma_controller *dma_controller_create (struct musb *musb,void __iomem *base) +struct dma_controller *musbhs_dma_controller_create (struct musb *musb, +void __iomem *base) {struct musb_dma_controller *controller;struct device *dev = musb->controller;
@@ -398,7 +400,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *baif (request_irq (irq, dma_controller_irq,0 ,dev_name (musb->controller), &controller->controller)) {dev_err (dev,"request_irq %d failed!\n" , irq); -dma_controller_destroy (&controller->controller); +musb_dma_controller_destroy (&controller->controller);return NULL ; }
@@ -407,3 +409,4 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *bareturn &controller->controller; } +EXPORT_SYMBOL_GPL (musbhs_dma_controller_create);
drivers/usb/musb/omap2430.c +4 -0
@@ -494,6 +494,10 @@ static int omap2430_musb_exit(struct musb *musb)static const struct musb_platform_ops omap2430_ops = { .quirks =MUSB_DMA_INVENTRA , +#ifdef CONFIG_USB_INVENTRA_DMA + .dma_init = musbhs_dma_controller_create, + .dma_exit = musbhs_dma_controller_destroy, +#endif .init = omap2430_musb_init, .exit = omap2430_musb_exit,
drivers/usb/musb/tusb6010.c +4 -0
@@ -1192,6 +1192,10 @@ static const struct musb_platform_ops tusb_ops = { .writeb = tusb_writeb, .read_fifo = tusb_read_fifo, .write_fifo = tusb_write_fifo, +#ifdef CONFIG_USB_TUSB_OMAP_DMA + .dma_init = tusb_dma_controller_create, + .dma_exit = tusb_dma_controller_destroy, +#endif .enable = tusb_musb_enable, .disable = tusb_musb_disable,
drivers/usb/musb/tusb6010_omap.c +6 -3
@@ -625,7 +625,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel) channel =NULL ; } -void dma_controller_destroy (struct dma_controller *c) +void tusb_dma_controller_destroy (struct dma_controller *c) {struct tusb_omap_dma *tusb_dma;int i;
@@ -644,8 +644,10 @@ void dma_controller_destroy(struct dma_controller *c)kfree (tusb_dma); } +EXPORT_SYMBOL_GPL (tusb_dma_controller_destroy); -struct dma_controller *dma_controller_create (struct musb *musb,void __iomem *base) +struct dma_controller * +tusb_dma_controller_create (struct musb *musb,void __iomem *base) {void __iomem *tbase = musb->ctrl_base;struct tusb_omap_dma *tusb_dma;
@@ -701,7 +703,8 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *bareturn &tusb_dma->controller; cleanup: -dma_controller_destroy (&tusb_dma->controller); +musb_dma_controller_destroy (&tusb_dma->controller); out:return NULL ; } +EXPORT_SYMBOL_GPL (tusb_dma_controller_create);
drivers/usb/musb/ux500.c +4 -0
@@ -189,6 +189,10 @@ static int ux500_musb_exit(struct musb *musb)static const struct musb_platform_ops ux500_ops = { .quirks =MUSB_DMA_UX500 |MUSB_INDEXED_EP , +#ifdef CONFIG_USB_UX500_DMA + .dma_init = ux500_dma_controller_create, + .dma_exit = ux500_dma_controller_destroy, +#endif .init = ux500_musb_init, .exit = ux500_musb_exit, .fifo_mode =5 ,
drivers/usb/musb/ux500_dma.c +5 -3
@@ -359,7 +359,7 @@ static int ux500_dma_controller_start(struct ux500_dma_controller *controller)return 0 ; } -void dma_controller_destroy (struct dma_controller *c) +void ux500_dma_controller_destroy (struct dma_controller *c) {struct ux500_dma_controller *controller =container_of (c, struct ux500_dma_controller, controller);
@@ -367,9 +367,10 @@ void dma_controller_destroy(struct dma_controller *c)ux500_dma_controller_stop (controller);kfree (controller); } +EXPORT_SYMBOL_GPL (ux500_dma_controller_destroy); -struct dma_controller *dma_controller_create (struct musb *musb, -void __iomem *base) +struct dma_controller * +ux500_dma_controller_create (struct musb *musb,void __iomem *base) {struct ux500_dma_controller *controller;struct platform_device *pdev =to_platform_device (musb->controller);
@@ -407,3 +408,4 @@ plat_get_fail: kzalloc_fail:return NULL ; } +EXPORT_SYMBOL_GPL (ux500_dma_controller_create);
Signature · 1 line
2.1.4
PATCH 3/12 usb: musb: Get rid of the DMA ifdefs for musb_core.c
In reply to Tony LindgrenFor musb_core.c we can now just drop the DMA related ifdef and use the already existing runtime test for !is_cppi_enabled(musb) instead.
--- drivers/usb/musb/musb_core.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/musb/musb_core.c +0 -2
@@ -1667,7 +1667,6 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)/* called with controller lock already held */ if (!epnum) { -#ifndef CONFIG_USB_TUSB_OMAP_DMA if (!is_cppi_enabled (musb)) {/* endpoint 0 */ if (is_host_active (musb))
@@ -1675,7 +1674,6 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)else musb_g_ep0_irq (musb); } -#endif }else {/* endpoints 1..15 */ if (transmit) {
Signature · 1 line
2.1.4
PATCH 4/12 usb: musb: Remove DMA ifdef for musb_gadget.c short_packet
In reply to Tony LindgrenLet's get rid of the horrible ifdef in middle of the expression. We can do it by adding a variable for short_packet and testing it separately for DMA related code.
--- drivers/usb/musb/musb_gadget.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/usb/musb/musb_gadget.c +10 -6
@@ -489,6 +489,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)if (request) {u8 is_dma =0 ; +bool short_packet = false;if (dma && (csr &MUSB_TXCSR_DMAENAB )) { is_dma =1 ;
@@ -507,15 +508,18 @@ void musb_g_tx(struct musb *musb, u8 epnum)* First, maybe a terminating short packet. Some DMA * engines might handle this by themselves. */ - if ((request->zero && request->length +if ((request->zero && request->length) && (request->length % musb_ep->packet_sz ==0 ) && (request->actual == request->length)) -#if defined(CONFIG_USB_INVENTRA_DMA ) || defined(CONFIG_USB_UX500_DMA ) - || (is_dma && (!dma->desired_mode || + short_packet = true; + +if ((musb_dma_inventra (musb) ||musb_dma_ux500 (musb)) && + (is_dma && (!dma->desired_mode || (request->actual & - (musb_ep->packet_sz - 1)))) -#endif - ) { + (musb_ep->packet_sz -1 ))))) + short_packet = true; + +if (short_packet) {/* * On DMA completion, FIFO may not be * available yet...
Signature · 1 line
2.1.4
PATCH 6/12 usb: musb: Remove ifdefs for TX DMA for musb_host.c
In reply to Tony LindgrenWe can remove the ifdefs by setting up helper functions for mentor DMA and cppi/tusb DMA.
Note that I've kept the existing formatting as otherwise this patch becomes pretty much unreadable.
--- drivers/usb/musb/musb_host.c | 61 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 13 deletions(-)
drivers/usb/musb/musb_host.c +48 -13
@@ -617,23 +617,22 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) ep->rx_reinit =0 ; } -static bool musb_tx_dma_program (struct dma_controller *dma, +static int musb_tx_dma_set_mode_mentor (struct dma_controller *dma,struct musb_hw_ep *hw_ep,struct musb_qh *qh, -struct urb *urb,u32 offset,u32 length) +struct urb *urb,u32 offset, +u32 *length,u8 *mode) {struct dma_channel *channel = hw_ep->tx_channel;void __iomem *epio = hw_ep->regs;u16 pkt_size = qh->maxpacket;u16 csr; -u8 mode; -#if defined(CONFIG_USB_INVENTRA_DMA ) || defined(CONFIG_USB_UX500_DMA ) -if (length > channel->max_len) - length = channel->max_len; +if (*length > channel->max_len) + *length = channel->max_len; csr =musb_readw (epio,MUSB_TXCSR ); -if (length > pkt_size) { - mode =1 ; +if (*length > pkt_size) { + *mode =1 ; csr |=MUSB_TXCSR_DMAMODE |MUSB_TXCSR_DMAENAB ;/* autoset shouldn't be set in high bandwidth */ /*
@@ -649,15 +648,28 @@ static bool musb_tx_dma_program(struct dma_controller *dma, can_bulk_split(hw_ep->musb, qh->type))) csr |=MUSB_TXCSR_AUTOSET ; }else { - mode =0 ; + *mode =0 ; csr &= ~(MUSB_TXCSR_AUTOSET |MUSB_TXCSR_DMAMODE ); csr |=MUSB_TXCSR_DMAENAB ;/* against programmer's guide */ } channel->desired_mode = mode;musb_writew (epio,MUSB_TXCSR , csr); -#else + +return 0 ; +} + +static int musb_tx_dma_set_mode_cppi_tusb (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +u32 offset, +u32 *length, +u8 *mode) +{ +struct dma_channel *channel = hw_ep->tx_channel; +if (!is_cppi_enabled (hw_ep->musb) && !tusb_dma_omap (hw_ep->musb)) -return false; +return -ENODEV ; channel->actual_len =0 ;
@@ -665,8 +677,28 @@ static bool musb_tx_dma_program(struct dma_controller *dma,* TX uses "RNDIS" mode automatically but needs help * to identify the zero-length-final-packet case. */ - mode = (urb->transfer_flags &URB_ZERO_PACKET ) ?1 :0 ; -#endif + *mode = (urb->transfer_flags &URB_ZERO_PACKET ) ?1 :0 ; + +return 0 ; +} + +static bool musb_tx_dma_program (struct dma_controller *dma, +struct musb_hw_ep *hw_ep,struct musb_qh *qh, +struct urb *urb,u32 offset,u32 length) +{ +struct dma_channel *channel = hw_ep->tx_channel; +u16 pkt_size = qh->maxpacket; +u8 mode; +int res; + +if (musb_dma_inventra (hw_ep->musb) ||musb_dma_ux500 (hw_ep->musb)) + res =musb_tx_dma_set_mode_mentor (dma, hw_ep, qh, urb, + offset, &length, &mode); +else + res =musb_tx_dma_set_mode_cppi_tusb (dma, hw_ep, qh, urb, + offset, &length, &mode); +if (res) +return false; qh->segsize = length;
@@ -678,6 +710,9 @@ static bool musb_tx_dma_program(struct dma_controller *dma,if (!dma->channel_program (channel, pkt_size, mode, urb->transfer_dma + offset, length)) { +void __iomem *epio = hw_ep->regs; +u16 csr; + dma->channel_release (channel); hw_ep->tx_channel =NULL ;
Signature · 1 line
2.1.4
PATCH 8/12 usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part2
In reply to Tony LindgrenRemove ifdefs for musb_host_rx to get closer to building in all the DMA drivers.
--- drivers/usb/musb/musb_host.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_host.c +3 -4
@@ -1734,9 +1734,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)*/ /* FIXME this is _way_ too much in-line logic for Mentor DMA */ - -#if !defined(CONFIG_USB_INVENTRA_DMA ) && !defined(CONFIG_USB_UX500_DMA ) -if (rx_csr &MUSB_RXCSR_H_REQPKT ) { +if (!musb_dma_inventra (musb) && !musb_dma_ux500 (musb) && + (rx_csr &MUSB_RXCSR_H_REQPKT )) {/* REVISIT this happened for a while on some short reads... * the cleanup still needs investigation... looks bad... * and also duplicates dma cleanup code above ... plus,
@@ -1757,7 +1756,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)musb_writew (epio,MUSB_RXCSR ,MUSB_RXCSR_H_WZC_BITS | rx_csr); } -#endif +if (dma && (rx_csr &MUSB_RXCSR_DMAENAB )) { xfer_len = dma->actual_len;
Signature · 1 line
2.1.4
PATCH 9/12 usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part3
In reply to Tony LindgrenRemove ifdefs for musb_host_rx to get closer to building in all the DMA drivers.
--- drivers/usb/musb/musb_host.c | 124 ++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 50 deletions(-)
drivers/usb/musb/musb_host.c +74 -50
@@ -1572,8 +1572,8 @@ static inline int musb_rx_dma_iso_cppi41(struct dma_controller *dma, }#endif -#ifdef CONFIG_USB_INVENTRA_DMA - +#if defined(CONFIG_USB_INVENTRA_DMA ) || defined(CONFIG_USB_UX500_DMA ) || \ + defined(CONFIG_USB_TI_CPPI41_DMA )/* Host side RX (IN) using Mentor DMA works as follows: submit_urb -> - if queue was empty, ProgramEndpoint
@@ -1608,7 +1608,68 @@ static inline int musb_rx_dma_iso_cppi41(struct dma_controller *dma,* thus be a great candidate for using mode 1 ... for all but the * last packet of one URB's transfer. */ +static int musb_rx_dma_inventra_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len) +{ +struct dma_channel *channel = hw_ep->rx_channel; +void __iomem *epio = hw_ep->regs; +u16 val; +int pipe; +bool done; + + pipe = urb->pipe; + +if (usb_pipeisoc (pipe)) { +struct usb_iso_packet_descriptor *d; + + d = urb->iso_frame_desc + qh->iso_idx; + d->actual_length = len; + +/* even if there was an error, we did the dma +* for iso_frame_desc->length +*/ +if (d->status != -EILSEQ && d->status != -EOVERFLOW ) + d->status =0 ; + +if (++qh->iso_idx >= urb->number_of_packets) { + done = true; + }else { +/* REVISIT: Why ignore return value here? */ +if (musb_dma_cppi41 (hw_ep->musb)) + done =musb_rx_dma_iso_cppi41 (dma, hw_ep, qh, + urb, len); + done = false; + } + + }else { +/* done if urb buffer is full or short packet is recd */ + done = (urb->actual_length + len >= + urb->transfer_buffer_length + || channel->actual_len < qh->maxpacket + || channel->rx_packet_done); + } + +/* send IN token for next packet, without AUTOREQ */ +if (!done) { + val =musb_readw (epio,MUSB_RXCSR ); + val |=MUSB_RXCSR_H_REQPKT ; +musb_writew (epio,MUSB_RXCSR ,MUSB_RXCSR_H_WZC_BITS | val); + } +return done; +} +#else +static inline int musb_rx_dma_inventra_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len) +{ +return false; +}#endif /*
@@ -1619,6 +1680,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) {struct urb *urb;struct musb_hw_ep *hw_ep = musb->endpoints + epnum; +struct dma_controller *c = musb->dma_controller;void __iomem *epio = hw_ep->regs;struct musb_qh *qh = hw_ep->in_qh;size_t xfer_len;
@@ -1766,56 +1828,18 @@ void musb_host_rx(struct musb *musb, u8 epnum) | MUSB_RXCSR_RXPKTRDY);musb_writew (hw_ep->regs,MUSB_RXCSR , val); -#if defined(CONFIG_USB_INVENTRA_DMA ) || defined(CONFIG_USB_UX500_DMA ) || \ - defined(CONFIG_USB_TI_CPPI41_DMA ) -if (usb_pipeisoc (pipe)) { -struct usb_iso_packet_descriptor *d; - - d = urb->iso_frame_desc + qh->iso_idx; - d->actual_length = xfer_len; - -/* even if there was an error, we did the dma -* for iso_frame_desc->length -*/ -if (d->status != -EILSEQ && d->status != -EOVERFLOW ) - d->status =0 ; - -if (++qh->iso_idx >= urb->number_of_packets) { - done = true; - }else { -struct dma_controller *c = musb->dma_controller; - -/* REVISIT: Why ignore return value here? */ -if (musb_dma_cppi41 (musb)) - done =musb_rx_dma_iso_cppi41 (c, hw_ep, - qh, urb, - xfer_len); - - done = false; - } - - }else { -/* done if urb buffer is full or short packet is recd */ - done = (urb->actual_length + xfer_len >= - urb->transfer_buffer_length - || dma->actual_len < qh->maxpacket - || dma->rx_packet_done); - } - -/* send IN token for next packet, without AUTOREQ */ -if (!done) { - val |=MUSB_RXCSR_H_REQPKT ; -musb_writew (epio,MUSB_RXCSR , -MUSB_RXCSR_H_WZC_BITS | val); +if (musb_dma_inventra (musb) ||musb_dma_ux500 (musb) || +musb_dma_cppi41 (musb)) { + done =musb_rx_dma_inventra_cppi41 (c, hw_ep, qh, urb, xfer_len); +dev_dbg (hw_ep->musb->controller, +"ep %d dma %s, rxcsr %04x, rxcount %d\n" , + epnum, done ?"off" :"reset" , +musb_readw (epio,MUSB_RXCSR ), +musb_readw (epio,MUSB_RXCOUNT )); + }else { + done = true; } -dev_dbg (musb->controller,"ep %d dma %s, rxcsr %04x, rxcount %d\n" , epnum, - done ?"off" :"reset" , -musb_readw (epio,MUSB_RXCSR ), -musb_readw (epio,MUSB_RXCOUNT )); -#else - done = true; -#endif }else if (urb->status == -EINPROGRESS ) {/* if no errors, be sure a packet is ready for unloading */ if (unlikely (!(rx_csr &MUSB_RXCSR_RXPKTRDY ))) {
Signature · 1 line
2.1.4
PATCH 11/12 usb: musb: Remove ifdefs for musb_host_rx in musb_host.c part5
In reply to Tony LindgrenRemove ifdefs for musb_host_rx to get closer to building in all the DMA drivers.
--- drivers/usb/musb/musb_host.c | 254 ++++++++++++++++++++++++------------------- 1 file changed, 140 insertions(+), 114 deletions(-)
drivers/usb/musb/musb_host.c +140 -114
@@ -1661,6 +1661,122 @@ static int musb_rx_dma_inventra_cppi41(struct dma_controller *dma, return done; } + +/* Disadvantage of using mode 1: +* It's basically usable only for mass storage class; essentially all +* other protocols also terminate transfers on short packets. +* +* Details: +* An extra IN token is sent at the end of the transfer (due to AUTOREQ) +* If you try to use mode 1 for (transfer_buffer_length - 512), and try +* to use the extra IN token to grab the last packet using mode 0, then +* the problem is that you cannot be sure when the device will send the +* last packet and RxPktRdy set. Sometimes the packet is recd too soon +* such that it gets lost when RxCSR is re-set at the end of the mode 1 +* transfer, while sometimes it is recd just a little late so that if you +* try to configure for mode 0 soon after the mode 1 transfer is +* completed, you will find rxcount 0. Okay, so you might think why not +* wait for an interrupt when the pkt is recd. Well, you won't get any! +*/ +static int musb_rx_dma_in_inventra_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len, +u8 iso_err) +{ +struct musb *musb = hw_ep->musb; +void __iomem *epio = hw_ep->regs; +struct dma_channel *channel = hw_ep->rx_channel; +u16 rx_count, val; +int length, pipe, done; +dma_addr_t buf; + + rx_count =musb_readw (epio,MUSB_RXCOUNT ); + pipe = urb->pipe; + +if (usb_pipeisoc (pipe)) { +int d_status =0 ; +struct usb_iso_packet_descriptor *d; + + d = urb->iso_frame_desc + qh->iso_idx; + +if (iso_err) { + d_status = -EILSEQ ; + urb->error_count++; + } +if (rx_count > d->length) { +if (d_status ==0 ) { + d_status = -EOVERFLOW ; + urb->error_count++; + } +dev_dbg (musb->controller,"** OVERFLOW %d into %d\n" , + rx_count, d->length); + + length = d->length; + }else + length = rx_count; + d->status = d_status; + buf = urb->transfer_dma + d->offset; + }else { + length = rx_count; + buf = urb->transfer_dma + urb->actual_length; + } + + channel->desired_mode =0 ; +#ifdef USE_MODE1 +/* because of the issue below, mode 1 will +* only rarely behave with correct semantics. +*/ +if ((urb->transfer_flags &URB_SHORT_NOT_OK ) + && (urb->transfer_buffer_length - urb->actual_length) + > qh->maxpacket) + channel->desired_mode =1 ; +if (rx_count < hw_ep->max_packet_sz_rx) { + length = rx_count; + channel->desired_mode =0 ; + }else { + length = urb->transfer_buffer_length; + } +#endif + +/* See comments above on disadvantages of using mode 1 */ + val =musb_readw (epio,MUSB_RXCSR ); + val &= ~MUSB_RXCSR_H_REQPKT ; + +if (channel->desired_mode ==0 ) + val &= ~MUSB_RXCSR_H_AUTOREQ ; +else + val |=MUSB_RXCSR_H_AUTOREQ ; + val |=MUSB_RXCSR_DMAENAB ; + +/* autoclear shouldn't be set in high bandwidth */ +if (qh->hb_mult ==1 ) + val |=MUSB_RXCSR_AUTOCLEAR ; + +musb_writew (epio,MUSB_RXCSR ,MUSB_RXCSR_H_WZC_BITS | val); + +/* REVISIT if when actual_length != 0, +* transfer_buffer_length needs to be +* adjusted first... +*/ + done = dma->channel_program (channel, qh->maxpacket, + channel->desired_mode, + buf, length); + +if (!done) { + dma->channel_release (channel); + hw_ep->rx_channel =NULL ; + channel =NULL ; + val =musb_readw (epio,MUSB_RXCSR ); + val &= ~(MUSB_RXCSR_DMAENAB + |MUSB_RXCSR_H_AUTOREQ + |MUSB_RXCSR_AUTOCLEAR ); +musb_writew (epio,MUSB_RXCSR , val); + } + +return done; +}#else static inline int musb_rx_dma_inventra_cppi41(struct dma_controller *dma, struct musb_hw_ep *hw_ep,
@@ -1670,6 +1786,16 @@ static inline int musb_rx_dma_inventra_cppi41(struct dma_controller *dma, {return false; } + +static inline int musb_rx_dma_in_inventra_cppi41 (struct dma_controller *dma, +struct musb_hw_ep *hw_ep, +struct musb_qh *qh, +struct urb *urb, +size_t len, +u8 iso_err) +{ +return false; +}#endif /*
@@ -1859,121 +1985,21 @@ void musb_host_rx(struct musb *musb, u8 epnum)/* we are expecting IN packets */ if ((musb_dma_inventra (musb) ||musb_dma_ux500 (musb) ||musb_dma_cppi41 (musb)) && dma) { -struct dma_controller *c; -u16 rx_count; -int ret, length; -dma_addr_t buf; - - rx_count =musb_readw (epio,MUSB_RXCOUNT ); - -dev_dbg (musb->controller,"RX%d count %d, buffer 0x%llx len %d/%d\n" , - epnum, rx_count, - (unsigned long long ) urb->transfer_dma - + urb->actual_length, - qh->offset, - urb->transfer_buffer_length); - - c = musb->dma_controller; - -if (usb_pipeisoc (pipe)) { -int d_status =0 ; -struct usb_iso_packet_descriptor *d; - - d = urb->iso_frame_desc + qh->iso_idx; - -if (iso_err) { - d_status = -EILSEQ ; - urb->error_count++; - } -if (rx_count > d->length) { -if (d_status ==0 ) { - d_status = -EOVERFLOW ; - urb->error_count++; - } -dev_dbg (musb->controller,"** OVERFLOW %d into %d\n" ,\ - rx_count, d->length); - - length = d->length; - }else - length = rx_count; - d->status = d_status; - buf = urb->transfer_dma + d->offset; - }else { - length = rx_count; - buf = urb->transfer_dma + - urb->actual_length; - } - - dma->desired_mode =0 ; -#ifdef USE_MODE1 -/* because of the issue below, mode 1 will -* only rarely behave with correct semantics. -*/ -if ((urb->transfer_flags & -URB_SHORT_NOT_OK ) - && (urb->transfer_buffer_length - - urb->actual_length) - > qh->maxpacket) - dma->desired_mode =1 ; -if (rx_count < hw_ep->max_packet_sz_rx) { - length = rx_count; - dma->desired_mode =0 ; - }else { - length = urb->transfer_buffer_length; - } -#endif - -/* Disadvantage of using mode 1: -* It's basically usable only for mass storage class; essentially all -* other protocols also terminate transfers on short packets. -* -* Details: -* An extra IN token is sent at the end of the transfer (due to AUTOREQ) -* If you try to use mode 1 for (transfer_buffer_length - 512), and try -* to use the extra IN token to grab the last packet using mode 0, then -* the problem is that you cannot be sure when the device will send the -* last packet and RxPktRdy set. Sometimes the packet is recd too soon -* such that it gets lost when RxCSR is re-set at the end of the mode 1 -* transfer, while sometimes it is recd just a little late so that if you -* try to configure for mode 0 soon after the mode 1 transfer is -* completed, you will find rxcount 0. Okay, so you might think why not -* wait for an interrupt when the pkt is recd. Well, you won't get any! -*/ - - val =musb_readw (epio,MUSB_RXCSR ); - val &= ~MUSB_RXCSR_H_REQPKT ; - -if (dma->desired_mode ==0 ) - val &= ~MUSB_RXCSR_H_AUTOREQ ; +dev_dbg (hw_ep->musb->controller, +"RX%d count %d, buffer 0x%llx len %d/%d\n" , + epnum,musb_readw (epio,MUSB_RXCOUNT ), + (unsigned long long ) urb->transfer_dma + + urb->actual_length, + qh->offset, + urb->transfer_buffer_length); + + done =musb_rx_dma_in_inventra_cppi41 (c, hw_ep, qh, + urb, xfer_len, + iso_err); +if (done) + goto finish;else - val |=MUSB_RXCSR_H_AUTOREQ ; - val |=MUSB_RXCSR_DMAENAB ; - -/* autoclear shouldn't be set in high bandwidth */ -if (qh->hb_mult ==1 ) - val |=MUSB_RXCSR_AUTOCLEAR ; - -musb_writew (epio,MUSB_RXCSR , -MUSB_RXCSR_H_WZC_BITS | val); - -/* REVISIT if when actual_length != 0, -* transfer_buffer_length needs to be -* adjusted first... -*/ - ret = c->channel_program ( - dma, qh->maxpacket, - dma->desired_mode, buf, length); - -if (!ret) { - c->channel_release (dma); - hw_ep->rx_channel =NULL ; - dma =NULL ; - val =musb_readw (epio,MUSB_RXCSR ); - val &= ~(MUSB_RXCSR_DMAENAB - |MUSB_RXCSR_H_AUTOREQ - |MUSB_RXCSR_AUTOCLEAR ); -musb_writew (epio,MUSB_RXCSR , val); - } +dev_err (musb->controller,"error: rx_dma failed\n" ); }if (!dma) {
Signature · 1 line
2.1.4