aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBin Liu <b-liu@ti.com>2015-11-03 12:51:15 -0500
committerFelipe Balbi <balbi@ti.com>2015-12-15 10:12:41 -0500
commit98bfb39466954c69d2a448e6ddcab6d91cd48e25 (patch)
treee5a93ad5f204c67f04663a29c9217500bdd72c42
parentfa4dce2022241f3c938372af0faf9d263061f6a9 (diff)
usb: of: add an api to get dr_mode by the phy node
Some USB phy drivers have different handling for the controller in each dr_mode. But the phy driver does not have visibility to the dr_mode of the controller. This adds an api to return the dr_mode of the controller which associates the given phy node. Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/common/common.c60
-rw-r--r--include/linux/usb/of.h5
2 files changed, 59 insertions, 6 deletions
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index 673d53038ed2..e6ec125e4485 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -17,6 +17,7 @@
17#include <linux/usb/ch9.h> 17#include <linux/usb/ch9.h>
18#include <linux/usb/of.h> 18#include <linux/usb/of.h>
19#include <linux/usb/otg.h> 19#include <linux/usb/otg.h>
20#include <linux/of_platform.h>
20 21
21const char *usb_otg_state_string(enum usb_otg_state state) 22const char *usb_otg_state_string(enum usb_otg_state state)
22{ 23{
@@ -106,25 +107,72 @@ static const char *const usb_dr_modes[] = {
106 [USB_DR_MODE_OTG] = "otg", 107 [USB_DR_MODE_OTG] = "otg",
107}; 108};
108 109
110static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
111{
112 int i;
113
114 for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
115 if (!strcmp(usb_dr_modes[i], str))
116 return i;
117
118 return USB_DR_MODE_UNKNOWN;
119}
120
109enum usb_dr_mode usb_get_dr_mode(struct device *dev) 121enum usb_dr_mode usb_get_dr_mode(struct device *dev)
110{ 122{
111 const char *dr_mode; 123 const char *dr_mode;
112 int err, i; 124 int err;
113 125
114 err = device_property_read_string(dev, "dr_mode", &dr_mode); 126 err = device_property_read_string(dev, "dr_mode", &dr_mode);
115 if (err < 0) 127 if (err < 0)
116 return USB_DR_MODE_UNKNOWN; 128 return USB_DR_MODE_UNKNOWN;
117 129
118 for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++) 130 return usb_get_dr_mode_from_string(dr_mode);
119 if (!strcmp(dr_mode, usb_dr_modes[i]))
120 return i;
121
122 return USB_DR_MODE_UNKNOWN;
123} 131}
124EXPORT_SYMBOL_GPL(usb_get_dr_mode); 132EXPORT_SYMBOL_GPL(usb_get_dr_mode);
125 133
126#ifdef CONFIG_OF 134#ifdef CONFIG_OF
127/** 135/**
136 * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device
137 * which is associated with the given phy device_node
138 * @np: Pointer to the given phy device_node
139 *
140 * In dts a usb controller associates with phy devices. The function gets
141 * the string from property 'dr_mode' of the controller associated with the
142 * given phy device node, and returns the correspondig enum usb_dr_mode.
143 */
144enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
145{
146 struct device_node *controller = NULL;
147 struct device_node *phy;
148 const char *dr_mode;
149 int index;
150 int err;
151
152 do {
153 controller = of_find_node_with_property(controller, "phys");
154 index = 0;
155 do {
156 phy = of_parse_phandle(controller, "phys", index);
157 of_node_put(phy);
158 if (phy == phy_np)
159 goto finish;
160 index++;
161 } while (phy);
162 } while (controller);
163
164finish:
165 err = of_property_read_string(controller, "dr_mode", &dr_mode);
166 of_node_put(controller);
167
168 if (err < 0)
169 return USB_DR_MODE_UNKNOWN;
170
171 return usb_get_dr_mode_from_string(dr_mode);
172}
173EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
174
175/**
128 * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported 176 * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
129 * for given targeted hosts (non-PC hosts) 177 * for given targeted hosts (non-PC hosts)
130 * @np: Pointer to the given device_node 178 * @np: Pointer to the given device_node
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index c3fe9e48ce27..3805757dcdc2 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -12,10 +12,15 @@
12#include <linux/usb/phy.h> 12#include <linux/usb/phy.h>
13 13
14#if IS_ENABLED(CONFIG_OF) 14#if IS_ENABLED(CONFIG_OF)
15enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
15bool of_usb_host_tpl_support(struct device_node *np); 16bool of_usb_host_tpl_support(struct device_node *np);
16int of_usb_update_otg_caps(struct device_node *np, 17int of_usb_update_otg_caps(struct device_node *np,
17 struct usb_otg_caps *otg_caps); 18 struct usb_otg_caps *otg_caps);
18#else 19#else
20enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
21{
22 return USB_DR_MODE_UNKNOWN;
23}
19static inline bool of_usb_host_tpl_support(struct device_node *np) 24static inline bool of_usb_host_tpl_support(struct device_node *np)
20{ 25{
21 return false; 26 return false;