phy: phy-core: increment refcounting variables only on 'success'

Increment 'init_count' only if the 'init' callback succeeded and decrement
'init_count' only if the 'exit' callback succeded. Increment 'power_count'
only if 'power_on' callback succeded and if it failed disable the clocks using
phy_pm_runtime_put_sync(). Also decrement 'power_count' only if 'power_off'
callback succeded and if it failed do not disable the clocks.
Reported-by: default avatarGeorge Cherian <george.cherian@ti.com>
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parent cedb7f89
...@@ -167,13 +167,14 @@ int phy_init(struct phy *phy) ...@@ -167,13 +167,14 @@ int phy_init(struct phy *phy)
return ret; return ret;
mutex_lock(&phy->mutex); mutex_lock(&phy->mutex);
if (phy->init_count++ == 0 && phy->ops->init) { if (phy->init_count == 0 && phy->ops->init) {
ret = phy->ops->init(phy); ret = phy->ops->init(phy);
if (ret < 0) { if (ret < 0) {
dev_err(&phy->dev, "phy init failed --> %d\n", ret); dev_err(&phy->dev, "phy init failed --> %d\n", ret);
goto out; goto out;
} }
} }
++phy->init_count;
out: out:
mutex_unlock(&phy->mutex); mutex_unlock(&phy->mutex);
...@@ -191,13 +192,14 @@ int phy_exit(struct phy *phy) ...@@ -191,13 +192,14 @@ int phy_exit(struct phy *phy)
return ret; return ret;
mutex_lock(&phy->mutex); mutex_lock(&phy->mutex);
if (--phy->init_count == 0 && phy->ops->exit) { if (phy->init_count == 1 && phy->ops->exit) {
ret = phy->ops->exit(phy); ret = phy->ops->exit(phy);
if (ret < 0) { if (ret < 0) {
dev_err(&phy->dev, "phy exit failed --> %d\n", ret); dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
goto out; goto out;
} }
} }
--phy->init_count;
out: out:
mutex_unlock(&phy->mutex); mutex_unlock(&phy->mutex);
...@@ -215,16 +217,20 @@ int phy_power_on(struct phy *phy) ...@@ -215,16 +217,20 @@ int phy_power_on(struct phy *phy)
return ret; return ret;
mutex_lock(&phy->mutex); mutex_lock(&phy->mutex);
if (phy->power_count++ == 0 && phy->ops->power_on) { if (phy->power_count == 0 && phy->ops->power_on) {
ret = phy->ops->power_on(phy); ret = phy->ops->power_on(phy);
if (ret < 0) { if (ret < 0) {
dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
goto out; goto out;
} }
} }
++phy->power_count;
mutex_unlock(&phy->mutex);
return 0;
out: out:
mutex_unlock(&phy->mutex); mutex_unlock(&phy->mutex);
phy_pm_runtime_put_sync(phy);
return ret; return ret;
} }
...@@ -235,19 +241,19 @@ int phy_power_off(struct phy *phy) ...@@ -235,19 +241,19 @@ int phy_power_off(struct phy *phy)
int ret = -ENOTSUPP; int ret = -ENOTSUPP;
mutex_lock(&phy->mutex); mutex_lock(&phy->mutex);
if (--phy->power_count == 0 && phy->ops->power_off) { if (phy->power_count == 1 && phy->ops->power_off) {
ret = phy->ops->power_off(phy); ret = phy->ops->power_off(phy);
if (ret < 0) { if (ret < 0) {
dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
goto out; mutex_unlock(&phy->mutex);
return ret;
} }
} }
--phy->power_count;
out:
mutex_unlock(&phy->mutex); mutex_unlock(&phy->mutex);
phy_pm_runtime_put(phy); phy_pm_runtime_put(phy);
return ret; return 0;
} }
EXPORT_SYMBOL_GPL(phy_power_off); EXPORT_SYMBOL_GPL(phy_power_off);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment