]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/phy/phy-core.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[mirror_ubuntu-artful-kernel.git] / drivers / phy / phy-core.c
index 58e0e97390287364287eae1eecdf8b43ba7b72f1..645c867c12573e554d43e3700155db5469841caa 100644 (file)
@@ -94,19 +94,31 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
 
 int phy_pm_runtime_get(struct phy *phy)
 {
+       int ret;
+
        if (!pm_runtime_enabled(&phy->dev))
                return -ENOTSUPP;
 
-       return pm_runtime_get(&phy->dev);
+       ret = pm_runtime_get(&phy->dev);
+       if (ret < 0 && ret != -EINPROGRESS)
+               pm_runtime_put_noidle(&phy->dev);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(phy_pm_runtime_get);
 
 int phy_pm_runtime_get_sync(struct phy *phy)
 {
+       int ret;
+
        if (!pm_runtime_enabled(&phy->dev))
                return -ENOTSUPP;
 
-       return pm_runtime_get_sync(&phy->dev);
+       ret = pm_runtime_get_sync(&phy->dev);
+       if (ret < 0)
+               pm_runtime_put_sync(&phy->dev);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync);
 
@@ -155,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);
@@ -179,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);
@@ -196,23 +210,27 @@ EXPORT_SYMBOL_GPL(phy_exit);
 
 int phy_power_on(struct phy *phy)
 {
-       int ret = -ENOTSUPP;
+       int ret;
 
        ret = phy_pm_runtime_get_sync(phy);
        if (ret < 0 && ret != -ENOTSUPP)
                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;
 }
@@ -220,22 +238,22 @@ EXPORT_SYMBOL_GPL(phy_power_on);
 
 int phy_power_off(struct phy *phy)
 {
-       int ret = -ENOTSUPP;
+       int ret;
 
        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);
 
@@ -360,7 +378,7 @@ EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
 struct phy *phy_get(struct device *dev, const char *string)
 {
        int index = 0;
-       struct phy *phy = NULL;
+       struct phy *phy;
 
        if (string == NULL) {
                dev_WARN(dev, "missing string\n");