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

Commit 1e723afa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: phy: msm: Handle multiport suspend/resume"

parents f1e8dfdc fc017bf3
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ struct msm_hsphy {
	bool			cable_connected;
};

/* global reference counter between all HSPHY instances */
static atomic_t hsphy_active_count;

static int msm_hsusb_config_vdd(struct msm_hsphy *phy, int high)
{
	int min, ret;
@@ -263,6 +266,13 @@ static int msm_hsphy_reset(struct usb_phy *uphy)
	u32 val;
	int ret;

	/* skip reset if there are other active PHY instances */
	ret = atomic_read(&hsphy_active_count);
	if (ret > 1) {
		dev_dbg(uphy->dev, "skipping reset, inuse count=%d\n", ret);
		return 0;
	}

	if (phy->tcsr) {
		val = readl_relaxed(phy->tcsr);

@@ -354,7 +364,7 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
	struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
	bool host = uphy->flags & PHY_HOST_MODE;
	bool chg_connected = uphy->flags & PHY_CHARGER_CONNECTED;
	int i;
	int i, count;

	if (!!suspend == phy->suspended) {
		dev_dbg(uphy->dev, "%s\n", suspend ? "already suspended"
@@ -438,7 +448,15 @@ static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
			}
			msm_hsusb_config_vdd(phy, 0);
		}

		count = atomic_dec_return(&hsphy_active_count);
		if (count < 0) {
			dev_WARN(uphy->dev, "hsphy_active_count=%d, something wrong?\n",
					count);
			atomic_set(&hsphy_active_count, 0);
		}
	} else {
		atomic_inc(&hsphy_active_count);
		if (phy->lpm_flags & PHY_RETENTIONED && !phy->cable_connected) {
			msm_hsusb_config_vdd(phy, 1);
			if (phy->ext_vbus_id) {
@@ -736,6 +754,7 @@ static int msm_hsphy_probe(struct platform_device *pdev)
	if (ret)
		goto disable_clk;

	atomic_inc(&hsphy_active_count);
	return 0;

disable_clk:
@@ -762,6 +781,8 @@ static int msm_hsphy_remove(struct platform_device *pdev)
	msm_hsusb_ldo_enable(phy, 0);
	regulator_disable(phy->vdd);
	msm_hsusb_config_vdd(phy, 0);
	if (!phy->suspended)
		atomic_dec(&hsphy_active_count);
	kfree(phy);

	return 0;
+25 −9
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct msm_ssphy {
	struct clk		*reset_clk;	/* SS PHY reset */
	struct regulator	*vdd;
	struct regulator	*vdda18;
	atomic_t		active_count;	/* num of active instances */
	bool			suspended;
	int			vdd_levels[3]; /* none, low, high */
	int			deemphasis_val;
@@ -331,18 +332,25 @@ static int msm_ssphy_set_suspend(struct usb_phy *uphy, int suspend)
{
	struct msm_ssphy *phy = container_of(uphy, struct msm_ssphy, phy);
	void __iomem *base = phy->base;
	int ret = 0;

	if (!!suspend == phy->suspended) {
		dev_dbg(uphy->dev, "%s\n", suspend ? "already suspended"
						   : "already resumed");
		return 0;
	}
	int count;

	/* Ensure clock is on before accessing QSCRATCH registers */
	clk_prepare_enable(phy->core_clk);

	if (suspend) {
		count = atomic_dec_return(&phy->active_count);
		if (count > 0 || phy->suspended) {
			dev_dbg(uphy->dev, "Skipping suspend, active_count=%d phy->suspended=%d\n",
					count, phy->suspended);
			goto done;
		}

		if (count < 0) {
			dev_WARN(uphy->dev, "Suspended too many times!  active_count=%d\n",
					count);
			atomic_set(&phy->active_count, 0);
		}

		/* Clear REF_SS_PHY_EN */
		msm_usb_write_readback(base, SS_PHY_CTRL_REG, REF_SS_PHY_EN, 0);
		/* Clear REF_USE_PAD */
@@ -359,7 +367,16 @@ static int msm_ssphy_set_suspend(struct usb_phy *uphy, int suspend)

		msm_ssusb_ldo_enable(phy, 0);
		msm_ssusb_config_vdd(phy, 0);
		phy->suspended = true;
	} else {
		count = atomic_inc_return(&phy->active_count);
		if (count > 1 || !phy->suspended) {
			dev_dbg(uphy->dev, "Skipping resume, active_count=%d phy->suspended=%d\n",
					count, phy->suspended);
			goto done;
		}

		phy->suspended = false;
		msm_ssusb_config_vdd(phy, 1);
		msm_ssusb_ldo_enable(phy, 1);

@@ -401,8 +418,7 @@ static int msm_ssphy_set_suspend(struct usb_phy *uphy, int suspend)

done:
	clk_disable_unprepare(phy->core_clk);
	phy->suspended = !!suspend; /* double-NOT coerces to bool value */
	return ret;
	return 0;
}

static int msm_ssphy_notify_connect(struct usb_phy *uphy,