static int xhci_dwc_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_phy *usb_phy; struct xhci_hcd *xhci = hcd_to_xhci(hcd); usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); otg_set_host(usb_phy->otg, NULL); usb_put_phy(usb_phy); if (xhci) dwc3_stop_host(hcd); usb_put_hcd(hcd); pm_runtime_disable(hcd->self.controller); pm_runtime_set_suspended(hcd->self.controller); wake_lock_destroy(&dwc3_xhci.wakelock); return 0; }
/** * ohci_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of ohci_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static int ohci_hcd_omap_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); dev_dbg(hcd->self.controller, "stopping USB Controller\n"); usb_remove_hcd(hcd); omap_ohci_clock_power(0); if (!IS_ERR_OR_NULL(hcd->usb_phy)) { (void) otg_set_host(hcd->usb_phy->otg, 0); usb_put_phy(hcd->usb_phy); } if (machine_is_omap_osk()) gpio_free(9); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); clk_put(usb_dc_ck); clk_put(usb_host_ck); return 0; }
static int xhci_plat_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); usb_remove_hcd(hcd); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); kfree(xhci); if (phy && phy->otg) { otg_set_host(phy->otg, NULL); usb_put_transceiver(phy); } return 0; }
/** * musb_platform_set_mode() - Set the mode for the USB driver. * @musb: struct musb pointer. * @musb_mode: usb mode. * * This function set the mode for the USB. */ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) { u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); devctl |= MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); switch (musb_mode) { case MUSB_HOST: otg_set_host(musb->xceiv, musb->xceiv->host); break; case MUSB_PERIPHERAL: otg_set_peripheral(musb->xceiv, musb->xceiv->gadget); break; case MUSB_OTG: break; default: return -EINVAL; } return 0; }
static int __devexit exynos_xhci_remove(struct platform_device *pdev) { struct exynos_xhci_hcd *exynos_xhci = platform_get_drvdata(pdev); struct usb_hcd *hcd = exynos_xhci->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); if (exynos_xhci->core->otg) otg_set_host(exynos_xhci->core->otg, NULL); pm_runtime_disable(&pdev->dev); usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); usb_remove_hcd(hcd); usb_put_hcd(hcd); kfree(xhci); return 0; }
static int mv_ehci_remove(struct platform_device *pdev) { struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_mv->hcd; if (hcd->rh_registered) usb_remove_hcd(hcd); if (!IS_ERR_OR_NULL(ehci_mv->otg)) otg_set_host(ehci_mv->otg->otg, NULL); if (ehci_mv->mode == MV_USB_MODE_HOST) { if (ehci_mv->pdata->set_vbus) ehci_mv->pdata->set_vbus(0); mv_ehci_disable(ehci_mv); } usb_put_hcd(hcd); return 0; }
/** * usb_hcd_omap_remove - shutdown processing for OMAP-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static inline void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); usb_remove_hcd(hcd); if (ohci->transceiver) { (void) otg_set_host(ohci->transceiver, 0); put_device(ohci->transceiver->dev); } #ifndef CONFIG_ARCH_OMAP34XX if (machine_is_omap_osk()) gpio_free(9); #endif iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); #ifndef CONFIG_ARCH_OMAP34XX clk_put(usb_dc_ck); clk_put(usb_host_ck); #endif }
static void msm_xusb_uninit_host(struct msmusb_hcd *mhcd) { struct usb_hcd *hcd = mhcd_to_hcd(mhcd); struct msm_usb_host_platform_data *pdata = mhcd->pdata; switch (PHY_TYPE(pdata->phy_info)) { case USB_PHY_INTEGRATED: if (pdata->vbus_init) pdata->vbus_init(0); otg_set_host(mhcd->xceiv, NULL); otg_put_transceiver(mhcd->xceiv); cancel_work_sync(&mhcd->otg_work); break; case USB_PHY_SERIAL_PMIC: iounmap(hcd->regs); clk_put(mhcd->clk); clk_put(mhcd->pclk); msm_fsusb_reset_phy(); msm_fsusb_rpc_deinit(); break; default: pr_err("phy type is bad\n"); } }
static int pxa310_start_otg_host_transcvr(struct usb_bus *host) { int err; pxa310_otg_transceiver_rtsm(); err = usb_phy_init(u2d->otg); if (err) { pr_err("OTG transceiver init failed"); return err; } err = otg_set_vbus(u2d->otg->otg, 1); if (err) { pr_err("OTG transceiver VBUS set failed"); return err; } err = otg_set_host(u2d->otg->otg, host); if (err) pr_err("OTG transceiver Host mode set failed"); return err; }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci_to_hcd(ohci)->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } } #endif omap_ohci_clock_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); omap_request_gpio(9); omap_set_gpio_direction(9, 1 /* IN */); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); distrust_firmware = 0; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static int ohci_omap_reset(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = dev_get_platdata(hcd->self.controller); int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { hcd->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ hcd->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); /* XXX OMAP16xx only */ if (config->ocpi_enable) config->ocpi_enable(); #ifdef CONFIG_USB_OTG if (need_transceiver) { hcd->phy = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(hcd->phy)) { int status = otg_set_host(hcd->phy->otg, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s phy, status %d\n", hcd->phy->label, status); if (status) { usb_put_phy(hcd->phy); return status; } } else { dev_err(hcd->self.controller, "can't find phy\n"); return -ENODEV; } ohci->start_hnp = start_hnp; } #endif omap_ohci_clock_power(1); if (cpu_is_omap15xx()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } ret = ohci_setup(hcd); if (ret < 0) return ret; if (config->otg || config->rwc) { ohci->hc_control = OHCI_CTRL_RWC; writel(OHCI_CTRL_RWC, &ohci->regs->control); } /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); gpio_request(9, "OHCI overcurrent"); gpio_direction_input(9); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); ohci->flags &= ~OHCI_QUIRK_HUB_POWER; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; struct usb_hcd *hcd; struct tegra_ehci_hcd *tegra; struct tegra_usb_platform_data *pdata; int err = 0; int irq; int instance = pdev->id; /* Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &tegra_ehci_dma_mask; pdata = dev_get_platdata(&pdev->dev); tegra = devm_kzalloc(&pdev->dev, sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) { dev_err(&pdev->dev, "memory alloc failed\n"); return -ENOMEM; } mutex_init(&tegra->sync_lock); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "unable to create HCD\n"); return -ENOMEM; } platform_set_drvdata(pdev, tegra); #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ tegra->boost_requested = false; /* Add boost enable/disable knob */ tegra->boost_enable = true; err = device_create_file(hcd->self.controller, &dev_attr_boost_enable); if (err < 0) goto fail_sysfs; #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } /* This is pretty ugly and needs to be fixed when we do only * device-tree probing. Old code relies on the platform_device * numbering that we lack for device-tree-instantiated devices. */ if (instance < 0) { switch (res->start) { case TEGRA_USB_BASE: instance = 0; break; case TEGRA_USB2_BASE: instance = 1; break; case TEGRA_USB3_BASE: instance = 2; break; default: err = -ENODEV; dev_err(&pdev->dev, "unknown usb instance\n"); goto fail_io; } } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get IRQ\n"); err = -ENODEV; goto fail_io; } tegra->irq = irq; tegra->unaligned_dma_buf_supported = pdata->unaligned_dma_buf_supported; tegra->has_hostpc = pdata->has_hostpc; tegra->phy = tegra_usb_phy_open(pdev); hcd->phy = get_usb_phy(tegra->phy); if (IS_ERR(tegra->phy)) { dev_err(&pdev->dev, "failed to open USB phy\n"); err = -ENXIO; goto fail_io; } err = tegra_usb_phy_power_on(tegra->phy); if (err) { dev_err(&pdev->dev, "failed to power on the phy\n"); goto fail_phy; } err = usb_phy_init(get_usb_phy(tegra->phy)); if (err) { dev_err(&pdev->dev, "failed to init the phy\n"); goto fail_phy; } err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_TRIGGER_HIGH); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err); goto fail_phy; } tegra->ehci = hcd_to_ehci(hcd); if (pdata->port_otg) { tegra->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, &hcd->self); } tegra_pd_add_device(&pdev->dev); pm_runtime_enable(&pdev->dev); #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ INIT_DELAYED_WORK(&tegra->boost_cpu_freq_work, tegra_ehci_boost_cpu_frequency_work); pm_qos_add_request(&tegra->boost_cpu_freq_req, PM_QOS_CPU_FREQ_MIN, PM_QOS_DEFAULT_VALUE); schedule_delayed_work(&tegra->boost_cpu_freq_work, 12000); tegra->cpu_boost_in_work = true; #endif wake_lock_init(&tegra->ehci_wake_lock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev)); return err; fail_phy: usb_phy_shutdown(get_usb_phy(tegra->phy)); fail_io: #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ device_remove_file(hcd->self.controller, &dev_attr_boost_enable); fail_sysfs: #endif usb_put_hcd(hcd); return err; }
static int msm_xusb_init_host(struct platform_device *pdev, struct msmusb_hcd *mhcd) { int ret = 0; struct msm_otg *otg; struct usb_hcd *hcd = mhcd_to_hcd(mhcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct msm_usb_host_platform_data *pdata = mhcd->pdata; switch (PHY_TYPE(pdata->phy_info)) { case USB_PHY_INTEGRATED: msm_hsusb_rpc_connect(); if (pdata->vbus_init) pdata->vbus_init(1); /* VBUS might be present. Turn off vbus */ if (pdata->vbus_power) pdata->vbus_power(pdata->phy_info, 0); INIT_WORK(&mhcd->otg_work, msm_hsusb_otg_work); mhcd->xceiv = usb_get_transceiver(); if (!mhcd->xceiv) return -ENODEV; otg = container_of(mhcd->xceiv, struct msm_otg, phy); hcd->regs = otg->regs; otg->start_host = msm_hsusb_start_host; ret = otg_set_host(mhcd->xceiv->otg, &hcd->self); ehci->transceiver = mhcd->xceiv; break; case USB_PHY_SERIAL_PMIC: hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) return -EFAULT; /* get usb clocks */ mhcd->alt_core_clk = clk_get(&pdev->dev, "alt_core_clk"); if (IS_ERR(mhcd->alt_core_clk)) { iounmap(hcd->regs); return PTR_ERR(mhcd->alt_core_clk); } mhcd->iface_clk = clk_get(&pdev->dev, "iface_clk"); if (IS_ERR(mhcd->iface_clk)) { iounmap(hcd->regs); clk_put(mhcd->alt_core_clk); return PTR_ERR(mhcd->iface_clk); } mhcd->otg_ops.request = msm_hsusb_request_host; mhcd->otg_ops.handle = (void *) mhcd; ret = msm_xusb_init_phy(mhcd); if (ret < 0) { iounmap(hcd->regs); clk_put(mhcd->alt_core_clk); clk_put(mhcd->iface_clk); } break; default: pr_err("phy type is bad\n"); } return ret; }
static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; struct usb_hcd *hcd; struct tegra_ehci_hcd *tegra; struct tegra_usb_platform_data *pdata; int err = 0; int irq; int instance = pdev->id; /* Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &tegra_ehci_dma_mask; setup_vbus_gpio(pdev); tegra = devm_kzalloc(&pdev->dev, sizeof(struct tegra_ehci_hcd), GFP_KERNEL); if (!tegra) { dev_err(&pdev->dev, "memory alloc failed\n"); return -ENOMEM; } mutex_init(&tegra->sync_lock); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "unable to create HCD\n"); return -ENOMEM; } platform_set_drvdata(pdev, tegra); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); err = -ENXIO; goto fail_io; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); err = -ENOMEM; goto fail_io; } /* This is pretty ugly and needs to be fixed when we do only * device-tree probing. Old code relies on the platform_device * numbering that we lack for device-tree-instantiated devices. */ if (instance < 0) { switch (res->start) { case TEGRA_USB_BASE: instance = 0; break; case TEGRA_USB2_BASE: instance = 1; break; case TEGRA_USB3_BASE: instance = 2; break; default: err = -ENODEV; dev_err(&pdev->dev, "unknown usb instance\n"); goto fail_phy; } } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get IRQ\n"); err = -ENODEV; goto fail_irq; } tegra->irq = irq; pdata = dev_get_platdata(&pdev->dev); tegra->unaligned_dma_buf_supported = pdata->unaligned_dma_buf_supported; tegra->has_hostpc = pdata->has_hostpc; tegra->phy = tegra_usb_phy_open(pdev); if (IS_ERR(tegra->phy)) { dev_err(&pdev->dev, "failed to open USB phy\n"); err = -ENXIO; goto fail_irq; } err = tegra_usb_phy_power_on(tegra->phy); if (err) { dev_err(&pdev->dev, "failed to power on the phy\n"); goto fail_phy; } err = usb_phy_init(get_usb_phy(tegra->phy)); if (err) { dev_err(&pdev->dev, "failed to init the phy\n"); goto fail_phy; } err = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_TRIGGER_HIGH); if (err) { dev_err(&pdev->dev, "Failed to add USB HCD, error=%d\n", err); goto fail_phy; } err = enable_irq_wake(tegra->irq); if (err < 0) { dev_warn(&pdev->dev, "Couldn't enable USB host mode wakeup, irq=%d, " "error=%d\n", irq, err); err = 0; tegra->irq = 0; } tegra->ehci = hcd_to_ehci(hcd); #ifdef CONFIG_USB_OTG_UTILS if (pdata->port_otg) { tegra->transceiver = usb_get_transceiver(); if (tegra->transceiver) otg_set_host(tegra->transceiver->otg, &hcd->self); } #endif return err; fail_phy: usb_phy_shutdown(get_usb_phy(tegra->phy)); fail_irq: iounmap(hcd->regs); fail_io: usb_put_hcd(hcd); return err; }
static int xhci_dwc_drv_probe(struct platform_device *pdev) { struct dwc_otg2 *otg; struct usb_phy *usb_phy; struct dwc_device_par *pdata; struct usb_hcd *hcd; struct resource *res; int retval = 0; int ret; if (usb_disabled()) return -ENODEV; pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ pdata = (struct dwc_device_par *)pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", dev_name(&pdev->dev)); return -ENODEV; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", dev_name(&pdev->dev)); return -ENODEV; } dwc3_xhci.otg_irqnum = res->start; hcd = usb_create_hcd(&xhci_dwc_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; return retval; } hcd->regs = pdata->io_addr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", dev_name(&pdev->dev)); return -ENODEV; } hcd->rsrc_start = res->start; hcd->rsrc_len = res->end - res->start; usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); if (usb_phy) otg_set_host(usb_phy->otg, &hcd->self); otg = container_of(usb_phy->otg, struct dwc_otg2, otg); if (otg) { otg->start_host = dwc3_start_host; otg->stop_host = dwc3_stop_host; otg->suspend_host = dwc3_suspend_host; otg->resume_host = dwc3_resume_host; } usb_put_phy(usb_phy); /* Enable wakeup irq */ hcd->has_wakeup_irq = 1; INIT_WORK(&dwc3_xhci.reset_hcd, dwc3_host_reset); INIT_WORK(&dwc3_xhci.poll_loopback, dwc3_poll_lp); wake_lock_init(&dwc3_xhci.wakelock, WAKE_LOCK_SUSPEND, "dwc3_host_wakelock"); platform_set_drvdata(pdev, hcd); pm_runtime_no_callbacks(hcd->self.controller); pm_runtime_enable(hcd->self.controller); ret = device_create_file(hcd->self.controller, &dev_attr_host_comp_test); if (ret < 0) dev_err(hcd->self.controller, "Can't register sysfs attribute: %d\n", ret); return retval; }
static int mv_ehci_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct ehci_hcd_mv *ehci_mv; struct resource *r; int clk_i, retval = -ENODEV; u32 offset; size_t size; if (!pdata) { dev_err(&pdev->dev, "missing platform_data\n"); return -ENODEV; } if (usb_disabled()) return -ENODEV; hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); if (!hcd) return -ENOMEM; size = sizeof(*ehci_mv) + sizeof(struct clk *) * pdata->clknum; ehci_mv = kzalloc(size, GFP_KERNEL); if (ehci_mv == NULL) { dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } platform_set_drvdata(pdev, ehci_mv); ehci_mv->pdata = pdata; ehci_mv->hcd = hcd; ehci_mv->clknum = pdata->clknum; for (clk_i = 0; clk_i < ehci_mv->clknum; clk_i++) { ehci_mv->clk[clk_i] = clk_get(&pdev->dev, pdata->clkname[clk_i]); if (IS_ERR(ehci_mv->clk[clk_i])) { dev_err(&pdev->dev, "error get clck \"%s\"\n", pdata->clkname[clk_i]); retval = PTR_ERR(ehci_mv->clk[clk_i]); goto err_put_clk; } } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); retval = -ENODEV; goto err_put_clk; } ehci_mv->phy_regs = ioremap(r->start, resource_size(r)); if (ehci_mv->phy_regs == 0) { dev_err(&pdev->dev, "failed to map phy I/O memory\n"); retval = -EFAULT; goto err_put_clk; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); if (!r) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); retval = -ENODEV; goto err_iounmap_phyreg; } ehci_mv->cap_regs = ioremap(r->start, resource_size(r)); if (ehci_mv->cap_regs == NULL) { dev_err(&pdev->dev, "failed to map I/O memory\n"); retval = -EFAULT; goto err_iounmap_phyreg; } retval = mv_ehci_enable(ehci_mv); if (retval) { dev_err(&pdev->dev, "init phy error %d\n", retval); goto err_iounmap_capreg; } offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; ehci_mv->op_regs = (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); hcd->rsrc_start = r->start; hcd->rsrc_len = r->end - r->start + 1; hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); if (!hcd->irq) { dev_err(&pdev->dev, "Cannot get irq."); retval = -ENODEV; goto err_disable_clk; } ehci = hcd_to_ehci(hcd); ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; ehci->regs = (struct ehci_regs *) ehci_mv->op_regs; ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { #ifdef CONFIG_USB_OTG_UTILS ehci_mv->otg = usb_get_transceiver(); if (!ehci_mv->otg) { dev_err(&pdev->dev, "unable to find transceiver\n"); retval = -ENODEV; goto err_disable_clk; } retval = otg_set_host(ehci_mv->otg->otg, &hcd->self); if (retval < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); retval = -ENODEV; goto err_put_transceiver; } /* */ mv_ehci_disable(ehci_mv); #else dev_info(&pdev->dev, "MV_USB_MODE_OTG " "must have CONFIG_USB_OTG_UTILS enabled\n"); goto err_disable_clk; #endif } else { if (pdata->set_vbus) pdata->set_vbus(1); retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (retval) { dev_err(&pdev->dev, "failed to add hcd with err %d\n", retval); goto err_set_vbus; } } if (pdata->private_init) pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs); dev_info(&pdev->dev, "successful find EHCI device with regs 0x%p irq %d" " working in %s mode\n", hcd->regs, hcd->irq, ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); return 0; err_set_vbus: if (pdata->set_vbus) pdata->set_vbus(0); #ifdef CONFIG_USB_OTG_UTILS err_put_transceiver: if (ehci_mv->otg) usb_put_transceiver(ehci_mv->otg); #endif err_disable_clk: mv_ehci_disable(ehci_mv); err_iounmap_capreg: iounmap(ehci_mv->cap_regs); err_iounmap_phyreg: iounmap(ehci_mv->phy_regs); err_put_clk: for (clk_i--; clk_i >= 0; clk_i--) clk_put(ehci_mv->clk[clk_i]); platform_set_drvdata(pdev, NULL); kfree(ehci_mv); err_put_hcd: usb_put_hcd(hcd); return retval; }
/** * usb_hcd_fsl_probe - initialize FSL-based HCDs * @drvier: Driver to be used for this HCD * @pdev: USB Host Controller being probed * Context: !in_interrupt() * * Allocates basic resources for this USB host controller. * */ int usb_hcd_fsl_probe(const struct hc_driver *driver, struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata; struct usb_hcd *hcd; struct resource *res; int irq; int retval; pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", dev_name(&pdev->dev)); return -ENODEV; } /* * This is a host mode driver, verify that we're supposed to be * in host mode. */ if (!((pdata->operating_mode == FSL_USB2_DR_HOST) || (pdata->operating_mode == FSL_USB2_MPH_HOST) || (pdata->operating_mode == FSL_USB2_DR_OTG))) { dev_err(&pdev->dev, "Non Host Mode configured for %s. Wrong driver linked.\n", dev_name(&pdev->dev)); return -ENODEV; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err1; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", dev_name(&pdev->dev)); return -ENODEV; } irq = res->start; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (pdata->operating_mode != FSL_USB2_DR_OTG) { 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; } pdata->regs = hcd->regs; /* * do platform specific init: check the clock, grab/config pins, etc. */ if (pdata->init && pdata->init(pdev)) { retval = -ENODEV; goto err3; } fsl_platform_set_host_mode(hcd); hcd->power_budget = pdata->power_budget; retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err4; if (pdata->operating_mode == FSL_USB2_DR_OTG) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); dbg("pdev=0x%p hcd=0x%p ehci=0x%p\n", pdev, hcd, ehci); ehci->transceiver = otg_get_transceiver(); dbg("ehci->transceiver=0x%p\n", ehci->transceiver); if (!ehci->transceiver) { printk(KERN_ERR "can't find transceiver\n"); retval = -ENODEV; goto err5; } retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self); if (retval) otg_put_transceiver(ehci->transceiver); } else if ((pdata->operating_mode == FSL_USB2_MPH_HOST) || \ (pdata->operating_mode == FSL_USB2_DR_HOST)) fsl_platform_set_vbus_power(pdata, 1); fsl_platform_set_ahb_burst(hcd); ehci_testmode_init(hcd_to_ehci(hcd)); return retval; err5: usb_remove_hcd(hcd); err4: iounmap(hcd->regs); err3: if (pdata->operating_mode != FSL_USB2_DR_OTG) 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); if (pdata->exit) pdata->exit(pdata->pdev); return retval; }
static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; struct tegra_hcd_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; int e = 0; int irq; unsigned int temp; struct ehci_hcd *ehci; if (!pdata) { dev_err(&pdev->dev, "platform data must be specified\n"); return -EINVAL; } WARN_ON(!pdev->dev.coherent_dma_mask || !pdev->dev.dma_mask); hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (IS_ERR_OR_NULL(hcd)) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } if (pdata->id_detect == ID_PIN_GPIO) { e = gpio_request(pdata->gpio_nr, dev_name(&pdev->dev)); if (e < 0) { dev_err(&pdev->dev, "request ID pin GPIO failed\n"); goto fail_hcd; } e = gpio_direction_input(pdata->gpio_nr); if (e < 0) { dev_err(&pdev->dev, "failed to set ID pin as input\n"); goto fail_gpio; } } INIT_WORK(&pdata->work, tegra_ehci_busy_hint_work); /* Init the tegra USB phy */ if (NvDdkUsbPhyOpen(s_hRmGlobal, pdata->instance, &pdata->hUsbPhy) != NvSuccess) { dev_err(&pdev->dev, "failed to open USB phy DDK\n"); e = -ENODEV; goto fail_gpio; } tegra_ehci_power_up(hcd); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); e = -ENXIO; goto fail_phy; } if (!pdata->otg_mode) { res = request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev)); if (!res) { dev_err(&pdev->dev, "resource in use\n"); e = -EBUSY; goto fail_phy; } } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(res->start, resource_size(res)); if (!hcd->regs) { e = -ENOMEM; goto fail_mem; } /* Set to Host mode by setting bit 0-1 of USB device mode register */ temp = readl(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET); writel((temp | TEGRA_USB_USBMODE_HOST), (hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET)); irq = platform_get_irq(pdev, 0); if (!irq) { e = -ENODEV; goto fail_iomap; } set_irq_flags(irq, IRQF_VALID); ehci = hcd_to_ehci(hcd); INIT_WORK(&ehci->irq_work, tegra_ehci_irq_work); e = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (e != 0) { dev_err(&pdev->dev, "failed to add HCD\n"); goto fail_iomap; } platform_set_drvdata(pdev, hcd); #ifdef CONFIG_DMABOUNCE e = dmabounce_register_dev(&pdev->dev, 1024, 32768); if (e != 0) { dev_err(&pdev->dev, "failed to register DMA bounce\n"); goto fail_add; } #endif #ifdef CONFIG_USB_OTG_UTILS if (pdata->otg_mode) { ehci->transceiver = otg_get_transceiver(); if (!ehci->transceiver) { dev_err(&pdev->dev, "Failed to get OTG transceiver\n"); e = -ENODEV; goto fail_dmabounce; } otg_set_host(ehci->transceiver, (struct usb_bus *)hcd); /* Stop the controller and power down the phy, OTG will * start the host driver based on the ID pin * detection */ ehci_halt(ehci); /* reset the host and put the controller in idle mode */ temp = ehci_readl(ehci, &ehci->regs->command); temp |= CMD_RESET; ehci_writel(ehci, temp, &ehci->regs->command); temp = readl(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET); writel((temp & ~TEGRA_USB_USBMODE_HOST), (hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET)); /* indicate hcd flags, that hardware is not accessable now * in host mode*/ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); tegra_ehci_power_down(hcd); ehci->host_reinited = 0; } else #endif { if (pdata->id_detect == ID_PIN_CABLE_ID) { /* enable the cable ID interrupt */ temp = readl(hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); temp |= TEGRA_USB_ID_INT_ENABLE; temp |= TEGRA_USB_ID_PIN_WAKEUP_ENABLE; writel(temp, (hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET)); /* Check if we detect any device connected */ if (temp & TEGRA_USB_ID_PIN_STATUS) { tegra_ehci_power_down(hcd); } else { tegra_ehci_power_up(hcd); } } } return 0; fail_dmabounce: #ifdef CONFIG_DMABOUNCE dmabounce_unregister_dev(&pdev->dev); #endif fail_add: usb_remove_hcd(hcd); fail_iomap: iounmap(hcd->regs); fail_mem: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); fail_phy: NvDdkUsbPhyClose(pdata->hUsbPhy); fail_gpio: if (pdata->gpio_nr) gpio_free(pdata->gpio_nr); fail_hcd: usb_put_hcd(hcd); return e; }
static int msm_xusb_init_host(struct msmusb_hcd *mhcd) { int ret = 0; struct msm_otg *otg; struct usb_hcd *hcd = mhcd_to_hcd(mhcd); struct msm_usb_host_platform_data *pdata = mhcd->pdata; struct device *dev = container_of((void *)hcd, struct device, platform_data); switch (PHY_TYPE(pdata->phy_info)) { case USB_PHY_INTEGRATED: msm_hsusb_rpc_connect(); if (pdata->vbus_init) pdata->vbus_init(1); if (pdata->vbus_power) pdata->vbus_power(pdata->phy_info, 0); INIT_WORK(&mhcd->otg_work, msm_hsusb_otg_work); mhcd->xceiv = otg_get_transceiver(); if (!mhcd->xceiv) return -ENODEV; otg = container_of(mhcd->xceiv, struct msm_otg, otg); hcd->regs = otg->regs; otg->start_host = msm_hsusb_start_host; ret = otg_set_host(mhcd->xceiv, &hcd->self); break; case USB_PHY_SERIAL_PMIC: hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) return -EFAULT; mhcd->clk = clk_get(dev, "usb_hs2_clk"); if (IS_ERR(mhcd->clk)) { iounmap(hcd->regs); return PTR_ERR(mhcd->clk); } mhcd->pclk = clk_get(dev, "usb_hs2_pclk"); if (IS_ERR(mhcd->pclk)) { iounmap(hcd->regs); clk_put(mhcd->clk); return PTR_ERR(mhcd->pclk); } mhcd->otg_ops.request = msm_hsusb_request_host; mhcd->otg_ops.handle = (void *) mhcd; ret = msm_xusb_init_phy(mhcd); if (ret < 0) { iounmap(hcd->regs); clk_put(mhcd->clk); clk_put(mhcd->pclk); } break; default: pr_err("phy type is bad\n"); } return ret; }
/** * usb_hcd_fsl_probe - initialize FSL-based HCDs * @drvier: Driver to be used for this HCD * @pdev: USB Host Controller being probed * Context: !in_interrupt() * * Allocates basic resources for this USB host controller. * */ static int usb_hcd_fsl_probe(const struct hc_driver *driver, struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; int irq; int retval; pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", pdev->dev.bus_id); return -ENODEV; } retval = fsl_platform_verify(pdev); if (retval) return retval; /* * do platform specific init: check the clock, grab/config pins, etc. */ if (pdata->platform_init && pdata->platform_init(pdev)) { retval = -ENODEV; goto err1; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", pdev->dev.bus_id); return -ENODEV; } irq = res->start; fsl_platform_set_vbus_power(pdata, 1); hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); if (!hcd) { retval = -ENOMEM; goto err1; } hcd->rsrc_start = pdata->r_start; hcd->rsrc_len = pdata->r_len; hcd->regs = pdata->regs; vdbg("rsrc_start=0x%llx rsrc_len=0x%llx virtual=0x%x\n", hcd->rsrc_start, hcd->rsrc_len, hcd->regs); hcd->power_budget = pdata->power_budget; /* DDD * the following must be done by this point, otherwise the OTG * host port doesn't make it thru initializtion. * ehci_halt(), called by ehci_fsl_setup() returns -ETIMEDOUT */ fsl_platform_set_host_mode(hcd); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval != 0) { pr_debug("failed with usb_add_hcd\n"); goto err2; } #if defined(CONFIG_USB_OTG) if (pdata->does_otg) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); dbg("pdev=0x%p hcd=0x%p ehci=0x%p\n", pdev, hcd, ehci); ehci->transceiver = otg_get_transceiver(); dbg("ehci->transceiver=0x%p\n", ehci->transceiver); if (ehci->transceiver) { retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self); if (retval) { if (ehci->transceiver) put_device(ehci->transceiver->dev); goto err2; } } else { printk(KERN_ERR "can't find transceiver\n"); retval = -ENODEV; goto err2; } } #endif return retval; err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval); if (pdata->platform_uninit) pdata->platform_uninit(pdata); return retval; }
static int __devinit exynos_xhci_probe(struct platform_device *pdev) { struct dwc3_exynos_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; const struct hc_driver *driver = &exynos_xhci_hc_driver; struct exynos_xhci_hcd *exynos_xhci; struct usb_hcd *hcd; struct xhci_hcd *xhci; struct resource *res; int irq; int err; if (usb_disabled()) return -ENODEV; if (!pdata) { dev_err(dev, "No platform data defined\n"); return -ENODEV; } exynos_xhci = devm_kzalloc(dev, sizeof(struct exynos_xhci_hcd), GFP_KERNEL); if (!exynos_xhci) { dev_err(dev, "Not enough memory\n"); return -ENOMEM; } exynos_xhci->dev = dev; exynos_xhci->pdata = pdata; exynos_xhci->core = exynos_drd_bind(pdev); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "Failed to get IRQ\n"); return -ENXIO; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Failed to get I/O memory\n"); return -ENXIO; } /* Create and add primary HCD */ hcd = usb_create_hcd(driver, dev, dev_name(dev)); if (!hcd) { dev_err(dev, "Failed to create primary HCD\n"); return -ENOMEM; } exynos_xhci->hcd = hcd; /* Rewrite driver data with our structure */ platform_set_drvdata(pdev, exynos_xhci); hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!devm_request_mem_region(dev, res->start, resource_size(res), dev_name(dev))) { dev_err(dev, "Failed to reserve registers\n"); err = -ENOENT; goto put_hcd; } hcd->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!hcd->regs) { dev_err(dev, "Failed to remap I/O memory\n"); err = -ENOMEM; goto put_hcd; } hcd->regs -= EXYNOS_USB3_XHCI_REG_START; err = exynos_drd_try_get(pdev); if (err) { /* REVISIT: what shall we do if UDC is already running */ dev_err(dev, "Failed to access DRD\n"); goto put_hcd; } /* Wake up and initialize DRD core */ pm_runtime_get_sync(dev->parent); if (exynos_xhci->core->ops->change_mode) exynos_xhci->core->ops->change_mode(exynos_xhci->core, true); if (exynos_xhci->core->ops->core_init) exynos_xhci->core->ops->core_init(exynos_xhci->core); err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) { dev_err(dev, "Failed to add primary HCD\n"); goto put_hcd; } /* Create and add shared HCD */ xhci = hcd_to_xhci(hcd); exynos_xhci_dbg = xhci; xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev), hcd); if (!xhci->shared_hcd) { dev_err(dev, "Failed to create shared HCD\n"); err = -ENOMEM; goto remove_hcd; } xhci->shared_hcd->regs = hcd->regs; /* * Set the xHCI pointer before exynos_xhci_setup() * (aka hcd_driver.reset) is called by usb_add_hcd(). */ *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; err = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (err) { dev_err(dev, "Failed to add shared HCD\n"); goto put_usb3_hcd; } pm_runtime_set_active(dev); pm_runtime_enable(dev); if (exynos_xhci->core->otg) { err = otg_set_host(exynos_xhci->core->otg, &hcd->self); if (err) { dev_err(dev, "Unable to bind hcd to DRD switch\n"); goto remove_usb3_hcd; } } return 0; remove_usb3_hcd: pm_runtime_disable(dev); usb_remove_hcd(xhci->shared_hcd); put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); remove_hcd: usb_remove_hcd(hcd); put_hcd: usb_put_hcd(hcd); return err; }
static int ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; int ret; dev_dbg(&pdev->dev, "ehci_msm proble\n"); hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } /* * OTG driver takes care of PHY initialization, clock management, * powering up VBUS, mapping of registers address space and power * management. */ otg = otg_get_transceiver(); if (!otg) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; goto unmap; } ret = otg_set_host(otg, &hcd->self); if (ret < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); goto put_transceiver; } device_init_wakeup(&pdev->dev, 1); /* * OTG device parent of HCD takes care of putting * hardware into low power mode. */ pm_runtime_no_callbacks(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; put_transceiver: otg_put_transceiver(otg); unmap: iounmap(hcd->regs); put_hcd: usb_put_hcd(hcd); return ret; }
static int mv_ehci_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev); struct usb_hcd *hcd; struct ehci_hcd *ehci; struct ehci_hcd_mv *ehci_mv; struct resource *r; int retval = -ENODEV; u32 offset; if (!pdata) { dev_err(&pdev->dev, "missing platform_data\n"); return -ENODEV; } if (usb_disabled()) return -ENODEV; hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); if (!hcd) return -ENOMEM; ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); if (ehci_mv == NULL) { dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } platform_set_drvdata(pdev, ehci_mv); ehci_mv->pdata = pdata; ehci_mv->hcd = hcd; ehci_mv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ehci_mv->clk)) { dev_err(&pdev->dev, "error getting clock\n"); retval = PTR_ERR(ehci_mv->clk); goto err_put_hcd; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); retval = -ENODEV; goto err_put_hcd; } ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->phy_regs)) { retval = PTR_ERR(ehci_mv->phy_regs); goto err_put_hcd; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "capregs"); if (!r) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); retval = -ENODEV; goto err_put_hcd; } ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(ehci_mv->cap_regs)) { retval = PTR_ERR(ehci_mv->cap_regs); goto err_put_hcd; } retval = mv_ehci_enable(ehci_mv); if (retval) { dev_err(&pdev->dev, "init phy error %d\n", retval); goto err_put_hcd; } offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; ehci_mv->op_regs = (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); hcd->rsrc_start = r->start; hcd->rsrc_len = resource_size(r); hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); if (!hcd->irq) { dev_err(&pdev->dev, "Cannot get irq."); retval = -ENODEV; goto err_disable_clk; } ehci = hcd_to_ehci(hcd); ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { ehci_mv->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(ehci_mv->otg)) { retval = PTR_ERR(ehci_mv->otg); if (retval == -ENXIO) dev_info(&pdev->dev, "MV_USB_MODE_OTG " "must have CONFIG_USB_PHY enabled\n"); else dev_err(&pdev->dev, "unable to find transceiver\n"); goto err_disable_clk; } retval = otg_set_host(ehci_mv->otg->otg, &hcd->self); if (retval < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); retval = -ENODEV; goto err_disable_clk; } /* otg will enable clock before use as host */ mv_ehci_disable(ehci_mv); } else { if (pdata->set_vbus) pdata->set_vbus(1); retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (retval) { dev_err(&pdev->dev, "failed to add hcd with err %d\n", retval); goto err_set_vbus; } device_wakeup_enable(hcd->self.controller); } if (pdata->private_init) pdata->private_init(ehci_mv->op_regs, ehci_mv->phy_regs); dev_info(&pdev->dev, "successful find EHCI device with regs 0x%p irq %d" " working in %s mode\n", hcd->regs, hcd->irq, ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); return 0; err_set_vbus: if (pdata->set_vbus) pdata->set_vbus(0); err_disable_clk: mv_ehci_disable(ehci_mv); err_put_hcd: usb_put_hcd(hcd); return retval; }
static int mv_ehci_probe(struct platform_device *pdev) { struct mv_usb_platform_data *pdata; struct device *dev = &pdev->dev; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct ehci_hcd_mv *ehci_mv; struct resource *r; int retval = -ENODEV; u32 offset; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&pdev->dev, "failed to allocate memory for platform_data\n"); return -ENODEV; } mv_ehci_dt_parse(pdev, pdata); /* * Right now device-tree probed devices don't get dma_mask set. * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away. */ if (!dev->dma_mask) dev->dma_mask = &dev->coherent_dma_mask; if (!dev->coherent_dma_mask) dev->coherent_dma_mask = DMA_BIT_MASK(32); if (usb_disabled()) return -ENODEV; hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); if (!hcd) return -ENOMEM; ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); if (ehci_mv == NULL) { dev_err(&pdev->dev, "cannot allocate ehci_hcd_mv\n"); retval = -ENOMEM; goto err_put_hcd; } platform_set_drvdata(pdev, ehci_mv); ehci_mv->pdata = pdata; ehci_mv->hcd = hcd; ehci_mv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ehci_mv->clk)) { dev_err(&pdev->dev, "error getting clock\n"); retval = PTR_ERR(ehci_mv->clk); goto err_clear_drvdata; } clk_prepare(ehci_mv->clk); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); retval = -ENODEV; goto err_clear_drvdata; } ehci_mv->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (ehci_mv->cap_regs == NULL) { dev_err(&pdev->dev, "failed to map I/O memory\n"); retval = -EFAULT; goto err_clear_drvdata; } ehci_mv->phy = devm_usb_get_phy_dev(&pdev->dev, MV_USB2_PHY_INDEX); if (IS_ERR_OR_NULL(ehci_mv->phy)) { retval = PTR_ERR(ehci_mv->phy); if (retval != -EPROBE_DEFER && retval != -ENODEV) dev_err(&pdev->dev, "failed to get the outer phy\n"); else { kfree(hcd->bandwidth_mutex); kfree(hcd); return -EPROBE_DEFER; } goto err_clear_drvdata; } retval = mv_ehci_enable(ehci_mv); if (retval) { dev_err(&pdev->dev, "init phy error %d\n", retval); goto err_clear_drvdata; } offset = readl(ehci_mv->cap_regs) & CAPLENGTH_MASK; ehci_mv->op_regs = (void __iomem *) ((unsigned long) ehci_mv->cap_regs + offset); hcd->rsrc_start = r->start; hcd->rsrc_len = resource_size(r); hcd->regs = ehci_mv->op_regs; hcd->irq = platform_get_irq(pdev, 0); if (!hcd->irq) { dev_err(&pdev->dev, "Cannot get irq."); retval = -ENODEV; goto err_disable_clk; } ehci = hcd_to_ehci(hcd); ehci->caps = (struct ehci_caps *) ehci_mv->cap_regs; ehci_mv->mode = pdata->mode; if (ehci_mv->mode == MV_USB_MODE_OTG) { ehci_mv->otg = devm_usb_get_phy_dev(&pdev->dev, MV_USB2_OTG_PHY_INDEX); if (IS_ERR(ehci_mv->otg)) { retval = PTR_ERR(ehci_mv->otg); if (retval == -ENXIO) dev_info(&pdev->dev, "MV_USB_MODE_OTG " "must have CONFIG_USB_PHY enabled\n"); else if (retval != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to find transceiver\n"); goto err_disable_clk; } retval = otg_set_host(ehci_mv->otg->otg, &hcd->self); if (retval < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); retval = -ENODEV; goto err_disable_clk; } /* otg will enable clock before use as host */ mv_ehci_disable(ehci_mv); } else { pxa_usb_extern_call(pdata->id, vbus, set_vbus, 1); retval = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); if (retval) { dev_err(&pdev->dev, "failed to add hcd with err %d\n", retval); goto err_set_vbus; } } dev_info(&pdev->dev, "successful find EHCI device with regs 0x%p irq %d" " working in %s mode\n", hcd->regs, hcd->irq, ehci_mv->mode == MV_USB_MODE_OTG ? "OTG" : "Host"); return 0; err_set_vbus: pxa_usb_extern_call(pdata->id, vbus, set_vbus, 0); err_disable_clk: mv_ehci_disable(ehci_mv); err_clear_drvdata: platform_set_drvdata(pdev, NULL); err_put_hcd: usb_put_hcd(hcd); return retval; }
static int ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; int ret; dev_dbg(&pdev->dev, "ehci_msm proble\n"); if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &msm_ehci_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); hcd = usb_create_hcd(&ehci_msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd_to_bus(hcd)->skip_resume = true; hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } /* * OTG driver takes care of PHY initialization, clock management, * powering up VBUS, mapping of registers address space and power * management. */ phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(phy)) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -ENODEV; goto put_hcd; } ret = otg_set_host(phy->otg, &hcd->self); if (ret < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); goto put_hcd; } hcd->phy = phy; device_init_wakeup(&pdev->dev, 1); pm_runtime_enable(&pdev->dev); msm_bam_set_usb_host_dev(&pdev->dev); return 0; put_hcd: usb_put_hcd(hcd); return ret; }
static int ehci_mid_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct hc_driver *driver; struct usb_phy *otg; struct intel_mid_otg_xceiv *iotg; struct intel_mid_otg_pdata *otg_pdata; struct usb_hcd *hcd; struct ehci_hcd *ehci; int irq; int retval; pr_debug("initializing Intel MID USB OTG Host Controller\n"); /* we need not call pci_enable_dev since otg transceiver already take * the control of this device and this probe actaully gets called by * otg transceiver driver with HNP protocol. */ irq = pdev->irq; if (!id) return -EINVAL; driver = (struct hc_driver *)id->driver_data; if (!driver) return -EINVAL; hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; goto err1; } ehci = hcd_to_ehci(hcd); /* this will be called in ehci_bus_suspend and ehci_bus_resume */ ehci->otg_suspend = usb_otg_suspend; ehci->otg_resume = usb_otg_resume; /* this will be called by root hub code */ hcd->otg_notify = otg_notify; otg = usb_get_transceiver(); if (otg == NULL) { printk(KERN_ERR "%s Failed to get otg transceiver\n", __func__); retval = -EINVAL; goto err1; } iotg = otg_to_mid_xceiv(otg); hcd->regs = iotg->base; hcd->rsrc_start = pci_resource_start(pdev, 0); hcd->rsrc_len = pci_resource_len(pdev, 0); if (hcd->regs == NULL) { dev_dbg(&pdev->dev, "error mapping memory\n"); retval = -EFAULT; goto err2; } otg_pdata = pdev->dev.platform_data; if (otg_pdata == NULL) { dev_err(&pdev->dev, "Failed to get OTG platform data.\n"); retval = -ENODEV; goto err2; } hcd->power_budget = otg_pdata->power_budget; /* Mandatorily set the controller as remote-wakeup enabled */ device_set_wakeup_enable(&pdev->dev, true); retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err2; retval = otg_set_host(otg->otg, &hcd->self); if (!otg->otg->default_a) hcd->self.is_b_host = 1; usb_put_transceiver(otg); return retval; err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); return retval; }
static int ehci_msm_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct resource *res; struct usb_phy *phy; int ret; dev_dbg(&pdev->dev, "ehci_msm proble\n"); hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Unable to create HCD\n"); return -ENOMEM; } hcd->irq = platform_get_irq(pdev, 0); if (hcd->irq < 0) { dev_err(&pdev->dev, "Unable to get IRQ resource\n"); ret = hcd->irq; goto put_hcd; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Unable to get memory resource\n"); ret = -ENODEV; goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto put_hcd; } /* * OTG driver takes care of PHY initialization, clock management, * powering up VBUS, mapping of registers address space and power * management. */ if (pdev->dev.of_node) phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); else phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(phy)) { dev_err(&pdev->dev, "unable to find transceiver\n"); ret = -EPROBE_DEFER; goto put_hcd; } ret = otg_set_host(phy->otg, &hcd->self); if (ret < 0) { dev_err(&pdev->dev, "unable to register with transceiver\n"); goto put_hcd; } hcd->phy = phy; device_init_wakeup(&pdev->dev, 1); /* * OTG device parent of HCD takes care of putting * hardware into low power mode. */ pm_runtime_no_callbacks(&pdev->dev); pm_runtime_enable(&pdev->dev); /* FIXME: need to call usb_add_hcd() here? */ return 0; put_hcd: usb_put_hcd(hcd); return ret; }
/** * usb_hcd_fsl_probe - initialize FSL-based HCDs * @drvier: Driver to be used for this HCD * @pdev: USB Host Controller being probed * Context: !in_interrupt() * * Allocates basic resources for this USB host controller. * */ static int usb_hcd_fsl_probe(const struct hc_driver *driver, struct platform_device *pdev) { struct arc_usb_config *pdata; struct usb_hcd *hcd; struct resource *res; int irq; int retval; pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ pdata = (struct arc_usb_config *)pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", pdev->dev.bus_id); return -ENODEV; } retval = fsl_platform_verify(pdev); if (retval) return retval; /* * do platform specific init: check the clock, grab/config pins, etc. */ if (pdata->platform_init && pdata->platform_init()) { retval = -ENODEV; goto err1; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", pdev->dev.bus_id); return -ENODEV; } irq = res->start; if (pdata->set_vbus_power) pdata->set_vbus_power(1); hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); if (!hcd) { retval = -ENOMEM; goto err1; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no register addr. Check %s setup!\n", pdev->dev.bus_id); retval = -ENODEV; goto err2; } hcd->rsrc_start = res->start; hcd->rsrc_len = res->end - res->start + 1; vdbg("start=0x%x end=0x%x rsrc_start=0x%llx rsrc_len=0x%llx\n", res->start, res->end, hcd->rsrc_start, hcd->rsrc_len); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, driver->description)) { dev_dbg(&pdev->dev, "request_mem_region failed\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; } hcd->power_budget = pdata->power_budget; /* DDD * the following must be done by this point, otherwise the OTG * host port doesn't make it thru initializtion. * ehci_halt(), called by ehci_fsl_setup() returns -ETIMEDOUT */ fsl_platform_set_host_mode(hcd); retval = usb_add_hcd(hcd, irq, SA_SHIRQ); if (retval != 0) goto err4; #if defined(CONFIG_USB_OTG) if (pdata->does_otg) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); dbg("pdev=0x%p hcd=0x%p ehci=0x%p\n", pdev, hcd, ehci); ehci->transceiver = otg_get_transceiver(); dbg("ehci->transceiver=0x%p\n", ehci->transceiver); if (ehci->transceiver) { retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self); dev_dbg(ehci->transceiver->dev, "init %s transceiver, retval %d\n", ehci->transceiver->label, retval); if (retval) { if (ehci->transceiver) put_device(ehci->transceiver->dev); goto err3; } } else { printk(KERN_ERR "can't find transceiver\n"); retval = -ENODEV; goto err3; } } #endif return retval; 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", pdev->dev.bus_id, retval); if (pdata->platform_uninit) pdata->platform_uninit(); return retval; }
static int xhci_plat_probe(struct platform_device *pdev) { const struct hc_driver *driver; struct xhci_hcd *xhci; struct resource *res; struct usb_hcd *hcd; int ret; int irq; if (usb_disabled()) return -ENODEV; driver = &xhci_plat_xhci_driver; irq = platform_get_irq(pdev, 0); if (irq < 0) return -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) return -ENOMEM; hcd_to_bus(hcd)->skip_resume = true; hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, driver->description)) { dev_dbg(&pdev->dev, "controller already in use\n"); ret = -EBUSY; goto put_hcd; } hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_dbg(&pdev->dev, "error mapping memory\n"); ret = -EFAULT; goto release_mem_region; } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto unmap_registers; /* USB 2.0 roothub is stored in the platform_device now. */ hcd = dev_get_drvdata(&pdev->dev); xhci = hcd_to_xhci(hcd); xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, dev_name(&pdev->dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto dealloc_usb2_hcd; } hcd_to_bus(xhci->shared_hcd)->skip_resume = true; /* * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) * is called by usb_add_hcd(). */ *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto put_usb3_hcd; phy = usb_get_transceiver(); /* Register with OTG if present, ignore USB2 OTG using other PHY */ if (phy && phy->otg && !(phy->flags & ENABLE_SECONDARY_PHY)) { dev_dbg(&pdev->dev, "%s otg support available\n", __func__); ret = otg_set_host(phy->otg, &hcd->self); if (ret) { dev_err(&pdev->dev, "%s otg_set_host failed\n", __func__); usb_put_transceiver(phy); goto put_usb3_hcd; } } else { pm_runtime_no_callbacks(&pdev->dev); } pm_runtime_put(&pdev->dev); return 0; put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); dealloc_usb2_hcd: usb_remove_hcd(hcd); unmap_registers: iounmap(hcd->regs); release_mem_region: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); put_hcd: usb_put_hcd(hcd); return ret; }
/** * usb_hcd_fsl_probe - initialize FSL-based HCDs * @drvier: Driver to be used for this HCD * @pdev: USB Host Controller being probed * Context: !in_interrupt() * * Allocates basic resources for this USB host controller. * */ static int usb_hcd_fsl_probe(const struct hc_driver *driver, struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; int irq; int retval; u32 temp; pr_debug("initializing FSL-SOC USB Controller\n"); /* Need platform data for setup */ if (!pdata) { dev_err(&pdev->dev, "No platform data for %s.\n", pdev->dev.bus_id); return -ENODEV; } /* * This is a host mode driver, verify that we're supposed to be * in host mode. */ if (!((pdata->operating_mode == FSL_USB2_DR_HOST) || (pdata->operating_mode == FSL_USB2_MPH_HOST) || (pdata->operating_mode == FSL_USB2_DR_OTG))) { dev_err(&pdev->dev, "Non Host Mode configured for %s. " "Wrong driver linked.\n", pdev->dev.bus_id); return -ENODEV; } hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); if (!hcd) { retval = -ENOMEM; goto err1; } #if defined(CONFIG_USB_OTG) if (pdata->operating_mode == FSL_USB2_DR_OTG) { res = otg_get_resources(); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", pdev->dev.bus_id); return -ENODEV; } irq = res[1].start; hcd->rsrc_start = res[0].start; hcd->rsrc_len = res[0].end - res[0].start + 1; } else #endif { if ((pdev->dev.parent) && (to_platform_device(pdev->dev.parent)->resource)) { pdev->resource = to_platform_device(pdev->dev.parent)->resource; pdev->num_resources = to_platform_device(pdev->dev.parent)->num_resources; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", pdev->dev.bus_id); return -ENODEV; } irq = res->start; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); 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; } } if (!(pdata->port_enables & FSL_USB2_DONT_REMAP)) { 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; } regs_remapped = 1; } else hcd->regs = (void __iomem *)(u32)(hcd->rsrc_start); pdata->regs = hcd->regs; /* * do platform specific init: check the clock, grab/config pins, etc. */ if (pdata->platform_init && pdata->platform_init(pdev)) { retval = -ENODEV; goto err3; } fsl_platform_set_host_mode(hcd); hcd->power_budget = pdata->power_budget; retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err4; fsl_platform_set_vbus_power(pdata, 1); #ifdef CONFIG_USB_OTG if (pdata->operating_mode == FSL_USB2_DR_OTG) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); dbg("pdev=0x%p hcd=0x%p ehci=0x%p\n", pdev, hcd, ehci); ehci->transceiver = otg_get_transceiver(); dbg("ehci->transceiver=0x%p\n", ehci->transceiver); if (ehci->transceiver) { retval = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self); if (retval) { if (ehci->transceiver) put_device(ehci->transceiver->dev); goto err4; } } else { printk(KERN_ERR "can't find transceiver\n"); retval = -ENODEV; goto err4; } } #endif fsl_platform_set_ahb_burst(hcd); ehci_testmode_init(hcd_to_ehci(hcd)); return retval; err4: if (regs_remapped) iounmap(hcd->regs); err3: if (pdata->operating_mode != FSL_USB2_DR_OTG) release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval); if (pdata->platform_uninit) pdata->platform_uninit(pdata); return retval; }