diff options
Diffstat (limited to 'drivers/usb/phy/omap-usb3.c')
-rw-r--r-- | drivers/usb/phy/omap-usb3.c | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c index 695c7c69646..3b533a5dfa5 100644 --- a/drivers/usb/phy/omap-usb3.c +++ b/drivers/usb/phy/omap-usb3.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/usb/omap_control_usb.h> | 28 | #include <linux/usb/omap_control_usb.h> |
29 | #include <linux/of_platform.h> | ||
29 | 30 | ||
30 | #define NUM_SYS_CLKS 6 | 31 | #define NUM_SYS_CLKS 6 |
31 | #define PLL_STATUS 0x00000004 | 32 | #define PLL_STATUS 0x00000004 |
@@ -208,6 +209,10 @@ static int omap_usb3_probe(struct platform_device *pdev) | |||
208 | { | 209 | { |
209 | struct omap_usb *phy; | 210 | struct omap_usb *phy; |
210 | struct resource *res; | 211 | struct resource *res; |
212 | struct device_node *node = pdev->dev.of_node; | ||
213 | struct device_node *omap_control_usb_node; | ||
214 | struct platform_device *pdev_control_usb; | ||
215 | const char *clk_name; | ||
211 | 216 | ||
212 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); | 217 | phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); |
213 | if (!phy) { | 218 | if (!phy) { |
@@ -223,27 +228,40 @@ static int omap_usb3_probe(struct platform_device *pdev) | |||
223 | } | 228 | } |
224 | 229 | ||
225 | phy->dev = &pdev->dev; | 230 | phy->dev = &pdev->dev; |
226 | |||
227 | phy->phy.dev = phy->dev; | 231 | phy->phy.dev = phy->dev; |
228 | phy->phy.label = "omap-usb3"; | 232 | phy->phy.label = "omap-usb3"; |
229 | phy->phy.init = omap_usb3_init; | 233 | phy->phy.init = omap_usb3_init; |
230 | phy->phy.set_suspend = omap_usb3_suspend; | 234 | phy->phy.set_suspend = omap_usb3_suspend; |
231 | phy->phy.type = USB_PHY_TYPE_USB3; | 235 | phy->phy.type = USB_PHY_TYPE_USB3; |
232 | |||
233 | phy->is_suspended = 1; | 236 | phy->is_suspended = 1; |
234 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | 237 | |
235 | if (IS_ERR(phy->wkupclk)) { | 238 | of_property_read_string(node, "wkupclk", &clk_name); |
236 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | 239 | if (!clk_name) { |
237 | return PTR_ERR(phy->wkupclk); | 240 | dev_err(&pdev->dev, "unable to read wkupclk property from dt \n"); |
241 | return -EINVAL; | ||
242 | } else { | ||
243 | phy->wkupclk = devm_clk_get(phy->dev, clk_name); | ||
244 | if (IS_ERR(phy->wkupclk)) { | ||
245 | dev_err(&pdev->dev, "unable to get usb_phy wk clk\n"); | ||
246 | return PTR_ERR(phy->wkupclk); | ||
247 | } | ||
238 | } | 248 | } |
249 | |||
239 | clk_prepare(phy->wkupclk); | 250 | clk_prepare(phy->wkupclk); |
240 | 251 | ||
241 | phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); | 252 | of_property_read_string(node, "optclk", &clk_name); |
242 | if (IS_ERR(phy->optclk)) { | 253 | if (!clk_name) |
243 | dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n"); | 254 | dev_err(&pdev->dev, "unable to read optclk property from dt\n"); |
244 | return PTR_ERR(phy->optclk); | 255 | else { |
256 | phy->optclk = devm_clk_get(phy->dev, clk_name); | ||
257 | if (IS_ERR(phy->optclk)) { | ||
258 | dev_err(&pdev->dev, "unable to get usb_phy opt clk\n"); | ||
259 | return PTR_ERR(phy->optclk); | ||
260 | } | ||
261 | else | ||
262 | clk_prepare(phy->optclk); | ||
245 | } | 263 | } |
246 | clk_prepare(phy->optclk); | 264 | |
247 | 265 | ||
248 | phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); | 266 | phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin"); |
249 | if (IS_ERR(phy->sys_clk)) { | 267 | if (IS_ERR(phy->sys_clk)) { |
@@ -251,12 +269,28 @@ static int omap_usb3_probe(struct platform_device *pdev) | |||
251 | return -EINVAL; | 269 | return -EINVAL; |
252 | } | 270 | } |
253 | 271 | ||
254 | phy->control_dev = omap_get_control_dev(); | 272 | omap_control_usb_node = of_parse_phandle(node, "ctrl-module", 0); |
273 | if (IS_ERR(omap_control_usb_node)) { | ||
274 | dev_err(&pdev->dev, "Failed to find ctrl-module\n"); | ||
275 | return -EPROBE_DEFER; | ||
276 | } | ||
277 | |||
278 | pdev_control_usb = of_find_device_by_node(omap_control_usb_node); | ||
279 | if (IS_ERR(pdev_control_usb)) { | ||
280 | dev_dbg(&pdev->dev, "Attempt to get the platform control usb failed\n"); | ||
281 | return -EPROBE_DEFER; | ||
282 | } | ||
283 | |||
284 | phy->control_dev = &pdev_control_usb->dev; | ||
255 | if (IS_ERR(phy->control_dev)) { | 285 | if (IS_ERR(phy->control_dev)) { |
256 | dev_dbg(&pdev->dev, "Failed to get control device\n"); | 286 | dev_dbg(&pdev->dev, "Failed to get control device\n"); |
257 | return -ENODEV; | 287 | return -ENODEV; |
258 | } | 288 | } |
259 | 289 | ||
290 | dev_dbg(&pdev->dev, "got control usb name %s\n", | ||
291 | dev_name(phy->control_dev)); | ||
292 | phy->control_node = omap_control_usb_node; | ||
293 | |||
260 | omap_control_usb3_phy_power(phy->control_dev, 0); | 294 | omap_control_usb3_phy_power(phy->control_dev, 0); |
261 | usb_add_phy_dev(&phy->phy); | 295 | usb_add_phy_dev(&phy->phy); |
262 | 296 | ||
@@ -274,6 +308,7 @@ static int omap_usb3_remove(struct platform_device *pdev) | |||
274 | 308 | ||
275 | clk_unprepare(phy->wkupclk); | 309 | clk_unprepare(phy->wkupclk); |
276 | clk_unprepare(phy->optclk); | 310 | clk_unprepare(phy->optclk); |
311 | of_node_put(phy->control_node); | ||
277 | usb_remove_phy(&phy->phy); | 312 | usb_remove_phy(&phy->phy); |
278 | if (!pm_runtime_suspended(&pdev->dev)) | 313 | if (!pm_runtime_suspended(&pdev->dev)) |
279 | pm_runtime_put(&pdev->dev); | 314 | pm_runtime_put(&pdev->dev); |