aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/44x/beech-usb.c
blob: f3fa2613737bcebd815b37982a3f4a82a87d6476 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * AMCC Kilauea USB-OTG wrapper
 *
 * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
 *
 * Extract the resources (MEM & IRQ) from the dts file and put them
 * into the platform-device struct for usage in the platform-device
 * USB-OTG driver.
 *
 */

#include <linux/platform_device.h>
#include <linux/of_platform.h>
#define U64_TO_U32_LOW(val)     ((u32)((val) & 0x00000000ffffffffULL))
#define U64_TO_U32_HIGH(val)    ((u32)((val) >> 32))


/*
 * Resource template will be filled dynamically with the values
 * extracted from the dts file
 */
static struct resource usb_otg_resources[] = {
	[0] = {
		/* 405EX USB-OTG registers */
		.flags  = IORESOURCE_MEM,
	},
	[1] = {
		/* 405EX OTG IRQ */
		.flags  = IORESOURCE_IRQ,
	},
	[2] = {
		/* High-Power workaround IRQ */
		.flags  = IORESOURCE_IRQ,
	},
	[3] = {
		/* 405EX DMA IRQ */
		.flags  = IORESOURCE_IRQ,
	},
};

static u64 dma_mask = 0xffffffffULL;

static struct platform_device usb_otg_device = {
        .name = "dwc_otg",
        .id = 0,
        .num_resources = ARRAY_SIZE(usb_otg_resources),
        .resource = usb_otg_resources,
        .dev = {
                .dma_mask = &dma_mask,
                .coherent_dma_mask = 0xffffffffULL,
        }
};

static struct platform_device *ppc405ex_devs[] __initdata = {
        &usb_otg_device,
};

static int __devinit ppc405ex_usb_otg_probe(struct of_device *ofdev,
					    const struct of_device_id *match)
{
	struct device_node *np = ofdev->node;
	struct resource res;

	/*
	 * Extract register address reange from device tree and put it into
	 * the platform device structure
	 */
	if (of_address_to_resource(np, 0, &res)) {
		printk(KERN_ERR "%s: Can't get USB-OTG register address\n", __func__);
		return -ENOMEM;
	}
	usb_otg_resources[0].start = res.start;
	usb_otg_resources[0].end = res.end;

	/*
	 * Extract IRQ number(s) from device tree and put them into
	 * the platform device structure
	 */
	usb_otg_resources[1].start = usb_otg_resources[1].end =
		irq_of_parse_and_map(np, 0);
	usb_otg_resources[2].start = usb_otg_resources[2].end =
		irq_of_parse_and_map(np, 1);
	usb_otg_resources[3].start = usb_otg_resources[3].end =
		irq_of_parse_and_map(np, 2);
	return platform_add_devices(ppc405ex_devs, ARRAY_SIZE(ppc405ex_devs));
}

static int __devexit ppc405ex_usb_otg_remove(struct of_device *ofdev)
{
	/* Nothing to do here */
	return 0;
}

static const struct of_device_id ppc405ex_usb_otg_match[] = {
	{ .compatible = "amcc,usb-otg-405ex", },
	{}
};

static struct of_platform_driver ppc405ex_usb_otg_driver = {
	.name = "ppc405ex-usb-otg",
	.match_table = ppc405ex_usb_otg_match,
	.probe = ppc405ex_usb_otg_probe,
	.remove = ppc405ex_usb_otg_remove,
};

static int __init ppc405ex_usb_otg_init(void)
{
	return of_register_platform_driver(&ppc405ex_usb_otg_driver);
}
device_initcall(ppc405ex_usb_otg_init);