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>
This commit is contained in:
Lee Jones 2013-05-15 10:51:48 +01:00 committed by Linus Walleij
parent 2968da0b2c
commit 313bdb11e5
2 changed files with 101 additions and 0 deletions

View File

@ -0,0 +1,50 @@
Ux500 MUSB
Required properties:
- compatible : Should be "stericsson,db8500-musb"
- reg : Offset and length of registers
- interrupts : Interrupt; mode, number and trigger
- dr_mode : Dual-role; either host mode "host", peripheral mode "peripheral"
or both "otg"
Optional properties:
- dmas : A list of dma channels;
dma-controller, event-line, fixed-channel, flags
- dma-names : An ordered list of channel names affiliated to the above
Example:
usb_per5@a03e0000 {
compatible = "stericsson,db8500-musb", "mentor,musb";
reg = <0xa03e0000 0x10000>;
interrupts = <0 23 0x4>;
interrupt-names = "mc";
dr_mode = "otg";
dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
<&dma 38 0 0x0>, /* Logical - MemToDev */
<&dma 37 0 0x2>, /* Logical - DevToMem */
<&dma 37 0 0x0>, /* Logical - MemToDev */
<&dma 36 0 0x2>, /* Logical - DevToMem */
<&dma 36 0 0x0>, /* Logical - MemToDev */
<&dma 19 0 0x2>, /* Logical - DevToMem */
<&dma 19 0 0x0>, /* Logical - MemToDev */
<&dma 18 0 0x2>, /* Logical - DevToMem */
<&dma 18 0 0x0>, /* Logical - MemToDev */
<&dma 17 0 0x2>, /* Logical - DevToMem */
<&dma 17 0 0x0>, /* Logical - MemToDev */
<&dma 16 0 0x2>, /* Logical - DevToMem */
<&dma 16 0 0x0>, /* Logical - MemToDev */
<&dma 39 0 0x2>, /* Logical - DevToMem */
<&dma 39 0 0x0>; /* Logical - MemToDev */
dma-names = "iep_1_9", "oep_1_9",
"iep_2_10", "oep_2_10",
"iep_3_11", "oep_3_11",
"iep_4_12", "oep_4_12",
"iep_5_13", "oep_5_13",
"iep_6_14", "oep_6_14",
"iep_7_15", "oep_7_15",
"iep_8", "oep_8";
};

View File

@ -25,6 +25,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/usb/musb-ux500.h> #include <linux/usb/musb-ux500.h>
@ -194,14 +195,57 @@ static const struct musb_platform_ops ux500_ops = {
.set_vbus = ux500_musb_set_vbus, .set_vbus = ux500_musb_set_vbus,
}; };
static struct musb_hdrc_platform_data *
ux500_of_probe(struct platform_device *pdev, struct device_node *np)
{
struct musb_hdrc_platform_data *pdata;
const char *mode;
int strlen;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return NULL;
mode = of_get_property(np, "dr_mode", &strlen);
if (!mode) {
dev_err(&pdev->dev, "No 'dr_mode' property found\n");
return NULL;
}
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;
}
return pdata;
}
static int ux500_probe(struct platform_device *pdev) static int ux500_probe(struct platform_device *pdev)
{ {
struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
struct platform_device *musb; struct platform_device *musb;
struct ux500_glue *glue; struct ux500_glue *glue;
struct clk *clk; struct clk *clk;
int ret = -ENOMEM; int ret = -ENOMEM;
if (!pdata) {
if (np) {
pdata = ux500_of_probe(pdev, np);
if (!pdata)
goto err0;
pdev->dev.platform_data = pdata;
} else {
dev_err(&pdev->dev, "no pdata or device tree found\n");
goto err0;
}
}
glue = kzalloc(sizeof(*glue), GFP_KERNEL); glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) { if (!glue) {
dev_err(&pdev->dev, "failed to allocate glue context\n"); dev_err(&pdev->dev, "failed to allocate glue context\n");
@ -230,6 +274,7 @@ static int ux500_probe(struct platform_device *pdev)
musb->dev.parent = &pdev->dev; musb->dev.parent = &pdev->dev;
musb->dev.dma_mask = &pdev->dev.coherent_dma_mask; musb->dev.dma_mask = &pdev->dev.coherent_dma_mask;
musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
musb->dev.of_node = pdev->dev.of_node;
glue->dev = &pdev->dev; glue->dev = &pdev->dev;
glue->musb = musb; glue->musb = musb;
@ -328,12 +373,18 @@ static const struct dev_pm_ops ux500_pm_ops = {
#define DEV_PM_OPS NULL #define DEV_PM_OPS NULL
#endif #endif
static const struct of_device_id ux500_match[] = {
{ .compatible = "stericsson,db8500-musb", },
{}
};
static struct platform_driver ux500_driver = { static struct platform_driver ux500_driver = {
.probe = ux500_probe, .probe = ux500_probe,
.remove = ux500_remove, .remove = ux500_remove,
.driver = { .driver = {
.name = "musb-ux500", .name = "musb-ux500",
.pm = DEV_PM_OPS, .pm = DEV_PM_OPS,
.of_match_table = ux500_match,
}, },
}; };