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:
parent
2968da0b2c
commit
313bdb11e5
50
Documentation/devicetree/bindings/usb/ux500-usb.txt
Normal file
50
Documentation/devicetree/bindings/usb/ux500-usb.txt
Normal 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";
|
||||||
|
};
|
@ -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,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user