diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 17:57:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 17:57:16 -0500 |
commit | e7cf773d431a63a2417902696fcc9e0ebdc83bbe (patch) | |
tree | 86dbdceb7d91226507a3af0d57e03b0ca664b22e /drivers/phy/phy-core.c | |
parent | 7a02d089695a1217992434f03a78aa32bad85b5c (diff) | |
parent | 81e1dadfb5b2d47aa513ad60b1c9cf0ea17b6514 (diff) |
Merge tag 'usb-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH:
"Here's the big set of USB and PHY patches for 3.19-rc1.
The normal churn in the USB gadget area is in here, as well as xhci
and other individual USB driver updates. The PHY tree is also in
here, as there were dependancies on the USB tree.
All of these have been in linux-next"
* tag 'usb-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (351 commits)
arm: omap3: twl: remove usb phy init data
usbip: fix error handling in stub_probe()
usb: gadget: udc: missing curly braces
USB: mos7720: delete some unneeded code
wusb: replace memset by memzero_explicit
usbip: remove unneeded structure
usb: xhci: fix comment for PORT_DEV_REMOVE
xhci: don't use the same variable for stopped and halted rings current TD
xhci: clear extra bits from slot context when setting max exit latency
xhci: cleanup finish_td function
USB: adutux: NULL dereferences on disconnect
usb: chipidea: fix platform_no_drv_owner.cocci warnings
usb: chipidea: Fixed a few typos in comments
Documentation: bindings: add doc for the USB2 ChipIdea USB driver
usb: chipidea: add a usb2 driver for ci13xxx
usb: chipidea: fix phy handling
usb: chipidea: remove duplicate dev_set_drvdata for host_start
usb: chipidea: parameter 'mode' isn't needed for hw_device_reset
usb: chipidea: add controller reset API
usb: chipidea: remove flag CI_HDRC_REQUIRE_TRANSCEIVER
...
Diffstat (limited to 'drivers/phy/phy-core.c')
-rw-r--r-- | drivers/phy/phy-core.c | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index ff5eec5af817..a12d35338313 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | static struct class *phy_class; | 26 | static struct class *phy_class; |
27 | static DEFINE_MUTEX(phy_provider_mutex); | 27 | static DEFINE_MUTEX(phy_provider_mutex); |
28 | static LIST_HEAD(phy_provider_list); | 28 | static LIST_HEAD(phy_provider_list); |
29 | static LIST_HEAD(phys); | ||
29 | static DEFINE_IDA(phy_ida); | 30 | static DEFINE_IDA(phy_ida); |
30 | 31 | ||
31 | static void devm_phy_release(struct device *dev, void *res) | 32 | static void devm_phy_release(struct device *dev, void *res) |
@@ -54,34 +55,79 @@ static int devm_phy_match(struct device *dev, void *res, void *match_data) | |||
54 | return res == match_data; | 55 | return res == match_data; |
55 | } | 56 | } |
56 | 57 | ||
57 | static struct phy *phy_lookup(struct device *device, const char *port) | 58 | /** |
59 | * phy_create_lookup() - allocate and register PHY/device association | ||
60 | * @phy: the phy of the association | ||
61 | * @con_id: connection ID string on device | ||
62 | * @dev_id: the device of the association | ||
63 | * | ||
64 | * Creates and registers phy_lookup entry. | ||
65 | */ | ||
66 | int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) | ||
58 | { | 67 | { |
59 | unsigned int count; | 68 | struct phy_lookup *pl; |
60 | struct phy *phy; | ||
61 | struct device *dev; | ||
62 | struct phy_consumer *consumers; | ||
63 | struct class_dev_iter iter; | ||
64 | 69 | ||
65 | class_dev_iter_init(&iter, phy_class, NULL, NULL); | 70 | if (!phy || !dev_id || !con_id) |
66 | while ((dev = class_dev_iter_next(&iter))) { | 71 | return -EINVAL; |
67 | phy = to_phy(dev); | ||
68 | 72 | ||
69 | if (!phy->init_data) | 73 | pl = kzalloc(sizeof(*pl), GFP_KERNEL); |
70 | continue; | 74 | if (!pl) |
71 | count = phy->init_data->num_consumers; | 75 | return -ENOMEM; |
72 | consumers = phy->init_data->consumers; | 76 | |
73 | while (count--) { | 77 | pl->dev_id = dev_id; |
74 | if (!strcmp(consumers->dev_name, dev_name(device)) && | 78 | pl->con_id = con_id; |
75 | !strcmp(consumers->port, port)) { | 79 | pl->phy = phy; |
76 | class_dev_iter_exit(&iter); | 80 | |
77 | return phy; | 81 | mutex_lock(&phy_provider_mutex); |
78 | } | 82 | list_add_tail(&pl->node, &phys); |
79 | consumers++; | 83 | mutex_unlock(&phy_provider_mutex); |
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(phy_create_lookup); | ||
88 | |||
89 | /** | ||
90 | * phy_remove_lookup() - find and remove PHY/device association | ||
91 | * @phy: the phy of the association | ||
92 | * @con_id: connection ID string on device | ||
93 | * @dev_id: the device of the association | ||
94 | * | ||
95 | * Finds and unregisters phy_lookup entry that was created with | ||
96 | * phy_create_lookup(). | ||
97 | */ | ||
98 | void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id) | ||
99 | { | ||
100 | struct phy_lookup *pl; | ||
101 | |||
102 | if (!phy || !dev_id || !con_id) | ||
103 | return; | ||
104 | |||
105 | mutex_lock(&phy_provider_mutex); | ||
106 | list_for_each_entry(pl, &phys, node) | ||
107 | if (pl->phy == phy && !strcmp(pl->dev_id, dev_id) && | ||
108 | !strcmp(pl->con_id, con_id)) { | ||
109 | list_del(&pl->node); | ||
110 | kfree(pl); | ||
111 | break; | ||
80 | } | 112 | } |
81 | } | 113 | mutex_unlock(&phy_provider_mutex); |
114 | } | ||
115 | EXPORT_SYMBOL_GPL(phy_remove_lookup); | ||
82 | 116 | ||
83 | class_dev_iter_exit(&iter); | 117 | static struct phy *phy_find(struct device *dev, const char *con_id) |
84 | return ERR_PTR(-ENODEV); | 118 | { |
119 | const char *dev_id = dev_name(dev); | ||
120 | struct phy_lookup *p, *pl = NULL; | ||
121 | |||
122 | mutex_lock(&phy_provider_mutex); | ||
123 | list_for_each_entry(p, &phys, node) | ||
124 | if (!strcmp(p->dev_id, dev_id) && !strcmp(p->con_id, con_id)) { | ||
125 | pl = p; | ||
126 | break; | ||
127 | } | ||
128 | mutex_unlock(&phy_provider_mutex); | ||
129 | |||
130 | return pl ? pl->phy : ERR_PTR(-ENODEV); | ||
85 | } | 131 | } |
86 | 132 | ||
87 | static struct phy_provider *of_phy_provider_lookup(struct device_node *node) | 133 | static struct phy_provider *of_phy_provider_lookup(struct device_node *node) |
@@ -414,21 +460,13 @@ struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args | |||
414 | { | 460 | { |
415 | struct phy *phy; | 461 | struct phy *phy; |
416 | struct class_dev_iter iter; | 462 | struct class_dev_iter iter; |
417 | struct device_node *node = dev->of_node; | ||
418 | struct device_node *child; | ||
419 | 463 | ||
420 | class_dev_iter_init(&iter, phy_class, NULL, NULL); | 464 | class_dev_iter_init(&iter, phy_class, NULL, NULL); |
421 | while ((dev = class_dev_iter_next(&iter))) { | 465 | while ((dev = class_dev_iter_next(&iter))) { |
422 | phy = to_phy(dev); | 466 | phy = to_phy(dev); |
423 | if (node != phy->dev.of_node) { | 467 | if (args->np != phy->dev.of_node) |
424 | for_each_child_of_node(node, child) { | ||
425 | if (child == phy->dev.of_node) | ||
426 | goto phy_found; | ||
427 | } | ||
428 | continue; | 468 | continue; |
429 | } | ||
430 | 469 | ||
431 | phy_found: | ||
432 | class_dev_iter_exit(&iter); | 470 | class_dev_iter_exit(&iter); |
433 | return phy; | 471 | return phy; |
434 | } | 472 | } |
@@ -463,7 +501,7 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
463 | string); | 501 | string); |
464 | phy = _of_phy_get(dev->of_node, index); | 502 | phy = _of_phy_get(dev->of_node, index); |
465 | } else { | 503 | } else { |
466 | phy = phy_lookup(dev, string); | 504 | phy = phy_find(dev, string); |
467 | } | 505 | } |
468 | if (IS_ERR(phy)) | 506 | if (IS_ERR(phy)) |
469 | return phy; | 507 | return phy; |
@@ -588,13 +626,11 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get); | |||
588 | * @dev: device that is creating the new phy | 626 | * @dev: device that is creating the new phy |
589 | * @node: device node of the phy | 627 | * @node: device node of the phy |
590 | * @ops: function pointers for performing phy operations | 628 | * @ops: function pointers for performing phy operations |
591 | * @init_data: contains the list of PHY consumers or NULL | ||
592 | * | 629 | * |
593 | * Called to create a phy using phy framework. | 630 | * Called to create a phy using phy framework. |
594 | */ | 631 | */ |
595 | struct phy *phy_create(struct device *dev, struct device_node *node, | 632 | struct phy *phy_create(struct device *dev, struct device_node *node, |
596 | const struct phy_ops *ops, | 633 | const struct phy_ops *ops) |
597 | struct phy_init_data *init_data) | ||
598 | { | 634 | { |
599 | int ret; | 635 | int ret; |
600 | int id; | 636 | int id; |
@@ -632,7 +668,6 @@ struct phy *phy_create(struct device *dev, struct device_node *node, | |||
632 | phy->dev.of_node = node ?: dev->of_node; | 668 | phy->dev.of_node = node ?: dev->of_node; |
633 | phy->id = id; | 669 | phy->id = id; |
634 | phy->ops = ops; | 670 | phy->ops = ops; |
635 | phy->init_data = init_data; | ||
636 | 671 | ||
637 | ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id); | 672 | ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id); |
638 | if (ret) | 673 | if (ret) |
@@ -667,7 +702,6 @@ EXPORT_SYMBOL_GPL(phy_create); | |||
667 | * @dev: device that is creating the new phy | 702 | * @dev: device that is creating the new phy |
668 | * @node: device node of the phy | 703 | * @node: device node of the phy |
669 | * @ops: function pointers for performing phy operations | 704 | * @ops: function pointers for performing phy operations |
670 | * @init_data: contains the list of PHY consumers or NULL | ||
671 | * | 705 | * |
672 | * Creates a new PHY device adding it to the PHY class. | 706 | * Creates a new PHY device adding it to the PHY class. |
673 | * While at that, it also associates the device with the phy using devres. | 707 | * While at that, it also associates the device with the phy using devres. |
@@ -675,8 +709,7 @@ EXPORT_SYMBOL_GPL(phy_create); | |||
675 | * then, devres data is freed. | 709 | * then, devres data is freed. |
676 | */ | 710 | */ |
677 | struct phy *devm_phy_create(struct device *dev, struct device_node *node, | 711 | struct phy *devm_phy_create(struct device *dev, struct device_node *node, |
678 | const struct phy_ops *ops, | 712 | const struct phy_ops *ops) |
679 | struct phy_init_data *init_data) | ||
680 | { | 713 | { |
681 | struct phy **ptr, *phy; | 714 | struct phy **ptr, *phy; |
682 | 715 | ||
@@ -684,7 +717,7 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node, | |||
684 | if (!ptr) | 717 | if (!ptr) |
685 | return ERR_PTR(-ENOMEM); | 718 | return ERR_PTR(-ENOMEM); |
686 | 719 | ||
687 | phy = phy_create(dev, node, ops, init_data); | 720 | phy = phy_create(dev, node, ops); |
688 | if (!IS_ERR(phy)) { | 721 | if (!IS_ERR(phy)) { |
689 | *ptr = phy; | 722 | *ptr = phy; |
690 | devres_add(dev, ptr); | 723 | devres_add(dev, ptr); |