diff options
author | Hans de Goede <hdegoede@redhat.com> | 2016-06-10 05:46:25 -0400 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-06-21 03:52:39 -0400 |
commit | ce15ed4c5dfb3f7757e6611902aed5db253af977 (patch) | |
tree | 1aca75d0045e608b29c3451acc09a67d64198c27 /drivers/usb/common/common.c | |
parent | 882bd9fc46321c9d4721b376039a142cbfe8a17a (diff) |
USB: Fix of_usb_get_dr_mode_by_phy with a shared phy block
Some SoCs have a single phy-hw-block with multiple phys, this is
modelled by a single phy dts node, so we end up with multiple
controller nodes with a phys property pointing to the phy-node
of the otg-phy.
Only one of these controllers typically is an otg controller, yet we
were checking the first controller who uses a phy from the block and
then end up looking for a dr_mode property in e.g. the ehci controller.
This commit fixes this by adding an arg0 parameter to
of_usb_get_dr_mode_by_phy and make of_usb_get_dr_mode_by_phy
check that this matches the phandle args[0] value when looking for
the otg controller.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/common/common.c')
-rw-r--r-- | drivers/usb/common/common.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index e3d01619d6b3..5ef8da6e67c3 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c | |||
@@ -131,15 +131,17 @@ EXPORT_SYMBOL_GPL(usb_get_dr_mode); | |||
131 | * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device | 131 | * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device |
132 | * which is associated with the given phy device_node | 132 | * which is associated with the given phy device_node |
133 | * @np: Pointer to the given phy device_node | 133 | * @np: Pointer to the given phy device_node |
134 | * @arg0: phandle args[0] for phy's with #phy-cells >= 1, or -1 for | ||
135 | * phys which do not have phy-cells | ||
134 | * | 136 | * |
135 | * In dts a usb controller associates with phy devices. The function gets | 137 | * In dts a usb controller associates with phy devices. The function gets |
136 | * the string from property 'dr_mode' of the controller associated with the | 138 | * the string from property 'dr_mode' of the controller associated with the |
137 | * given phy device node, and returns the correspondig enum usb_dr_mode. | 139 | * given phy device node, and returns the correspondig enum usb_dr_mode. |
138 | */ | 140 | */ |
139 | enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) | 141 | enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0) |
140 | { | 142 | { |
141 | struct device_node *controller = NULL; | 143 | struct device_node *controller = NULL; |
142 | struct device_node *phy; | 144 | struct of_phandle_args args; |
143 | const char *dr_mode; | 145 | const char *dr_mode; |
144 | int index; | 146 | int index; |
145 | int err; | 147 | int err; |
@@ -148,12 +150,24 @@ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) | |||
148 | controller = of_find_node_with_property(controller, "phys"); | 150 | controller = of_find_node_with_property(controller, "phys"); |
149 | index = 0; | 151 | index = 0; |
150 | do { | 152 | do { |
151 | phy = of_parse_phandle(controller, "phys", index); | 153 | if (arg0 == -1) { |
152 | of_node_put(phy); | 154 | args.np = of_parse_phandle(controller, "phys", |
153 | if (phy == phy_np) | 155 | index); |
156 | args.args_count = 0; | ||
157 | } else { | ||
158 | err = of_parse_phandle_with_args(controller, | ||
159 | "phys", "#phy-cells", | ||
160 | index, &args); | ||
161 | if (err) | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | of_node_put(args.np); | ||
166 | if (args.np == np && (args.args_count == 0 || | ||
167 | args.args[0] == arg0)) | ||
154 | goto finish; | 168 | goto finish; |
155 | index++; | 169 | index++; |
156 | } while (phy); | 170 | } while (args.np); |
157 | } while (controller); | 171 | } while (controller); |
158 | 172 | ||
159 | finish: | 173 | finish: |