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

Commit 8f182e5d authored by Darius Augulis's avatar Darius Augulis Committed by Greg Kroah-Hartman
Browse files

USB: imx_udc: Fix IMX UDC gadget bugs



Fix small bugs and add some omptimization in IMX UDC Gadget.

Signed-off-by: default avatarDarius Augulis <augulis.darius@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 664d5df9
Loading
Loading
Loading
Loading
+19 −14
Original line number Original line Diff line number Diff line
@@ -283,7 +283,7 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
	imx_flush(imx_ep);
	imx_flush(imx_ep);


	/* Special care for ep0 */
	/* Special care for ep0 */
	if (EP_NO(imx_ep)) {
	if (!EP_NO(imx_ep)) {
		temp = __raw_readl(imx_usb->base + USB_CTRL);
		temp = __raw_readl(imx_usb->base + USB_CTRL);
		__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
		__raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
		do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
		do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
@@ -301,7 +301,7 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
	 			break;
	 			break;
	 		udelay(20);
	 		udelay(20);
	 	}
	 	}
		if (i == 50)
		if (i == 100)
			D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
			D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
				__func__, imx_ep->ep.name);
				__func__, imx_ep->ep.name);
	}
	}
@@ -539,10 +539,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
	struct imx_request *req = NULL;
	struct imx_request *req = NULL;
	int ret = 0;
	int ret = 0;


	if (!list_empty(&imx_ep->queue))
	if (!list_empty(&imx_ep->queue)) {
		req = list_entry(imx_ep->queue.next, struct imx_request, queue);
		req = list_entry(imx_ep->queue.next, struct imx_request, queue);


	if (req) {
		switch (imx_ep->imx_usb->ep0state) {
		switch (imx_ep->imx_usb->ep0state) {


		case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR */
		case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR */
@@ -561,6 +560,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
		}
		}
	}
	}


	else
		D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
						__func__, imx_ep->ep.name);

	return ret;
	return ret;
}
}


@@ -759,7 +762,7 @@ static int imx_ep_queue
	*/
	*/
	if (imx_usb->set_config && !EP_NO(imx_ep)) {
	if (imx_usb->set_config && !EP_NO(imx_ep)) {
		imx_usb->set_config = 0;
		imx_usb->set_config = 0;
		D_EPX(imx_usb->dev,
		D_ERR(imx_usb->dev,
			"<%s> gadget reply set config\n", __func__);
			"<%s> gadget reply set config\n", __func__);
		return 0;
		return 0;
	}
	}
@@ -779,8 +782,6 @@ static int imx_ep_queue
		return -ESHUTDOWN;
		return -ESHUTDOWN;
	}
	}


	local_irq_save(flags);

	/* Debug */
	/* Debug */
	D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
	D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
		__func__, EP_NO(imx_ep),
		__func__, EP_NO(imx_ep),
@@ -790,17 +791,18 @@ static int imx_ep_queue


	if (imx_ep->stopped) {
	if (imx_ep->stopped) {
		usb_req->status = -ESHUTDOWN;
		usb_req->status = -ESHUTDOWN;
		ret = -ESHUTDOWN;
		return -ESHUTDOWN;
		goto out;
	}
	}


	if (req->in_use) {
	if (req->in_use) {
		D_ERR(imx_usb->dev,
		D_ERR(imx_usb->dev,
			"<%s> refusing to queue req %p (already queued)\n",
			"<%s> refusing to queue req %p (already queued)\n",
			__func__, req);
			__func__, req);
		goto out;
		return 0;
	}
	}


	local_irq_save(flags);

	usb_req->status = -EINPROGRESS;
	usb_req->status = -EINPROGRESS;
	usb_req->actual = 0;
	usb_req->actual = 0;


@@ -810,7 +812,7 @@ static int imx_ep_queue
		ret = handle_ep0(imx_ep);
		ret = handle_ep0(imx_ep);
	else
	else
		ret = handle_ep(imx_ep);
		ret = handle_ep(imx_ep);
out:

	local_irq_restore(flags);
	local_irq_restore(flags);
	return ret;
	return ret;
}
}
@@ -1010,10 +1012,8 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
				dump_usb_stat(__func__, imx_usb);
				dump_usb_stat(__func__, imx_usb);
	}
	}


	if (!imx_usb->driver) {
	if (!imx_usb->driver)
		/*imx_udc_disable(imx_usb);*/
		goto end_irq;
		goto end_irq;
	}


	if (intr & INTR_WAKEUP) {
	if (intr & INTR_WAKEUP) {
		if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
		if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
@@ -1095,6 +1095,11 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
	}
	}


	if (intr & INTR_SOF) {
	if (intr & INTR_SOF) {
		/* Copy from Freescale BSP.
		   We must enable SOF intr and set CMDOVER.
		   Datasheet don't specifiy this action, but it
		   is done in Freescale BSP, so just copy it.
		*/
		if (imx_usb->ep0state == EP0_IDLE) {
		if (imx_usb->ep0state == EP0_IDLE) {
			temp = __raw_readl(imx_usb->base + USB_CTRL);
			temp = __raw_readl(imx_usb->base + USB_CTRL);
			__raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
			__raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
+1 −1
Original line number Original line Diff line number Diff line
@@ -170,7 +170,7 @@ struct imx_udc_struct {
/* #define DEBUG_IRQ */
/* #define DEBUG_IRQ */
/* #define DEBUG_EPIRQ */
/* #define DEBUG_EPIRQ */
/* #define DEBUG_DUMP */
/* #define DEBUG_DUMP */
#define DEBUG_ERR
/* #define DEBUG_ERR */


#ifdef DEBUG_REQ
#ifdef DEBUG_REQ
	#define D_REQ(dev, args...)	dev_dbg(dev, ## args)
	#define D_REQ(dev, args...)	dev_dbg(dev, ## args)