aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/phy-core.c')
-rw-r--r--drivers/phy/phy-core.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 49c446530101..ff5eec5af817 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);
@@ -86,10 +87,15 @@ static struct phy *phy_lookup(struct device *device, const char *port)
86static struct phy_provider *of_phy_provider_lookup(struct device_node *node) 87static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
87{ 88{
88 struct phy_provider *phy_provider; 89 struct phy_provider *phy_provider;
90 struct device_node *child;
89 91
90 list_for_each_entry(phy_provider, &phy_provider_list, list) { 92 list_for_each_entry(phy_provider, &phy_provider_list, list) {
91 if (phy_provider->dev->of_node == node) 93 if (phy_provider->dev->of_node == node)
92 return phy_provider; 94 return phy_provider;
95
96 for_each_child_of_node(phy_provider->dev->of_node, child)
97 if (child == node)
98 return phy_provider;
93 } 99 }
94 100
95 return ERR_PTR(-EPROBE_DEFER); 101 return ERR_PTR(-EPROBE_DEFER);
@@ -226,6 +232,12 @@ int phy_power_on(struct phy *phy)
226 if (!phy) 232 if (!phy)
227 return 0; 233 return 0;
228 234
235 if (phy->pwr) {
236 ret = regulator_enable(phy->pwr);
237 if (ret)
238 return ret;
239 }
240
229 ret = phy_pm_runtime_get_sync(phy); 241 ret = phy_pm_runtime_get_sync(phy);
230 if (ret < 0 && ret != -ENOTSUPP) 242 if (ret < 0 && ret != -ENOTSUPP)
231 return ret; 243 return ret;
@@ -247,6 +259,8 @@ int phy_power_on(struct phy *phy)
247out: 259out:
248 mutex_unlock(&phy->mutex); 260 mutex_unlock(&phy->mutex);
249 phy_pm_runtime_put_sync(phy); 261 phy_pm_runtime_put_sync(phy);
262 if (phy->pwr)
263 regulator_disable(phy->pwr);
250 264
251 return ret; 265 return ret;
252} 266}
@@ -272,6 +286,9 @@ int phy_power_off(struct phy *phy)
272 mutex_unlock(&phy->mutex); 286 mutex_unlock(&phy->mutex);
273 phy_pm_runtime_put(phy); 287 phy_pm_runtime_put(phy);
274 288
289 if (phy->pwr)
290 regulator_disable(phy->pwr);
291
275 return 0; 292 return 0;
276} 293}
277EXPORT_SYMBOL_GPL(phy_power_off); 294EXPORT_SYMBOL_GPL(phy_power_off);
@@ -398,13 +415,20 @@ struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
398 struct phy *phy; 415 struct phy *phy;
399 struct class_dev_iter iter; 416 struct class_dev_iter iter;
400 struct device_node *node = dev->of_node; 417 struct device_node *node = dev->of_node;
418 struct device_node *child;
401 419
402 class_dev_iter_init(&iter, phy_class, NULL, NULL); 420 class_dev_iter_init(&iter, phy_class, NULL, NULL);
403 while ((dev = class_dev_iter_next(&iter))) { 421 while ((dev = class_dev_iter_next(&iter))) {
404 phy = to_phy(dev); 422 phy = to_phy(dev);
405 if (node != phy->dev.of_node) 423 if (node != phy->dev.of_node) {
424 for_each_child_of_node(node, child) {
425 if (child == phy->dev.of_node)
426 goto phy_found;
427 }
406 continue; 428 continue;
429 }
407 430
431phy_found:
408 class_dev_iter_exit(&iter); 432 class_dev_iter_exit(&iter);
409 return phy; 433 return phy;
410 } 434 }
@@ -562,13 +586,15 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
562/** 586/**
563 * phy_create() - create a new phy 587 * phy_create() - create a new phy
564 * @dev: device that is creating the new phy 588 * @dev: device that is creating the new phy
589 * @node: device node of the phy
565 * @ops: function pointers for performing phy operations 590 * @ops: function pointers for performing phy operations
566 * @init_data: contains the list of PHY consumers or NULL 591 * @init_data: contains the list of PHY consumers or NULL
567 * 592 *
568 * Called to create a phy using phy framework. 593 * Called to create a phy using phy framework.
569 */ 594 */
570struct phy *phy_create(struct device *dev, const struct phy_ops *ops, 595struct phy *phy_create(struct device *dev, struct device_node *node,
571 struct phy_init_data *init_data) 596 const struct phy_ops *ops,
597 struct phy_init_data *init_data)
572{ 598{
573 int ret; 599 int ret;
574 int id; 600 int id;
@@ -588,12 +614,22 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
588 goto free_phy; 614 goto free_phy;
589 } 615 }
590 616
617 /* phy-supply */
618 phy->pwr = regulator_get_optional(dev, "phy");
619 if (IS_ERR(phy->pwr)) {
620 if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) {
621 ret = -EPROBE_DEFER;
622 goto free_ida;
623 }
624 phy->pwr = NULL;
625 }
626
591 device_initialize(&phy->dev); 627 device_initialize(&phy->dev);
592 mutex_init(&phy->mutex); 628 mutex_init(&phy->mutex);
593 629
594 phy->dev.class = phy_class; 630 phy->dev.class = phy_class;
595 phy->dev.parent = dev; 631 phy->dev.parent = dev;
596 phy->dev.of_node = dev->of_node; 632 phy->dev.of_node = node ?: dev->of_node;
597 phy->id = id; 633 phy->id = id;
598 phy->ops = ops; 634 phy->ops = ops;
599 phy->init_data = init_data; 635 phy->init_data = init_data;
@@ -617,6 +653,9 @@ put_dev:
617 put_device(&phy->dev); /* calls phy_release() which frees resources */ 653 put_device(&phy->dev); /* calls phy_release() which frees resources */
618 return ERR_PTR(ret); 654 return ERR_PTR(ret);
619 655
656free_ida:
657 ida_simple_remove(&phy_ida, phy->id);
658
620free_phy: 659free_phy:
621 kfree(phy); 660 kfree(phy);
622 return ERR_PTR(ret); 661 return ERR_PTR(ret);
@@ -626,6 +665,7 @@ EXPORT_SYMBOL_GPL(phy_create);
626/** 665/**
627 * devm_phy_create() - create a new phy 666 * devm_phy_create() - create a new phy
628 * @dev: device that is creating the new phy 667 * @dev: device that is creating the new phy
668 * @node: device node of the phy
629 * @ops: function pointers for performing phy operations 669 * @ops: function pointers for performing phy operations
630 * @init_data: contains the list of PHY consumers or NULL 670 * @init_data: contains the list of PHY consumers or NULL
631 * 671 *
@@ -634,8 +674,9 @@ EXPORT_SYMBOL_GPL(phy_create);
634 * On driver detach, release function is invoked on the devres data, 674 * On driver detach, release function is invoked on the devres data,
635 * then, devres data is freed. 675 * then, devres data is freed.
636 */ 676 */
637struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops, 677struct phy *devm_phy_create(struct device *dev, struct device_node *node,
638 struct phy_init_data *init_data) 678 const struct phy_ops *ops,
679 struct phy_init_data *init_data)
639{ 680{
640 struct phy **ptr, *phy; 681 struct phy **ptr, *phy;
641 682
@@ -643,7 +684,7 @@ struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
643 if (!ptr) 684 if (!ptr)
644 return ERR_PTR(-ENOMEM); 685 return ERR_PTR(-ENOMEM);
645 686
646 phy = phy_create(dev, ops, init_data); 687 phy = phy_create(dev, node, ops, init_data);
647 if (!IS_ERR(phy)) { 688 if (!IS_ERR(phy)) {
648 *ptr = phy; 689 *ptr = phy;
649 devres_add(dev, ptr); 690 devres_add(dev, ptr);
@@ -800,6 +841,7 @@ static void phy_release(struct device *dev)
800 841
801 phy = to_phy(dev); 842 phy = to_phy(dev);
802 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev)); 843 dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
844 regulator_put(phy->pwr);
803 ida_simple_remove(&phy_ida, phy->id); 845 ida_simple_remove(&phy_ida, phy->id);
804 kfree(phy); 846 kfree(phy);
805} 847}