From: Anders Berg <anders.b...@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.b...@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.4.3 _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto