Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Roger Quadros and committed by
Felipe Balbi
bd27fa44 8e933359

+72 -45
+3 -4
Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
··· 15 15 16 16 - vcc-supply: phandle to the regulator that provides RESET to the PHY. 17 17 18 - - reset-supply: phandle to the regulator that provides power to the PHY. 18 + - reset-gpios: Should specify the GPIO for reset. 19 19 20 20 Example: 21 21 ··· 25 25 clocks = <&osc 0>; 26 26 clock-names = "main_clk"; 27 27 vcc-supply = <&hsusb1_vcc_regulator>; 28 - reset-supply = <&hsusb1_reset_regulator>; 28 + reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; 29 29 }; 30 30 31 31 hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator 32 32 and expects that clock to be configured to 19.2MHz by the NOP PHY driver. 33 - hsusb1_vcc_regulator provides power to the PHY and hsusb1_reset_regulator 34 - controls RESET. 33 + hsusb1_vcc_regulator provides power to the PHY and GPIO 7 controls RESET.
+1 -1
drivers/usb/phy/phy-am335x.c
··· 53 53 } 54 54 55 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 57 if (ret) 58 58 return ret; 59 59
+65 -37
drivers/usb/phy/phy-generic.c
··· 35 35 #include <linux/clk.h> 36 36 #include <linux/regulator/consumer.h> 37 37 #include <linux/of.h> 38 + #include <linux/of_gpio.h> 39 + #include <linux/gpio.h> 40 + #include <linux/delay.h> 38 41 39 42 #include "phy-generic.h" 40 43 ··· 67 64 return 0; 68 65 } 69 66 67 + static void nop_reset_set(struct usb_phy_gen_xceiv *nop, int asserted) 68 + { 69 + int value; 70 + 71 + if (!gpio_is_valid(nop->gpio_reset)) 72 + return; 73 + 74 + value = asserted; 75 + if (nop->reset_active_low) 76 + value = !value; 77 + 78 + gpio_set_value_cansleep(nop->gpio_reset, value); 79 + 80 + if (!asserted) 81 + usleep_range(10000, 20000); 82 + } 83 + 70 84 int usb_gen_phy_init(struct usb_phy *phy) 71 85 { 72 86 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); ··· 96 76 if (!IS_ERR(nop->clk)) 97 77 clk_prepare_enable(nop->clk); 98 78 99 - if (!IS_ERR(nop->reset)) { 100 - /* De-assert RESET */ 101 - if (regulator_enable(nop->reset)) 102 - dev_err(phy->dev, "Failed to de-assert reset\n"); 103 - } 79 + /* De-assert RESET */ 80 + nop_reset_set(nop, 0); 104 81 105 82 return 0; 106 83 } ··· 107 90 { 108 91 struct usb_phy_gen_xceiv *nop = dev_get_drvdata(phy->dev); 109 92 110 - if (!IS_ERR(nop->reset)) { 111 - /* Assert RESET */ 112 - if (regulator_disable(nop->reset)) 113 - dev_err(phy->dev, "Failed to assert reset\n"); 114 - } 93 + /* Assert RESET */ 94 + nop_reset_set(nop, 1); 115 95 116 96 if (!IS_ERR(nop->clk)) 117 97 clk_disable_unprepare(nop->clk); ··· 150 136 } 151 137 152 138 int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_gen_xceiv *nop, 153 - enum usb_phy_type type, u32 clk_rate, bool needs_vcc, 154 - bool needs_reset) 139 + enum usb_phy_type type, u32 clk_rate, bool needs_vcc) 155 140 { 156 141 int err; 157 142 ··· 181 168 return -EPROBE_DEFER; 182 169 } 183 170 184 - nop->reset = devm_regulator_get(dev, "reset"); 185 - if (IS_ERR(nop->reset)) { 186 - dev_dbg(dev, "Error getting reset regulator: %ld\n", 187 - PTR_ERR(nop->reset)); 188 - if (needs_reset) 189 - return -EPROBE_DEFER; 171 + if (gpio_is_valid(nop->gpio_reset)) { 172 + unsigned long gpio_flags; 173 + 174 + /* Assert RESET */ 175 + if (nop->reset_active_low) 176 + gpio_flags = GPIOF_OUT_INIT_LOW; 177 + else 178 + gpio_flags = GPIOF_OUT_INIT_HIGH; 179 + 180 + err = devm_gpio_request_one(dev, nop->gpio_reset, 181 + gpio_flags, dev_name(dev)); 182 + if (err) { 183 + dev_err(dev, "Error requesting RESET GPIO %d\n", 184 + nop->gpio_reset); 185 + return err; 186 + } 190 187 } 191 188 192 189 nop->dev = dev; ··· 225 202 int err; 226 203 u32 clk_rate = 0; 227 204 bool needs_vcc = false; 228 - bool needs_reset = false; 229 - 230 - if (dev->of_node) { 231 - struct device_node *node = dev->of_node; 232 - 233 - if (of_property_read_u32(node, "clock-frequency", &clk_rate)) 234 - clk_rate = 0; 235 - 236 - needs_vcc = of_property_read_bool(node, "vcc-supply"); 237 - needs_reset = of_property_read_bool(node, "reset-supply"); 238 - 239 - } else if (pdata) { 240 - type = pdata->type; 241 - clk_rate = pdata->clk_rate; 242 - needs_vcc = pdata->needs_vcc; 243 - needs_reset = pdata->needs_reset; 244 - } 245 205 246 206 nop = devm_kzalloc(dev, sizeof(*nop), GFP_KERNEL); 247 207 if (!nop) 248 208 return -ENOMEM; 249 209 210 + nop->reset_active_low = true; /* default behaviour */ 250 211 251 - err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc, 252 - needs_reset); 212 + if (dev->of_node) { 213 + struct device_node *node = dev->of_node; 214 + enum of_gpio_flags flags; 215 + 216 + if (of_property_read_u32(node, "clock-frequency", &clk_rate)) 217 + clk_rate = 0; 218 + 219 + needs_vcc = of_property_read_bool(node, "vcc-supply"); 220 + nop->gpio_reset = of_get_named_gpio_flags(node, "reset-gpios", 221 + 0, &flags); 222 + if (nop->gpio_reset == -EPROBE_DEFER) 223 + return -EPROBE_DEFER; 224 + 225 + nop->reset_active_low = flags & OF_GPIO_ACTIVE_LOW; 226 + 227 + } else if (pdata) { 228 + type = pdata->type; 229 + clk_rate = pdata->clk_rate; 230 + needs_vcc = pdata->needs_vcc; 231 + nop->gpio_reset = pdata->gpio_reset; 232 + } 233 + 234 + err = usb_phy_gen_create_phy(dev, nop, type, clk_rate, needs_vcc); 253 235 if (err) 254 236 return err; 255 237
+3 -3
drivers/usb/phy/phy-generic.h
··· 6 6 struct device *dev; 7 7 struct clk *clk; 8 8 struct regulator *vcc; 9 - struct regulator *reset; 9 + int gpio_reset; 10 + bool reset_active_low; 10 11 }; 11 12 12 13 int usb_gen_phy_init(struct usb_phy *phy); 13 14 void usb_gen_phy_shutdown(struct usb_phy *phy); 14 15 15 16 int 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 - bool needs_reset); 17 + enum usb_phy_type type, u32 clk_rate, bool needs_vcc); 18 18 19 19 #endif