Trying this again as plain text... sorry about that. Attached is a patch that adds device tree support to the da8xx musb driver. The current driver expects a board file to setup the platform device and perform the initialization. With this patch all of the setup is done through the device tree. diffstat for this patch is: Documentation/devicetree/bindings/usb/da8xx-usb.txt | 18 ++ drivers/usb/musb/Kconfig | 1 drivers/usb/musb/da8xx.c | 139 ++++++++++++++------ 3 files changed, 119 insertions(+), 39 deletions(-) To apply this patch, in the root of a kernel tree use: patch -p1 < da8xx-musb.patch Please let me know any feedback you have on this patch. Thanks Andrew Holcomb Software Engineer RELM Wireless Signed-off-by: Andrew T Holcomb <aholcomb@xxxxxxxxxx> ----------------------------------------------------------------------------------------------------------------------------- diff -pruN linux-4.1/Documentation/devicetree/bindings/usb/da8xx-usb.txt linux-4.1.musb/Documentation/devicetree/bindings/usb/da8xx-usb.txt --- linux-4.1/Documentation/devicetree/bindings/usb/da8xx-usb.txt 1969-12-31 18:00:00.000000000 -0600 +++ linux-4.1.musb/Documentation/devicetree/bindings/usb/da8xx-usb.txt 2015-07-23 10:49:35.926160500 -0500 @@ -0,0 +1,18 @@ +DA8XX MUSB + +Required properties: + - compatible : Should be "ti,da8xx-musb" + - reg : Offset and length of registers + - interrupts : Interrupt number + - mode : Dual-role; either host mode "host", peripheral mode "peripheral" + or both "otg" + +Example: + +musb@1e00000 { + compatible = "ti,da8xx-musb"; + reg = <0x01e00000 0x10000>; + interrupts = <58>; + interrupt-names = "mc"; + mode = "peripheral"; +}; diff -pruN linux-4.1/drivers/usb/musb/da8xx.c linux-4.1.musb/drivers/usb/musb/da8xx.c --- linux-4.1/drivers/usb/musb/da8xx.c 2015-06-22 00:05:43.000000000 -0500 +++ linux-4.1.musb/drivers/usb/musb/da8xx.c 2015-07-23 10:49:35.926160500 -0500 @@ -89,6 +89,36 @@ struct da8xx_glue { struct clk *clk; }; +static struct musb_hdrc_eps_bits musb_eps[] = { + { "ep1_tx", 8, }, + { "ep1_rx", 8, }, + { "ep2_tx", 8, }, + { "ep2_rx", 8, }, + { "ep3_tx", 5, }, + { "ep3_rx", 5, }, + { "ep4_tx", 5, }, + { "ep4_rx", 5, }, +}; + +static struct musb_hdrc_config musb_config = { + .multipoint = true, + .dyn_fifo = true, + .soft_con = true, + .dma = true, + + .num_eps = 5, + .dma_channels = 8, + .ram_bits = 10, + .eps_bits = musb_eps, +}; + +static struct musb_hdrc_platform_data usb_data = { + /* OTG requires a Mini-AB connector */ + .mode = MUSB_PERIPHERAL, + .clock = "usb20", + .config = &musb_config, +}; + /* * REVISIT (PM): we should be able to keep the PHY in low power mode most * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 @@ -105,6 +135,9 @@ static inline void phy_on(void) */ cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN); cfgchip2 |= CFGCHIP2_PHY_PLLON; + /* USB2.0 PHY reference clock is 24 MHz */ + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; __raw_writel(cfgchip2, CFGCHIP2); pr_info("Waiting for USB PHY clock good...\n"); @@ -480,44 +513,68 @@ static const struct platform_device_info static int da8xx_probe(struct platform_device *pdev) { - struct resource musb_resources[2]; + struct resource musb_resources[2]; struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct device_node *np = pdev->dev.of_node; struct platform_device *musb; struct da8xx_glue *glue; - struct platform_device_info pinfo; struct clk *clk; - int ret = -ENOMEM; + const char *mode; + int strlen; - glue = kzalloc(sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(&pdev->dev, "failed to allocate glue context\n"); + glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); + if (!glue) + goto err0; + + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); goto err0; } - clk = clk_get(&pdev->dev, "usb20"); + clk = devm_clk_get(&pdev->dev, "usb20"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clock\n"); ret = PTR_ERR(clk); - goto err3; + goto err1; } - ret = clk_enable(clk); + ret = clk_prepare_enable(clk); if (ret) { dev_err(&pdev->dev, "failed to enable clock\n"); - goto err4; + goto err1; } + musb->dev.parent = &pdev->dev; + musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; + musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; + glue->dev = &pdev->dev; + glue->musb = musb; glue->clk = clk; - pdata->platform_ops = &da8xx_ops; + if (np) { + pdata = &usb_data; + /* Mode can be overridden */ + mode = of_get_property(np, "mode", &strlen); + if (!mode) { + dev_info(&pdev->dev, "No 'mode' property found... defaulting to MUSB_PERIPHERAL.\n"); + pdata->mode = MUSB_PERIPHERAL; + } - glue->phy = usb_phy_generic_register(); - if (IS_ERR(glue->phy)) { - ret = PTR_ERR(glue->phy); - goto err5; + if (strlen > 0) { + if (!strcmp(mode, "host")) + pdata->mode = MUSB_HOST; + if (!strcmp(mode, "otg")) + pdata->mode = MUSB_OTG; + if (!strcmp(mode, "peripheral")) + pdata->mode = MUSB_PERIPHERAL; + } } + + pdata->platform_ops = &da8xx_ops; + platform_set_drvdata(pdev, glue); memset(musb_resources, 0x00, sizeof(*musb_resources) * @@ -533,34 +590,31 @@ static int da8xx_probe(struct platform_d musb_resources[1].end = pdev->resource[1].end; musb_resources[1].flags = pdev->resource[1].flags; - pinfo = da8xx_dev_info; - pinfo.parent = &pdev->dev; - pinfo.res = musb_resources; - pinfo.num_res = ARRAY_SIZE(musb_resources); - pinfo.data = pdata; - pinfo.size_data = sizeof(*pdata); - - glue->musb = musb = platform_device_register_full(&pinfo); - if (IS_ERR(musb)) { - ret = PTR_ERR(musb); - dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); - goto err6; + ret = platform_device_add_resources(musb, musb_resources, + ARRAY_SIZE(musb_resources)); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err2; } - return 0; - -err6: - usb_phy_generic_unregister(glue->phy); - -err5: - clk_disable(clk); + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err2; + } -err4: - clk_put(clk); + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); + goto err2; + } -err3: - kfree(glue); + return 0; +err2: + clk_disable_unprepare(clk); +err1: + platform_device_put(musb); err0: return ret; } @@ -578,11 +632,20 @@ static int da8xx_remove(struct platform_ return 0; } +static const struct of_device_id da8xx_id_table[] = { + { + .compatible = "ti,da8xx-musb" + }, + {}, +}; +MODULE_DEVICE_TABLE(of, da8xx_id_table); + static struct platform_driver da8xx_driver = { .probe = da8xx_probe, .remove = da8xx_remove, .driver = { .name = "musb-da8xx", + .of_match_table = of_match_ptr(da8xx_id_table), }, }; diff -pruN linux-4.1/drivers/usb/musb/Kconfig linux-4.1.musb/drivers/usb/musb/Kconfig --- linux-4.1/drivers/usb/musb/Kconfig 2015-06-22 00:05:43.000000000 -0500 +++ linux-4.1.musb/drivers/usb/musb/Kconfig 2015-07-23 10:49:35.926160500 -0500 @@ -70,7 +70,6 @@ config USB_MUSB_DA8XX tristate "DA8xx/OMAP-L1x" depends on ARCH_DAVINCI_DA8XX depends on NOP_USB_XCEIV - depends on BROKEN config USB_MUSB_TUSB6010 tristate "TUSB6010" -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html