aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-core.c
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2013-12-20 00:06:49 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2013-12-24 13:22:58 -0500
commit637d378cea0b463c466a61a6564cdd541d689af5 (patch)
tree51cb3c6ca847c33d0305547ba2b1f21d47759ff8 /drivers/phy/phy-core.c
parentcedb7f89d1e1f631b7e5d920fe1ea7f742d07f79 (diff)
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 <george.cherian@ti.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy/phy-core.c')
-rw-r--r--drivers/phy/phy-core.c22
1 files changed, 14 insertions, 8 deletions
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)
167 return ret; 167 return ret;
168 168
169 mutex_lock(&phy->mutex); 169 mutex_lock(&phy->mutex);
170 if (phy->init_count++ == 0 && phy->ops->init) { 170 if (phy->init_count == 0 && phy->ops->init) {
171 ret = phy->ops->init(phy); 171 ret = phy->ops->init(phy);
172 if (ret < 0) { 172 if (ret < 0) {
173 dev_err(&phy->dev, "phy init failed --> %d\n", ret); 173 dev_err(&phy->dev, "phy init failed --> %d\n", ret);
174 goto out; 174 goto out;
175 } 175 }
176 } 176 }
177 ++phy->init_count;
177 178
178out: 179out:
179 mutex_unlock(&phy->mutex); 180 mutex_unlock(&phy->mutex);
@@ -191,13 +192,14 @@ int phy_exit(struct phy *phy)
191 return ret; 192 return ret;
192 193
193 mutex_lock(&phy->mutex); 194 mutex_lock(&phy->mutex);
194 if (--phy->init_count == 0 && phy->ops->exit) { 195 if (phy->init_count == 1 && phy->ops->exit) {
195 ret = phy->ops->exit(phy); 196 ret = phy->ops->exit(phy);
196 if (ret < 0) { 197 if (ret < 0) {
197 dev_err(&phy->dev, "phy exit failed --> %d\n", ret); 198 dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
198 goto out; 199 goto out;
199 } 200 }
200 } 201 }
202 --phy->init_count;
201 203
202out: 204out:
203 mutex_unlock(&phy->mutex); 205 mutex_unlock(&phy->mutex);
@@ -215,16 +217,20 @@ int phy_power_on(struct phy *phy)
215 return ret; 217 return ret;
216 218
217 mutex_lock(&phy->mutex); 219 mutex_lock(&phy->mutex);
218 if (phy->power_count++ == 0 && phy->ops->power_on) { 220 if (phy->power_count == 0 && phy->ops->power_on) {
219 ret = phy->ops->power_on(phy); 221 ret = phy->ops->power_on(phy);
220 if (ret < 0) { 222 if (ret < 0) {
221 dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); 223 dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
222 goto out; 224 goto out;
223 } 225 }
224 } 226 }
227 ++phy->power_count;
228 mutex_unlock(&phy->mutex);
229 return 0;
225 230
226out: 231out:
227 mutex_unlock(&phy->mutex); 232 mutex_unlock(&phy->mutex);
233 phy_pm_runtime_put_sync(phy);
228 234
229 return ret; 235 return ret;
230} 236}
@@ -235,19 +241,19 @@ int phy_power_off(struct phy *phy)
235 int ret = -ENOTSUPP; 241 int ret = -ENOTSUPP;
236 242
237 mutex_lock(&phy->mutex); 243 mutex_lock(&phy->mutex);
238 if (--phy->power_count == 0 && phy->ops->power_off) { 244 if (phy->power_count == 1 && phy->ops->power_off) {
239 ret = phy->ops->power_off(phy); 245 ret = phy->ops->power_off(phy);
240 if (ret < 0) { 246 if (ret < 0) {
241 dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret); 247 dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
242 goto out; 248 mutex_unlock(&phy->mutex);
249 return ret;
243 } 250 }
244 } 251 }
245 252 --phy->power_count;
246out:
247 mutex_unlock(&phy->mutex); 253 mutex_unlock(&phy->mutex);
248 phy_pm_runtime_put(phy); 254 phy_pm_runtime_put(phy);
249 255
250 return ret; 256 return 0;
251} 257}
252EXPORT_SYMBOL_GPL(phy_power_off); 258EXPORT_SYMBOL_GPL(phy_power_off);
253 259