diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
| -rw-r--r-- | drivers/usb/musb/musb_gadget.c | 1040 | 
1 files changed, 549 insertions, 491 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 36cfd060dbe..d4aa779339f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -40,58 +40,102 @@  #include <linux/smp.h>  #include <linux/spinlock.h>  #include <linux/delay.h> -#include <linux/moduleparam.h> -#include <linux/stat.h>  #include <linux/dma-mapping.h>  #include <linux/slab.h>  #include "musb_core.h" -/* MUSB PERIPHERAL status 3-mar-2006: - * - * - EP0 seems solid.  It passes both USBCV and usbtest control cases. - *   Minor glitches: - * - *     + remote wakeup to Linux hosts work, but saw USBCV failures; - *       in one test run (operator error?) - *     + endpoint halt tests -- in both usbtest and usbcv -- seem - *       to break when dma is enabled ... is something wrongly - *       clearing SENDSTALL? - * - * - Mass storage behaved ok when last tested.  Network traffic patterns - *   (with lots of short transfers etc) need retesting; they turn up the - *   worst cases of the DMA, since short packets are typical but are not - *   required. - * - * - TX/IN - *     + both pio and dma behave in with network and g_zero tests - *     + no cppi throughput issues other than no-hw-queueing - *     + failed with FLAT_REG (DaVinci) - *     + seems to behave with double buffering, PIO -and- CPPI - *     + with gadgetfs + AIO, requests got lost? - * - * - RX/OUT - *     + both pio and dma behave in with network and g_zero tests - *     + dma is slow in typical case (short_not_ok is clear) - *     + double buffering ok with PIO - *     + double buffering *FAILS* with CPPI, wrong data bytes sometimes - *     + request lossage observed with gadgetfs - * - * - ISO not tested ... might work, but only weakly isochronous - * - * - Gadget driver disabling of softconnect during bind() is ignored; so - *   drivers can't hold off host requests until userspace is ready. - *   (Workaround:  they can turn it off later.) - * - * - PORTABILITY (assumes PIO works): - *     + DaVinci, basically works with cppi dma - *     + OMAP 2430, ditto with mentor dma - *     + TUSB 6010, platform-specific dma in the works - */ -  /* ----------------------------------------------------------------------- */ +#define is_buffer_mapped(req) (is_dma_capable() && \ +					(req->map_state != UN_MAPPED)) + +/* Maps the buffer to dma  */ + +static inline void map_dma_buffer(struct musb_request *request, +			struct musb *musb, struct musb_ep *musb_ep) +{ +	int compatible = true; +	struct dma_controller *dma = musb->dma_controller; + +	request->map_state = UN_MAPPED; + +	if (!is_dma_capable() || !musb_ep->dma) +		return; + +	/* Check if DMA engine can handle this request. +	 * DMA code must reject the USB request explicitly. +	 * Default behaviour is to map the request. +	 */ +	if (dma->is_compatible) +		compatible = dma->is_compatible(musb_ep->dma, +				musb_ep->packet_sz, request->request.buf, +				request->request.length); +	if (!compatible) +		return; + +	if (request->request.dma == DMA_ADDR_INVALID) { +		dma_addr_t dma_addr; +		int ret; + +		dma_addr = dma_map_single( +				musb->controller, +				request->request.buf, +				request->request.length, +				request->tx +					? DMA_TO_DEVICE +					: DMA_FROM_DEVICE); +		ret = dma_mapping_error(musb->controller, dma_addr); +		if (ret) +			return; + +		request->request.dma = dma_addr; +		request->map_state = MUSB_MAPPED; +	} else { +		dma_sync_single_for_device(musb->controller, +			request->request.dma, +			request->request.length, +			request->tx +				? DMA_TO_DEVICE +				: DMA_FROM_DEVICE); +		request->map_state = PRE_MAPPED; +	} +} + +/* Unmap the buffer from dma and maps it back to cpu */ +static inline void unmap_dma_buffer(struct musb_request *request, +				struct musb *musb) +{ +	struct musb_ep *musb_ep = request->ep; + +	if (!is_buffer_mapped(request) || !musb_ep->dma) +		return; + +	if (request->request.dma == DMA_ADDR_INVALID) { +		dev_vdbg(musb->controller, +				"not unmapping a never mapped buffer\n"); +		return; +	} +	if (request->map_state == MUSB_MAPPED) { +		dma_unmap_single(musb->controller, +			request->request.dma, +			request->request.length, +			request->tx +				? DMA_TO_DEVICE +				: DMA_FROM_DEVICE); +		request->request.dma = DMA_ADDR_INVALID; +	} else { /* PRE_MAPPED */ +		dma_sync_single_for_cpu(musb->controller, +			request->request.dma, +			request->request.length, +			request->tx +				? DMA_TO_DEVICE +				: DMA_FROM_DEVICE); +	} +	request->map_state = UN_MAPPED; +} +  /*   * Immediately complete a request.   * @@ -112,37 +156,23 @@ __acquires(ep->musb->lock)  	req = to_musb_request(request); -	list_del(&request->list); +	list_del(&req->list);  	if (req->request.status == -EINPROGRESS)  		req->request.status = status;  	musb = req->musb;  	ep->busy = 1;  	spin_unlock(&musb->lock); -	if (is_dma_capable()) { -		if (req->mapped) { -			dma_unmap_single(musb->controller, -					req->request.dma, -					req->request.length, -					req->tx -						? DMA_TO_DEVICE -						: DMA_FROM_DEVICE); -			req->request.dma = DMA_ADDR_INVALID; -			req->mapped = 0; -		} else if (req->request.dma != DMA_ADDR_INVALID) -			dma_sync_single_for_cpu(musb->controller, -					req->request.dma, -					req->request.length, -					req->tx -						? DMA_TO_DEVICE -						: DMA_FROM_DEVICE); -	} + +	if (!dma_mapping_error(&musb->g.dev, request->dma)) +		unmap_dma_buffer(req, musb); +  	if (request->status == 0) -		DBG(5, "%s done request %p,  %d/%d\n", +		dev_dbg(musb->controller, "%s done request %p,  %d/%d\n",  				ep->end_point.name, request,  				req->request.actual, req->request.length);  	else -		DBG(2, "%s request %p, %d/%d fault %d\n", +		dev_dbg(musb->controller, "%s request %p, %d/%d fault %d\n",  				ep->end_point.name, request,  				req->request.actual, req->request.length,  				request->status); @@ -159,6 +189,7 @@ __acquires(ep->musb->lock)   */  static void nuke(struct musb_ep *ep, const int status)  { +	struct musb		*musb = ep->musb;  	struct musb_request	*req = NULL;  	void __iomem *epio = ep->musb->endpoints[ep->current_epnum].regs; @@ -186,14 +217,14 @@ static void nuke(struct musb_ep *ep, const int status)  		}  		value = c->channel_abort(ep->dma); -		DBG(value ? 1 : 6, "%s: abort DMA --> %d\n", ep->name, value); +		dev_dbg(musb->controller, "%s: abort DMA --> %d\n", +				ep->name, value);  		c->channel_release(ep->dma);  		ep->dma = NULL;  	} -	while (!list_empty(&(ep->req_list))) { -		req = container_of(ep->req_list.next, struct musb_request, -				request.list); +	while (!list_empty(&ep->req_list)) { +		req = list_first_entry(&ep->req_list, struct musb_request, list);  		musb_g_giveback(ep, &req->request, status);  	}  } @@ -215,41 +246,6 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)  		return ep->packet_sz;  } - -#ifdef CONFIG_USB_INVENTRA_DMA - -/* Peripheral tx (IN) using Mentor DMA works as follows: -	Only mode 0 is used for transfers <= wPktSize, -	mode 1 is used for larger transfers, - -	One of the following happens: -	- Host sends IN token which causes an endpoint interrupt -		-> TxAvail -			-> if DMA is currently busy, exit. -			-> if queue is non-empty, txstate(). - -	- Request is queued by the gadget driver. -		-> if queue was previously empty, txstate() - -	txstate() -		-> start -		  /\	-> setup DMA -		  |     (data is transferred to the FIFO, then sent out when -		  |	IN token(s) are recd from Host. -		  |		-> DMA interrupt on completion -		  |		   calls TxAvail. -		  |		      -> stop DMA, ~DMAENAB, -		  |		      -> set TxPktRdy for last short pkt or zlp -		  |		      -> Complete Request -		  |		      -> Continue next request (call txstate) -		  |___________________________________| - - * Non-Mentor DMA engines can of course work differently, such as by - * upleveling from irq-per-packet to irq-per-buffer. - */ - -#endif -  /*   * An endpoint is transmitting data. This can be called either from   * the IRQ routine or from ep.queue() to kickstart a request on an @@ -268,9 +264,16 @@ static void txstate(struct musb *musb, struct musb_request *req)  	musb_ep = req->ep; +	/* Check if EP is disabled */ +	if (!musb_ep->desc) { +		dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", +						musb_ep->end_point.name); +		return; +	} +  	/* we shouldn't get here while DMA is active ... but we do ... */  	if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { -		DBG(4, "dma pending...\n"); +		dev_dbg(musb->controller, "dma pending...\n");  		return;  	} @@ -282,23 +285,23 @@ static void txstate(struct musb *musb, struct musb_request *req)  			(int)(request->length - request->actual));  	if (csr & MUSB_TXCSR_TXPKTRDY) { -		DBG(5, "%s old packet still ready , txcsr %03x\n", +		dev_dbg(musb->controller, "%s old packet still ready , txcsr %03x\n",  				musb_ep->end_point.name, csr);  		return;  	}  	if (csr & MUSB_TXCSR_P_SENDSTALL) { -		DBG(5, "%s stalling, txcsr %03x\n", +		dev_dbg(musb->controller, "%s stalling, txcsr %03x\n",  				musb_ep->end_point.name, csr);  		return;  	} -	DBG(4, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x\n", +	dev_dbg(musb->controller, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x\n",  			epnum, musb_ep->packet_sz, fifo_count,  			csr);  #ifndef	CONFIG_MUSB_PIO_ONLY -	if (is_dma_capable() && musb_ep->dma) { +	if (is_buffer_mapped(req)) {  		struct dma_controller	*c = musb->dma_controller;  		size_t request_size; @@ -306,11 +309,11 @@ static void txstate(struct musb *musb, struct musb_request *req)  		request_size = min_t(size_t, request->length - request->actual,  					musb_ep->dma->max_len); -		use_dma = (request->dma != DMA_ADDR_INVALID); +		use_dma = (request->dma != DMA_ADDR_INVALID && request_size);  		/* MUSB_TXCSR_P_ISO is still set correctly */ -#ifdef CONFIG_USB_INVENTRA_DMA +#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)  		{  			if (request_size < musb_ep->packet_sz)  				musb_ep->dma->desired_mode = 0; @@ -341,7 +344,19 @@ static void txstate(struct musb *musb, struct musb_request *req)  					csr |= (MUSB_TXCSR_DMAENAB  							| MUSB_TXCSR_DMAMODE  							| MUSB_TXCSR_MODE); -					if (!musb_ep->hb_mult) +					/* +					 * Enable Autoset according to table +					 * below +					 * bulk_split hb_mult	Autoset_Enable +					 *	0	0	Yes(Normal) +					 *	0	>0	No(High BW ISO) +					 *	1	0	Yes(HS bulk) +					 *	1	>0	Yes(FS bulk) +					 */ +					if (!musb_ep->hb_mult || +						(musb_ep->hb_mult && +						 can_bulk_split(musb, +						    musb_ep->type)))  						csr |= MUSB_TXCSR_AUTOSET;  				}  				csr &= ~MUSB_TXCSR_P_UNDERRUN; @@ -350,51 +365,59 @@ static void txstate(struct musb *musb, struct musb_request *req)  			}  		} -#elif defined(CONFIG_USB_TI_CPPI_DMA) -		/* program endpoint CSR first, then setup DMA */ -		csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); -		csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE | -		       MUSB_TXCSR_MODE; -		musb_writew(epio, MUSB_TXCSR, -			(MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) -				| csr); - -		/* ensure writebuffer is empty */ -		csr = musb_readw(epio, MUSB_TXCSR); - -		/* NOTE host side sets DMAENAB later than this; both are -		 * OK since the transfer dma glue (between CPPI and Mentor -		 * fifos) just tells CPPI it could start.  Data only moves -		 * to the USB TX fifo when both fifos are ready. -		 */ - -		/* "mode" is irrelevant here; handle terminating ZLPs like -		 * PIO does, since the hardware RNDIS mode seems unreliable -		 * except for the last-packet-is-already-short case. -		 */ -		use_dma = use_dma && c->channel_program( -				musb_ep->dma, musb_ep->packet_sz, -				0, -				request->dma + request->actual, -				request_size); -		if (!use_dma) { -			c->channel_release(musb_ep->dma); -			musb_ep->dma = NULL; -			csr &= ~MUSB_TXCSR_DMAENAB; -			musb_writew(epio, MUSB_TXCSR, csr); -			/* invariant: prequest->buf is non-null */ -		} -#elif defined(CONFIG_USB_TUSB_OMAP_DMA) -		use_dma = use_dma && c->channel_program( -				musb_ep->dma, musb_ep->packet_sz, -				request->zero, -				request->dma + request->actual, -				request_size);  #endif +		if (is_cppi_enabled()) { +			/* program endpoint CSR first, then setup DMA */ +			csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); +			csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE | +				MUSB_TXCSR_MODE; +			musb_writew(epio, MUSB_TXCSR, (MUSB_TXCSR_P_WZC_BITS & +						~MUSB_TXCSR_P_UNDERRUN) | csr); + +			/* ensure writebuffer is empty */ +			csr = musb_readw(epio, MUSB_TXCSR); + +			/* +			 * NOTE host side sets DMAENAB later than this; both are +			 * OK since the transfer dma glue (between CPPI and +			 * Mentor fifos) just tells CPPI it could start. Data +			 * only moves to the USB TX fifo when both fifos are +			 * ready. +			 */ +			/* +			 * "mode" is irrelevant here; handle terminating ZLPs +			 * like PIO does, since the hardware RNDIS mode seems +			 * unreliable except for the +			 * last-packet-is-already-short case. +			 */ +			use_dma = use_dma && c->channel_program( +					musb_ep->dma, musb_ep->packet_sz, +					0, +					request->dma + request->actual, +					request_size); +			if (!use_dma) { +				c->channel_release(musb_ep->dma); +				musb_ep->dma = NULL; +				csr &= ~MUSB_TXCSR_DMAENAB; +				musb_writew(epio, MUSB_TXCSR, csr); +				/* invariant: prequest->buf is non-null */ +			} +		} else if (tusb_dma_omap()) +			use_dma = use_dma && c->channel_program( +					musb_ep->dma, musb_ep->packet_sz, +					request->zero, +					request->dma + request->actual, +					request_size);  	}  #endif  	if (!use_dma) { +		/* +		 * Unmap the dma buffer back to cpu if dma channel +		 * programming fails +		 */ +		unmap_dma_buffer(req, musb); +  		musb_write_fifo(musb_ep->hw_ep, fifo_count,  				(u8 *) (request->buf + request->actual));  		request->actual += fifo_count; @@ -404,7 +427,7 @@ static void txstate(struct musb *musb, struct musb_request *req)  	}  	/* host may already have the data when this message shows... */ -	DBG(3, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d\n", +	dev_dbg(musb->controller, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d\n",  			musb_ep->end_point.name, use_dma ? "dma" : "pio",  			request->actual, request->length,  			musb_readw(epio, MUSB_TXCSR), @@ -419,6 +442,7 @@ static void txstate(struct musb *musb, struct musb_request *req)  void musb_g_tx(struct musb *musb, u8 epnum)  {  	u16			csr; +	struct musb_request	*req;  	struct usb_request	*request;  	u8 __iomem		*mbase = musb->mregs;  	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_in; @@ -426,10 +450,11 @@ void musb_g_tx(struct musb *musb, u8 epnum)  	struct dma_channel	*dma;  	musb_ep_select(mbase, epnum); -	request = next_request(musb_ep); +	req = next_request(musb_ep); +	request = &req->request;  	csr = musb_readw(epio, MUSB_TXCSR); -	DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr); +	dev_dbg(musb->controller, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr);  	dma = is_dma_capable() ? musb_ep->dma : NULL; @@ -449,7 +474,8 @@ void musb_g_tx(struct musb *musb, u8 epnum)  		csr |=	 MUSB_TXCSR_P_WZC_BITS;  		csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);  		musb_writew(epio, MUSB_TXCSR, csr); -		DBG(20, "underrun on ep%d, req %p\n", epnum, request); +		dev_vdbg(musb->controller, "underrun on ep%d, req %p\n", +				epnum, request);  	}  	if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { @@ -457,7 +483,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)  		 * SHOULD NOT HAPPEN... has with CPPI though, after  		 * changing SENDSTALL (and other cases); harmless?  		 */ -		DBG(5, "%s dma still busy?\n", musb_ep->end_point.name); +		dev_dbg(musb->controller, "%s dma still busy?\n", musb_ep->end_point.name);  		return;  	} @@ -468,12 +494,12 @@ void musb_g_tx(struct musb *musb, u8 epnum)  			is_dma = 1;  			csr |= MUSB_TXCSR_P_WZC_BITS;  			csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN | -				 MUSB_TXCSR_TXPKTRDY); +				 MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_AUTOSET);  			musb_writew(epio, MUSB_TXCSR, csr);  			/* Ensure writebuffer is empty. */  			csr = musb_readw(epio, MUSB_TXCSR);  			request->actual += musb_ep->dma->actual_len; -			DBG(4, "TXCSR%d %04x, DMA off, len %zu, req %p\n", +			dev_dbg(musb->controller, "TXCSR%d %04x, DMA off, len %zu, req %p\n",  				epnum, csr, musb_ep->dma->actual_len, request);  		} @@ -484,7 +510,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)  		if ((request->zero && request->length  			&& (request->length % musb_ep->packet_sz == 0)  			&& (request->actual == request->length)) -#ifdef CONFIG_USB_INVENTRA_DMA +#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_UX500_DMA)  			|| (is_dma && (!dma->desired_mode ||  				(request->actual &  					(musb_ep->packet_sz - 1)))) @@ -497,7 +523,7 @@ void musb_g_tx(struct musb *musb, u8 epnum)  			if (csr & MUSB_TXCSR_TXPKTRDY)  				return; -			DBG(4, "sending zero pkt\n"); +			dev_dbg(musb->controller, "sending zero pkt\n");  			musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE  					| MUSB_TXCSR_TXPKTRDY);  			request->zero = 0; @@ -505,51 +531,29 @@ void musb_g_tx(struct musb *musb, u8 epnum)  		if (request->actual == request->length) {  			musb_g_giveback(musb_ep, request, 0); -			request = musb_ep->desc ? next_request(musb_ep) : NULL; -			if (!request) { -				DBG(4, "%s idle now\n", +			/* +			 * In the giveback function the MUSB lock is +			 * released and acquired after sometime. During +			 * this time period the INDEX register could get +			 * changed by the gadget_queue function especially +			 * on SMP systems. Reselect the INDEX to be sure +			 * we are reading/modifying the right registers +			 */ +			musb_ep_select(mbase, epnum); +			req = musb_ep->desc ? next_request(musb_ep) : NULL; +			if (!req) { +				dev_dbg(musb->controller, "%s idle now\n",  					musb_ep->end_point.name);  				return;  			}  		} -		txstate(musb, to_musb_request(request)); +		txstate(musb, req);  	}  }  /* ------------------------------------------------------------ */ -#ifdef CONFIG_USB_INVENTRA_DMA - -/* Peripheral rx (OUT) using Mentor DMA works as follows: -	- Only mode 0 is used. - -	- Request is queued by the gadget class driver. -		-> if queue was previously empty, rxstate() - -	- Host sends OUT token which causes an endpoint interrupt -	  /\      -> RxReady -	  |	      -> if request queued, call rxstate -	  |		/\	-> setup DMA -	  |		|	     -> DMA interrupt on completion -	  |		|		-> RxReady -	  |		|		      -> stop DMA -	  |		|		      -> ack the read -	  |		|		      -> if data recd = max expected -	  |		|				by the request, or host -	  |		|				sent a short packet, -	  |		|				complete the request, -	  |		|				and start the next one. -	  |		|_____________________________________| -	  |					 else just wait for the host -	  |					    to send the next OUT token. -	  |__________________________________________________| - - * Non-Mentor DMA engines can of course work differently. - */ - -#endif -  /*   * Context: controller locked, IRQs blocked, endpoint selected   */ @@ -559,31 +563,39 @@ static void rxstate(struct musb *musb, struct musb_request *req)  	struct usb_request	*request = &req->request;  	struct musb_ep		*musb_ep;  	void __iomem		*epio = musb->endpoints[epnum].regs; -	unsigned		fifo_count = 0; -	u16			len; +	unsigned		len = 0; +	u16			fifo_count;  	u16			csr = musb_readw(epio, MUSB_RXCSR);  	struct musb_hw_ep	*hw_ep = &musb->endpoints[epnum]; +	u8			use_mode_1;  	if (hw_ep->is_shared_fifo)  		musb_ep = &hw_ep->ep_in;  	else  		musb_ep = &hw_ep->ep_out; -	len = musb_ep->packet_sz; +	fifo_count = musb_ep->packet_sz; + +	/* Check if EP is disabled */ +	if (!musb_ep->desc) { +		dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", +						musb_ep->end_point.name); +		return; +	}  	/* We shouldn't get here while DMA is active, but we do... */  	if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { -		DBG(4, "DMA pending...\n"); +		dev_dbg(musb->controller, "DMA pending...\n");  		return;  	}  	if (csr & MUSB_RXCSR_P_SENDSTALL) { -		DBG(5, "%s stalling, RXCSR %04x\n", +		dev_dbg(musb->controller, "%s stalling, RXCSR %04x\n",  		    musb_ep->end_point.name, csr);  		return;  	} -	if (is_cppi_enabled() && musb_ep->dma) { +	if (is_cppi_enabled() && is_buffer_mapped(req)) {  		struct dma_controller	*c = musb->dma_controller;  		struct dma_channel	*channel = musb_ep->dma; @@ -611,13 +623,26 @@ static void rxstate(struct musb *musb, struct musb_request *req)  	}  	if (csr & MUSB_RXCSR_RXPKTRDY) { -		len = musb_readw(epio, MUSB_RXCOUNT); +		fifo_count = musb_readw(epio, MUSB_RXCOUNT); + +		/* +		 * Enable Mode 1 on RX transfers only when short_not_ok flag +		 * is set. Currently short_not_ok flag is set only from +		 * file_storage and f_mass_storage drivers +		 */ + +		if (request->short_not_ok && fifo_count == musb_ep->packet_sz) +			use_mode_1 = 1; +		else +			use_mode_1 = 0; +  		if (request->actual < request->length) {  #ifdef CONFIG_USB_INVENTRA_DMA -			if (is_dma_capable() && musb_ep->dma) { +			if (is_buffer_mapped(req)) {  				struct dma_controller	*c;  				struct dma_channel	*channel;  				int			use_dma = 0; +				unsigned int transfer_size;  				c = musb->dma_controller;  				channel = musb_ep->dma; @@ -633,7 +658,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)  	 * most these gadgets, end of is signified either by a short packet,  	 * or filling the last byte of the buffer.  (Sending extra data in  	 * that last pckate should trigger an overflow fault.)  But in mode 1, -	 * we don't get DMA completion interrrupt for short packets. +	 * we don't get DMA completion interrupt for short packets.  	 *  	 * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),  	 * to get endpoint interrupt on every DMA req, but that didn't seem @@ -643,62 +668,111 @@ static void rxstate(struct musb *musb, struct musb_request *req)  	 * then becomes usable as a runtime "use mode 1" hint...  	 */ -				csr |= MUSB_RXCSR_DMAENAB; -#ifdef USE_MODE1 -				csr |= MUSB_RXCSR_AUTOCLEAR; -				/* csr |= MUSB_RXCSR_DMAMODE; */ - -				/* this special sequence (enabling and then -				 * disabling MUSB_RXCSR_DMAMODE) is required -				 * to get DMAReq to activate -				 */ -				musb_writew(epio, MUSB_RXCSR, -					csr | MUSB_RXCSR_DMAMODE); -#else -				if (!musb_ep->hb_mult && -					musb_ep->hw_ep->rx_double_buffered) +				/* Experimental: Mode1 works with mass storage use cases */ +				if (use_mode_1) {  					csr |= MUSB_RXCSR_AUTOCLEAR; -#endif -				musb_writew(epio, MUSB_RXCSR, csr); +					musb_writew(epio, MUSB_RXCSR, csr); +					csr |= MUSB_RXCSR_DMAENAB; +					musb_writew(epio, MUSB_RXCSR, csr); -				if (request->actual < request->length) { -					int transfer_size = 0; -#ifdef USE_MODE1 -					transfer_size = min(request->length - request->actual, +					/* +					 * this special sequence (enabling and then +					 * disabling MUSB_RXCSR_DMAMODE) is required +					 * to get DMAReq to activate +					 */ +					musb_writew(epio, MUSB_RXCSR, +						csr | MUSB_RXCSR_DMAMODE); +					musb_writew(epio, MUSB_RXCSR, csr); + +					transfer_size = min_t(unsigned int, +							request->length - +							request->actual,  							channel->max_len); -#else +					musb_ep->dma->desired_mode = 1; +				} else { +					if (!musb_ep->hb_mult && +						musb_ep->hw_ep->rx_double_buffered) +						csr |= MUSB_RXCSR_AUTOCLEAR; +					csr |= MUSB_RXCSR_DMAENAB; +					musb_writew(epio, MUSB_RXCSR, csr); +  					transfer_size = min(request->length - request->actual, -							(unsigned)len); -#endif -					if (transfer_size <= musb_ep->packet_sz) -						musb_ep->dma->desired_mode = 0; -					else -						musb_ep->dma->desired_mode = 1; +							(unsigned)fifo_count); +					musb_ep->dma->desired_mode = 0; +				} + +				use_dma = c->channel_program( +						channel, +						musb_ep->packet_sz, +						channel->desired_mode, +						request->dma +						+ request->actual, +						transfer_size); + +				if (use_dma) +					return; +			} +#elif defined(CONFIG_USB_UX500_DMA) +			if ((is_buffer_mapped(req)) && +				(request->actual < request->length)) { -					use_dma = c->channel_program( -							channel, +				struct dma_controller *c; +				struct dma_channel *channel; +				unsigned int transfer_size = 0; + +				c = musb->dma_controller; +				channel = musb_ep->dma; + +				/* In case first packet is short */ +				if (fifo_count < musb_ep->packet_sz) +					transfer_size = fifo_count; +				else if (request->short_not_ok) +					transfer_size =	min_t(unsigned int, +							request->length - +							request->actual, +							channel->max_len); +				else +					transfer_size = min_t(unsigned int, +							request->length - +							request->actual, +							(unsigned)fifo_count); + +				csr &= ~MUSB_RXCSR_DMAMODE; +				csr |= (MUSB_RXCSR_DMAENAB | +					MUSB_RXCSR_AUTOCLEAR); + +				musb_writew(epio, MUSB_RXCSR, csr); + +				if (transfer_size <= musb_ep->packet_sz) { +					musb_ep->dma->desired_mode = 0; +				} else { +					musb_ep->dma->desired_mode = 1; +					/* Mode must be set after DMAENAB */ +					csr |= MUSB_RXCSR_DMAMODE; +					musb_writew(epio, MUSB_RXCSR, csr); +				} + +				if (c->channel_program(channel,  							musb_ep->packet_sz,  							channel->desired_mode,  							request->dma  							+ request->actual, -							transfer_size); -				} +							transfer_size)) -				if (use_dma)  					return;  			}  #endif	/* Mentor's DMA */ -			fifo_count = request->length - request->actual; -			DBG(3, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n", +			len = request->length - request->actual; +			dev_dbg(musb->controller, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n",  					musb_ep->end_point.name, -					len, fifo_count, +					fifo_count, len,  					musb_ep->packet_sz);  			fifo_count = min_t(unsigned, len, fifo_count);  #ifdef	CONFIG_USB_TUSB_OMAP_DMA -			if (tusb_dma_omap() && musb_ep->dma) { +			if (tusb_dma_omap() && 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; @@ -713,6 +787,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)  					return;  			}  #endif +			/* +			 * Unmap the dma buffer back to cpu if dma channel +			 * programming fails. This buffer is mapped if the +			 * channel allocation is successful +			 */ +			 if (is_buffer_mapped(req)) { +				unmap_dma_buffer(req, musb); + +				/* +				 * Clear DMAENAB and AUTOCLEAR for the +				 * PIO mode transfer +				 */ +				csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR); +				musb_writew(epio, MUSB_RXCSR, csr); +			}  			musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)  					(request->buf + request->actual)); @@ -730,7 +819,8 @@ static void rxstate(struct musb *musb, struct musb_request *req)  	}  	/* reach the end or short packet detected */ -	if (request->actual == request->length || len < musb_ep->packet_sz) +	if (request->actual == request->length || +	    fifo_count < musb_ep->packet_sz)  		musb_g_giveback(musb_ep, request, 0);  } @@ -740,6 +830,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)  void musb_g_rx(struct musb *musb, u8 epnum)  {  	u16			csr; +	struct musb_request	*req;  	struct usb_request	*request;  	void __iomem		*mbase = musb->mregs;  	struct musb_ep		*musb_ep; @@ -754,14 +845,16 @@ void musb_g_rx(struct musb *musb, u8 epnum)  	musb_ep_select(mbase, epnum); -	request = next_request(musb_ep); -	if (!request) +	req = next_request(musb_ep); +	if (!req)  		return; +	request = &req->request; +  	csr = musb_readw(epio, MUSB_RXCSR);  	dma = is_dma_capable() ? musb_ep->dma : NULL; -	DBG(4, "<== %s, rxcsr %04x%s %p\n", musb_ep->end_point.name, +	dev_dbg(musb->controller, "<== %s, rxcsr %04x%s %p\n", musb_ep->end_point.name,  			csr, dma ? " (dma)" : "", request);  	if (csr & MUSB_RXCSR_P_SENTSTALL) { @@ -776,19 +869,18 @@ void musb_g_rx(struct musb *musb, u8 epnum)  		csr &= ~MUSB_RXCSR_P_OVERRUN;  		musb_writew(epio, MUSB_RXCSR, csr); -		DBG(3, "%s iso overrun on %p\n", musb_ep->name, request); +		dev_dbg(musb->controller, "%s iso overrun on %p\n", musb_ep->name, request);  		if (request->status == -EINPROGRESS)  			request->status = -EOVERFLOW;  	}  	if (csr & MUSB_RXCSR_INCOMPRX) {  		/* REVISIT not necessarily an error */ -		DBG(4, "%s, incomprx\n", musb_ep->end_point.name); +		dev_dbg(musb->controller, "%s, incomprx\n", musb_ep->end_point.name);  	}  	if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {  		/* "should not happen"; likely RXPKTRDY pending for DMA */ -		DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1, -			"%s busy, csr %04x\n", +		dev_dbg(musb->controller, "%s busy, csr %04x\n",  			musb_ep->end_point.name, csr);  		return;  	} @@ -802,12 +894,13 @@ void musb_g_rx(struct musb *musb, u8 epnum)  		request->actual += musb_ep->dma->actual_len; -		DBG(4, "RXCSR%d %04x, dma off, %04x, len %zu, req %p\n", +		dev_dbg(musb->controller, "RXCSR%d %04x, dma off, %04x, len %zu, req %p\n",  			epnum, csr,  			musb_readw(epio, MUSB_RXCSR),  			musb_ep->dma->actual_len, request); -#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) +#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) || \ +	defined(CONFIG_USB_UX500_DMA)  		/* Autoclear doesn't clear RxPktRdy for short packets */  		if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered)  				|| (dma->actual_len @@ -832,14 +925,26 @@ void musb_g_rx(struct musb *musb, u8 epnum)  		}  #endif  		musb_g_giveback(musb_ep, request, 0); +		/* +		 * In the giveback function the MUSB lock is +		 * released and acquired after sometime. During +		 * this time period the INDEX register could get +		 * changed by the gadget_queue function especially +		 * on SMP systems. Reselect the INDEX to be sure +		 * we are reading/modifying the right registers +		 */ +		musb_ep_select(mbase, epnum); -		request = next_request(musb_ep); -		if (!request) +		req = next_request(musb_ep); +		if (!req)  			return;  	} +#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) || \ +	defined(CONFIG_USB_UX500_DMA)  exit: +#endif  	/* Analyze request */ -	rxstate(musb, to_musb_request(request)); +	rxstate(musb, req);  }  /* ------------------------------------------------------------ */ @@ -881,7 +986,7 @@ static int musb_gadget_enable(struct usb_ep *ep,  		goto fail;  	/* REVISIT this rules out high bandwidth periodic transfers */ -	tmp = le16_to_cpu(desc->wMaxPacketSize); +	tmp = usb_endpoint_maxp(desc);  	if (tmp & ~0x07ff) {  		int ok; @@ -891,7 +996,7 @@ static int musb_gadget_enable(struct usb_ep *ep,  			ok = musb->hb_iso_rx;  		if (!ok) { -			DBG(4, "%s: not support ISO high bandwidth\n", __func__); +			dev_dbg(musb->controller, "no support for high bandwidth ISO\n");  			goto fail;  		}  		musb_ep->hb_mult = (tmp >> 11) & 3; @@ -907,7 +1012,6 @@ static int musb_gadget_enable(struct usb_ep *ep,  	 */  	musb_ep_select(mbase, epnum);  	if (usb_endpoint_dir_in(desc)) { -		u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);  		if (hw_ep->is_shared_fifo)  			musb_ep->is_in = 1; @@ -915,12 +1019,12 @@ static int musb_gadget_enable(struct usb_ep *ep,  			goto fail;  		if (tmp > hw_ep->max_packet_sz_tx) { -			DBG(4, "%s: packet size beyond hw fifo size\n", __func__); +			dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n");  			goto fail;  		} -		int_txe |= (1 << epnum); -		musb_writew(mbase, MUSB_INTRTXE, int_txe); +		musb->intrtxe |= (1 << epnum); +		musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);  		/* REVISIT if can_bulk_split(), use by updating "tmp";  		 * likewise high bandwidth periodic tx @@ -928,7 +1032,15 @@ static int musb_gadget_enable(struct usb_ep *ep,  		/* Set TXMAXP with the FIFO size of the endpoint  		 * to disable double buffering mode.  		 */ -		musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); +		if (musb->double_buffer_not_ok) { +			musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); +		} else { +			if (can_bulk_split(musb, musb_ep->type)) +				musb_ep->hb_mult = (hw_ep->max_packet_sz_tx / +							musb_ep->packet_sz) - 1; +			musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz +					| (musb_ep->hb_mult << 11)); +		}  		csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;  		if (musb_readw(regs, MUSB_TXCSR) @@ -943,7 +1055,6 @@ static int musb_gadget_enable(struct usb_ep *ep,  		musb_writew(regs, MUSB_TXCSR, csr);  	} else { -		u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE);  		if (hw_ep->is_shared_fifo)  			musb_ep->is_in = 0; @@ -951,12 +1062,12 @@ static int musb_gadget_enable(struct usb_ep *ep,  			goto fail;  		if (tmp > hw_ep->max_packet_sz_rx) { -			DBG(4, "%s: packet size beyond hw fifo size\n", __func__); +			dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n");  			goto fail;  		} -		int_rxe |= (1 << epnum); -		musb_writew(mbase, MUSB_INTRRXE, int_rxe); +		musb->intrrxe |= (1 << epnum); +		musb_writew(mbase, MUSB_INTRRXE, musb->intrrxe);  		/* REVISIT if can_bulk_combine() use by updating "tmp"  		 * likewise high bandwidth periodic rx @@ -964,7 +1075,11 @@ static int musb_gadget_enable(struct usb_ep *ep,  		/* Set RXMAXP with the FIFO size of the endpoint  		 * to disable double buffering mode.  		 */ -		musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); +		if (musb->double_buffer_not_ok) +			musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_tx); +		else +			musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz +					| (musb_ep->hb_mult << 11));  		/* force shared fifo to OUT-only mode */  		if (hw_ep->is_shared_fifo) { @@ -1006,7 +1121,7 @@ static int musb_gadget_enable(struct usb_ep *ep,  			case USB_ENDPOINT_XFER_BULK:	s = "bulk"; break;  			case USB_ENDPOINT_XFER_INT:	s = "int"; break;  			default:			s = "iso"; break; -			}; s; }), +			} s; }),  			musb_ep->is_in ? "IN" : "OUT",  			musb_ep->dma ? "dma, " : "",  			musb_ep->packet_sz); @@ -1040,18 +1155,17 @@ static int musb_gadget_disable(struct usb_ep *ep)  	/* zero the endpoint sizes */  	if (musb_ep->is_in) { -		u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE); -		int_txe &= ~(1 << epnum); -		musb_writew(musb->mregs, MUSB_INTRTXE, int_txe); +		musb->intrtxe &= ~(1 << epnum); +		musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe);  		musb_writew(epio, MUSB_TXMAXP, 0);  	} else { -		u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE); -		int_rxe &= ~(1 << epnum); -		musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe); +		musb->intrrxe &= ~(1 << epnum); +		musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe);  		musb_writew(epio, MUSB_RXMAXP, 0);  	}  	musb_ep->desc = NULL; +	musb_ep->end_point.desc = NULL;  	/* abort all pending DMA and requests */  	nuke(musb_ep, -ESHUTDOWN); @@ -1060,7 +1174,7 @@ static int musb_gadget_disable(struct usb_ep *ep)  	spin_unlock_irqrestore(&(musb->lock), flags); -	DBG(2, "%s\n", musb_ep->end_point.name); +	dev_dbg(musb->controller, "%s\n", musb_ep->end_point.name);  	return status;  } @@ -1072,16 +1186,19 @@ static int musb_gadget_disable(struct usb_ep *ep)  struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)  {  	struct musb_ep		*musb_ep = to_musb_ep(ep); +	struct musb		*musb = musb_ep->musb;  	struct musb_request	*request = NULL;  	request = kzalloc(sizeof *request, gfp_flags); -	if (request) { -		INIT_LIST_HEAD(&request->request.list); -		request->request.dma = DMA_ADDR_INVALID; -		request->epnum = musb_ep->current_epnum; -		request->ep = musb_ep; +	if (!request) { +		dev_dbg(musb->controller, "not enough memory\n"); +		return NULL;  	} +	request->request.dma = DMA_ADDR_INVALID; +	request->epnum = musb_ep->current_epnum; +	request->ep = musb_ep; +  	return &request->request;  } @@ -1108,7 +1225,7 @@ struct free_record {   */  void musb_ep_restart(struct musb *musb, struct musb_request *req)  { -	DBG(3, "<== %s request %p len %u on hw_ep%d\n", +	dev_dbg(musb->controller, "<== %s request %p len %u on hw_ep%d\n",  		req->tx ? "TX/IN" : "RX/OUT",  		&req->request, req->request.length, req->epnum); @@ -1142,7 +1259,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,  	if (request->ep != musb_ep)  		return -EINVAL; -	DBG(4, "<== to %s request=%p\n", ep->name, req); +	dev_dbg(musb->controller, "<== to %s request=%p\n", ep->name, req);  	/* request is mine now... */  	request->request.actual = 0; @@ -1150,46 +1267,27 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,  	request->epnum = musb_ep->current_epnum;  	request->tx = musb_ep->is_in; -	if (is_dma_capable() && musb_ep->dma) { -		if (request->request.dma == DMA_ADDR_INVALID) { -			request->request.dma = dma_map_single( -					musb->controller, -					request->request.buf, -					request->request.length, -					request->tx -						? DMA_TO_DEVICE -						: DMA_FROM_DEVICE); -			request->mapped = 1; -		} else { -			dma_sync_single_for_device(musb->controller, -					request->request.dma, -					request->request.length, -					request->tx -						? DMA_TO_DEVICE -						: DMA_FROM_DEVICE); -			request->mapped = 0; -		} -	} else -		request->mapped = 0; +	map_dma_buffer(request, musb, musb_ep);  	spin_lock_irqsave(&musb->lock, lockflags);  	/* don't queue if the ep is down */  	if (!musb_ep->desc) { -		DBG(4, "req %p queued to %s while ep %s\n", +		dev_dbg(musb->controller, "req %p queued to %s while ep %s\n",  				req, ep->name, "disabled");  		status = -ESHUTDOWN; -		goto cleanup; +		unmap_dma_buffer(request, musb); +		goto unlock;  	}  	/* add request to the list */ -	list_add_tail(&(request->request.list), &(musb_ep->req_list)); +	list_add_tail(&request->list, &musb_ep->req_list);  	/* it this is the head of the queue, start i/o ... */ -	if (!musb_ep->busy && &request->request.list == musb_ep->req_list.next) +	if (!musb_ep->busy && &request->list == musb_ep->req_list.next)  		musb_ep_restart(musb, request); -cleanup: +unlock:  	spin_unlock_irqrestore(&musb->lock, lockflags);  	return status;  } @@ -1197,7 +1295,8 @@ cleanup:  static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request)  {  	struct musb_ep		*musb_ep = to_musb_ep(ep); -	struct usb_request	*r; +	struct musb_request	*req = to_musb_request(request); +	struct musb_request	*r;  	unsigned long		flags;  	int			status = 0;  	struct musb		*musb = musb_ep->musb; @@ -1208,17 +1307,17 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request)  	spin_lock_irqsave(&musb->lock, flags);  	list_for_each_entry(r, &musb_ep->req_list, list) { -		if (r == request) +		if (r == req)  			break;  	} -	if (r != request) { -		DBG(3, "request %p not queued to %s\n", request, ep->name); +	if (r != req) { +		dev_dbg(musb->controller, "request %p not queued to %s\n", request, ep->name);  		status = -EINVAL;  		goto done;  	}  	/* if the hardware doesn't have the request, easy ... */ -	if (musb_ep->req_list.next != &request->list || musb_ep->busy) +	if (musb_ep->req_list.next != &req->list || musb_ep->busy)  		musb_g_giveback(musb_ep, request, -ECONNRESET);  	/* ... else abort the dma transfer ... */ @@ -1275,10 +1374,10 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value)  	musb_ep_select(mbase, epnum); -	request = to_musb_request(next_request(musb_ep)); +	request = next_request(musb_ep);  	if (value) {  		if (request) { -			DBG(3, "request in progress, cannot halt %s\n", +			dev_dbg(musb->controller, "request in progress, cannot halt %s\n",  			    ep->name);  			status = -EAGAIN;  			goto done; @@ -1287,7 +1386,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value)  		if (musb_ep->is_in) {  			csr = musb_readw(epio, MUSB_TXCSR);  			if (csr & MUSB_TXCSR_FIFONOTEMPTY) { -				DBG(3, "FIFO busy, cannot halt %s\n", ep->name); +				dev_dbg(musb->controller, "FIFO busy, cannot halt %s\n", ep->name);  				status = -EAGAIN;  				goto done;  			} @@ -1296,7 +1395,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value)  		musb_ep->wedged = 0;  	/* set/clear the stall and toggle bits */ -	DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); +	dev_dbg(musb->controller, "%s: %s stall\n", ep->name, value ? "set" : "clear");  	if (musb_ep->is_in) {  		csr = musb_readw(epio, MUSB_TXCSR);  		csr |= MUSB_TXCSR_P_WZC_BITS @@ -1323,7 +1422,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value)  	/* maybe start the first request in the queue */  	if (!musb_ep->busy && !value && request) { -		DBG(3, "restarting the request\n"); +		dev_dbg(musb->controller, "restarting the request\n");  		musb_ep_restart(musb, request);  	} @@ -1378,7 +1477,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)  	void __iomem	*epio = musb->endpoints[epnum].regs;  	void __iomem	*mbase;  	unsigned long	flags; -	u16		csr, int_txe; +	u16		csr;  	mbase = musb->mregs; @@ -1386,13 +1485,18 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)  	musb_ep_select(mbase, (u8) epnum);  	/* disable interrupts */ -	int_txe = musb_readw(mbase, MUSB_INTRTXE); -	musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum)); +	musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe & ~(1 << epnum));  	if (musb_ep->is_in) {  		csr = musb_readw(epio, MUSB_TXCSR);  		if (csr & MUSB_TXCSR_FIFONOTEMPTY) {  			csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS; +			/* +			 * Setting both TXPKTRDY and FLUSHFIFO makes controller +			 * to interrupt current FIFO loading, but not flushing +			 * the already loaded ones. +			 */ +			csr &= ~MUSB_TXCSR_TXPKTRDY;  			musb_writew(epio, MUSB_TXCSR, csr);  			/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */  			musb_writew(epio, MUSB_TXCSR, csr); @@ -1405,7 +1509,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)  	}  	/* re-enable interrupt */ -	musb_writew(mbase, MUSB_INTRTXE, int_txe); +	musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe);  	spin_unlock_irqrestore(&musb->lock, flags);  } @@ -1454,7 +1558,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)  	case OTG_STATE_B_IDLE:  		/* Start SRP ... OTG not required. */  		devctl = musb_readb(mregs, MUSB_DEVCTL); -		DBG(2, "Sending SRP: devctl: %02x\n", devctl); +		dev_dbg(musb->controller, "Sending SRP: devctl: %02x\n", devctl);  		devctl |= MUSB_DEVCTL_SESSION;  		musb_writeb(mregs, MUSB_DEVCTL, devctl);  		devctl = musb_readb(mregs, MUSB_DEVCTL); @@ -1471,6 +1575,10 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)  				break;  		} +		spin_unlock_irqrestore(&musb->lock, flags); +		otg_start_srp(musb->xceiv->otg); +		spin_lock_irqsave(&musb->lock, flags); +  		/* Block idling for at least 1s */  		musb_platform_try_idle(musb,  			jiffies + msecs_to_jiffies(1 * HZ)); @@ -1478,7 +1586,8 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)  		status = 0;  		goto done;  	default: -		DBG(2, "Unhandled wake: %s\n", otg_state_string(musb)); +		dev_dbg(musb->controller, "Unhandled wake: %s\n", +			usb_otg_state_string(musb->xceiv->state));  		goto done;  	} @@ -1487,7 +1596,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)  	power = musb_readb(mregs, MUSB_POWER);  	power |= MUSB_POWER_RESUME;  	musb_writeb(mregs, MUSB_POWER, power); -	DBG(2, "issue wakeup\n"); +	dev_dbg(musb->controller, "issue wakeup\n");  	/* FIXME do this next chunk in a timer callback, no udelay */  	mdelay(2); @@ -1521,15 +1630,15 @@ static void musb_pullup(struct musb *musb, int is_on)  	/* FIXME if on, HdrcStart; if off, HdrcStop */ -	DBG(3, "gadget %s D+ pullup %s\n", -		musb->gadget_driver->function, is_on ? "on" : "off"); +	dev_dbg(musb->controller, "gadget D+ pullup %s\n", +		is_on ? "on" : "off");  	musb_writeb(musb->mregs, MUSB_POWER, power);  }  #if 0  static int musb_gadget_vbus_session(struct usb_gadget *gadget, int is_active)  { -	DBG(2, "<= %s =>\n", __func__); +	dev_dbg(musb->controller, "<= %s =>\n", __func__);  	/*  	 * FIXME iff driver's softconnect flag is set (as it is during probe, @@ -1546,7 +1655,7 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)  	if (!musb->xceiv->set_power)  		return -EOPNOTSUPP; -	return otg_set_power(musb->xceiv, mA); +	return usb_phy_set_power(musb->xceiv, mA);  }  static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) @@ -1556,6 +1665,8 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)  	is_on = !!is_on; +	pm_runtime_get_sync(musb->controller); +  	/* NOTE: this assumes we are sensing vbus; we'd rather  	 * not pullup unless the B-session is active.  	 */ @@ -1565,9 +1676,17 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)  		musb_pullup(musb, is_on);  	}  	spin_unlock_irqrestore(&musb->lock, flags); + +	pm_runtime_put(musb->controller); +  	return 0;  } +static int musb_gadget_start(struct usb_gadget *g, +		struct usb_gadget_driver *driver); +static int musb_gadget_stop(struct usb_gadget *g, +		struct usb_gadget_driver *driver); +  static const struct usb_gadget_ops musb_gadget_operations = {  	.get_frame		= musb_gadget_get_frame,  	.wakeup			= musb_gadget_wakeup, @@ -1575,6 +1694,8 @@ static const struct usb_gadget_ops musb_gadget_operations = {  	/* .vbus_session		= musb_gadget_vbus_session, */  	.vbus_draw		= musb_gadget_vbus_draw,  	.pullup			= musb_gadget_pullup, +	.udc_start		= musb_gadget_start, +	.udc_stop		= musb_gadget_stop,  };  /* ----------------------------------------------------------------------- */ @@ -1585,16 +1706,8 @@ static const struct usb_gadget_ops musb_gadget_operations = {   * about there being only one external upstream port.  It assumes   * all peripheral ports are external...   */ -static struct musb *the_gadget; - -static void musb_gadget_release(struct device *dev) -{ -	/* kref_put(WHAT) */ -	dev_dbg(dev, "%s\n", __func__); -} - -static void __init +static void  init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)  {  	struct musb_hw_ep	*hw_ep = musb->endpoints + epnum; @@ -1614,14 +1727,14 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)  	ep->end_point.name = ep->name;  	INIT_LIST_HEAD(&ep->end_point.ep_list);  	if (!epnum) { -		ep->end_point.maxpacket = 64; +		usb_ep_set_maxpacket_limit(&ep->end_point, 64);  		ep->end_point.ops = &musb_g_ep0_ops;  		musb->g.ep0 = &ep->end_point;  	} else {  		if (is_in) -			ep->end_point.maxpacket = hw_ep->max_packet_sz_tx; +			usb_ep_set_maxpacket_limit(&ep->end_point, hw_ep->max_packet_sz_tx);  		else -			ep->end_point.maxpacket = hw_ep->max_packet_sz_rx; +			usb_ep_set_maxpacket_limit(&ep->end_point, hw_ep->max_packet_sz_rx);  		ep->end_point.ops = &musb_ep_ops;  		list_add_tail(&ep->end_point.ep_list, &musb->g.ep_list);  	} @@ -1631,13 +1744,13 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)   * Initialize the endpoints exposed to peripheral drivers, with backlinks   * to the rest of the driver state.   */ -static inline void __init musb_g_init_endpoints(struct musb *musb) +static inline void musb_g_init_endpoints(struct musb *musb)  {  	u8			epnum;  	struct musb_hw_ep	*hw_ep;  	unsigned		count = 0; -	/* intialize endpoint list just once */ +	/* initialize endpoint list just once */  	INIT_LIST_HEAD(&(musb->g.ep_list));  	for (epnum = 0, hw_ep = musb->endpoints; @@ -1664,7 +1777,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb)  /* called once during driver setup to initialize and link into   * the driver model; memory is zeroed.   */ -int __init musb_gadget_setup(struct musb *musb) +int musb_gadget_setup(struct musb *musb)  {  	int status; @@ -1672,44 +1785,44 @@ int __init musb_gadget_setup(struct musb *musb)  	 * musb peripherals at the same time, only the bus lock  	 * is probably held.  	 */ -	if (the_gadget) -		return -EBUSY; -	the_gadget = musb;  	musb->g.ops = &musb_gadget_operations; -	musb->g.is_dualspeed = 1; +	musb->g.max_speed = USB_SPEED_HIGH;  	musb->g.speed = USB_SPEED_UNKNOWN; +	MUSB_DEV_MODE(musb); +	musb->xceiv->otg->default_a = 0; +	musb->xceiv->state = OTG_STATE_B_IDLE; +  	/* this "gadget" abstracts/virtualizes the controller */ -	dev_set_name(&musb->g.dev, "gadget"); -	musb->g.dev.parent = musb->controller; -	musb->g.dev.dma_mask = musb->controller->dma_mask; -	musb->g.dev.release = musb_gadget_release;  	musb->g.name = musb_driver_name; - -	if (is_otg_enabled(musb)) -		musb->g.is_otg = 1; +#if IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE) +	musb->g.is_otg = 1; +#elif IS_ENABLED(CONFIG_USB_MUSB_GADGET) +	musb->g.is_otg = 0; +#endif  	musb_g_init_endpoints(musb);  	musb->is_active = 0;  	musb_platform_try_idle(musb, 0); -	status = device_register(&musb->g.dev); -	if (status != 0) { -		put_device(&musb->g.dev); -		the_gadget = NULL; -	} +	status = usb_add_gadget_udc(musb->controller, &musb->g); +	if (status) +		goto err; + +	return 0; +err: +	musb->g.dev.parent = NULL; +	device_unregister(&musb->g.dev);  	return status;  }  void musb_gadget_cleanup(struct musb *musb)  { -	if (musb != the_gadget) +	if (musb->port_mode == MUSB_PORT_MODE_HOST)  		return; - -	device_unregister(&musb->g.dev); -	the_gadget = NULL; +	usb_del_gadget_udc(&musb->g);  }  /* @@ -1718,98 +1831,55 @@ void musb_gadget_cleanup(struct musb *musb)   *   * -EINVAL something went wrong (not driver)   * -EBUSY another gadget is already using the controller - * -ENOMEM no memeory to perform the operation + * -ENOMEM no memory to perform the operation   *   * @param driver the gadget driver - * @param bind the driver's bind function   * @return <0 if error, 0 if everything is fine   */ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, -		int (*bind)(struct usb_gadget *)) +static int musb_gadget_start(struct usb_gadget *g, +		struct usb_gadget_driver *driver)  { -	int retval; -	unsigned long flags; -	struct musb *musb = the_gadget; - -	if (!driver -			|| driver->speed != USB_SPEED_HIGH -			|| !bind || !driver->setup) -		return -EINVAL; - -	/* driver must be initialized to support peripheral mode */ -	if (!musb) { -		DBG(1, "%s, no dev??\n", __func__); -		return -ENODEV; -	} - -	DBG(3, "registering driver %s\n", driver->function); -	spin_lock_irqsave(&musb->lock, flags); +	struct musb		*musb = gadget_to_musb(g); +	struct usb_otg		*otg = musb->xceiv->otg; +	unsigned long		flags; +	int			retval = 0; -	if (musb->gadget_driver) { -		DBG(1, "%s is already bound to %s\n", -				musb_driver_name, -				musb->gadget_driver->driver.name); -		retval = -EBUSY; -	} else { -		musb->gadget_driver = driver; -		musb->g.dev.driver = &driver->driver; -		driver->driver.bus = NULL; -		musb->softconnect = 1; -		retval = 0; +	if (driver->max_speed < USB_SPEED_HIGH) { +		retval = -EINVAL; +		goto err;  	} -	spin_unlock_irqrestore(&musb->lock, flags); - -	if (retval == 0) { -		retval = bind(&musb->g); -		if (retval != 0) { -			DBG(3, "bind to driver %s failed --> %d\n", -					driver->driver.name, retval); -			musb->gadget_driver = NULL; -			musb->g.dev.driver = NULL; -		} +	pm_runtime_get_sync(musb->controller); -		spin_lock_irqsave(&musb->lock, flags); +	dev_dbg(musb->controller, "registering driver %s\n", driver->function); -		otg_set_peripheral(musb->xceiv, &musb->g); -		musb->xceiv->state = OTG_STATE_B_IDLE; -		musb->is_active = 1; +	musb->softconnect = 0; +	musb->gadget_driver = driver; -		/* FIXME this ignores the softconnect flag.  Drivers are -		 * allowed hold the peripheral inactive until for example -		 * userspace hooks up printer hardware or DSP codecs, so -		 * hosts only see fully functional devices. -		 */ +	spin_lock_irqsave(&musb->lock, flags); +	musb->is_active = 1; -		if (!is_otg_enabled(musb)) -			musb_start(musb); +	otg_set_peripheral(otg, &musb->g); +	musb->xceiv->state = OTG_STATE_B_IDLE; +	spin_unlock_irqrestore(&musb->lock, flags); -		otg_set_peripheral(musb->xceiv, &musb->g); +	musb_start(musb); -		spin_unlock_irqrestore(&musb->lock, flags); +	/* REVISIT:  funcall to other code, which also +	 * handles power budgeting ... this way also +	 * ensures HdrcStart is indirectly called. +	 */ +	if (musb->xceiv->last_event == USB_EVENT_ID) +		musb_platform_set_vbus(musb, 1); -		if (is_otg_enabled(musb)) { -			DBG(3, "OTG startup...\n"); +	if (musb->xceiv->last_event == USB_EVENT_NONE) +		pm_runtime_put(musb->controller); -			/* REVISIT:  funcall to other code, which also -			 * handles power budgeting ... this way also -			 * ensures HdrcStart is indirectly called. -			 */ -			retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); -			if (retval < 0) { -				DBG(1, "add_hcd failed, %d\n", retval); -				spin_lock_irqsave(&musb->lock, flags); -				otg_set_peripheral(musb->xceiv, NULL); -				musb->gadget_driver = NULL; -				musb->g.dev.driver = NULL; -				spin_unlock_irqrestore(&musb->lock, flags); -			} -		} -	} +	return 0; +err:  	return retval;  } -EXPORT_SYMBOL(usb_gadget_probe_driver);  static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)  { @@ -1846,10 +1916,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)  					nuke(&hw_ep->ep_out, -ESHUTDOWN);  			}  		} - -		spin_unlock(&musb->lock); -		driver->disconnect(&musb->g); -		spin_lock(&musb->lock);  	}  } @@ -1859,59 +1925,48 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)   *   * @param driver the gadget driver to unregister   */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +static int musb_gadget_stop(struct usb_gadget *g, +		struct usb_gadget_driver *driver)  { +	struct musb	*musb = gadget_to_musb(g);  	unsigned long	flags; -	int		retval = 0; -	struct musb	*musb = the_gadget; -	if (!driver || !driver->unbind || !musb) -		return -EINVAL; +	if (musb->xceiv->last_event == USB_EVENT_NONE) +		pm_runtime_get_sync(musb->controller); -	/* REVISIT always use otg_set_peripheral() here too; +	/* +	 * REVISIT always use otg_set_peripheral() here too;  	 * this needs to shut down the OTG engine.  	 */  	spin_lock_irqsave(&musb->lock, flags); -#ifdef	CONFIG_USB_MUSB_OTG  	musb_hnp_stop(musb); -#endif - -	if (musb->gadget_driver == driver) { - -		(void) musb_gadget_vbus_draw(&musb->g, 0); -		musb->xceiv->state = OTG_STATE_UNDEFINED; -		stop_activity(musb, driver); -		otg_set_peripheral(musb->xceiv, NULL); +	(void) musb_gadget_vbus_draw(&musb->g, 0); -		DBG(3, "unregistering driver %s\n", driver->function); -		spin_unlock_irqrestore(&musb->lock, flags); -		driver->unbind(&musb->g); -		spin_lock_irqsave(&musb->lock, flags); +	musb->xceiv->state = OTG_STATE_UNDEFINED; +	stop_activity(musb, driver); +	otg_set_peripheral(musb->xceiv->otg, NULL); -		musb->gadget_driver = NULL; -		musb->g.dev.driver = NULL; +	dev_dbg(musb->controller, "unregistering driver %s\n", +				  driver ? driver->function : "(removed)"); -		musb->is_active = 0; -		musb_platform_try_idle(musb, 0); -	} else -		retval = -EINVAL; +	musb->is_active = 0; +	musb->gadget_driver = NULL; +	musb_platform_try_idle(musb, 0);  	spin_unlock_irqrestore(&musb->lock, flags); -	if (is_otg_enabled(musb) && retval == 0) { -		usb_remove_hcd(musb_to_hcd(musb)); -		/* FIXME we need to be able to register another -		 * gadget driver here and have everything work; -		 * that currently misbehaves. -		 */ -	} +	/* +	 * FIXME we need to be able to register another +	 * gadget driver here and have everything work; +	 * that currently misbehaves. +	 */ -	return retval; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); +	pm_runtime_put(musb->controller); +	return 0; +}  /* ----------------------------------------------------------------------- */ @@ -1934,7 +1989,7 @@ void musb_g_resume(struct musb *musb)  		break;  	default:  		WARNING("unhandled RESUME transition (%s)\n", -				otg_state_string(musb)); +				usb_otg_state_string(musb->xceiv->state));  	}  } @@ -1944,7 +1999,7 @@ void musb_g_suspend(struct musb *musb)  	u8	devctl;  	devctl = musb_readb(musb->mregs, MUSB_DEVCTL); -	DBG(3, "devctl %02x\n", devctl); +	dev_dbg(musb->controller, "devctl %02x\n", devctl);  	switch (musb->xceiv->state) {  	case OTG_STATE_B_IDLE: @@ -1964,7 +2019,7 @@ void musb_g_suspend(struct musb *musb)  		 * A_PERIPHERAL may need care too  		 */  		WARNING("unhandled SUSPEND transition (%s)\n", -				otg_state_string(musb)); +				usb_otg_state_string(musb->xceiv->state));  	}  } @@ -1980,7 +2035,7 @@ void musb_g_disconnect(struct musb *musb)  	void __iomem	*mregs = musb->mregs;  	u8	devctl = musb_readb(mregs, MUSB_DEVCTL); -	DBG(3, "devctl %02x\n", devctl); +	dev_dbg(musb->controller, "devctl %02x\n", devctl);  	/* clear HR */  	musb_writeb(mregs, MUSB_DEVCTL, devctl & MUSB_DEVCTL_SESSION); @@ -1997,9 +2052,8 @@ void musb_g_disconnect(struct musb *musb)  	switch (musb->xceiv->state) {  	default: -#ifdef	CONFIG_USB_MUSB_OTG -		DBG(2, "Unhandled disconnect %s, setting a_idle\n", -			otg_state_string(musb)); +		dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", +			usb_otg_state_string(musb->xceiv->state));  		musb->xceiv->state = OTG_STATE_A_IDLE;  		MUSB_HST_MODE(musb);  		break; @@ -2009,7 +2063,6 @@ void musb_g_disconnect(struct musb *musb)  		break;  	case OTG_STATE_B_WAIT_ACON:  	case OTG_STATE_B_HOST: -#endif  	case OTG_STATE_B_PERIPHERAL:  	case OTG_STATE_B_IDLE:  		musb->xceiv->state = OTG_STATE_B_IDLE; @@ -2029,10 +2082,9 @@ __acquires(musb->lock)  	u8		devctl = musb_readb(mbase, MUSB_DEVCTL);  	u8		power; -	DBG(3, "<== %s addr=%x driver '%s'\n", +	dev_dbg(musb->controller, "<== %s driver '%s'\n",  			(devctl & MUSB_DEVCTL_BDEVICE)  				? "B-Device" : "A-Device", -			musb_readb(mbase, MUSB_FADDR),  			musb->gadget_driver  				? musb->gadget_driver->driver.name  				: NULL @@ -2067,16 +2119,22 @@ __acquires(musb->lock)  	/* Normal reset, as B-Device;  	 * or else after HNP, as A-Device  	 */ -	if (devctl & MUSB_DEVCTL_BDEVICE) { +	if (!musb->g.is_otg) { +		/* USB device controllers that are not OTG compatible +		 * may not have DEVCTL register in silicon. +		 * In that case, do not rely on devctl for setting +		 * peripheral mode. +		 */ +		musb->xceiv->state = OTG_STATE_B_PERIPHERAL; +		musb->g.is_a_peripheral = 0; +	} else if (devctl & MUSB_DEVCTL_BDEVICE) {  		musb->xceiv->state = OTG_STATE_B_PERIPHERAL;  		musb->g.is_a_peripheral = 0; -	} else if (is_otg_enabled(musb)) { +	} else {  		musb->xceiv->state = OTG_STATE_A_PERIPHERAL;  		musb->g.is_a_peripheral = 1; -	} else -		WARN_ON(1); +	}  	/* start with default limits on VBUS power draw */ -	(void) musb_gadget_vbus_draw(&musb->g, -			is_otg_enabled(musb) ? 8 : 100); +	(void) musb_gadget_vbus_draw(&musb->g, 8);  }  | 
