aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-core.c
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2014-07-04 05:55:45 -0400
committerKishon Vijay Abraham I <kishon@ti.com>2014-07-22 03:16:10 -0400
commit3be88125d85df587085b0be0a5c0e9953eb5ed6b (patch)
treec0fd6fcb0c03681d6442381480e6f30c8d6f250d /drivers/phy/phy-core.c
parent016e0d3cb72c1433810fd85a7a7c0946e710d3d6 (diff)
phy: core: Support regulator supply for PHY power
Some PHYs can be powered by an external power regulator. e.g. USB_HS PHY on DRA7 SoC. Make the PHY core support a power regulator. Signed-off-by: Roger Quadros <rogerq@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.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 49c446530101..75c97396dbfa 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -21,6 +21,7 @@
21#include <linux/phy/phy.h> 21#include <linux/phy/phy.h>
22#include <linux/idr.h> 22#include <linux/idr.h>
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/regulator/consumer.h>
24 25
25static struct class *phy_class; 26static struct class *phy_class;
26static DEFINE_MUTEX(phy_provider_mutex); 27static DEFINE_MUTEX(phy_provider_mutex);
@@ -226,6 +227,12 @@ int phy_power_on(struct phy *phy)
226 if (!phy) 227 if (!phy)
227 return 0; 228 return 0;
228 229
230 if (phy->pwr) {
231 ret = regulator_enable(phy->pwr);
232 if (ret)
233 return ret;
234 }
235
229 ret = phy_pm_runtime_get_sync(phy); 236 ret = phy_pm_runtime_get_sync(phy);
230 if (ret < 0 && ret != -ENOTSUPP) 237 if (ret < 0 && ret != -ENOTSUPP)
231 return ret; 238 return ret;
@@ -247,6 +254,8 @@ int phy_power_on(struct phy *phy)
247out: 254out:
248 mutex_unlock(&phy->mutex); 255 mutex_unlock(&phy->mutex);
249 phy_pm_runtime_put_sync(phy); 256 phy_pm_runtime_put_sync(phy);
257 if (phy->pwr)
258 regulator_disable(phy->pwr);
250 259
251 return ret; 260 return ret;
252} 261}
@@ -272,6 +281,9 @@ int phy_power_off(struct phy *phy)
272 mutex_unlock(&phy->mutex); 281 mutex_unlock(&phy->mutex);
273 phy_pm_runtime_put(phy); 282 phy_pm_runtime_put(phy);
274 283
284 if (phy->pwr)
285 regulator_disable(phy->pwr);
286
275 return 0; 287 return 0;
276} 288}
277EXPORT_SYMBOL_GPL(phy_power_off); 289EXPORT_SYMBOL_GPL(phy_power_off);
@@ -588,6 +600,16 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
588 goto free_phy; 600 goto free_phy;
589 } 601 }
590 602
603 /* phy-supply */
604 phy->pwr = regulator_get_optional(dev, "phy");
605 if (IS_ERR(phy->pwr)) {
606 if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) {
607 ret = -EPROBE_DEFER;
608 goto free_ida;
609 }
610 phy->pwr = NULL;
611 }
612
591 device_initialize(&phy->dev); 613 device_initialize(&phy->dev);
592 mutex_init(&phy->mutex); 614 mutex_init(&phy->mutex);
593 615
@@ -617,6 +639,9 @@ put_dev:
617 put_device(&phy->dev); /* calls phy_release() which frees resources */ 639 put_device(&phy->dev); /* calls phy_release() which frees resources */
618 return ERR_PTR(ret); 640 return ERR_PTR(ret);
619 641
642free_ida:
643 ida_simple_remove(&phy_ida, phy->id);
644
620free_phy: 645free_phy:
621 kfree(phy); 646 kfree(phy);
622 return ERR_PTR(ret); 647 return ERR_PTR(ret);
@@ -800,6 +825,7 @@ static void phy_release(struct device *dev)
800 825
801 phy = to_phy(dev); 826 phy = to_phy(dev);
802 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); 827 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
828 regulator_put(phy->pwr);
803 ida_simple_remove(&phy_ida, phy->id); 829 ida_simple_remove(&phy_ida, phy->id);
804 kfree(phy); 830 kfree(phy);
805} 831}