[linux-yocto] [PATCH 80/94] usb: Cleanup USB host controller driver ehci-ci13612

Paul Butler butler.paul at gmail.com
Thu Nov 7 17:13:34 PST 2013


From: Anders Berg <anders.berg at lsi.com>

Fixed a number of issues;
 * Don't use CONFIG_LSI_USB_SW_WORKAROUND for stuff other than name suggests.
 * Remove unnecessary ifdefs in probe function.
 * Remove hard coded IRQ number.
 * Check for correct return value from platform_get_irq()

Signed-off-by: Anders Berg <anders.berg at lsi.com>
---
 drivers/usb/host/ehci-ci13612.c | 157 +++++++++++++++++-----------------------
 drivers/usb/host/ehci-ci13612.h |   2 +-
 2 files changed, 67 insertions(+), 92 deletions(-)

diff --git a/drivers/usb/host/ehci-ci13612.c b/drivers/usb/host/ehci-ci13612.c
index 164c5e2..68ac2f4 100644
--- a/drivers/usb/host/ehci-ci13612.c
+++ b/drivers/usb/host/ehci-ci13612.c
@@ -46,7 +46,7 @@ static void ci13612_usb_setup(struct usb_hcd *hcd)
 	 * TXFIFOTHRES * VUSB_HS_TX_BURST >= MAXIMUM PACKET SIZE of packet
 	 * relationship.
 	 */
-	VUSB_HS_TX_BURST = inl(USB_HWTXBUF) & 0x0f;
+	VUSB_HS_TX_BURST = readl(USB_HWTXBUF) & 0x0f;
 	USB_TXFIFOTHRES = (32 << 16);
 	txfulltuning = (txfulltuning  & 0xffc0ffff) | USB_TXFIFOTHRES;
 	writel(txfulltuning, (void __iomem *)USB_TXFILLTUNING);
@@ -117,78 +117,85 @@ static int ci13612_ehci_init(struct usb_hcd *hcd)
 	return retval;
 }
 
-static int ehci_run_fix(struct usb_hcd *hcd)
-{
-	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 #ifdef CONFIG_LSI_USB_SW_WORKAROUND
+/*
+ * ci13612_fixup_usbcmd_rs
+ *
+ * Fix HW errata 0003256: Do not enable USBCMD.RS for some time after the USB
+ * reset has been completed (PORTSCx.PR=0). This ensures that the host does not
+ * send the SOF until the ULPI post reset processing has been completed. Note:
+ * This workaround reduces the likelihood of this problem occuring, but it may
+ * not entirely eliminate it.
+ */
+static int
+ci13612_fixup_usbcmd_rs(struct ehci_hcd *ehci)
+{
 	u32 port_status;
-#endif
-	unsigned burst_size;
-	int retval;
-	unsigned usb_cmd;
 
-#ifdef CONFIG_LSI_USB_SW_WORKAROUND
-	/* Fix HW errata 0003256: Do not enable USBCMD.RS for some time after
-	 * the USB reset has been completed (PORTSCx.PR=0). This ensures that
-	 * the host does not send the SOF until the ULPI post reset processing
-	 * has been completed. Note: This workaround reduces the likelihood of
-`	 * this problem occuring, but it may not entirely eliminate it.
-	 */
 	port_status = ehci_readl(ehci, &ehci->regs->port_status[0]);
-	printk(KERN_INFO "ehci_run: port_status = 0x%x\n", port_status);
+	pr_info("ehci-ci13612: port_status = 0x%x\n", port_status);
 	if (port_status & 0x100) {
-		printk(KERN_ERR
-		       "USB port is in reset status, not able to change"
-			"host controller status to run\n");
+		pr_err("ehci-ci13612: USB port is in reset status, "
+		       "not able to change HC status to run\n");
 		return -EFAULT;
 	}
+	return 0;
+}
+#else
+#define ci13612_fixup_usbcmd_rs(_ehci) (0)
+#endif
 
-	retval = ehci_run(hcd);
-	if (retval)
-		return retval;
 
-    /* Fix for HW errata 9000373951: You can adjust the burst size and fill the
-     * level to minimize under-run possibilities. In the failing case, the
-     * transfer size was 96 bytes, the burst size was 16, and the fill
-     * threshold level was set to 2. Because of this, the Host core issued
-     * the Out token when it requested the second burst of data. If the
-     * burst size had been changed to 8, and the fill level set to 3,
-     * then the core would have pre-fetched the 96 bytes before issuing
-     * the OUT token.
-     */
-	burst_size = ehci_readl(ehci, &ehci->regs->reserved[1]);
-	burst_size = (burst_size & 0xffff00ff) | 0x4000;	/* TXPBURST */
-	ehci_writel(ehci, burst_size, &ehci->regs->reserved[1]);
+#ifdef CONFIG_LSI_USB_SW_WORKAROUND
+/*
+ * ci13612_fixup_txpburst
+ *
+ * Fix for HW errata 9000373951: You can adjust the burst size and fill the
+ * level to minimize under-run possibilities. In the failing case, the transfer
+ * size was 96 bytes, the burst size was 16, and the fill threshold level was
+ * set to 2. Because of this, the Host core issued the Out token when it
+ * requested the second burst of data. If the burst size had been changed to 8,
+ * and the fill level set to 3, then the core would have pre-fetched the 96
+ * bytes before issuing the OUT token.
+ */
+static void
+ci13612_fixup_txpburst(struct ehci_hcd *ehci)
+{
+	unsigned burst_size;
 
-#else
-    /* Fix for HW errata 9000373951: You can adjust the burst size and fill the
-     * level to minimize under-run possibilities. In the failing case, the
-     * transfer size was 96 bytes, the burst size was 16, and the fill
-     * threshold level was set to 2. Because of this, the Host core issued
-     * the Out token when it requested the second burst of data. If the
-     * burst size had been changed to 8, and the fill level set to 3,
-     * then the core would have pre-fetched the 96 bytes before issuing
-     * the OUT token.
-     */
 	burst_size = ehci_readl(ehci, &ehci->regs->reserved[1]);
 	burst_size = (burst_size & 0xffff00ff) | 0x4000;	/* TXPBURST */
 	ehci_writel(ehci, burst_size, &ehci->regs->reserved[1]);
+}
+#else
+#define ci13612_fixup_txpburst(ehci) do { (void)ehci; } while(0)
+#endif
 
-	/* Set the SBUSCFG[2:0] to 3 (AHBBRST3) */
-	writel(0x3, (void __iomem *)USB_SBUSCFG);
+static int ci13612_ehci_run(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+	u32 tmp;
 
-	retval = ehci_run(hcd);
+	retval = ci13612_fixup_usbcmd_rs(ehci);
+	if (retval)
+		return retval;
 
-	/* Performance tweaking */
-	/* Clear ITC field 23:16 to zero */
-	usb_cmd = inl(USB_USBCMD) & 0xFF00FFFF;
-	writel(usb_cmd, (void __iomem *)USB_USBCMD);
+	/* Setup AMBA interface to force INCR16 busts when possible */
+	writel(3, USB_SBUSCFG);
 
+	retval = ehci_run(hcd);
 	if (retval)
 		return retval;
-#endif
 
-	return 0;
+	ci13612_fixup_txpburst(ehci);
+
+	/* Set ITC (bits [23:16]) to zero for interrupt on every micro-frame */
+	tmp = ehci_readl(ehci, &ehci->regs->command);
+	tmp &= 0xFFFF;
+	ehci_writel(ehci, tmp & 0xFFFF, &ehci->regs->command);
+
+	return retval;
 }
 
 static const struct hc_driver ci13612_hc_driver = {
@@ -198,7 +205,7 @@ static const struct hc_driver ci13612_hc_driver = {
 	.irq			= ehci_irq,
 	.flags			= HCD_MEMORY | HCD_USB2,
 	.reset			= ci13612_ehci_init,
-	.start			= ehci_run_fix,
+	.start			= ci13612_ehci_run,
 	.stop			= ehci_stop,
 	.shutdown		= ehci_shutdown,
 	.urb_enqueue		= ehci_urb_enqueue,
@@ -217,46 +224,19 @@ static const struct hc_driver ci13612_hc_driver = {
 
 static int ci13612_ehci_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct usb_hcd *hcd;
-	const struct hc_driver *driver = &ci13612_hc_driver;
 	void __iomem *gpreg_base;
 	int irq;
 	int retval;
-	struct device_node *np = pdev->dev.of_node;
 	struct resource *res;
 
-#ifdef CONFIG_LSI_USB_SW_WORKAROUND
-
-      /* Check if device is enabled */
-	if (!of_device_is_available(np)) {
-		printk(KERN_INFO "%s: Port disabled via device-tree\n",
-			np->full_name);
-		return -ENODEV;
-	}
-
 	if (usb_disabled())
 		return -ENODEV;
 
-	/* Map the irq in the PPC476 to get the irq number */
 	irq = platform_get_irq(pdev, 0);
-
-	if (NO_IRQ == irq) {
-		dev_dbg(&pdev->dev, "error getting irq number\n");
-		retval = -EBUSY;
-		goto fail_create_hcd;
-	}
-
-	if (0 != irq_set_irq_type(87, IRQ_TYPE_LEVEL_HIGH)) {
-		dev_dbg(&pdev->dev, "set_irq_type() failed\n");
-		retval = -EBUSY;
-		goto fail_create_hcd;
-	}
-#else
-
-	irq = irq_of_parse_and_map(np, 0);
-	if (NO_IRQ == irq) {
-		dev_dbg(&pdev->dev, "error getting irq number\n");
-		retval = -EBUSY;
+	if (irq < 0) {
+		retval = irq;
 		goto fail_create_hcd;
 	}
 
@@ -266,9 +246,6 @@ static int ci13612_ehci_probe(struct platform_device *pdev)
 		goto fail_create_hcd;
 	}
 
-#endif
-
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "Error: resource addr %s setup!\n",
@@ -280,13 +257,12 @@ static int ci13612_ehci_probe(struct platform_device *pdev)
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
-	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = usb_create_hcd(&ci13612_hc_driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd) {
 		retval = -ENOMEM;
 		goto fail_create_hcd;
 	}
 
-
 	hcd->rsrc_start = res->start;
 	hcd->rsrc_len = resource_size(res);
 
@@ -297,7 +273,6 @@ static int ci13612_ehci_probe(struct platform_device *pdev)
 		goto fail_put_hcd;
 	}
 
-
 	gpreg_base = of_iomap(np, 1);
 	if (!gpreg_base) {
 		dev_warn(&pdev->dev, "of_iomap error can't map region 1\n");
@@ -313,7 +288,7 @@ static int ci13612_ehci_probe(struct platform_device *pdev)
 		iounmap(gpreg_base);
 	}
 
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	retval = usb_add_hcd(hcd, irq, 0);
 	if (retval == 0) {
 		platform_set_drvdata(pdev, hcd);
 		return retval;
diff --git a/drivers/usb/host/ehci-ci13612.h b/drivers/usb/host/ehci-ci13612.h
index b257cf7..7785bdd 100644
--- a/drivers/usb/host/ehci-ci13612.h
+++ b/drivers/usb/host/ehci-ci13612.h
@@ -3,7 +3,7 @@
  */
 
 /* define CI13612 USB registers here */
-#define CI13612_USB_BASE	((unsigned) hcd->regs)
+#define CI13612_USB_BASE	(hcd->regs)
 
 #define USB_ID			(CI13612_USB_BASE + 0x0000)
 #define USB_HWGENERAL		(CI13612_USB_BASE + 0x0004)
-- 
1.8.3.4




More information about the linux-yocto mailing list