aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2013-09-24 04:53:48 -0400
committerFelipe Balbi <balbi@ti.com>2013-10-04 10:29:03 -0400
commitbd27fa44e13830d2baa278d5702e766380659cb3 (patch)
tree2e5d979de074d710c507b2cf918a0a6974d00c5b /drivers/usb/phy
parent8e933359ee2c3a861d5022b83110ce88ba3a2dda (diff)
usb: phy: generic: Don't use regulator framework for RESET line
Modelling the RESET line as a regulator supply wasn't a good idea as it kind of abuses the regulator framework and also makes adaptation code more complex. Instead, manage the RESET gpio line directly in the driver. Update the device tree binding information. This also makes us easy to migrate to a dedicated GPIO RESET controller whenever it becomes available. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/phy-am335x.c2
-rw-r--r--drivers/usb/phy/phy-generic.c84
-rw-r--r--drivers/usb/phy/phy-generic.h6
3 files changed, 60 insertions, 32 deletions
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
index 1495cdc751ad..6370e50649d7 100644
--- a/drivers/usb/phy/phy-am335x.c
+++ b/drivers/usb/phy/phy-am335x.c
@@ -53,7 +53,7 @@ static int am335x_phy_probe(struct platform_device *pdev)
53 } 53 }
54 54
55 ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen, 55 ret = usb_phy_gen_create_phy(dev, &am_phy->usb_phy_gen,
56 USB_PHY_TYPE_USB2, 0, false, false); 56 USB_PHY_TYPE_USB2, 0, false);
57 if (ret) 57 if (ret)
58 return ret; 58 return ret;
59 59
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index fcc31045fda7..fce3a9e9bb5d 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -35,6 +35,9 @@
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/regulator/consumer.h> 36#include <linux/regulator/consumer.h>
37#include <linux/of.h> 37#include <linux/of.h>
38#include <linux/of_gpio.h>
39#include <linux/gpio.h>
40#include <linux/delay.h>
38 41
39#include "phy-generic.h" 42#include "phy-generic.h"
40 43
@@ -64,6 +67,23 @@ static int nop_set_suspend(struct usb_phy *x, int suspend)
64 return 0; 67 return 0;
65} 68}
66 69
70static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted)
71{
72 int value;
73
74 if (!gpio_is_valid(nop->gpio_reset))
75 return;
76
77 value = asserted;
78 if (nop->reset_active_low)
79 value = !value;
80
81 gpio_set_value_cansleep(nop->gpio_reset, value);
82
83 if (!asserted)
84 usleep_range(10000, 20000);
85}
86
67int usb_gen_phy_init(struct usb_phy *phy) 87int usb_gen_phy_init(struct usb_phy *phy)
68{ 88{
69 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); 89 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
@@ -76,11 +96,8 @@ int usb_gen_phy_init(struct usb_phy *phy)
76 if (!IS_ERR(nop->clk)) 96 if (!IS_ERR(nop->clk))
77 clk_prepare_enable(nop->clk); 97 clk_prepare_enable(nop->clk);
78 98
79 if (!IS_ERR(nop->reset)) { 99 /* De-assert RESET */
80 /* De-assert RESET */ 100 nop_reset_set(nop, 0);
81 if (regulator_enable(nop->reset))
82 dev_err(phy->dev, "Failed to de-assert reset\n");
83 }
84 101
85 return 0; 102 return 0;
86} 103}
@@ -90,11 +107,8 @@ void usb_gen_phy_shutdown(struct usb_phy *phy)
90{ 107{
91 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); 108 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev);
92 109
93 if (!IS_ERR(nop->reset)) { 110 /* Assert RESET */
94 /* Assert RESET */ 111 nop_reset_set(nop, 1);
95 if (regulator_disable(nop->reset))
96 dev_err(phy->dev, "Failed to assert reset\n");
97 }
98 112
99 if (!IS_ERR(nop->clk)) 113 if (!IS_ERR(nop->clk))
100 clk_disable_unprepare(nop->clk); 114 clk_disable_unprepare(nop->clk);
@@ -136,8 +150,7 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host)
136} 150}
137 151
138int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, 152int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
139 enum usb_phy_type type, u32 clk_rate, bool needs_vcc, 153 enum usb_phy_type type, u32 clk_rate, bool needs_vcc)
140 bool needs_reset)
141{ 154{
142 int err; 155 int err;
143 156
@@ -168,12 +181,22 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
168 return -EPROBE_DEFER; 181 return -EPROBE_DEFER;
169 } 182 }
170 183
171 nop->reset = devm_regulator_get(dev, "reset"); 184 if (gpio_is_valid(nop->gpio_reset)) {
172 if (IS_ERR(nop->reset)) { 185 unsigned long gpio_flags;
173 dev_dbg(dev, "Error getting reset regulator: %ld\n", 186
174 PTR_ERR(nop->reset)); 187 /* Assert RESET */
175 if (needs_reset) 188 if (nop->reset_active_low)
176 return -EPROBE_DEFER; 189 gpio_flags = GPIOF_OUT_INIT_LOW;
190 else
191 gpio_flags = GPIOF_OUT_INIT_HIGH;
192
193 err = devm_gpio_request_one(dev, nop->gpio_reset,
194 gpio_flags, dev_name(dev));
195 if (err) {
196 dev_err(dev, "Error requesting RESET GPIO %d\n",
197 nop->gpio_reset);
198 return err;
199 }
177 } 200 }
178 201
179 nop->dev = dev; 202 nop->dev = dev;
@@ -202,31 +225,36 @@ static int usb_phy_gen_xceiv_probe(struct platform_device *pdev)
202 int err; 225 int err;
203 u32 clk_rate = 0; 226 u32 clk_rate = 0;
204 bool needs_vcc = false; 227 bool needs_vcc = false;
205 bool needs_reset = false; 228
229 nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL);
230 if (!nop)
231 return -ENOMEM;
232
233 nop->reset_active_low = true; /* default behaviour */
206 234
207 if (dev->of_node) { 235 if (dev->of_node) {
208 struct device_node *node = dev->of_node; 236 struct device_node *node = dev->of_node;
237 enum of_gpio_flags flags;
209 238
210 if (of_property_read_u32(node, "clock-frequency", &clk_rate)) 239 if (of_property_read_u32(node, "clock-frequency", &clk_rate))
211 clk_rate = 0; 240 clk_rate = 0;
212 241
213 needs_vcc = of_property_read_bool(node, "vcc-supply"); 242 needs_vcc = of_property_read_bool(node, "vcc-supply");
214 needs_reset = of_property_read_bool(node, "reset-supply"); 243 nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios",
244 0, &flags);
245 if (nop->gpio_reset == -EPROBE_DEFER)
246 return -EPROBE_DEFER;
247
248 nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
215 249
216 } else if (pdata) { 250 } else if (pdata) {
217 type = pdata->type; 251 type = pdata->type;
218 clk_rate = pdata->clk_rate; 252 clk_rate = pdata->clk_rate;
219 needs_vcc = pdata->needs_vcc; 253 needs_vcc = pdata->needs_vcc;
220 needs_reset = pdata->needs_reset; 254 nop->gpio_reset = pdata->gpio_reset;
221 } 255 }
222 256
223 nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); 257 err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc);
224 if (!nop)
225 return -ENOMEM;
226
227
228 err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc,
229 needs_reset);
230 if (err) 258 if (err)
231 return err; 259 return err;
232 260
diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h
index 386d11b375aa..d2a220d81734 100644
--- a/drivers/usb/phy/phy-generic.h
+++ b/drivers/usb/phy/phy-generic.h
@@ -6,14 +6,14 @@ struct usb_phy_gen_xceiv {
6 struct device *dev; 6 struct device *dev;
7 struct clk *clk; 7 struct clk *clk;
8 struct regulator *vcc; 8 struct regulator *vcc;
9 struct regulator *reset; 9 int gpio_reset;
10 bool reset_active_low;
10}; 11};
11 12
12int usb_gen_phy_init(struct usb_phy *phy); 13int usb_gen_phy_init(struct usb_phy *phy);
13void usb_gen_phy_shutdown(struct usb_phy *phy); 14void usb_gen_phy_shutdown(struct usb_phy *phy);
14 15
15int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, 16int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop,
16 enum usb_phy_type type, u32 clk_rate, bool needs_vcc, 17 enum usb_phy_type type, u32 clk_rate, bool needs_vcc);
17 bool needs_reset);
18 18
19#endif 19#endif