From 637d378cea0b463c466a61a6564cdd541d689af5 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 20 Dec 2013 10:36:49 +0530 Subject: 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: George Cherian Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/phy/phy-core.c') diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 8797bb7d9c48..33fcbcc5561f 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -167,13 +167,14 @@ int phy_init(struct phy *phy) return ret; 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); if (ret < 0) { dev_err(&phy->dev, "phy init failed --> %d\n", ret); goto out; } } + ++phy->init_count; out: mutex_unlock(&phy->mutex); @@ -191,13 +192,14 @@ int phy_exit(struct phy *phy) return ret; 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); if (ret < 0) { dev_err(&phy->dev, "phy exit failed --> %d\n", ret); goto out; } } + --phy->init_count; out: mutex_unlock(&phy->mutex); @@ -215,16 +217,20 @@ int phy_power_on(struct phy *phy) return ret; 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); if (ret < 0) { dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); goto out; } } + ++phy->power_count; + mutex_unlock(&phy->mutex); + return 0; out: mutex_unlock(&phy->mutex); + phy_pm_runtime_put_sync(phy); return ret; } @@ -235,19 +241,19 @@ int phy_power_off(struct phy *phy) int ret = -ENOTSUPP; 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); if (ret < 0) { dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); - goto out; + mutex_unlock(&phy->mutex); + return ret; } } - -out: + --phy->power_count; mutex_unlock(&phy->mutex); phy_pm_runtime_put(phy); - return ret; + return 0; } EXPORT_SYMBOL_GPL(phy_power_off); -- cgit