diff options
Diffstat (limited to 'arch/mips/alchemy/devboards/platform.c')
-rw-r--r-- | arch/mips/alchemy/devboards/platform.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c new file mode 100644 index 000000000000..49a4b3244d8e --- /dev/null +++ b/arch/mips/alchemy/devboards/platform.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * devoard misc stuff. | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <linux/mtd/mtd.h> | ||
7 | #include <linux/mtd/map.h> | ||
8 | #include <linux/mtd/physmap.h> | ||
9 | #include <linux/slab.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/pm.h> | ||
12 | |||
13 | #include <asm/reboot.h> | ||
14 | #include <asm/mach-db1x00/bcsr.h> | ||
15 | |||
16 | static void db1x_power_off(void) | ||
17 | { | ||
18 | bcsr_write(BCSR_RESETS, 0); | ||
19 | bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET); | ||
20 | } | ||
21 | |||
22 | static void db1x_reset(char *c) | ||
23 | { | ||
24 | bcsr_write(BCSR_RESETS, 0); | ||
25 | bcsr_write(BCSR_SYSTEM, 0); | ||
26 | } | ||
27 | |||
28 | static int __init db1x_poweroff_setup(void) | ||
29 | { | ||
30 | if (!pm_power_off) | ||
31 | pm_power_off = db1x_power_off; | ||
32 | if (!_machine_halt) | ||
33 | _machine_halt = db1x_power_off; | ||
34 | if (!_machine_restart) | ||
35 | _machine_restart = db1x_reset; | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | late_initcall(db1x_poweroff_setup); | ||
40 | |||
41 | /* register a pcmcia socket */ | ||
42 | int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, | ||
43 | phys_addr_t pcmcia_attr_end, | ||
44 | phys_addr_t pcmcia_mem_start, | ||
45 | phys_addr_t pcmcia_mem_end, | ||
46 | phys_addr_t pcmcia_io_start, | ||
47 | phys_addr_t pcmcia_io_end, | ||
48 | int card_irq, | ||
49 | int cd_irq, | ||
50 | int stschg_irq, | ||
51 | int eject_irq, | ||
52 | int id) | ||
53 | { | ||
54 | int cnt, i, ret; | ||
55 | struct resource *sr; | ||
56 | struct platform_device *pd; | ||
57 | |||
58 | cnt = 5; | ||
59 | if (eject_irq) | ||
60 | cnt++; | ||
61 | if (stschg_irq) | ||
62 | cnt++; | ||
63 | |||
64 | sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL); | ||
65 | if (!sr) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | pd = platform_device_alloc("db1xxx_pcmcia", id); | ||
69 | if (!pd) { | ||
70 | ret = -ENOMEM; | ||
71 | goto out; | ||
72 | } | ||
73 | |||
74 | sr[0].name = "pcmcia-attr"; | ||
75 | sr[0].flags = IORESOURCE_MEM; | ||
76 | sr[0].start = pcmcia_attr_start; | ||
77 | sr[0].end = pcmcia_attr_end; | ||
78 | |||
79 | sr[1].name = "pcmcia-mem"; | ||
80 | sr[1].flags = IORESOURCE_MEM; | ||
81 | sr[1].start = pcmcia_mem_start; | ||
82 | sr[1].end = pcmcia_mem_end; | ||
83 | |||
84 | sr[2].name = "pcmcia-io"; | ||
85 | sr[2].flags = IORESOURCE_MEM; | ||
86 | sr[2].start = pcmcia_io_start; | ||
87 | sr[2].end = pcmcia_io_end; | ||
88 | |||
89 | sr[3].name = "insert"; | ||
90 | sr[3].flags = IORESOURCE_IRQ; | ||
91 | sr[3].start = sr[3].end = cd_irq; | ||
92 | |||
93 | sr[4].name = "card"; | ||
94 | sr[4].flags = IORESOURCE_IRQ; | ||
95 | sr[4].start = sr[4].end = card_irq; | ||
96 | |||
97 | i = 5; | ||
98 | if (stschg_irq) { | ||
99 | sr[i].name = "stschg"; | ||
100 | sr[i].flags = IORESOURCE_IRQ; | ||
101 | sr[i].start = sr[i].end = stschg_irq; | ||
102 | i++; | ||
103 | } | ||
104 | if (eject_irq) { | ||
105 | sr[i].name = "eject"; | ||
106 | sr[i].flags = IORESOURCE_IRQ; | ||
107 | sr[i].start = sr[i].end = eject_irq; | ||
108 | } | ||
109 | |||
110 | pd->resource = sr; | ||
111 | pd->num_resources = cnt; | ||
112 | |||
113 | ret = platform_device_add(pd); | ||
114 | if (!ret) | ||
115 | return 0; | ||
116 | |||
117 | platform_device_put(pd); | ||
118 | out: | ||
119 | kfree(sr); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | #define YAMON_SIZE 0x00100000 | ||
124 | #define YAMON_ENV_SIZE 0x00040000 | ||
125 | |||
126 | int __init db1x_register_norflash(unsigned long size, int width, | ||
127 | int swapped) | ||
128 | { | ||
129 | struct physmap_flash_data *pfd; | ||
130 | struct platform_device *pd; | ||
131 | struct mtd_partition *parts; | ||
132 | struct resource *res; | ||
133 | int ret, i; | ||
134 | |||
135 | if (size < (8 * 1024 * 1024)) | ||
136 | return -EINVAL; | ||
137 | |||
138 | ret = -ENOMEM; | ||
139 | parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL); | ||
140 | if (!parts) | ||
141 | goto out; | ||
142 | |||
143 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
144 | if (!res) | ||
145 | goto out1; | ||
146 | |||
147 | pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL); | ||
148 | if (!pfd) | ||
149 | goto out2; | ||
150 | |||
151 | pd = platform_device_alloc("physmap-flash", 0); | ||
152 | if (!pd) | ||
153 | goto out3; | ||
154 | |||
155 | /* NOR flash ends at 0x20000000, regardless of size */ | ||
156 | res->start = 0x20000000 - size; | ||
157 | res->end = 0x20000000 - 1; | ||
158 | res->flags = IORESOURCE_MEM; | ||
159 | |||
160 | /* partition setup. Most Develboards have a switch which allows | ||
161 | * to swap the physical locations of the 2 NOR flash banks. | ||
162 | */ | ||
163 | i = 0; | ||
164 | if (!swapped) { | ||
165 | /* first NOR chip */ | ||
166 | parts[i].offset = 0; | ||
167 | parts[i].name = "User FS"; | ||
168 | parts[i].size = size / 2; | ||
169 | i++; | ||
170 | } | ||
171 | |||
172 | parts[i].offset = MTDPART_OFS_APPEND; | ||
173 | parts[i].name = "User FS 2"; | ||
174 | parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000); | ||
175 | i++; | ||
176 | |||
177 | parts[i].offset = MTDPART_OFS_APPEND; | ||
178 | parts[i].name = "YAMON"; | ||
179 | parts[i].size = YAMON_SIZE; | ||
180 | parts[i].mask_flags = MTD_WRITEABLE; | ||
181 | i++; | ||
182 | |||
183 | parts[i].offset = MTDPART_OFS_APPEND; | ||
184 | parts[i].name = "raw kernel"; | ||
185 | parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE; | ||
186 | i++; | ||
187 | |||
188 | parts[i].offset = MTDPART_OFS_APPEND; | ||
189 | parts[i].name = "YAMON Env"; | ||
190 | parts[i].size = YAMON_ENV_SIZE; | ||
191 | parts[i].mask_flags = MTD_WRITEABLE; | ||
192 | i++; | ||
193 | |||
194 | if (swapped) { | ||
195 | parts[i].offset = MTDPART_OFS_APPEND; | ||
196 | parts[i].name = "User FS"; | ||
197 | parts[i].size = size / 2; | ||
198 | i++; | ||
199 | } | ||
200 | |||
201 | pfd->width = width; | ||
202 | pfd->parts = parts; | ||
203 | pfd->nr_parts = 5; | ||
204 | |||
205 | pd->dev.platform_data = pfd; | ||
206 | pd->resource = res; | ||
207 | pd->num_resources = 1; | ||
208 | |||
209 | ret = platform_device_add(pd); | ||
210 | if (!ret) | ||
211 | return ret; | ||
212 | |||
213 | platform_device_put(pd); | ||
214 | out3: | ||
215 | kfree(pfd); | ||
216 | out2: | ||
217 | kfree(res); | ||
218 | out1: | ||
219 | kfree(parts); | ||
220 | out: | ||
221 | return ret; | ||
222 | } | ||