Exemplo n.º 1
0
/*
 * 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);

	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_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);

	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);
}