diff options
Diffstat (limited to 'drivers/usb/musb/cppi_dma.c')
| -rw-r--r-- | drivers/usb/musb/cppi_dma.c | 127 | 
1 files changed, 61 insertions, 66 deletions
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index f5a65ff0ac2..904fb85d85a 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -6,6 +6,7 @@   * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.   */ +#include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/slab.h>  #include <linux/usb.h> @@ -104,7 +105,7 @@ static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr)  	musb_writel(&tx->tx_complete, 0, ptr);  } -static void __init cppi_pool_init(struct cppi *cppi, struct cppi_channel *c) +static void cppi_pool_init(struct cppi *cppi, struct cppi_channel *c)  {  	int	j; @@ -149,14 +150,11 @@ static void cppi_pool_free(struct cppi_channel *c)  	c->last_processed = NULL;  } -static int __init cppi_controller_start(struct dma_controller *c) +static void cppi_controller_start(struct cppi *controller)  { -	struct cppi	*controller;  	void __iomem	*tibase;  	int		i; -	controller = container_of(c, struct cppi, controller); -  	/* do whatever is necessary to start controller */  	for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {  		controller->tx[i].transmit = true; @@ -211,8 +209,6 @@ static int __init cppi_controller_start(struct dma_controller *c)  	/* disable RNDIS mode, also host rx RNDIS autorequest */  	musb_writel(tibase, DAVINCI_RNDIS_REG, 0);  	musb_writel(tibase, DAVINCI_AUTOREQ_REG, 0); - -	return 0;  }  /* @@ -221,13 +217,13 @@ static int __init cppi_controller_start(struct dma_controller *c)   *  De-Init the DMA controller as necessary.   */ -static int cppi_controller_stop(struct dma_controller *c) +static void cppi_controller_stop(struct cppi *controller)  { -	struct cppi		*controller;  	void __iomem		*tibase;  	int			i; +	struct musb		*musb; -	controller = container_of(c, struct cppi, controller); +	musb = controller->musb;  	tibase = controller->tibase;  	/* DISABLE INDIVIDUAL CHANNEL Interrupts */ @@ -236,7 +232,7 @@ static int cppi_controller_stop(struct dma_controller *c)  	musb_writel(tibase, DAVINCI_RXCPPI_INTCLR_REG,  			DAVINCI_DMA_ALL_CHANNELS_ENABLE); -	DBG(1, "Tearing down RX and TX Channels\n"); +	dev_dbg(musb->controller, "Tearing down RX and TX Channels\n");  	for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {  		/* FIXME restructure of txdma to use bds like rxdma */  		controller->tx[i].last_processed = NULL; @@ -252,8 +248,6 @@ static int cppi_controller_stop(struct dma_controller *c)  	/*disable tx/rx cppi */  	musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE);  	musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE); - -	return 0;  }  /* While dma channel is allocated, we only want the core irqs active @@ -289,9 +283,11 @@ cppi_channel_allocate(struct dma_controller *c,  	u8			index;  	struct cppi_channel	*cppi_ch;  	void __iomem		*tibase; +	struct musb		*musb;  	controller = container_of(c, struct cppi, controller);  	tibase = controller->tibase; +	musb = controller->musb;  	/* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */  	index = ep->epnum - 1; @@ -301,13 +297,13 @@ cppi_channel_allocate(struct dma_controller *c,  	 */  	if (transmit) {  		if (index >= ARRAY_SIZE(controller->tx)) { -			DBG(1, "no %cX%d CPPI channel\n", 'T', index); +			dev_dbg(musb->controller, "no %cX%d CPPI channel\n", 'T', index);  			return NULL;  		}  		cppi_ch = controller->tx + index;  	} else {  		if (index >= ARRAY_SIZE(controller->rx)) { -			DBG(1, "no %cX%d CPPI channel\n", 'R', index); +			dev_dbg(musb->controller, "no %cX%d CPPI channel\n", 'R', index);  			return NULL;  		}  		cppi_ch = controller->rx + index; @@ -318,13 +314,13 @@ cppi_channel_allocate(struct dma_controller *c,  	 * with the other DMA engine too  	 */  	if (cppi_ch->hw_ep) -		DBG(1, "re-allocating DMA%d %cX channel %p\n", +		dev_dbg(musb->controller, "re-allocating DMA%d %cX channel %p\n",  				index, transmit ? 'T' : 'R', cppi_ch);  	cppi_ch->hw_ep = ep;  	cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;  	cppi_ch->channel.max_len = 0x7fffffff; -	DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); +	dev_dbg(musb->controller, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');  	return &cppi_ch->channel;  } @@ -339,7 +335,8 @@ static void cppi_channel_release(struct dma_channel *channel)  	c = container_of(channel, struct cppi_channel, channel);  	tibase = c->controller->tibase;  	if (!c->hw_ep) -		DBG(1, "releasing idle DMA channel %p\n", c); +		dev_dbg(c->controller->musb->controller, +			"releasing idle DMA channel %p\n", c);  	else if (!c->transmit)  		core_rxirq_enable(tibase, c->index + 1); @@ -357,10 +354,11 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag)  	musb_ep_select(base, c->index + 1); -	DBG(level, "RX DMA%d%s: %d left, csr %04x, " -			"%08x H%08x S%08x C%08x, " -			"B%08x L%08x %08x .. %08x" -			"\n", +	dev_dbg(c->controller->musb->controller, +		"RX DMA%d%s: %d left, csr %04x, " +		"%08x H%08x S%08x C%08x, " +		"B%08x L%08x %08x .. %08x" +		"\n",  		c->index, tag,  		musb_readl(c->controller->tibase,  			DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index), @@ -387,10 +385,11 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag)  	musb_ep_select(base, c->index + 1); -	DBG(level, "TX DMA%d%s: csr %04x, " -			"H%08x S%08x C%08x %08x, " -			"F%08x L%08x .. %08x" -			"\n", +	dev_dbg(c->controller->musb->controller, +		"TX DMA%d%s: csr %04x, " +		"H%08x S%08x C%08x %08x, " +		"F%08x L%08x .. %08x" +		"\n",  		c->index, tag,  		musb_readw(c->hw_ep->regs, MUSB_TXCSR), @@ -427,7 +426,6 @@ cppi_rndis_update(struct cppi_channel *c, int is_rx,  	}  } -#ifdef CONFIG_USB_MUSB_DEBUG  static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)  {  	pr_debug("RXBD/%s %08x: " @@ -436,21 +434,16 @@ static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)  			bd->hw_next, bd->hw_bufp, bd->hw_off_len,  			bd->hw_options);  } -#endif  static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx)  { -#ifdef CONFIG_USB_MUSB_DEBUG  	struct cppi_descriptor	*bd; -	if (!_dbg_level(level)) -		return;  	cppi_dump_rx(level, rx, tag);  	if (rx->last_processed)  		cppi_dump_rxbd("last", rx->last_processed);  	for (bd = rx->head; bd; bd = bd->next)  		cppi_dump_rxbd("active", bd); -#endif  } @@ -506,7 +499,7 @@ static inline int cppi_autoreq_update(struct cppi_channel *rx,  		if (!(val & MUSB_RXCSR_H_REQPKT)) {  			val |= MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_H_WZC_BITS;  			musb_writew(regs, MUSB_RXCSR, val); -			/* flush writebufer */ +			/* flush writebuffer */  			val = musb_readw(regs, MUSB_RXCSR);  		}  	} @@ -597,12 +590,12 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)  		length = min(n_bds * maxpacket, length);  	} -	DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%x len %u\n", +	dev_dbg(musb->controller, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u\n",  			tx->index,  			maxpacket,  			rndis ? "rndis" : "transparent",  			n_bds, -			addr, length); +			(unsigned long long)addr, length);  	cppi_rndis_update(tx, 0, musb->ctrl_base, rndis); @@ -654,7 +647,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)  				bd->hw_options |= CPPI_ZERO_SET;  		} -		DBG(5, "TXBD %p: nxt %08x buf %08x len %04x opt %08x\n", +		dev_dbg(musb->controller, "TXBD %p: nxt %08x buf %08x len %04x opt %08x\n",  				bd, bd->hw_next, bd->hw_bufp,  				bd->hw_off_len, bd->hw_options); @@ -743,7 +736,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)   * So this module parameter lets the heuristic be disabled.  When using   * gadgetfs, the heuristic will probably need to be disabled.   */ -static int cppi_rx_rndis = 1; +static bool cppi_rx_rndis = 1;  module_param(cppi_rx_rndis, bool, 0);  MODULE_PARM_DESC(cppi_rx_rndis, "enable/disable RX RNDIS heuristic"); @@ -776,6 +769,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)  	void __iomem		*tibase = musb->ctrl_base;  	int			is_rndis = 0;  	struct cppi_rx_stateram	__iomem *rx_ram = rx->state_ram; +	struct cppi_descriptor	*d;  	if (onepacket) {  		/* almost every USB driver, host or peripheral side */ @@ -819,8 +813,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)  	length = min(n_bds * maxpacket, length); -	DBG(4, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " -			"dma 0x%x len %u %u/%u\n", +	dev_dbg(musb->controller, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " +			"dma 0x%llx len %u %u/%u\n",  			rx->index, maxpacket,  			onepacket  				? (is_rndis ? "rndis" : "onepacket") @@ -829,7 +823,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)  			musb_readl(tibase,  				DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))  					& 0xffff, -			addr, length, rx->channel.actual_len, rx->buf_len); +			(unsigned long long)addr, length, +			rx->channel.actual_len, rx->buf_len);  	/* only queue one segment at a time, since the hardware prevents  	 * correct queue shutdown after unexpected short packets @@ -888,14 +883,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)  	bd->hw_options |= CPPI_SOP_SET;  	tail->hw_options |= CPPI_EOP_SET; -#ifdef CONFIG_USB_MUSB_DEBUG -	if (_dbg_level(5)) { -		struct cppi_descriptor	*d; - -		for (d = rx->head; d; d = d->next) -			cppi_dump_rxbd("S", d); -	} -#endif +	for (d = rx->head; d; d = d->next) +		cppi_dump_rxbd("S", d);  	/* in case the preceding transfer left some state... */  	tail = rx->last_processed; @@ -935,7 +924,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)  			DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))  			& 0xffff;  	if (i < (2 + n_bds)) { -		DBG(2, "bufcnt%d underrun - %d (for %d)\n", +		dev_dbg(musb->controller, "bufcnt%d underrun - %d (for %d)\n",  					rx->index, i, n_bds);  		musb_writel(tibase,  			DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4), @@ -984,7 +973,7 @@ static int cppi_channel_program(struct dma_channel *ch,  		/* WARN_ON(1); */  		break;  	case MUSB_DMA_STATUS_UNKNOWN: -		DBG(1, "%cX DMA%d not allocated!\n", +		dev_dbg(musb->controller, "%cX DMA%d not allocated!\n",  				cppi_ch->transmit ? 'T' : 'R',  				cppi_ch->index);  		/* FALLTHROUGH */ @@ -1021,6 +1010,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)  	int				i;  	dma_addr_t			safe2ack;  	void __iomem			*regs = rx->hw_ep->regs; +	struct musb			*musb = cppi->musb;  	cppi_dump_rx(6, rx, "/K"); @@ -1039,9 +1029,9 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)  		if (!completed && (bd->hw_options & CPPI_OWN_SET))  			break; -		DBG(5, "C/RXBD %08x: nxt %08x buf %08x " +		dev_dbg(musb->controller, "C/RXBD %llx: nxt %08x buf %08x "  			"off.len %08x opt.len %08x (%d)\n", -			bd->dma, bd->hw_next, bd->hw_bufp, +			(unsigned long long)bd->dma, bd->hw_next, bd->hw_bufp,  			bd->hw_off_len, bd->hw_options,  			rx->channel.actual_len); @@ -1061,7 +1051,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)  			 * CPPI ignores those BDs even though OWN is still set.  			 */  			completed = true; -			DBG(3, "rx short %d/%d (%d)\n", +			dev_dbg(musb->controller, "rx short %d/%d (%d)\n",  					len, bd->buflen,  					rx->channel.actual_len);  		} @@ -1111,11 +1101,12 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)  		musb_ep_select(cppi->mregs, rx->index + 1);  		csr = musb_readw(regs, MUSB_RXCSR);  		if (csr & MUSB_RXCSR_DMAENAB) { -			DBG(4, "list%d %p/%p, last %08x%s, csr %04x\n", +			dev_dbg(musb->controller, "list%d %p/%p, last %llx%s, csr %04x\n",  				rx->index,  				rx->head, rx->tail,  				rx->last_processed -					? rx->last_processed->dma +					? (unsigned long long) +						rx->last_processed->dma  					: 0,  				completed ? ", completed" : "",  				csr); @@ -1167,10 +1158,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)  	tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);  	rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); -	if (!tx && !rx) +	if (!tx && !rx) { +		if (cppi->irq) +			spin_unlock_irqrestore(&musb->lock, flags);  		return IRQ_NONE; +	} -	DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); +	dev_dbg(musb->controller, "CPPI IRQ Tx%x Rx%x\n", tx, rx);  	/* process TX channels */  	for (index = 0; tx; tx = tx >> 1, index++) { @@ -1198,8 +1192,8 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)  		 * that needs to be acknowledged.  		 */  		if (NULL == bd) { -			DBG(1, "null BD\n"); -			tx_ram->tx_complete = 0; +			dev_dbg(musb->controller, "null BD\n"); +			musb_writel(&tx_ram->tx_complete, 0, 0);  			continue;  		} @@ -1213,7 +1207,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)  			if (bd->hw_options & CPPI_OWN_SET)  				break; -			DBG(5, "C/TXBD %p n %x b %x off %x opt %x\n", +			dev_dbg(musb->controller, "C/TXBD %p n %x b %x off %x opt %x\n",  					bd, bd->hw_next, bd->hw_bufp,  					bd->hw_off_len, bd->hw_options); @@ -1300,15 +1294,15 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)  	return IRQ_HANDLED;  } +EXPORT_SYMBOL_GPL(cppi_interrupt);  /* Instantiate a software object representing a DMA controller. */ -struct dma_controller *__init -dma_controller_create(struct musb *musb, void __iomem *mregs) +struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mregs)  {  	struct cppi		*controller;  	struct device		*dev = musb->controller;  	struct platform_device	*pdev = to_platform_device(dev); -	int			irq = platform_get_irq(pdev, 1); +	int			irq = platform_get_irq_byname(pdev, "dma");  	controller = kzalloc(sizeof *controller, GFP_KERNEL);  	if (!controller) @@ -1318,8 +1312,6 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)  	controller->tibase = mregs - DAVINCI_BASE_OFFSET;  	controller->musb = musb; -	controller->controller.start = cppi_controller_start; -	controller->controller.stop = cppi_controller_stop;  	controller->controller.channel_alloc = cppi_channel_allocate;  	controller->controller.channel_release = cppi_channel_release;  	controller->controller.channel_program = cppi_channel_program; @@ -1348,6 +1340,7 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)  		controller->irq = irq;  	} +	cppi_controller_start(controller);  	return &controller->controller;  } @@ -1360,6 +1353,8 @@ void dma_controller_destroy(struct dma_controller *c)  	cppi = container_of(c, struct cppi, controller); +	cppi_controller_stop(cppi); +  	if (cppi->irq)  		free_irq(cppi->irq, cppi->musb); @@ -1452,7 +1447,7 @@ static int cppi_channel_abort(struct dma_channel *channel)  		 *    compare mode by writing 1 to the tx_complete register.  		 */  		cppi_reset_tx(tx_ram, 1); -		cppi_ch->head = 0; +		cppi_ch->head = NULL;  		musb_writel(&tx_ram->tx_complete, 0, 1);  		cppi_dump_tx(5, cppi_ch, " (done teardown)");  | 
