static void msm7201_shutdown_phy(struct usb_hcd *hcd) { struct msm7201_usb_priv *msm7201 = hcd_to_msm7201(hcd); if (msm7201->phy_shutdown) msm7201->phy_shutdown(); /* disable interface protect circuit to drop current consumption */ ulpi_write(hcd, (1 << 7), 0x08); /* clear the SuspendM bit -> suspend the PHY */ ulpi_write(hcd, ULPI_FUNC_SUSPENDM, ULPI_FUNC_CTRL_CLR); }
static void msm7201_setup_phy(struct usb_hcd *hcd) { struct msm7201_usb_priv *msm7201 = hcd_to_msm7201(hcd); int *seq = msm7201->phy_init_seq; if (!seq) return; while (seq[0] >= 0) { ulpi_write(hcd, seq[0], seq[1]); seq += 2; } }
/** * usb_hcd_msm7201_remove - shutdown processing for MSM7201-based HCDs * @pdev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_msm7201_probe(). * */ static int usb_hcd_msm7201_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct msm7201_usb_priv *msm7201 = hcd_to_msm7201(hcd); usb_remove_hcd(hcd); msm7201_shutdown_phy(hcd); clk_put(msm7201->clk); clk_put(msm7201->pclk); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); return 0; }
static void msm7201_usb_setup(struct usb_hcd *hcd) { struct msm7201_usb_priv *msm7201 = hcd_to_msm7201(hcd); #ifdef CONFIG_ARCH_QSD8X50 /* bursts of unspecified length. */ writel(0x0, USB_AHBBURST); /* Use the AHB transactor */ writel(0x0, USB_AHBMODE); #else /* INCR8 BURST mode */ writel(0x02, USB_SBUSCFG); /*boost performance to fix CRC error.*/ #endif /* select ULPI phy */ writel(0x80000000, USB_PORTSC); if (msm7201->phy_reset) msm7201->phy_reset(); msm7201_setup_phy(hcd); }
/** * usb_hcd_msm7201_probe - initialize MSM7201-based HCDs * @pdev: USB Host Controller being probed * Context: !in_interrupt() * * Allocates basic resources for this USB host controller. * */ static int usb_hcd_msm7201_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct msm7201_usb_priv *msm7201; int irq; int retval; const struct hc_driver *driver = &ehci_msm7201_hc_driver; struct msm_hsusb_platform_data *pdata = pdev->dev.platform_data; pr_debug("usb_hcd_msm7201_probe()\n"); if (usb_disabled()) return -ENODEV; pr_debug("initializing MSM7201/QSD8X50/MSM7227 USB Controller\n"); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "irq < 0. Check %s setup!\n", dev_name(&pdev->dev)); return -ENODEV; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err1; } msm7201 = hcd_to_msm7201(hcd); if (pdata) { msm7201->phy_reset = pdata->phy_reset; #ifndef CONFIG_ARCH_QSD8X50 /// msm7201->phy_shutdown = pdata->phy_shutdown; #endif /// msm7201->phy_init_seq = pdata->phy_init_seq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no register addr. Check %s setup!\n", dev_name(&pdev->dev)); retval = -ENODEV; goto err2; } hcd->rsrc_start = res->start; hcd->rsrc_len = res->end - res->start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, driver->description)) { dev_dbg(&pdev->dev, "controller already in use\n"); retval = -EBUSY; goto err2; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_dbg(&pdev->dev, "error mapping memory\n"); retval = -EFAULT; goto err3; } msm7201->clk = clk_get(&pdev->dev, "usb_hs_clk"); if (IS_ERR(msm7201->clk)) { dev_dbg(&pdev->dev, "error getting usb_hs_clk\n"); retval = -EFAULT; goto err4; } msm7201->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); if (IS_ERR(msm7201->pclk)) { dev_dbg(&pdev->dev, "error getting usb_hs_pclk\n"); retval = -EFAULT; goto err5; } clk_enable(msm7201->clk); clk_enable(msm7201->pclk); /* wait for a while after enable usb clk*/ msleep(5); /* clear interrupts before requesting irq */ writel(0, USB_USBINTR); writel(0, USB_OTGSC); disable_irq(irq); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); enable_irq(irq); // Unbalanced (?) /* enable interrupts */ writel(STS_URI | STS_SLI | STS_UI | STS_PCI, USB_USBINTR); if (retval != 0) goto err6; return retval; err6: clk_put(msm7201->pclk); err5: clk_put(msm7201->clk); err4: iounmap(hcd->regs); err3: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); return retval; }