diff options
author | Lee Jones <lee.jones@linaro.org> | 2013-05-15 05:51:48 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-06-04 05:12:05 -0400 |
commit | 313bdb11e52a301aa7f6f8729a87ff0908785163 (patch) | |
tree | b0c2c6da3561c8bbe844e6e7a297129e363807e7 /drivers/usb/musb | |
parent | 2968da0b2c7297a29d49c7084d6865c2cf627093 (diff) |
usb: musb: ux500: add device tree probing support
This patch will allow ux500-musb to be probed and configured solely from
configuration found in Device Tree.
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: linux-usb@vger.kernel.org
Cc: devicetree-discuss@lists.ozlabs.org
Acked-by: Felipe Balbi <balbi@ti.com>
Acked-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/ux500.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 3cf10bcaf118..f0beee7b868e 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/of.h> | ||
28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
29 | #include <linux/usb/musb-ux500.h> | 30 | #include <linux/usb/musb-ux500.h> |
30 | 31 | ||
@@ -194,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = { | |||
194 | .set_vbus = ux500_musb_set_vbus, | 195 | .set_vbus = ux500_musb_set_vbus, |
195 | }; | 196 | }; |
196 | 197 | ||
198 | static struct musb_hdrc_platform_data * | ||
199 | ux500_of_probe(struct platform_device *pdev, struct device_node *np) | ||
200 | { | ||
201 | struct musb_hdrc_platform_data *pdata; | ||
202 | const char *mode; | ||
203 | int strlen; | ||
204 | |||
205 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
206 | if (!pdata) | ||
207 | return NULL; | ||
208 | |||
209 | mode = of_get_property(np, "dr_mode", &strlen); | ||
210 | if (!mode) { | ||
211 | dev_err(&pdev->dev, "No 'dr_mode' property found\n"); | ||
212 | return NULL; | ||
213 | } | ||
214 | |||
215 | if (strlen > 0) { | ||
216 | if (!strcmp(mode, "host")) | ||
217 | pdata->mode = MUSB_HOST; | ||
218 | if (!strcmp(mode, "otg")) | ||
219 | pdata->mode = MUSB_OTG; | ||
220 | if (!strcmp(mode, "peripheral")) | ||
221 | pdata->mode = MUSB_PERIPHERAL; | ||
222 | } | ||
223 | |||
224 | return pdata; | ||
225 | } | ||
226 | |||
197 | static int ux500_probe(struct platform_device *pdev) | 227 | static int ux500_probe(struct platform_device *pdev) |
198 | { | 228 | { |
199 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | 229 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; |
230 | struct device_node *np = pdev->dev.of_node; | ||
200 | struct platform_device *musb; | 231 | struct platform_device *musb; |
201 | struct ux500_glue *glue; | 232 | struct ux500_glue *glue; |
202 | struct clk *clk; | 233 | struct clk *clk; |
203 | int ret = -ENOMEM; | 234 | int ret = -ENOMEM; |
204 | 235 | ||
236 | if (!pdata) { | ||
237 | if (np) { | ||
238 | pdata = ux500_of_probe(pdev, np); | ||
239 | if (!pdata) | ||
240 | goto err0; | ||
241 | |||
242 | pdev->dev.platform_data = pdata; | ||
243 | } else { | ||
244 | dev_err(&pdev->dev, "no pdata or device tree found\n"); | ||
245 | goto err0; | ||
246 | } | ||
247 | } | ||
248 | |||
205 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 249 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
206 | if (!glue) { | 250 | if (!glue) { |
207 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | 251 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
@@ -230,6 +274,7 @@ static int ux500_probe(struct platform_device *pdev) | |||
230 | musb->dev.parent = &pdev->dev; | 274 | musb->dev.parent = &pdev->dev; |
231 | musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; | 275 | musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; |
232 | musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; | 276 | musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; |
277 | musb->dev.of_node = pdev->dev.of_node; | ||
233 | 278 | ||
234 | glue->dev = &pdev->dev; | 279 | glue->dev = &pdev->dev; |
235 | glue->musb = musb; | 280 | glue->musb = musb; |
@@ -328,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = { | |||
328 | #define DEV_PM_OPS NULL | 373 | #define DEV_PM_OPS NULL |
329 | #endif | 374 | #endif |
330 | 375 | ||
376 | static const struct of_device_id ux500_match[] = { | ||
377 | { .compatible = "stericsson,db8500-musb", }, | ||
378 | {} | ||
379 | }; | ||
380 | |||
331 | static struct platform_driver ux500_driver = { | 381 | static struct platform_driver ux500_driver = { |
332 | .probe = ux500_probe, | 382 | .probe = ux500_probe, |
333 | .remove = ux500_remove, | 383 | .remove = ux500_remove, |
334 | .driver = { | 384 | .driver = { |
335 | .name = "musb-ux500", | 385 | .name = "musb-ux500", |
336 | .pm = DEV_PM_OPS, | 386 | .pm = DEV_PM_OPS, |
387 | .of_match_table = ux500_match, | ||
337 | }, | 388 | }, |
338 | }; | 389 | }; |
339 | 390 | ||