Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7a5100b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge branch 'for-greg' of git://gitorious.org/usb/usb into work

parents 82442723 07a8cdd2
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
	 */
	 */


	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
		if (hcd->self.uses_pio_for_control)
			return ret;
		if (hcd->self.uses_dma) {
		if (hcd->self.uses_dma) {
			urb->setup_dma = dma_map_single(
			urb->setup_dma = dma_map_single(
					hcd->self.controller,
					hcd->self.controller,
+3 −0
Original line number Original line Diff line number Diff line
@@ -2116,12 +2116,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
	 * Otherwise, wait till the gadget driver hooks up.
	 * Otherwise, wait till the gadget driver hooks up.
	 */
	 */
	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
		struct usb_hcd	*hcd = musb_to_hcd(musb);

		MUSB_HST_MODE(musb);
		MUSB_HST_MODE(musb);
		musb->xceiv->default_a = 1;
		musb->xceiv->default_a = 1;
		musb->xceiv->state = OTG_STATE_A_IDLE;
		musb->xceiv->state = OTG_STATE_A_IDLE;


		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);


		hcd->self.uses_pio_for_control = 1;
		DBG(1, "%s mode, status %d, devctl %02x %c\n",
		DBG(1, "%s mode, status %d, devctl %02x %c\n",
			"HOST", status,
			"HOST", status,
			musb_readb(musb->mregs, MUSB_DEVCTL),
			musb_readb(musb->mregs, MUSB_DEVCTL),
+86 −38
Original line number Original line Diff line number Diff line
@@ -92,6 +92,59 @@


/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */


/* Maps the buffer to dma  */

static inline void map_dma_buffer(struct musb_request *request,
				struct musb *musb)
{
	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;
	}
}

/* Unmap the buffer from dma and maps it back to cpu */
static inline void unmap_dma_buffer(struct musb_request *request,
				struct musb *musb)
{
	if (request->request.dma == DMA_ADDR_INVALID) {
		DBG(20, "not unmapping a never mapped buffer\n");
		return;
	}
	if (request->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;
		request->mapped = 0;
	} else {
		dma_sync_single_for_cpu(musb->controller,
			request->request.dma,
			request->request.length,
			request->tx
				? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);

	}
}

/*
/*
 * Immediately complete a request.
 * Immediately complete a request.
 *
 *
@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)


	ep->busy = 1;
	ep->busy = 1;
	spin_unlock(&musb->lock);
	spin_unlock(&musb->lock);
	if (is_dma_capable()) {
	if (is_dma_capable() && ep->dma)
		if (req->mapped) {
		unmap_dma_buffer(req, musb);
			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 (request->status == 0)
	if (request->status == 0)
		DBG(5, "%s done request %p,  %d/%d\n",
		DBG(5, "%s done request %p,  %d/%d\n",
				ep->end_point.name, request,
				ep->end_point.name, request,
@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
#endif
#endif


	if (!use_dma) {
	if (!use_dma) {
		/*
		 * Unmap the dma buffer back to cpu if dma channel
		 * programming fails
		 */
		if (is_dma_capable() && musb_ep->dma)
			unmap_dma_buffer(req, musb);

		musb_write_fifo(musb_ep->hw_ep, fifo_count,
		musb_write_fifo(musb_ep->hw_ep, fifo_count,
				(u8 *) (request->buf + request->actual));
				(u8 *) (request->buf + request->actual));
		request->actual += fifo_count;
		request->actual += fifo_count;
@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
					return;
					return;
			}
			}
#endif
#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_dma_capable() && musb_ep->dma) {
				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 *)
			musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
					(request->buf + request->actual));
					(request->buf + request->actual));
@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
		if (!request)
		if (!request)
			return;
			return;
	}
	}
#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
exit:
exit:
#endif
	/* Analyze request */
	/* Analyze request */
	rxstate(musb, to_musb_request(request));
	rxstate(musb, to_musb_request(request));
}
}
@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
	request->epnum = musb_ep->current_epnum;
	request->epnum = musb_ep->current_epnum;
	request->tx = musb_ep->is_in;
	request->tx = musb_ep->is_in;


	if (is_dma_capable() && musb_ep->dma) {
	if (is_dma_capable() && musb_ep->dma)
		if (request->request.dma == DMA_ADDR_INVALID) {
		map_dma_buffer(request, musb);
			request->request.dma = dma_map_single(
	else
					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;
		request->mapped = 0;


	spin_lock_irqsave(&musb->lock, lockflags);
	spin_lock_irqsave(&musb->lock, lockflags);
@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
		spin_unlock_irqrestore(&musb->lock, flags);
		spin_unlock_irqrestore(&musb->lock, flags);


		if (is_otg_enabled(musb)) {
		if (is_otg_enabled(musb)) {
			struct usb_hcd	*hcd = musb_to_hcd(musb);

			DBG(3, "OTG startup...\n");
			DBG(3, "OTG startup...\n");


			/* REVISIT:  funcall to other code, which also
			/* REVISIT:  funcall to other code, which also
@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
				musb->gadget_driver = NULL;
				musb->gadget_driver = NULL;
				musb->g.dev.driver = NULL;
				musb->g.dev.driver = NULL;
				spin_unlock_irqrestore(&musb->lock, flags);
				spin_unlock_irqrestore(&musb->lock, flags);
			} else {
				hcd->self.uses_pio_for_control = 1;
			}
			}
		}
		}
	}
	}
+4 −0
Original line number Original line Diff line number Diff line
@@ -313,6 +313,10 @@ struct usb_bus {
	int busnum;			/* Bus number (in order of reg) */
	int busnum;			/* Bus number (in order of reg) */
	const char *bus_name;		/* stable id (PCI slot_name etc) */
	const char *bus_name;		/* stable id (PCI slot_name etc) */
	u8 uses_dma;			/* Does the host controller use DMA? */
	u8 uses_dma;			/* Does the host controller use DMA? */
	u8 uses_pio_for_control;	/*
					 * Does the host controller use PIO
					 * for control transfers?
					 */
	u8 otg_port;			/* 0, or number of OTG/HNP port */
	u8 otg_port;			/* 0, or number of OTG/HNP port */
	unsigned is_b_host:1;		/* true during some HNP roleswitches */
	unsigned is_b_host:1;		/* true during some HNP roleswitches */
	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */