static void exynos_dp_bridge_enable(struct drm_bridge *bridge) { struct exynos_dp_device *dp = bridge->driver_private; struct exynos_drm_crtc *crtc = dp_to_crtc(dp); if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; pm_runtime_get_sync(dp->dev); if (dp->panel) { if (drm_panel_prepare(dp->panel)) { DRM_ERROR("failed to setup the panel\n"); return; } } if (crtc->ops->clock_enable) crtc->ops->clock_enable(dp_to_crtc(dp), true); phy_power_on(dp->phy); exynos_dp_init_dp(dp); enable_irq(dp->irq); exynos_dp_commit(&dp->encoder); dp->dpms_mode = DRM_MODE_DPMS_ON; }
static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) { int ret; struct device *dev = &bsp_priv->pdev->dev; /*rmii or rgmii*/ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { dev_info(dev, "init for RGMII\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay); } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { dev_info(dev, "init for RMII\n"); bsp_priv->ops->set_to_rmii(bsp_priv); } else { dev_err(dev, "NO interface defined!\n"); } ret = phy_power_on(bsp_priv, true); if (ret) return ret; ret = gmac_clk_enable(bsp_priv, true); if (ret) return ret; pm_runtime_enable(dev); pm_runtime_get_sync(dev); return 0; }
static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); int ret; ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) return ret; ret = clk_prepare_enable(hsotg->clk); if (ret) return ret; if (hsotg->uphy) ret = usb_phy_init(hsotg->uphy); else if (hsotg->plat && hsotg->plat->phy_init) ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); else { ret = phy_power_on(hsotg->phy); if (ret == 0) ret = phy_init(hsotg->phy); } return ret; }
static void rk_gmac_exit(struct platform_device *pdev, void *priv) { struct rk_priv_data *gmac = priv; phy_power_on(gmac, false); gmac_clk_enable(gmac, false); }
static int da8xx_musb_init(struct musb *musb) { struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); void __iomem *reg_base = musb->ctrl_base; u32 rev; int ret = -ENODEV; musb->mregs += DA8XX_MENTOR_CORE_OFFSET; ret = clk_prepare_enable(glue->clk); if (ret) { dev_err(glue->dev, "failed to enable clock\n"); return ret; } /* Returns zero if e.g. not clocked */ rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG); if (!rev) goto fail; musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) { ret = -EPROBE_DEFER; goto fail; } setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); /* Reset the controller */ musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); /* Start the on-chip PHY and its PLL. */ ret = phy_init(glue->phy); if (ret) { dev_err(glue->dev, "Failed to init phy.\n"); goto fail; } ret = phy_power_on(glue->phy); if (ret) { dev_err(glue->dev, "Failed to power on phy.\n"); goto err_phy_power_on; } msleep(5); /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */ pr_debug("DA8xx OTG revision %08x, control %02x\n", rev, musb_readb(reg_base, DA8XX_USB_CTRL_REG)); musb->isr = da8xx_musb_interrupt; return 0; err_phy_power_on: phy_exit(glue->phy); fail: clk_disable_unprepare(glue->clk); return ret; }
static void rk_gmac_powerdown(struct rk_priv_data *gmac) { struct device *dev = &gmac->pdev->dev; pm_runtime_put_sync(dev); pm_runtime_disable(dev); phy_power_on(gmac, false); gmac_clk_enable(gmac, false); }
static void exynos_dp_phy_init(struct exynos_dp_device *dp) { if (dp->phy) { phy_power_on(dp->phy); } else if (dp->phy_addr) { u32 reg; reg = __raw_readl(dp->phy_addr); reg |= dp->enable_mask; __raw_writel(reg, dp->phy_addr); } }
static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) { int ret; ret = phy_power_on(bsp_priv, true); if (ret) return ret; ret = gmac_clk_enable(bsp_priv, true); if (ret) return ret; return 0; }
static int st_ehci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct st_ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); int clk, ret; ret = reset_control_deassert(priv->pwr); if (ret) return ret; ret = reset_control_deassert(priv->rst); if (ret) goto err_assert_power; /* some SoCs don't have a dedicated 48Mhz clock, but those that do need the rate to be explicitly set */ if (priv->clk48) { ret = clk_set_rate(priv->clk48, 48000000); if (ret) goto err_assert_reset; } for (clk = 0; clk < USB_MAX_CLKS && priv->clks[clk]; clk++) { ret = clk_prepare_enable(priv->clks[clk]); if (ret) goto err_disable_clks; } ret = phy_init(priv->phy); if (ret) goto err_disable_clks; ret = phy_power_on(priv->phy); if (ret) goto err_exit_phy; return 0; err_exit_phy: phy_exit(priv->phy); err_disable_clks: while (--clk >= 0) clk_disable_unprepare(priv->clks[clk]); err_assert_reset: reset_control_assert(priv->rst); err_assert_power: reset_control_assert(priv->pwr); return ret; }
static int omap2430_runtime_resume(struct device *dev) { struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); if (musb) { omap2430_low_level_init(musb); musb_writel(musb->mregs, OTG_INTERFSEL, musb->context.otg_interfsel); phy_power_on(musb->phy); } return 0; }
static int rk_gmac_init(struct platform_device *pdev, void *priv) { struct rk_priv_data *bsp_priv = priv; int ret; ret = phy_power_on(bsp_priv, true); if (ret) return ret; ret = gmac_clk_enable(bsp_priv, true); if (ret) return ret; return 0; }
static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) { int ret; struct device *dev = &bsp_priv->pdev->dev; ret = gmac_clk_enable(bsp_priv, true); if (ret) return ret; /*rmii or rgmii*/ switch (bsp_priv->phy_iface) { case PHY_INTERFACE_MODE_RGMII: dev_info(dev, "init for RGMII\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay); break; case PHY_INTERFACE_MODE_RGMII_ID: dev_info(dev, "init for RGMII_ID\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); break; case PHY_INTERFACE_MODE_RGMII_RXID: dev_info(dev, "init for RGMII_RXID\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); break; case PHY_INTERFACE_MODE_RGMII_TXID: dev_info(dev, "init for RGMII_TXID\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); break; case PHY_INTERFACE_MODE_RMII: dev_info(dev, "init for RMII\n"); bsp_priv->ops->set_to_rmii(bsp_priv); break; default: dev_err(dev, "NO interface defined!\n"); } ret = phy_power_on(bsp_priv, true); if (ret) return ret; pm_runtime_enable(dev); pm_runtime_get_sync(dev); if (bsp_priv->integrated_phy) rk_gmac_integrated_phy_powerup(bsp_priv); return 0; }
static int xhci_mtk_phy_power_on(struct xhci_hcd_mtk *mtk) { int i; int ret; for (i = 0; i < mtk->num_phys; i++) { ret = phy_power_on(mtk->phys[i]); if (ret) goto power_off_phy; } return 0; power_off_phy: for (; i > 0; i--) phy_power_off(mtk->phys[i - 1]); return ret; }
static int ssusb_phy_power_on(struct ssusb_mtk *ssusb) { int i; int ret; for (i = 0; i < ssusb->num_phys; i++) { ret = phy_power_on(ssusb->phys[i]); if (ret) goto power_off_phy; } return 0; power_off_phy: for (; i > 0; i--) phy_power_off(ssusb->phys[i - 1]); return ret; }
static int ahci_resume(struct device *dev) { struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; int rc; if (!IS_ERR(hpriv->clk)) { rc = clk_prepare_enable(hpriv->clk); if (rc) { dev_err(dev, "clock prepare enable failed"); return rc; } } if (!IS_ERR(hpriv->phy)) { phy_init(hpriv->phy); phy_power_on(hpriv->phy); } if (pdata && pdata->resume) { rc = pdata->resume(dev); if (rc) goto disable_unprepare_clk; } if (dev->power.power_state.event == PM_EVENT_SUSPEND) { rc = ahci_reset_controller(host); if (rc) goto disable_unprepare_clk; ahci_init_controller(host); } ata_host_resume(host); return 0; disable_unprepare_clk: if (!IS_ERR(hpriv->clk)) clk_disable_unprepare(hpriv->clk); return rc; }
static void analogix_dp_bridge_enable(struct drm_bridge *bridge) { struct analogix_dp_device *dp = bridge->driver_private; if (dp->dpms_mode == DRM_MODE_DPMS_ON) return; pm_runtime_get_sync(dp->dev); if (dp->plat_data->power_on) dp->plat_data->power_on(dp->plat_data); phy_power_on(dp->phy); analogix_dp_init_dp(dp); enable_irq(dp->irq); analogix_dp_commit(dp); dp->dpms_mode = DRM_MODE_DPMS_ON; }
static int ehci_platform_power_on(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); int clk, ret, phy_num; for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { ret = clk_prepare_enable(priv->clks[clk]); if (ret) goto err_disable_clks; } for (phy_num = 0; phy_num < priv->num_phys; phy_num++) { if (priv->phys[phy_num]) { ret = phy_init(priv->phys[phy_num]); if (ret) goto err_exit_phy; ret = phy_power_on(priv->phys[phy_num]); if (ret) { phy_exit(priv->phys[phy_num]); goto err_exit_phy; } } } return 0; err_exit_phy: while (--phy_num >= 0) { if (priv->phys[phy_num]) { phy_power_off(priv->phys[phy_num]); phy_exit(priv->phys[phy_num]); } } err_disable_clks: while (--clk >= 0) clk_disable_unprepare(priv->clks[clk]); return ret; }
static int msm_ahci_resume(struct device *ahci_dev) { int ret; struct device *dev = ahci_dev->parent; struct msm_ahci_host *host = dev_get_drvdata(dev); ret = msm_ahci_setup_clocks(host, true); if (ret) goto out; ret = phy_power_on(host->phy); if (ret) { dev_err(dev, "%s: PHY power on failed %d\n", __func__, ret); goto out; } else { host->phy_powered_on = true; } /* asic0 and rbc0 clks needs to be ungated only after phy power on */ ret = msm_ahci_setup_asic_rbc_clks(host, true); out: return ret; }
static int msm_ahci_init_phy(struct msm_ahci_host *host) { int ret = 0; struct device *dev = host->ahci_pdev->dev.parent; host->phy = devm_phy_get(dev, "sata-6g"); if (IS_ERR(host->phy)) { ret = PTR_ERR(host->phy); dev_err(dev, "PHY get failed %d\n", ret); goto out; } ret = phy_init(host->phy); if (ret) { dev_err(dev, "PHY initialization failed %d\n", ret); goto out; } ret = phy_power_on(host->phy); if (ret) { dev_err(dev, "PHY power on failed %d\n", ret); goto out; } host->phy_powered_on = true; /* asic0 and rbc0 clks needs to be ungated only after phy power on */ ret = msm_ahci_setup_asic_rbc_clks(host, true); if (ret) { dev_err(dev, "failed to enable asic0/rbc0 clks %d", ret); goto out; } out: return ret; }
/** * ahci_platform_enable_resources - Enable platform resources * @hpriv: host private area to store config values * * This function enables all ahci_platform managed resources in the * following order: * 1) Regulator * 2) Clocks (through ahci_platform_enable_clks) * 3) Phy * * If resource enabling fails at any point the previous enabled resources * are disabled in reverse order. * * RETURNS: * 0 on success otherwise a negative error code */ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv) { int rc; if (hpriv->target_pwr) { rc = regulator_enable(hpriv->target_pwr); if (rc) return rc; } rc = ahci_platform_enable_clks(hpriv); if (rc) goto disable_regulator; if (hpriv->phy) { rc = phy_init(hpriv->phy); if (rc) goto disable_clks; rc = phy_power_on(hpriv->phy); if (rc) { phy_exit(hpriv->phy); goto disable_clks; } } return 0; disable_clks: ahci_platform_disable_clks(hpriv); disable_regulator: if (hpriv->target_pwr) regulator_disable(hpriv->target_pwr); return rc; }
static int exynos_pcie_establish_link(struct exynos_pcie *ep) { struct dw_pcie *pci = ep->pci; struct pcie_port *pp = &pci->pp; struct device *dev = pci->dev; if (dw_pcie_link_up(pci)) { dev_err(dev, "Link already up\n"); return 0; } exynos_pcie_assert_core_reset(ep); phy_reset(ep->phy); exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_PWR_RESET); phy_power_on(ep->phy); phy_init(ep->phy); exynos_pcie_deassert_core_reset(ep); dw_pcie_setup_rc(pp); exynos_pcie_assert_reset(ep); /* assert LTSSM enable */ exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE, PCIE_APP_LTSSM_ENABLE); /* check if the link is up or not */ if (!dw_pcie_wait_for_link(pci)) return 0; phy_power_off(ep->phy); return -ETIMEDOUT; }
static int __init dra7xx_pcie_probe(struct platform_device *pdev) { u32 reg; int ret; int irq; int i; int phy_count; struct phy **phy; void __iomem *base; struct resource *res; struct dra7xx_pcie *dra7xx; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; char name[10]; int gpio_sel; enum of_gpio_flags flags; unsigned long gpio_flags; dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); if (!dra7xx) return -ENOMEM; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, IRQF_SHARED, "dra7xx-pcie-main", dra7xx); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!base) return -ENOMEM; phy_count = of_property_count_strings(np, "phy-names"); if (phy_count < 0) { dev_err(dev, "unable to find the strings\n"); return phy_count; } phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); if (!phy) return -ENOMEM; for (i = 0; i < phy_count; i++) { snprintf(name, sizeof(name), "pcie-phy%d", i); phy[i] = devm_phy_get(dev, name); if (IS_ERR(phy[i])) return PTR_ERR(phy[i]); ret = phy_init(phy[i]); if (ret < 0) goto err_phy; ret = phy_power_on(phy[i]); if (ret < 0) { phy_exit(phy[i]); goto err_phy; } } dra7xx->base = base; dra7xx->phy = phy; dra7xx->dev = dev; dra7xx->phy_count = phy_count; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "pm_runtime_get_sync failed\n"); goto err_get_sync; } gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags); if (gpio_is_valid(gpio_sel)) { gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags, "pcie_reset"); if (ret) { dev_err(&pdev->dev, "gpio%d request failed, ret %d\n", gpio_sel, ret); goto err_gpio; } } else if (gpio_sel == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto err_gpio; } reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); reg &= ~LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); platform_set_drvdata(pdev, dra7xx); ret = dra7xx_add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_gpio; return 0; err_gpio: pm_runtime_put(dev); err_get_sync: pm_runtime_disable(dev); err_phy: while (--i >= 0) { phy_power_off(phy[i]); phy_exit(phy[i]); } return ret; }
static void exynos_dp_phy_init(struct exynos_dp_device *dp) { if (dp->phy) phy_power_on(dp->phy); }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *plat = dev_get_platdata(dev); struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ if (dev->parent->of_node) { musb->phy = devm_phy_get(dev->parent, "usb2-phy"); /* We can't totally remove musb->xceiv as of now because * musb core uses xceiv.state and xceiv.otg. Once we have * a separate state machine to handle otg, these can be moved * out of xceiv and then we can start using the generic PHY * framework */ musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); } else { musb->xceiv = devm_usb_get_phy_dev(dev, 0); musb->phy = devm_phy_get(dev, "usb"); } if (IS_ERR(musb->xceiv)) { status = PTR_ERR(musb->xceiv); if (status == -ENXIO) return status; dev_dbg(dev, "HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER; } if (IS_ERR(musb->phy)) { dev_err(dev, "HS USB OTG: no PHY configured\n"); return PTR_ERR(musb->phy); } musb->isr = omap2430_musb_interrupt; phy_init(musb->phy); phy_power_on(musb->phy); l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); dev_dbg(dev, "HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); if (glue->status != MUSB_UNKNOWN) omap_musb_set_mailbox(glue); return 0; }
static int dsps_musb_init(struct musb *musb) { struct device *dev = musb->controller; struct dsps_glue *glue = dev_get_drvdata(dev->parent); struct platform_device *parent = to_platform_device(dev->parent); const struct dsps_musb_wrapper *wrp = glue->wrp; void __iomem *reg_base; struct resource *r; u32 rev, val; int ret; r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control"); reg_base = devm_ioremap_resource(dev, r); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); musb->ctrl_base = reg_base; /* NOP driver needs change if supporting dual instance */ musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "phys", 0); if (IS_ERR(musb->xceiv)) return PTR_ERR(musb->xceiv); musb->phy = devm_phy_get(dev->parent, "usb2-phy"); /* Returns zero if e.g. not clocked */ rev = musb_readl(reg_base, wrp->revision); if (!rev) return -ENODEV; if (IS_ERR(musb->phy)) { musb->phy = NULL; } else { ret = phy_init(musb->phy); if (ret < 0) return ret; ret = phy_power_on(musb->phy); if (ret) { phy_exit(musb->phy); return ret; } } timer_setup(&musb->dev_timer, otg_timer, 0); /* Reset the musb */ musb_writel(reg_base, wrp->control, (1 << wrp->reset)); musb->isr = dsps_interrupt; /* reset the otgdisable bit, needed for host mode to work */ val = musb_readl(reg_base, wrp->phy_utmi); val &= ~(1 << wrp->otg_disable); musb_writel(musb->ctrl_base, wrp->phy_utmi, val); /* * Check whether the dsps version has babble control enabled. * In latest silicon revision the babble control logic is enabled. * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control * logic enabled. */ val = musb_readb(musb->mregs, MUSB_BABBLE_CTL); if (val & MUSB_BABBLE_RCV_DISABLE) { glue->sw_babble_enabled = true; val |= MUSB_BABBLE_SW_SESSION_CTRL; musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); } dsps_mod_timer(glue, -1); return dsps_musb_dbg_init(musb, glue); }
static int dwc3_resume(struct device *dev) { struct dwc3 *dwc = dev_get_drvdata(dev); unsigned long flags; int ret; pinctrl_pm_select_default_state(dev); usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) return ret; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err_usb2phy_power; usb_phy_init(dwc->usb3_phy); usb_phy_init(dwc->usb2_phy); ret = phy_init(dwc->usb2_generic_phy); if (ret < 0) goto err_usb3phy_power; ret = phy_init(dwc->usb3_generic_phy); if (ret < 0) goto err_usb2phy_init; spin_lock_irqsave(&dwc->lock, flags); dwc3_event_buffers_setup(dwc); dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl); switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: case USB_DR_MODE_OTG: dwc3_gadget_resume(dwc); /* FALLTHROUGH */ case USB_DR_MODE_HOST: default: /* do nothing */ break; } spin_unlock_irqrestore(&dwc->lock, flags); pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; err_usb2phy_init: phy_exit(dwc->usb2_generic_phy); err_usb3phy_power: phy_power_off(dwc->usb3_generic_phy); err_usb2phy_power: phy_power_off(dwc->usb2_generic_phy); return ret; }
static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct resource *res; struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; u32 fladj = 0; int ret; void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) return -ENOMEM; dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; dwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; res->start += DWC3_GLOBALS_REGS_START; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) { ret = PTR_ERR(regs); goto err0; } dwc->regs = regs; dwc->regs_size = resource_size(res); /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; /* default to -3.5dB de-emphasis */ tx_de_emphasis = 1; /* * default to assert utmi_sleep_n and use maximum allowed HIRD * threshold value of 0b1100 */ hird_threshold = 12; dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->dr_mode = usb_get_dr_mode(dev); dwc->has_lpm_erratum = device_property_read_bool(dev, "snps,has-lpm-erratum"); device_property_read_u8(dev, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); dwc->is_utmi_l1_suspend = device_property_read_bool(dev, "snps,is-utmi-l1-suspend"); device_property_read_u8(dev, "snps,hird-threshold", &hird_threshold); dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); dwc->needs_fifo_resize = device_property_read_bool(dev, "tx-fifo-resize"); dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = device_property_read_bool(dev, "snps,u2exit_lfps_quirk"); dwc->u2ss_inp3_quirk = device_property_read_bool(dev, "snps,u2ss_inp3_quirk"); dwc->req_p1p2p3_quirk = device_property_read_bool(dev, "snps,req_p1p2p3_quirk"); dwc->del_p1p2p3_quirk = device_property_read_bool(dev, "snps,del_p1p2p3_quirk"); dwc->del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,del_phy_power_chg_quirk"); dwc->lfps_filter_quirk = device_property_read_bool(dev, "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = device_property_read_bool(dev, "snps,rx_detect_poll_quirk"); dwc->dis_u3_susphy_quirk = device_property_read_bool(dev, "snps,dis_u3_susphy_quirk"); dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); dwc->dis_enblslpm_quirk = device_property_read_bool(dev, "snps,dis_enblslpm_quirk"); dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); device_property_read_u8(dev, "snps,tx_de_emphasis", &tx_de_emphasis); device_property_read_string(dev, "snps,hsphy_interface", &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &fladj); if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; if (pdata->lpm_nyet_threshold) lpm_nyet_threshold = pdata->lpm_nyet_threshold; dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend; if (pdata->hird_threshold) hird_threshold = pdata->hird_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->usb3_lpm_capable = pdata->usb3_lpm_capable; dwc->dr_mode = pdata->dr_mode; dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) tx_de_emphasis = pdata->tx_de_emphasis; dwc->hsphy_interface = pdata->hsphy_interface; fladj = pdata->fladj_value; } dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc); ret = dwc3_phy_setup(dwc); if (ret) goto err0; ret = dwc3_core_get_phy(dwc); if (ret) goto err0; spin_lock_init(&dwc->lock); if (!dev->dma_mask) { dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); } pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err1; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc->dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) dwc->dr_mode = USB_DR_MODE_PERIPHERAL; if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) dwc->dr_mode = USB_DR_MODE_OTG; ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err1; } /* Check the maximum_speed parameter */ switch (dwc->maximum_speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_SUPER: case USB_SPEED_SUPER_PLUS: break; default: dev_err(dev, "invalid maximum_speed parameter %d\n", dwc->maximum_speed); /* fall through */ case USB_SPEED_UNKNOWN: /* default to superspeed */ dwc->maximum_speed = USB_SPEED_SUPER; /* * default to superspeed plus if we are capable. */ if (dwc3_is_usb31(dwc) && (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) dwc->maximum_speed = USB_SPEED_SUPER_PLUS; break; } /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc, fladj); usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) goto err2; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err3; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err4; } ret = dwc3_core_init_mode(dwc); if (ret) goto err5; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err6; } pm_runtime_allow(dev); return 0; err6: dwc3_core_exit_mode(dwc); err5: dwc3_event_buffers_cleanup(dwc); err4: phy_power_off(dwc->usb3_generic_phy); err3: phy_power_off(dwc->usb2_generic_phy); err2: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); dwc3_core_exit(dwc); err1: dwc3_free_event_buffers(dwc); dwc3_ulpi_exit(dwc); err0: /* * restore res->start back to its original value so that, in case the * probe is deferred, we don't end up getting error in request the * memory region the next time probe is called. */ res->start -= DWC3_GLOBALS_REGS_START; return ret; }
/** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure * * Returns 0 on success otherwise negative errno. */ static int dwc3_core_init(struct dwc3 *dwc) { u32 reg; int ret; if (!dwc3_core_is_valid(dwc)) { dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); ret = -ENODEV; goto err0; } /* * Write Linux Version Code to our GUID register so it's easy to figure * out which kernel version a bug was found. */ dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); /* Handle USB2.0-only core configuration */ if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { if (dwc->maximum_speed == USB_SPEED_SUPER) dwc->maximum_speed = USB_SPEED_HIGH; } ret = dwc3_core_soft_reset(dwc); if (ret) goto err0; ret = dwc3_phy_setup(dwc); if (ret) goto err0; dwc3_core_setup_global_control(dwc); dwc3_core_num_eps(dwc); ret = dwc3_setup_scratch_buffers(dwc); if (ret) goto err1; /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc); usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) goto err2; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err3; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err4; } /* * ENDXFER polling is available on version 3.10a and later of * the DWC_usb3 controller. It is NOT available in the * DWC_usb31 controller. */ if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); reg |= DWC3_GUCTL2_RST_ACTBITLATER; dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); } /* * Enable hardware control of sending remote wakeup in HS when * the device is in the L1 state. */ if (dwc->revision >= DWC3_REVISION_290A) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); } return 0; err4: phy_power_off(dwc->usb3_generic_phy); err3: phy_power_off(dwc->usb2_generic_phy); err2: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); err1: usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb3_generic_phy); err0: return ret; }
int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; struct resource *res; unsigned int irq_flags; int ret; if (!plat_data) { dev_err(dev, "Invalided input plat_data\n"); return -EINVAL; } dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); if (!dp) return -ENOMEM; dev_set_drvdata(dev, dp); dp->dev = &pdev->dev; dp->dpms_mode = DRM_MODE_DPMS_OFF; mutex_init(&dp->panel_lock); dp->panel_is_modeset = false; /* * platform dp driver need containor_of the plat_data to get * the driver private data, so we need to store the point of * plat_data, not the context of plat_data. */ dp->plat_data = plat_data; ret = analogix_dp_dt_parse_pdata(dp); if (ret) return ret; dp->phy = devm_phy_get(dp->dev, "dp"); if (IS_ERR(dp->phy)) { dev_err(dp->dev, "no DP phy configured\n"); ret = PTR_ERR(dp->phy); if (ret) { /* * phy itself is not enabled, so we can move forward * assigning NULL to phy pointer. */ if (ret == -ENOSYS || ret == -ENODEV) dp->phy = NULL; else return ret; } } dp->clock = devm_clk_get(&pdev->dev, "dp"); if (IS_ERR(dp->clock)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(dp->clock); } clk_prepare_enable(dp->clock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dp->reg_base)) return PTR_ERR(dp->reg_base); dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); if (!gpio_is_valid(dp->hpd_gpio)) dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); if (gpio_is_valid(dp->hpd_gpio)) { /* * Set up the hotplug GPIO from the device tree as an interrupt. * Simply specifying a different interrupt in the device tree * doesn't work since we handle hotplug rather differently when * using a GPIO. We also need the actual GPIO specifier so * that we can get the current state of the GPIO. */ ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, "hpd_gpio"); if (ret) { dev_err(&pdev->dev, "failed to get hpd gpio\n"); return ret; } dp->irq = gpio_to_irq(dp->hpd_gpio); irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { dp->hpd_gpio = -ENODEV; dp->irq = platform_get_irq(pdev, 0); irq_flags = 0; } if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); return -ENODEV; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); ret = devm_request_threaded_irq(&pdev->dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); goto err_disable_pm_runtime; } disable_irq(dp->irq); dp->drm_dev = drm_dev; dp->encoder = dp->plat_data->encoder; dp->aux.name = "DP-AUX"; dp->aux.transfer = analogix_dpaux_transfer; dp->aux.dev = &pdev->dev; ret = drm_dp_aux_register(&dp->aux); if (ret) goto err_disable_pm_runtime; ret = analogix_dp_create_bridge(drm_dev, dp); if (ret) { DRM_ERROR("failed to create bridge (%d)\n", ret); drm_encoder_cleanup(dp->encoder); goto err_disable_pm_runtime; } phy_power_off(dp->phy); pm_runtime_put(dev); return 0; err_disable_pm_runtime: phy_power_off(dp->phy); pm_runtime_put(dev); pm_runtime_disable(dev); return ret; }
static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct device_node *node = dev->of_node; struct resource *res; struct dwc3 *dwc; int ret = -ENOMEM; void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) { dev_err(dev, "not enough memory\n"); return -ENOMEM; } dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; } else { dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); } /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; if (IS_ERR(dwc->usb2_phy)) { ret = PTR_ERR(dwc->usb2_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb2_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } if (IS_ERR(dwc->usb3_phy)) { ret = PTR_ERR(dwc->usb3_phy); if (ret == -ENXIO || ret == -ENODEV) { dwc->usb3_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); if (IS_ERR(dwc->usb2_generic_phy)) { ret = PTR_ERR(dwc->usb2_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb2_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb2 phy configured\n"); return ret; } } dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); if (IS_ERR(dwc->usb3_generic_phy)) { ret = PTR_ERR(dwc->usb3_generic_phy); if (ret == -ENOSYS || ret == -ENODEV) { dwc->usb3_generic_phy = NULL; } else if (ret == -EPROBE_DEFER) { return ret; } else { dev_err(dev, "no usb3 phy configured\n"); return ret; } } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; res->start += DWC3_GLOBALS_REGS_START; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) return PTR_ERR(regs); spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); dwc->regs = regs; dwc->regs_size = resource_size(res); dwc->dev = dev; dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); dwc3_cache_hwparams(dwc); ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err0; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc->dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) dwc->dr_mode = USB_DR_MODE_PERIPHERAL; if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) dwc->dr_mode = USB_DR_MODE_OTG; ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err0; } usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) goto err1; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err_usb2phy_power; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err_usb3phy_power; } switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; case USB_DR_MODE_HOST: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } break; case USB_DR_MODE_OTG: dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG); ret = dwc3_host_init(dwc); if (ret) { dev_err(dev, "failed to initialize host\n"); goto err2; } ret = dwc3_gadget_init(dwc); if (ret) { dev_err(dev, "failed to initialize gadget\n"); goto err2; } break; default: dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); goto err2; } ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err3; } pm_runtime_allow(dev); return 0; err3: switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: dwc3_gadget_exit(dwc); break; case USB_DR_MODE_HOST: dwc3_host_exit(dwc); break; case USB_DR_MODE_OTG: dwc3_host_exit(dwc); dwc3_gadget_exit(dwc); break; default: /* do nothing */ break; } err2: dwc3_event_buffers_cleanup(dwc); err_usb3phy_power: phy_power_off(dwc->usb3_generic_phy); err_usb2phy_power: phy_power_off(dwc->usb2_generic_phy); err1: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); dwc3_core_exit(dwc); err0: dwc3_free_event_buffers(dwc); return ret; }