Merge branch 'rmobile-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / m68k / platform / 523x / config.c
1 /***************************************************************************/
2
3 /*
4  *      linux/arch/m68knommu/platform/523x/config.c
5  *
6  *      Sub-architcture dependent initialization code for the Freescale
7  *      523x CPUs.
8  *
9  *      Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com)
10  *      Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
11  */
12
13 /***************************************************************************/
14
15 #include <linux/kernel.h>
16 #include <linux/param.h>
17 #include <linux/init.h>
18 #include <linux/io.h>
19 #include <linux/spi/spi.h>
20 #include <linux/gpio.h>
21 #include <asm/machdep.h>
22 #include <asm/coldfire.h>
23 #include <asm/mcfsim.h>
24 #include <asm/mcfuart.h>
25 #include <asm/mcfqspi.h>
26
27 /***************************************************************************/
28
29 static struct mcf_platform_uart m523x_uart_platform[] = {
30         {
31                 .mapbase        = MCFUART_BASE1,
32                 .irq            = MCFINT_VECBASE + MCFINT_UART0,
33         },
34         {
35                 .mapbase        = MCFUART_BASE2,
36                 .irq            = MCFINT_VECBASE + MCFINT_UART0 + 1,
37         },
38         {
39                 .mapbase        = MCFUART_BASE3,
40                 .irq            = MCFINT_VECBASE + MCFINT_UART0 + 2,
41         },
42         { },
43 };
44
45 static struct platform_device m523x_uart = {
46         .name                   = "mcfuart",
47         .id                     = 0,
48         .dev.platform_data      = m523x_uart_platform,
49 };
50
51 static struct resource m523x_fec_resources[] = {
52         {
53                 .start          = MCFFEC_BASE,
54                 .end            = MCFFEC_BASE + MCFFEC_SIZE - 1,
55                 .flags          = IORESOURCE_MEM,
56         },
57         {
58                 .start          = 64 + 23,
59                 .end            = 64 + 23,
60                 .flags          = IORESOURCE_IRQ,
61         },
62         {
63                 .start          = 64 + 27,
64                 .end            = 64 + 27,
65                 .flags          = IORESOURCE_IRQ,
66         },
67         {
68                 .start          = 64 + 29,
69                 .end            = 64 + 29,
70                 .flags          = IORESOURCE_IRQ,
71         },
72 };
73
74 static struct platform_device m523x_fec = {
75         .name                   = "fec",
76         .id                     = 0,
77         .num_resources          = ARRAY_SIZE(m523x_fec_resources),
78         .resource               = m523x_fec_resources,
79 };
80
81 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
82 static struct resource m523x_qspi_resources[] = {
83         {
84                 .start          = MCFQSPI_IOBASE,
85                 .end            = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
86                 .flags          = IORESOURCE_MEM,
87         },
88         {
89                 .start          = MCFINT_VECBASE + MCFINT_QSPI,
90                 .end            = MCFINT_VECBASE + MCFINT_QSPI,
91                 .flags          = IORESOURCE_IRQ,
92         },
93 };
94
95 #define MCFQSPI_CS0    91
96 #define MCFQSPI_CS1    92
97 #define MCFQSPI_CS2    103
98 #define MCFQSPI_CS3    99
99
100 static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control)
101 {
102         int status;
103
104         status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
105         if (status) {
106                 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
107                 goto fail0;
108         }
109         status = gpio_direction_output(MCFQSPI_CS0, 1);
110         if (status) {
111                 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
112                 goto fail1;
113         }
114
115         status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
116         if (status) {
117                 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
118                 goto fail1;
119         }
120         status = gpio_direction_output(MCFQSPI_CS1, 1);
121         if (status) {
122                 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
123                 goto fail2;
124         }
125
126         status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
127         if (status) {
128                 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
129                 goto fail2;
130         }
131         status = gpio_direction_output(MCFQSPI_CS2, 1);
132         if (status) {
133                 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
134                 goto fail3;
135         }
136
137         status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
138         if (status) {
139                 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
140                 goto fail3;
141         }
142         status = gpio_direction_output(MCFQSPI_CS3, 1);
143         if (status) {
144                 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
145                 goto fail4;
146         }
147
148         return 0;
149
150 fail4:
151         gpio_free(MCFQSPI_CS3);
152 fail3:
153         gpio_free(MCFQSPI_CS2);
154 fail2:
155         gpio_free(MCFQSPI_CS1);
156 fail1:
157         gpio_free(MCFQSPI_CS0);
158 fail0:
159         return status;
160 }
161
162 static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control)
163 {
164         gpio_free(MCFQSPI_CS3);
165         gpio_free(MCFQSPI_CS2);
166         gpio_free(MCFQSPI_CS1);
167         gpio_free(MCFQSPI_CS0);
168 }
169
170 static void m523x_cs_select(struct mcfqspi_cs_control *cs_control,
171                             u8 chip_select, bool cs_high)
172 {
173         switch (chip_select) {
174         case 0:
175                 gpio_set_value(MCFQSPI_CS0, cs_high);
176                 break;
177         case 1:
178                 gpio_set_value(MCFQSPI_CS1, cs_high);
179                 break;
180         case 2:
181                 gpio_set_value(MCFQSPI_CS2, cs_high);
182                 break;
183         case 3:
184                 gpio_set_value(MCFQSPI_CS3, cs_high);
185                 break;
186         }
187 }
188
189 static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control,
190                               u8 chip_select, bool cs_high)
191 {
192         switch (chip_select) {
193         case 0:
194                 gpio_set_value(MCFQSPI_CS0, !cs_high);
195                 break;
196         case 1:
197                 gpio_set_value(MCFQSPI_CS1, !cs_high);
198                 break;
199         case 2:
200                 gpio_set_value(MCFQSPI_CS2, !cs_high);
201                 break;
202         case 3:
203                 gpio_set_value(MCFQSPI_CS3, !cs_high);
204                 break;
205         }
206 }
207
208 static struct mcfqspi_cs_control m523x_cs_control = {
209         .setup                  = m523x_cs_setup,
210         .teardown               = m523x_cs_teardown,
211         .select                 = m523x_cs_select,
212         .deselect               = m523x_cs_deselect,
213 };
214
215 static struct mcfqspi_platform_data m523x_qspi_data = {
216         .bus_num                = 0,
217         .num_chipselect         = 4,
218         .cs_control             = &m523x_cs_control,
219 };
220
221 static struct platform_device m523x_qspi = {
222         .name                   = "mcfqspi",
223         .id                     = 0,
224         .num_resources          = ARRAY_SIZE(m523x_qspi_resources),
225         .resource               = m523x_qspi_resources,
226         .dev.platform_data      = &m523x_qspi_data,
227 };
228
229 static void __init m523x_qspi_init(void)
230 {
231         u16 par;
232
233         /* setup QSPS pins for QSPI with gpio CS control */
234         writeb(0x1f, MCFGPIO_PAR_QSPI);
235         /* and CS2 & CS3 as gpio */
236         par = readw(MCFGPIO_PAR_TIMER);
237         par &= 0x3f3f;
238         writew(par, MCFGPIO_PAR_TIMER);
239 }
240 #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
241
242 static struct platform_device *m523x_devices[] __initdata = {
243         &m523x_uart,
244         &m523x_fec,
245 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
246         &m523x_qspi,
247 #endif
248 };
249
250 /***************************************************************************/
251
252 static void __init m523x_fec_init(void)
253 {
254         u16 par;
255         u8 v;
256
257         /* Set multi-function pins to ethernet use */
258         par = readw(MCF_IPSBAR + 0x100082);
259         writew(par | 0xf00, MCF_IPSBAR + 0x100082);
260         v = readb(MCF_IPSBAR + 0x100078);
261         writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
262 }
263
264 /***************************************************************************/
265
266 static void m523x_cpu_reset(void)
267 {
268         local_irq_disable();
269         __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
270 }
271
272 /***************************************************************************/
273
274 void __init config_BSP(char *commandp, int size)
275 {
276         mach_reset = m523x_cpu_reset;
277 }
278
279 /***************************************************************************/
280
281 static int __init init_BSP(void)
282 {
283         m523x_fec_init();
284 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
285         m523x_qspi_init();
286 #endif
287         platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
288         return 0;
289 }
290
291 arch_initcall(init_BSP);
292
293 /***************************************************************************/