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

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>

authored by

Lee Jones and committed by
Linus Walleij
313bdb11 2968da0b

+101
+50
Documentation/devicetree/bindings/usb/ux500-usb.txt
··· 1 + Ux500 MUSB 2 + 3 + Required properties: 4 + - compatible : Should be "stericsson,db8500-musb" 5 + - reg : Offset and length of registers 6 + - interrupts : Interrupt; mode, number and trigger 7 + - dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral" 8 + or both "otg" 9 + 10 + Optional properties: 11 + - dmas : A list of dma channels; 12 + dma-controller, event-line, fixed-channel, flags 13 + - dma-names : An ordered list of channel names affiliated to the above 14 + 15 + Example: 16 + 17 + usb_per5@a03e0000 { 18 + compatible = "stericsson,db8500-musb", "mentor,musb"; 19 + reg = <0xa03e0000 0x10000>; 20 + interrupts = <0 23 0x4>; 21 + interrupt-names = "mc"; 22 + 23 + dr_mode = "otg"; 24 + 25 + dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */ 26 + <&dma 38 0 0x0>, /* Logical - MemToDev */ 27 + <&dma 37 0 0x2>, /* Logical - DevToMem */ 28 + <&dma 37 0 0x0>, /* Logical - MemToDev */ 29 + <&dma 36 0 0x2>, /* Logical - DevToMem */ 30 + <&dma 36 0 0x0>, /* Logical - MemToDev */ 31 + <&dma 19 0 0x2>, /* Logical - DevToMem */ 32 + <&dma 19 0 0x0>, /* Logical - MemToDev */ 33 + <&dma 18 0 0x2>, /* Logical - DevToMem */ 34 + <&dma 18 0 0x0>, /* Logical - MemToDev */ 35 + <&dma 17 0 0x2>, /* Logical - DevToMem */ 36 + <&dma 17 0 0x0>, /* Logical - MemToDev */ 37 + <&dma 16 0 0x2>, /* Logical - DevToMem */ 38 + <&dma 16 0 0x0>, /* Logical - MemToDev */ 39 + <&dma 39 0 0x2>, /* Logical - DevToMem */ 40 + <&dma 39 0 0x0>; /* Logical - MemToDev */ 41 + 42 + dma-names = "iep_1_9", "oep_1_9", 43 + "iep_2_10", "oep_2_10", 44 + "iep_3_11", "oep_3_11", 45 + "iep_4_12", "oep_4_12", 46 + "iep_5_13", "oep_5_13", 47 + "iep_6_14", "oep_6_14", 48 + "iep_7_15", "oep_7_15", 49 + "iep_8", "oep_8"; 50 + };
+51
drivers/usb/musb/ux500.c
··· 25 25 #include <linux/clk.h> 26 26 #include <linux/err.h> 27 27 #include <linux/io.h> 28 + #include <linux/of.h> 28 29 #include <linux/platform_device.h> 29 30 #include <linux/usb/musb-ux500.h> 30 31 ··· 195 194 .set_vbus = ux500_musb_set_vbus, 196 195 }; 197 196 197 + static struct musb_hdrc_platform_data * 198 + ux500_of_probe(struct platform_device *pdev, struct device_node *np) 199 + { 200 + struct musb_hdrc_platform_data *pdata; 201 + const char *mode; 202 + int strlen; 203 + 204 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 205 + if (!pdata) 206 + return NULL; 207 + 208 + mode = of_get_property(np, "dr_mode", &strlen); 209 + if (!mode) { 210 + dev_err(&pdev->dev, "No 'dr_mode' property found\n"); 211 + return NULL; 212 + } 213 + 214 + if (strlen > 0) { 215 + if (!strcmp(mode, "host")) 216 + pdata->mode = MUSB_HOST; 217 + if (!strcmp(mode, "otg")) 218 + pdata->mode = MUSB_OTG; 219 + if (!strcmp(mode, "peripheral")) 220 + pdata->mode = MUSB_PERIPHERAL; 221 + } 222 + 223 + return pdata; 224 + } 225 + 198 226 static int ux500_probe(struct platform_device *pdev) 199 227 { 200 228 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 229 + struct device_node *np = pdev->dev.of_node; 201 230 struct platform_device *musb; 202 231 struct ux500_glue *glue; 203 232 struct clk *clk; 204 233 int ret = -ENOMEM; 234 + 235 + if (!pdata) { 236 + if (np) { 237 + pdata = ux500_of_probe(pdev, np); 238 + if (!pdata) 239 + goto err0; 240 + 241 + pdev->dev.platform_data = pdata; 242 + } else { 243 + dev_err(&pdev->dev, "no pdata or device tree found\n"); 244 + goto err0; 245 + } 246 + } 205 247 206 248 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 207 249 if (!glue) { ··· 274 230 musb->dev.parent = &pdev->dev; 275 231 musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; 276 232 musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; 233 + musb->dev.of_node = pdev->dev.of_node; 277 234 278 235 glue->dev = &pdev->dev; 279 236 glue->musb = musb; ··· 373 328 #define DEV_PM_OPS NULL 374 329 #endif 375 330 331 + static const struct of_device_id ux500_match[] = { 332 + { .compatible = "stericsson,db8500-musb", }, 333 + {} 334 + }; 335 + 376 336 static struct platform_driver ux500_driver = { 377 337 .probe = ux500_probe, 378 338 .remove = ux500_remove, 379 339 .driver = { 380 340 .name = "musb-ux500", 381 341 .pm = DEV_PM_OPS, 342 + .of_match_table = ux500_match, 382 343 }, 383 344 }; 384 345