/* * The function passed to the usb driver for phy shutdown */ static void samsung_usb3phy_shutdown(struct usb_phy *phy) { struct samsung_usbphy *sphy; unsigned long flags; sphy = phy_to_sphy(phy); if (clk_prepare_enable(sphy->clk)) { dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); return; } spin_lock_irqsave(&sphy->lock, flags); /* setting default phy-type for USB 3.0 */ samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); /* De-initialize usb phy registers */ sphy->drv_data->phy_disable(sphy); /* Enable phy isolation */ if (sphy->drv_data->set_isolation) sphy->drv_data->set_isolation(sphy, true); spin_unlock_irqrestore(&sphy->lock, flags); clk_disable_unprepare(sphy->clk); }
static int samsung_usb3phy_init(struct usb_phy *phy) { struct samsung_usbphy *sphy; unsigned long flags; int ret = 0; sphy = phy_to_sphy(phy); /* Enable the phy clock */ ret = clk_prepare_enable(sphy->clk); if (ret) { dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); return ret; } spin_lock_irqsave(&sphy->lock, flags); /* setting default phy-type for USB 3.0 */ samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); /* Disable phy isolation */ if (sphy->drv_data->set_isolation) sphy->drv_data->set_isolation(sphy, false); /* Initialize usb phy registers */ sphy->drv_data->phy_enable(sphy); spin_unlock_irqrestore(&sphy->lock, flags); /* Disable the phy clock */ clk_disable_unprepare(sphy->clk); return ret; }
/* * PHYs are different for USB Device and USB Host. * This make sure that correct PHY type is selected before * any operation on PHY. */ static int samsung_usbphy_set_type(struct usb_phy *phy, enum samsung_usb_phy_type phy_type) { struct samsung_usbphy *sphy = phy_to_sphy(phy); sphy->phy_type = phy_type; return 0; }
/* * The function passed to the usb driver for phy initialization */ static int samsung_usbphy_init(struct usb_phy *phy) { struct samsung_usbphy *sphy; struct usb_bus *host = NULL; unsigned long flags; int ret = 0; sphy = phy_to_sphy(phy); host = phy->otg->host; /* Enable the phy clock */ ret = clk_prepare_enable(sphy->clk); if (ret) { dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); return ret; } spin_lock_irqsave(&sphy->lock, flags); if (host) { /* setting default phy-type for USB 2.0 */ if (!strstr(dev_name(host->controller), "ehci") || !strstr(dev_name(host->controller), "ohci")) samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); } else { samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); } /* Disable phy isolation */ if (sphy->plat && sphy->plat->pmu_isolation) sphy->plat->pmu_isolation(false); else samsung_usbphy_set_isolation(sphy, false); /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ samsung_usbphy_cfg_sel(sphy); /* Initialize usb phy registers */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) samsung_exynos5_usbphy_enable(sphy); else samsung_usbphy_enable(sphy); spin_unlock_irqrestore(&sphy->lock, flags); /* Disable the phy clock */ clk_disable_unprepare(sphy->clk); return ret; }
static bool samsung_usb2phy_is_active(struct usb_phy *phy) { struct samsung_usbphy *sphy = phy_to_sphy(phy); unsigned long flags; bool ret; spin_lock_irqsave(&sphy->lock, flags); if (!sphy->usage_count || pm_runtime_suspended(sphy->dev)) ret = false; else ret = true; spin_unlock_irqrestore(&sphy->lock, flags); return ret; }
/* * The function passed to the usb driver for phy shutdown */ static void samsung_usbphy_shutdown(struct usb_phy *phy) { struct samsung_usbphy *sphy; struct usb_bus *host = NULL; unsigned long flags; sphy = phy_to_sphy(phy); host = phy->otg->host; if (clk_prepare_enable(sphy->clk)) { dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__); return; } spin_lock_irqsave(&sphy->lock, flags); if (host) { /* setting default phy-type for USB 2.0 */ if (!strstr(dev_name(host->controller), "ehci") || !strstr(dev_name(host->controller), "ohci")) samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); } else { samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); } /* De-initialize usb phy registers */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) samsung_exynos5_usbphy_disable(sphy); else samsung_usbphy_disable(sphy); /* Enable phy isolation */ if (sphy->plat && sphy->plat->pmu_isolation) sphy->plat->pmu_isolation(true); else samsung_usbphy_set_isolation(sphy, true); spin_unlock_irqrestore(&sphy->lock, flags); clk_disable_unprepare(sphy->clk); }
/* * The function passed to the usb driver for phy shutdown */ static void samsung_usb2phy_shutdown(struct usb_phy *phy) { struct samsung_usbphy *sphy; struct usb_bus *host = NULL; unsigned long flags; sphy = phy_to_sphy(phy); dev_dbg(sphy->dev, "%s\n", __func__); host = phy->otg->host; if (clk_enable(sphy->clk)) { dev_err(sphy->dev, "%s: clk_enable failed\n", __func__); return; } spin_lock_irqsave(&sphy->lock, flags); if (!sphy->usage_count) { dev_dbg(sphy->dev, "PHY is already shutdown\n"); spin_unlock_irqrestore(&sphy->lock, flags); goto exit1; } sphy->usage_count--; if (sphy->usage_count) { dev_dbg(sphy->dev, "PHY is still in use\n"); spin_unlock_irqrestore(&sphy->lock, flags); goto exit2; } if (host) { /* setting default phy-type for USB 2.0 */ if (!strstr(dev_name(host->controller), "ehci") || !strstr(dev_name(host->controller), "ohci")) samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); } else { samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); } /* De-initialize usb phy registers */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250 || sphy->drv_data->cpu_type == TYPE_EXYNOS5) samsung_exynos5_usb2phy_disable(sphy); else samsung_usb2phy_disable(sphy); /* Enable phy isolation */ if (sphy->plat && sphy->plat->pmu_isolation) { sphy->plat->pmu_isolation(true); } else { samsung_usbphy_set_isolation(sphy, true); if (sphy->has_hsic_pmureg == true) samsung_hsicphy_set_isolation(sphy, true); } spin_unlock_irqrestore(&sphy->lock, flags); pm_runtime_disable(phy->dev); pm_runtime_set_suspended(phy->dev); exit2: pm_runtime_put_noidle(phy->dev); exit1: clk_disable(sphy->clk); }
/* * The function passed to the usb driver for phy initialization */ static int samsung_usb2phy_init(struct usb_phy *phy) { struct samsung_usbphy *sphy; struct usb_bus *host = NULL; unsigned long flags; int ret = 0; sphy = phy_to_sphy(phy); dev_dbg(sphy->dev, "%s\n", __func__); host = phy->otg->host; /* Enable the phy clock */ ret = clk_enable(sphy->clk); if (ret) { dev_err(sphy->dev, "%s: clk_enable failed\n", __func__); return ret; } spin_lock_irqsave(&sphy->lock, flags); sphy->usage_count++; if (sphy->usage_count - 1) { dev_dbg(sphy->dev, "PHY is already initialized\n"); spin_unlock_irqrestore(&sphy->lock, flags); goto exit; } if (host) { /* setting default phy-type for USB 2.0 */ if (!strstr(dev_name(host->controller), "ehci") || !strstr(dev_name(host->controller), "ohci")) samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST); } else { samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE); } /* Disable phy isolation */ if (sphy->plat && sphy->plat->pmu_isolation) { sphy->plat->pmu_isolation(false); } else { samsung_usbphy_set_isolation(sphy, false); if (sphy->has_hsic_pmureg == true) samsung_hsicphy_set_isolation(sphy, false); } /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */ samsung_usbphy_cfg_sel(sphy); /* Initialize usb phy registers */ if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250 || sphy->drv_data->cpu_type == TYPE_EXYNOS5) samsung_exynos5_usb2phy_enable(sphy); else samsung_usb2phy_enable(sphy); spin_unlock_irqrestore(&sphy->lock, flags); pm_runtime_set_active(phy->dev); pm_runtime_enable(phy->dev); exit: pm_runtime_get_noresume(phy->dev); /* Disable the phy clock */ clk_disable(sphy->clk); return ret; }