Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d33d480 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: phy: qusb: Rely on regulator_enable() for ref_counting"

parents 74364669 6c84f205
Loading
Loading
Loading
Loading
+13 −49
Original line number Diff line number Diff line
@@ -119,8 +119,6 @@ struct qusb_phy {
	int			efuse_bit_pos;
	int			efuse_num_of_bits;

	int			power_enabled_ref;
	bool			clocks_enabled;
	bool			cable_connected;
	bool			suspended;
	bool			dpdm_enable;
@@ -148,10 +146,9 @@ struct qusb_phy {

static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
{
	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
			__func__, qphy->clocks_enabled, on);
	dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on);

	if (!qphy->clocks_enabled && on) {
	if (on) {
		clk_prepare_enable(qphy->ref_clk_src);
		if (qphy->ref_clk)
			clk_prepare_enable(qphy->ref_clk);
@@ -159,10 +156,7 @@ static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
		if (qphy->cfg_ahb_clk)
			clk_prepare_enable(qphy->cfg_ahb_clk);

		qphy->clocks_enabled = true;
	}

	if (qphy->clocks_enabled && !on) {
	} else {
		if (qphy->cfg_ahb_clk)
			clk_disable_unprepare(qphy->cfg_ahb_clk);

@@ -170,11 +164,7 @@ static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
			clk_disable_unprepare(qphy->ref_clk);

		clk_disable_unprepare(qphy->ref_clk_src);
		qphy->clocks_enabled = false;
	}

	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d\n", __func__,
						qphy->clocks_enabled);
}

static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high)
@@ -200,30 +190,12 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)

	mutex_lock(&qphy->lock);

	dev_dbg(qphy->phy.dev,
		"%s:req to turn %s regulators. power_enabled_ref:%d\n",
			__func__, on ? "on" : "off", qphy->power_enabled_ref);

	if (on && ++qphy->power_enabled_ref > 1) {
		dev_dbg(qphy->phy.dev, "PHYs' regulators are already on\n");
		goto done;
	}

	if (!on) {
		if (on == qphy->power_enabled_ref) {
			dev_dbg(qphy->phy.dev,
				"PHYs' regulators are already off\n");
			goto done;
		}
	dev_dbg(qphy->phy.dev, "%s:req to turn %s regulators\n",
			__func__, on ? "on" : "off");

		qphy->power_enabled_ref--;
		if (!qphy->power_enabled_ref)
	if (!on)
		goto disable_vdda33;

		dev_dbg(qphy->phy.dev, "Skip turning off PHYs' regulators\n");
		goto done;
	}

	ret = qusb_phy_config_vdd(qphy, true);
	if (ret) {
		dev_err(qphy->phy.dev, "Unable to config VDD:%d\n",
@@ -328,11 +300,8 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
err_vdd:
	dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n");

	/* in case of error in turning on regulators */
	if (qphy->power_enabled_ref)
		qphy->power_enabled_ref--;
done:
	mutex_unlock(&qphy->lock);

	return ret;
}

@@ -473,17 +442,11 @@ static void qusb_phy_host_init(struct usb_phy *phy)
static int qusb_phy_init(struct usb_phy *phy)
{
	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
	int ret, p_index;
	int p_index;
	u8 reg;

	dev_dbg(phy->dev, "%s\n", __func__);

	ret = qusb_phy_enable_power(qphy, true);
	if (ret)
		return ret;

	qusb_phy_enable_clocks(qphy, true);

	qusb_phy_reset(qphy);

	if (qphy->qusb_phy_host_init_seq && qphy->phy.flags & PHY_HOST_MODE) {
@@ -609,7 +572,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
	u32 linestate = 0, intr_mask = 0;

	if (qphy->suspended && suspend) {
	if (qphy->suspended == suspend) {
		dev_dbg(phy->dev, "%s: USB PHY is already suspended\n",
			__func__);
		return 0;
@@ -1137,6 +1100,7 @@ static int qusb_phy_probe(struct platform_device *pdev)
	if (ret)
		usb_remove_phy(&qphy->phy);

	qphy->suspended = true;
	qusb_phy_create_debugfs(qphy);

	return ret;
@@ -1147,8 +1111,8 @@ static int qusb_phy_remove(struct platform_device *pdev)
	struct qusb_phy *qphy = platform_get_drvdata(pdev);

	usb_remove_phy(&qphy->phy);
	qusb_phy_enable_clocks(qphy, false);
	qusb_phy_enable_power(qphy, false);
	qphy->cable_connected = false;
	qusb_phy_set_suspend(&qphy->phy, true);
	debugfs_remove_recursive(qphy->root);

	return 0;
+20 −52
Original line number Diff line number Diff line
@@ -149,8 +149,6 @@ struct qusb_phy {
	int			tune2_efuse_num_of_bits;
	int			tune2_efuse_correction;

	bool			power_enabled;
	bool			clocks_enabled;
	bool			cable_connected;
	bool			suspended;
	bool			ulpi_mode;
@@ -175,19 +173,15 @@ struct qusb_phy {

static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
{
	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
			__func__, qphy->clocks_enabled, on);
	dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on);

	if (!qphy->clocks_enabled && on) {
	if (on) {
		clk_prepare_enable(qphy->ref_clk_src);
		clk_prepare_enable(qphy->ref_clk);
		clk_prepare_enable(qphy->iface_clk);
		clk_prepare_enable(qphy->core_clk);
		clk_prepare_enable(qphy->cfg_ahb_clk);
		qphy->clocks_enabled = true;
	}

	if (qphy->clocks_enabled && !on) {
	} else {
		clk_disable_unprepare(qphy->cfg_ahb_clk);
		/*
		 * FSM depedency beween iface_clk and core_clk.
@@ -197,11 +191,8 @@ static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
		clk_disable_unprepare(qphy->iface_clk);
		clk_disable_unprepare(qphy->ref_clk);
		clk_disable_unprepare(qphy->ref_clk_src);
		qphy->clocks_enabled = false;
	}

	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d\n", __func__,
						qphy->clocks_enabled);
}

static int qusb_phy_gdsc(struct qusb_phy *qphy, bool on)
@@ -251,13 +242,8 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
{
	int ret = 0;

	dev_dbg(qphy->phy.dev, "%s turn %s regulators. power_enabled:%d\n",
			__func__, on ? "on" : "off", qphy->power_enabled);

	if (qphy->power_enabled == on) {
		dev_dbg(qphy->phy.dev, "PHYs' regulators are already ON.\n");
		return 0;
	}
	dev_dbg(qphy->phy.dev, "%s turn %s regulators\n",
			__func__, on ? "on" : "off");

	if (!on)
		goto disable_vdda33;
@@ -315,8 +301,6 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
		goto unset_vdd33;
	}

	qphy->power_enabled = true;

	pr_debug("%s(): QUSB PHY's regulators are turned ON.\n", __func__);
	return ret;

@@ -364,8 +348,8 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
		dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n",
								ret);
err_vdd:
	qphy->power_enabled = false;
	dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n");

	return ret;
}

@@ -440,12 +424,6 @@ static int qusb_phy_init(struct usb_phy *phy)

	dev_dbg(phy->dev, "%s\n", __func__);

	ret = qusb_phy_enable_power(qphy, true);
	if (ret)
		return ret;

	qusb_phy_enable_clocks(qphy, true);

	/*
	 * ref clock is enabled by default after power on reset. Linux clock
	 * driver will disable this clock as part of late init if peripheral
@@ -648,7 +626,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
	u32 linestate = 0, intr_mask = 0;

	if (qphy->suspended && suspend) {
	if (qphy->suspended == suspend) {
		dev_dbg(phy->dev, "%s: USB PHY is already suspended\n",
			__func__);
		return 0;
@@ -722,11 +700,7 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
			}

			qusb_phy_enable_clocks(qphy, false);
			/* Do not disable power rails if there is vote for it */
			if (!qphy->dpdm_enable)
			qusb_phy_enable_power(qphy, false);
			else
				dev_dbg(phy->dev, "race with rm_pulldown. Keep ldo ON\n");
			mutex_unlock(&qphy->phy_lock);

			/*
@@ -861,20 +835,19 @@ static int qusb_phy_dpdm_regulator_disable(struct regulator_dev *rdev)

	mutex_lock(&qphy->phy_lock);
	if (qphy->dpdm_enable) {
		/* If usb core is active, rely on set_suspend to clamp phy */
		if (!qphy->cable_connected) {
			if (qphy->tcsr_clamp_dig_n)
				writel_relaxed(0x0,
					qphy->tcsr_clamp_dig_n);
			dev_dbg(qphy->phy.dev, "turn off for HVDCP case\n");
		}
		ret = qusb_phy_enable_power(qphy, false);
		if (ret < 0) {
			dev_dbg(qphy->phy.dev,
					"dpdm regulator disable failed:%d\n",
					ret);
				"dpdm regulator disable failed:%d\n", ret);
			mutex_unlock(&qphy->phy_lock);
			return ret;
		}
		}
		qphy->dpdm_enable = false;
	}
	mutex_unlock(&qphy->phy_lock);
@@ -1241,6 +1214,8 @@ static int qusb_phy_probe(struct platform_device *pdev)
	if (qphy->tcsr_clamp_dig_n)
		writel_relaxed(0x0, qphy->tcsr_clamp_dig_n);

	qphy->suspended = true;

	return ret;
}

@@ -1249,15 +1224,8 @@ static int qusb_phy_remove(struct platform_device *pdev)
	struct qusb_phy *qphy = platform_get_drvdata(pdev);

	usb_remove_phy(&qphy->phy);

	if (qphy->clocks_enabled) {
		clk_disable_unprepare(qphy->cfg_ahb_clk);
		clk_disable_unprepare(qphy->ref_clk);
		clk_disable_unprepare(qphy->ref_clk_src);
		qphy->clocks_enabled = false;
	}

	qusb_phy_enable_power(qphy, false);
	qphy->cable_connected = false;
	qusb_phy_set_suspend(&qphy->phy, true);

	return 0;
}