add preliminary coldfire v4e support
[openwrt/openwrt.git] / target / linux / coldfire / patches / 001-cf.patch
1 --- /dev/null
2 +++ b/arch/m68k/coldfire/cache.c
3 @@ -0,0 +1,43 @@
4 +/*
5 + * linux/arch/m68k/coldfire/cache.c
6 + *
7 + * Matt Waddel Matt.Waddel@freescale.com
8 + * Kurt Mahan kmahan@freescale.com
9 + * Copyright Freescale Semiconductor, Inc. 2007
10 + *
11 + * This program is free software; you can redistribute it and/or modify
12 + * it under the terms of the GNU General Public License as published by
13 + * the Free Software Foundation; either version 2 of the License, or
14 + * (at your option) any later version.
15 + */
16 +
17 +#include <linux/interrupt.h>
18 +#include <asm/cfcache.h>
19 +#include <asm/coldfire.h>
20 +#include <asm/system.h>
21 +
22 +/* Cache Control Reg shadow reg */
23 +unsigned long shadow_cacr;
24 +
25 +/**
26 + * cacr_set - Set the Cache Control Register
27 + * @x Value to set
28 + */
29 +void cacr_set(unsigned long x)
30 +{
31 + shadow_cacr = x;
32 +
33 + __asm__ __volatile__ ("movec %0, %%cacr"
34 + : /* no outputs */
35 + : "r" (shadow_cacr));
36 +}
37 +
38 +/**
39 + * cacr_get - Get the current value of the Cache Control Register
40 + *
41 + * @return CACR value
42 + */
43 +unsigned long cacr_get(void)
44 +{
45 + return shadow_cacr;
46 +}
47 --- /dev/null
48 +++ b/arch/m68k/coldfire/config.c
49 @@ -0,0 +1,483 @@
50 +/*
51 + * linux/arch/m68k/coldfire/config.c
52 + *
53 + * Kurt Mahan kmahan@freescale.com
54 + * Matt Waddel Matt.Waddel@freescale.com
55 + * Copyright Freescale Semiconductor, Inc. 2007, 2008
56 + *
57 + * This program is free software; you can redistribute it and/or modify
58 + * it under the terms of the GNU General Public License as published by
59 + * the Free Software Foundation; either version 2 of the License, or
60 + * (at your option) any later version.
61 + */
62 +
63 +#include <linux/module.h>
64 +#include <linux/init.h>
65 +#include <linux/string.h>
66 +#include <linux/kernel.h>
67 +#include <linux/console.h>
68 +#include <linux/bootmem.h>
69 +#include <linux/mm.h>
70 +#include <asm/bootinfo.h>
71 +#include <asm/machdep.h>
72 +#include <asm/coldfire.h>
73 +#include <asm/cfcache.h>
74 +#include <asm/cacheflush.h>
75 +#include <asm/io.h>
76 +#include <asm/cfmmu.h>
77 +#include <asm/setup.h>
78 +#include <asm/irq.h>
79 +#include <asm/traps.h>
80 +#include <asm/movs.h>
81 +#include <asm/movs.h>
82 +#include <asm/page.h>
83 +#include <asm/pgalloc.h>
84 +
85 +#include <asm/mcfsim.h>
86 +
87 +#if defined(CONFIG_M5445X)
88 +#define UBOOT_EXTRA_CLOCKS
89 +#elif defined(CONFIG_M547X_8X)
90 +#define UBOOT_PCI
91 +#endif
92 +#include <asm/bootinfo.h>
93 +
94 +#ifdef CONFIG_M5445X
95 +#include <asm/mcf5445x_intc.h>
96 +#include <asm/mcf5445x_sdramc.h>
97 +#include <asm/mcf5445x_fbcs.h>
98 +#include <asm/mcf5445x_dtim.h>
99 +#include <asm/mcf5445x_xbs.h>
100 +#endif
101 +
102 +#ifdef CONFIG_M547X_8X
103 +#include <asm/m5485gpt.h>
104 +#endif
105 +
106 +extern int get_irq_list(struct seq_file *p, void *v);
107 +extern char _text, _end;
108 +extern char _etext, _edata, __init_begin, __init_end;
109 +extern struct console mcfrs_console;
110 +extern char m68k_command_line[CL_SIZE];
111 +extern unsigned long availmem;
112 +
113 +static int irq_enable[NR_IRQS];
114 +unsigned long num_pages;
115 +
116 +/* ethernet mac addresses from uboot */
117 +unsigned char uboot_enet0[6];
118 +unsigned char uboot_enet1[6];
119 +
120 +void coldfire_sort_memrec(void)
121 +{
122 + int i, j;
123 +
124 + /* Sort the m68k_memory records by address */
125 + for (i = 0; i < m68k_num_memory; ++i) {
126 + for (j = i + 1; j < m68k_num_memory; ++j) {
127 + if (m68k_memory[i].addr > m68k_memory[j].addr) {
128 + struct mem_info tmp;
129 + tmp = m68k_memory[i];
130 + m68k_memory[i] = m68k_memory[j];
131 + m68k_memory[j] = tmp;
132 + }
133 + }
134 + }
135 + /* Trim off discontiguous bits */
136 + for (i = 1; i < m68k_num_memory; ++i) {
137 + if ((m68k_memory[i-1].addr + m68k_memory[i-1].size) !=
138 + m68k_memory[i].addr) {
139 + printk(KERN_DEBUG "m68k_parse_bootinfo: addr gap between \
140 + 0x%lx & 0x%lx\n",
141 + m68k_memory[i-1].addr+m68k_memory[i-1].size,
142 + m68k_memory[i].addr);
143 + m68k_num_memory = i;
144 + break;
145 + }
146 + }
147 +}
148 +
149 +/*
150 + * UBoot Handler
151 + */
152 +int __init uboot_commandline(char *bootargs)
153 +{
154 + int len = 0, cmd_line_len;
155 + static struct uboot_record uboot_info;
156 + u32 offset = PAGE_OFFSET_RAW - PHYS_OFFSET;
157 +
158 + extern unsigned long uboot_info_stk;
159 +
160 + /* validate address */
161 + if ((uboot_info_stk < PAGE_OFFSET_RAW) ||
162 + (uboot_info_stk >= (PAGE_OFFSET_RAW + CONFIG_SDRAM_SIZE)))
163 + return 0;
164 +
165 + /* Add offset to get post-remapped kernel memory location */
166 + uboot_info.bdi = (struct bd_info *)((*(u32 *)(uboot_info_stk)) + offset);
167 + uboot_info.initrd_start = (*(u32 *)(uboot_info_stk+4)) + offset;
168 + uboot_info.initrd_end = (*(u32 *)(uboot_info_stk+8)) + offset;
169 + uboot_info.cmd_line_start = (*(u32 *)(uboot_info_stk+12)) + offset;
170 + uboot_info.cmd_line_stop = (*(u32 *)(uboot_info_stk+16)) + offset;
171 +
172 + /* copy over mac addresses */
173 + memcpy(uboot_enet0, uboot_info.bdi->bi_enet0addr, 6);
174 + memcpy(uboot_enet1, uboot_info.bdi->bi_enet1addr, 6);
175 +
176 + /* copy command line */
177 + cmd_line_len = uboot_info.cmd_line_stop - uboot_info.cmd_line_start;
178 + if ((cmd_line_len > 0) && (cmd_line_len < CL_SIZE-1))
179 + len = (int)strncpy(bootargs, (char *)uboot_info.cmd_line_start,\
180 + cmd_line_len);
181 +
182 + return len;
183 +}
184 +
185 +/*
186 + * This routine does things not done in the bootloader.
187 + */
188 +#if defined(CONFIG_M54451)
189 +#define DEFAULT_COMMAND_LINE "debug root=/dev/nfs rw nfsroot=172.27.155.1:/tftpboot/redstripe/rootfs/ ip=172.27.155.51:172.27.155.1"
190 +#elif defined(CONFIG_M54455)
191 +#define MTD_DEFAULT_COMMAND_LINE "root=/dev/mtdblock1 rw rootfstype=jffs2 ip=none mtdparts=physmap-flash.0:5M(kernel)ro,-(jffs2)"
192 +#define DEFAULT_COMMAND_LINE "debug root=/dev/nfs rw nfsroot=172.27.155.1:/tftpboot/redstripe/rootfs/ ip=172.27.155.55:172.27.155.1"
193 +#elif defined(CONFIG_M547X_8X)
194 +#define DEFAULT_COMMAND_LINE "debug root=/dev/nfs rw nfsroot=172.27.155.1:/tftpboot/rigo/rootfs/ ip=172.27.155.75:172.27.155.1"
195 +#endif
196 +asmlinkage void __init cf_early_init(void)
197 +{
198 + struct bi_record *record = (struct bi_record *) &_end;
199 +
200 + extern char _end;
201 +
202 +#if defined(CONFIG_M5445X)
203 + SET_VBR((void *)MCF_RAMBAR1);
204 +#elif defined(CONFIG_M547X_8X)
205 + SET_VBR((void *)MCF_RAMBAR0);
206 +#endif
207 +
208 + /* Mask all interrupts */
209 +#if defined(CONFIG_M5445X)
210 + MCF_INTC0_IMRL = 0xFFFFFFFF;
211 + MCF_INTC0_IMRH = 0xFFFFFFFF;
212 + MCF_INTC1_IMRL = 0xFFFFFFFF;
213 + MCF_INTC1_IMRH = 0xFFFFFFFF;
214 +#elif defined(CONFIG_M547X_8X)
215 + MCF_IMRL = 0xFFFFFFFF;
216 + MCF_IMRH = 0xFFFFFFFF;
217 +#endif
218 +
219 +#if defined(CONFIG_M5445X)
220 +#if defined(CONFIG_NOR_FLASH_BASE)
221 + MCF_FBCS_CSAR(1) = CONFIG_NOR_FLASH_BASE;
222 +#else
223 + MCF_FBCS_CSAR(1) = 0x00000000;
224 +#endif
225 +
226 +#if CONFIG_SDRAM_SIZE > (256*1024*1024)
227 + /* Init optional SDRAM chip select */
228 + MCF_SDRAMC_SDCS(1) = (256*1024*1024) | 0x1B;
229 +#endif
230 +#endif /* CONFIG_M5445X */
231 +
232 +#if defined(CONFIG_M5445X)
233 + /* Setup SDRAM crossbar(XBS) priorities */
234 + MCF_XBS_PRS2 = (MCF_XBS_PRS_M0(MCF_XBS_PRI_2) |
235 + MCF_XBS_PRS_M1(MCF_XBS_PRI_3) |
236 + MCF_XBS_PRS_M2(MCF_XBS_PRI_4) |
237 + MCF_XBS_PRS_M3(MCF_XBS_PRI_5) |
238 + MCF_XBS_PRS_M5(MCF_XBS_PRI_6) |
239 + MCF_XBS_PRS_M6(MCF_XBS_PRI_1) |
240 + MCF_XBS_PRS_M7(MCF_XBS_PRI_7));
241 +#endif
242 +
243 + m68k_machtype = MACH_CFMMU;
244 + m68k_fputype = FPU_CFV4E;
245 + m68k_mmutype = MMU_CFV4E;
246 + m68k_cputype = CPU_CFV4E;
247 +
248 + m68k_num_memory = 0;
249 + m68k_memory[m68k_num_memory].addr = CONFIG_SDRAM_BASE;
250 + m68k_memory[m68k_num_memory++].size = CONFIG_SDRAM_SIZE;
251 +
252 + if (!uboot_commandline(m68k_command_line)) {
253 +#if defined(CONFIG_BOOTPARAM)
254 + strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE-1);
255 +#else
256 + strcpy(m68k_command_line, DEFAULT_COMMAND_LINE);
257 +#endif
258 + }
259 +
260 +#if defined(CONFIG_BLK_DEV_INITRD)
261 + /* add initrd image */
262 + record = (struct bi_record *) ((void *)record + record->size);
263 + record->tag = BI_RAMDISK;
264 + record->size = sizeof(record->tag) + sizeof(record->size)
265 + + sizeof(record->data[0]) + sizeof(record->data[1]);
266 +#endif
267 +
268 + /* Mark end of tags. */
269 + record = (struct bi_record *) ((void *) record + record->size);
270 + record->tag = 0;
271 + record->data[0] = 0;
272 + record->data[1] = 0;
273 + record->size = sizeof(record->tag) + sizeof(record->size)
274 + + sizeof(record->data[0]) + sizeof(record->data[1]);
275 +
276 + /* Invalidate caches via CACR */
277 + flush_bcache();
278 + cacr_set(CACHE_DISABLE_MODE);
279 +
280 + /* Turn on caches via CACR, enable EUSP */
281 + cacr_set(CACHE_INITIAL_MODE);
282 +
283 +}
284 +
285 +#if defined(CONFIG_M5445X)
286 +void settimericr(unsigned int timer, unsigned int level)
287 +{
288 + volatile unsigned char *icrp;
289 + unsigned int icr;
290 + unsigned char irq;
291 +
292 + if (timer <= 2) {
293 + switch (timer) {
294 + case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
295 + default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
296 + }
297 +
298 + icrp = (volatile unsigned char *) (icr);
299 + *icrp = level;
300 + coldfire_enable_irq0(irq);
301 + }
302 +}
303 +#endif
304 +
305 +/* Assembler routines */
306 +asmlinkage void buserr(void);
307 +asmlinkage void trap(void);
308 +asmlinkage void system_call(void);
309 +asmlinkage void inthandler(void);
310 +
311 +void __init coldfire_trap_init(void)
312 +{
313 + int i = 0;
314 + e_vector *vectors;
315 +
316 +#if defined(CONFIG_M5445X)
317 + vectors = (e_vector *)MCF_RAMBAR1;
318 +#elif defined(CONFIG_M547X_8X)
319 + vectors = (e_vector *)MCF_RAMBAR0;
320 +#endif
321 + /*
322 + * There is a common trap handler and common interrupt
323 + * handler that handle almost every vector. We treat
324 + * the system call and bus error special, they get their
325 + * own first level handlers.
326 + */
327 + for (i = 3; (i <= 23); i++)
328 + vectors[i] = trap;
329 + for (i = 33; (i <= 63); i++)
330 + vectors[i] = trap;
331 + for (i = 24; (i <= 31); i++)
332 + vectors[i] = inthandler;
333 + for (i = 64; (i < 255); i++)
334 + vectors[i] = inthandler;
335 +
336 + vectors[255] = 0;
337 + vectors[2] = buserr;
338 + vectors[32] = system_call;
339 +}
340 +
341 +#if defined(CONFIG_M5445X)
342 +
343 +void coldfire_tick(void)
344 +{
345 + /* Reset the ColdFire timer */
346 + __raw_writeb(MCF_DTIM_DTER_CAP | MCF_DTIM_DTER_REF, MCF_DTIM0_DTER);
347 +}
348 +
349 +void __init coldfire_sched_init(irq_handler_t handler)
350 +{
351 + unsigned int mcf_timerlevel = 5;
352 + unsigned int mcf_timervector = 64+32;
353 +
354 + __raw_writew(MCF_DTIM_DTMR_RST_RST, MCF_DTIM0_DTMR);
355 + __raw_writel(((MCF_BUSCLK / 16) / HZ), MCF_DTIM0_DTRR);
356 + __raw_writew(MCF_DTIM_DTMR_ORRI | MCF_DTIM_DTMR_CLK_DIV16 |
357 + MCF_DTIM_DTMR_FRR | MCF_DTIM_DTMR_RST_EN, \
358 + MCF_DTIM0_DTMR);
359 +
360 + request_irq(mcf_timervector, handler, IRQF_DISABLED, \
361 + "timer", (void *)MCF_DTIM0_DTMR);
362 +
363 + settimericr(1, mcf_timerlevel);
364 +}
365 +
366 +int timerirqpending(int timer)
367 +{
368 + unsigned int imr = 0;
369 +
370 + switch (timer) {
371 + case 1: imr = 0x1; break;
372 + case 2: imr = 0x2; break;
373 + default: break;
374 + }
375 +
376 + return (getiprh() & imr);
377 +}
378 +
379 +unsigned long coldfire_gettimeoffset(void)
380 +{
381 + volatile unsigned long trr, tcn, offset;
382 +
383 + tcn = __raw_readw(MCF_DTIM0_DTCN);
384 + trr = __raw_readl(MCF_DTIM0_DTRR);
385 + offset = (tcn * (1000000 / HZ)) / trr;
386 +
387 + /* Check if we just wrapped the counters and maybe missed a tick */
388 + if ((offset < (1000000 / HZ / 2)) && timerirqpending(1))
389 + offset += 1000000 / HZ;
390 + return offset;
391 +}
392 +
393 +#elif defined(CONFIG_M547X_8X)
394 +
395 +void coldfire_tick(void)
396 +{
397 + /* Reset the ColdFire timer */
398 + MCF_SSR(0) = MCF_SSR_ST;
399 +}
400 +
401 +void __init coldfire_sched_init(irq_handler_t handler)
402 +{
403 + int irq = ISC_SLTn(0);
404 +
405 + MCF_SCR(0) = 0;
406 + MCF_ICR(irq) = ILP_SLT0;
407 + request_irq(64 + irq, handler, IRQF_DISABLED, "ColdFire Timer 0", NULL);
408 + MCF_SLTCNT(0) = MCF_BUSCLK / HZ;
409 + MCF_SCR(0) |= MCF_SCR_TEN | MCF_SCR_IEN | MCF_SCR_RUN;
410 +}
411 +
412 +unsigned long coldfire_gettimeoffset(void)
413 +{
414 + volatile unsigned long trr, tcn, offset;
415 + trr = MCF_SLTCNT(0);
416 + tcn = MCF_SCNT(0);
417 +
418 + offset = (trr - tcn) * ((1000000 >> 3) / HZ) / (trr >> 3);
419 + if (MCF_SSR(0) & MCF_SSR_ST)
420 + offset += 1000000 / HZ;
421 +
422 + return offset;
423 +}
424 +
425 +#endif
426 +
427 +void coldfire_reboot(void)
428 +{
429 +#if defined(CONFIG_M5445X)
430 + /* disable interrupts and do a software reset */
431 + asm("movew #0x2700, %%sr\n\t"
432 + "moveb #0x80, %%d0\n\t"
433 + "moveb %%d0, 0xfc0a0000\n\t"
434 + : : : "%d0");
435 +#elif defined(CONFIG_M547X_8X)
436 + /* disable interrupts and enable the watchdog */
437 + printk(KERN_INFO "Rebooting\n");
438 + asm("movew #0x2700, %sr\n");
439 + MCF_GPT_GMS0 = MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4);
440 +#endif
441 +}
442 +
443 +static void coldfire_get_model(char *model)
444 +{
445 + sprintf(model, "Version 4 ColdFire");
446 +}
447 +
448 +static void __init
449 +coldfire_bootmem_alloc(unsigned long memory_start, unsigned long memory_end)
450 +{
451 + unsigned long base_pfn;
452 +
453 + /* compute total pages in system */
454 + num_pages = PAGE_ALIGN(memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
455 +
456 + /* align start/end to page boundries */
457 + memory_start = PAGE_ALIGN(memory_start);
458 + memory_end = memory_end & PAGE_MASK;
459 +
460 + /* page numbers */
461 + base_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT;
462 + min_low_pfn = __pa(memory_start) >> PAGE_SHIFT;
463 + max_low_pfn = __pa(memory_end) >> PAGE_SHIFT;
464 +
465 + high_memory = (void *)memory_end;
466 + availmem = memory_start;
467 +
468 + /* setup bootmem data */
469 + m68k_setup_node(0);
470 + availmem += init_bootmem_node(NODE_DATA(0), min_low_pfn,
471 + base_pfn, max_low_pfn);
472 + availmem = PAGE_ALIGN(availmem);
473 + free_bootmem(__pa(availmem), memory_end - (availmem));
474 +}
475 +
476 +void __init config_coldfire(void)
477 +{
478 + unsigned long endmem, startmem;
479 + int i;
480 +
481 + /*
482 + * Calculate endmem from m68k_memory, assume all are contiguous
483 + */
484 + startmem = ((((int) &_end) + (PAGE_SIZE - 1)) & PAGE_MASK);
485 + endmem = PAGE_OFFSET;
486 + for (i = 0; i < m68k_num_memory; ++i)
487 + endmem += m68k_memory[i].size;
488 +
489 + printk(KERN_INFO "starting up linux startmem 0x%lx, endmem 0x%lx, \
490 + size %luMB\n", startmem, endmem, (endmem - startmem) >> 20);
491 +
492 + memset(irq_enable, 0, sizeof(irq_enable));
493 +
494 + /*
495 + * Setup coldfire mach-specific handlers
496 + */
497 + mach_max_dma_address = 0xffffffff;
498 + mach_sched_init = coldfire_sched_init;
499 + mach_tick = coldfire_tick;
500 + mach_gettimeoffset = coldfire_gettimeoffset;
501 + mach_reset = coldfire_reboot;
502 +/* mach_hwclk = coldfire_hwclk; to be done */
503 + mach_get_model = coldfire_get_model;
504 +
505 + coldfire_bootmem_alloc(startmem, endmem-1);
506 +
507 + /*
508 + * initrd setup
509 + */
510 +/* #ifdef CONFIG_BLK_DEV_INITRD
511 + if (m68k_ramdisk.size) {
512 + reserve_bootmem (__pa(m68k_ramdisk.addr), m68k_ramdisk.size);
513 + initrd_start = (unsigned long) m68k_ramdisk.addr;
514 + initrd_end = initrd_start + m68k_ramdisk.size;
515 + printk (KERN_DEBUG "initrd: %08lx - %08lx\n", initrd_start,
516 + initrd_end);
517 + }
518 +#endif */
519 +
520 +#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_FRAMEBUFFER_CONSOLE)
521 + conswitchp = &dummy_con;
522 +#endif
523 +
524 +#if defined(CONFIG_SERIAL_COLDFIRE)
525 + /*
526 + * This causes trouble when it is re-registered later.
527 + * Currently this is fixed by conditionally commenting
528 + * out the register_console in mcf_serial.c
529 + */
530 + register_console(&mcfrs_console);
531 +#endif
532 +}
533 --- /dev/null
534 +++ b/arch/m68k/coldfire/entry.S
535 @@ -0,0 +1,711 @@
536 +/*
537 + * arch/m68k/coldfire/entry.S
538 + *
539 + * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
540 + * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
541 + * Kenneth Albanowski <kjahds@kjahds.com>,
542 + * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
543 + * Copyright (C) 2004-2006 Macq Electronique SA. (www.macqel.com)
544 + * Matt Waddel Matt.Waddel@freescale.com
545 + * Kurt Mahan kmahan@freescale.com
546 + * Copyright Freescale Semiconductor, Inc. 2007
547 + *
548 + * Modify irq status in buserr -- (c) Copyright 2008, SYSTEM electronic Gmbh
549 + *
550 + * Based on:
551 + *
552 + * arch/m68knommu/platform/5307/entry.S &
553 + * arch/m68k/kernel/entry.S
554 + *
555 + * Copyright (C) 1991, 1992 Linus Torvalds
556 + *
557 + * This file is subject to the terms and conditions of the GNU General Public
558 + * License. See the file README.legal in the main directory of this archive
559 + * for more details.
560 + *
561 + * Linux/m68k support by Hamish Macdonald
562 + *
563 + * ColdFire support by Greg Ungerer (gerg@snapgear.com)
564 + * 5307 fixes by David W. Miller
565 + * linux 2.4 support David McCullough <davidm@snapgear.com>
566 + * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
567 + * Ported to mmu Coldfire by Matt Waddel
568 + */
569 +
570 +#include <linux/sys.h>
571 +#include <linux/linkage.h>
572 +#include <asm/cf_entry.h>
573 +#include <asm/errno.h>
574 +#include <asm/setup.h>
575 +#include <asm/segment.h>
576 +#include <asm/traps.h>
577 +#include <asm/unistd.h>
578 +
579 +/*
580 + * TASK_INFO:
581 + *
582 + * - TINFO_PREEMPT (struct thread_info / preempt_count)
583 + * Used to keep track of preemptability
584 + * - TINFO_FLAGS (struct thread_info / flags - include/asm-m68k/thread_info.h)
585 + * Various bit flags that are checked for scheduling/tracing
586 + * Bits 0-7 are checked every exception exit
587 + * 8-15 are checked every syscall exit
588 + *
589 + * TIF_SIGPENDING 6
590 + * TIF_NEED_RESCHED 7
591 + * TIF_DELAYED_TRACE 14
592 + * TIF_SYSCALL_TRACE 15
593 + * TIF_MEMDIE 16 (never checked here)
594 + */
595 +
596 +.bss
597 +
598 +sw_ksp:
599 +.long 0
600 +
601 +sw_usp:
602 +.long 0
603 +
604 +.text
605 +
606 +.globl system_call
607 +.globl buserr
608 +.globl trap
609 +.globl resume
610 +.globl ret_from_exception
611 +.globl ret_from_signal
612 +.globl sys_call_table
613 +.globl ret_from_interrupt
614 +.globl inthandler
615 +
616 +ENTRY(buserr)
617 +#ifdef CONFIG_COLDFIRE_FOO
618 + movew #0x2700,%sr /* lock interrupts */
619 +#endif
620 + SAVE_ALL_INT
621 +#ifdef CONFIG_COLDFIRE_FOO
622 + movew PT_SR(%sp),%d3 /* get original %sr */
623 + oril #0x2000,%d3 /* set supervisor mode in it */
624 + movew %d3,%sr /* recover irq state */
625 +#endif
626 + GET_CURRENT(%d0)
627 + movel %sp,%sp@- /* stack frame pointer argument */
628 + jsr buserr_c
629 + addql #4,%sp
630 + jra .Lret_from_exception
631 +
632 +ENTRY(trap)
633 + SAVE_ALL_INT
634 + GET_CURRENT(%d0)
635 + movel %sp,%sp@- /* stack frame pointer argument */
636 + jsr trap_c
637 + addql #4,%sp
638 + jra .Lret_from_exception
639 +
640 + /* After a fork we jump here directly from resume,
641 + %d1 contains the previous task schedule_tail */
642 +ENTRY(ret_from_fork)
643 + movel %d1,%sp@-
644 + jsr schedule_tail
645 + addql #4,%sp
646 + jra .Lret_from_exception
647 +
648 +do_trace_entry:
649 + movel #-ENOSYS,%d1 /* needed for strace */
650 + movel %d1,%sp@(PT_D0)
651 + subql #4,%sp
652 + SAVE_SWITCH_STACK
653 + jbsr syscall_trace
654 + RESTORE_SWITCH_STACK
655 + addql #4,%sp
656 + movel %sp@(PT_ORIG_D0),%d0
657 + cmpl #NR_syscalls,%d0
658 + jcs syscall
659 +badsys:
660 + movel #-ENOSYS,%d1
661 + movel %d1,%sp@(PT_D0)
662 + jra ret_from_exception
663 +
664 +do_trace_exit:
665 + subql #4,%sp
666 + SAVE_SWITCH_STACK
667 + jbsr syscall_trace
668 + RESTORE_SWITCH_STACK
669 + addql #4,%sp
670 + jra .Lret_from_exception
671 +
672 +ENTRY(ret_from_signal)
673 + RESTORE_SWITCH_STACK
674 + addql #4,%sp
675 + jra .Lret_from_exception
676 +
677 +ENTRY(system_call)
678 + SAVE_ALL_SYS
679 +
680 + GET_CURRENT(%d1)
681 + /* save top of frame */
682 + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
683 +
684 + /* syscall trace */
685 + tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
686 + jmi do_trace_entry /* SYSCALL_TRACE is set */
687 + cmpl #NR_syscalls,%d0
688 + jcc badsys
689 +syscall:
690 + movel #sys_call_table,%a0
691 + asll #2,%d0
692 + addl %d0,%a0
693 + movel %a0@,%a0
694 + jsr %a0@
695 + movel %d0,%sp@(PT_D0) /* save the return value */
696 +ret_from_syscall:
697 + movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
698 + jne syscall_exit_work /* flags set so process */
699 +1: RESTORE_ALL
700 +
701 +syscall_exit_work:
702 + btst #5,%sp@(PT_SR) /* check if returning to kernel */
703 + bnes 1b /* if so, skip resched, signals */
704 +
705 + btstl #15,%d0 /* check if SYSCALL_TRACE */
706 + jne do_trace_exit
707 + btstl #14,%d0 /* check if DELAYED_TRACE */
708 + jne do_delayed_trace
709 + btstl #6,%d0 /* check if SIGPENDING */
710 + jne do_signal_return
711 + pea resume_userspace
712 + jra schedule
713 +
714 +ENTRY(ret_from_exception)
715 +.Lret_from_exception:
716 + btst #5,%sp@(PT_SR) /* check if returning to kernel */
717 + bnes 1f /* if so, skip resched, signals */
718 + movel %d0,%sp@- /* Only allow interrupts when we are */
719 + move %sr,%d0 /* last one on the kernel stack, */
720 + andl #ALLOWINT,%d0 /* otherwise stack overflow can occur */
721 + move %d0,%sr /* during heavy interrupt load. */
722 + movel %sp@+,%d0
723 +
724 +resume_userspace:
725 + moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
726 + jne exit_work /* SIGPENDING and/or NEED_RESCHED set */
727 +1: RESTORE_ALL
728 +
729 +exit_work:
730 + /* save top of frame */
731 + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
732 + btstl #6,%d0 /* check for SIGPENDING in flags */
733 + jne do_signal_return
734 + pea resume_userspace
735 + jra schedule
736 +
737 +do_signal_return:
738 + subql #4,%sp /* dummy return address */
739 + SAVE_SWITCH_STACK
740 + pea %sp@(SWITCH_STACK_SIZE)
741 + clrl %sp@-
742 + bsrl do_signal
743 + addql #8,%sp
744 + RESTORE_SWITCH_STACK
745 + addql #4,%sp
746 + jbra resume_userspace
747 +
748 +do_delayed_trace:
749 + bclr #7,%sp@(PT_SR) /* clear trace bit in SR */
750 + pea 1 /* send SIGTRAP */
751 + movel %curptr,%sp@-
752 + pea LSIGTRAP
753 + jbsr send_sig
754 + addql #8,%sp
755 + addql #4,%sp
756 + jbra resume_userspace
757 +
758 +/*
759 + * This is the interrupt handler (for all hardware interrupt
760 + * sources). It figures out the vector number and calls the appropriate
761 + * interrupt service routine directly.
762 + */
763 +ENTRY(inthandler)
764 + SAVE_ALL_INT
765 + GET_CURRENT(%d0)
766 + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
767 + /* put exception # in d0 */
768 + movel %sp@(PT_VECTOR),%d0
769 + swap %d0 /* extract bits 25:18 */
770 + lsrl #2,%d0
771 + andl #0x0ff,%d0
772 +
773 + movel %sp,%sp@-
774 + movel %d0,%sp@- /* put vector # on stack */
775 +auto_irqhandler_fixup = . + 2
776 + jbsr process_int /* process the IRQ */
777 + addql #8,%sp /* pop parameters off stack */
778 +
779 +ENTRY(ret_from_interrupt)
780 +ret_from_interrupt:
781 +
782 + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
783 + jeq ret_from_last_interrupt
784 +2: RESTORE_ALL
785 +
786 + ALIGN
787 +ret_from_last_interrupt:
788 + moveb %sp@(PT_SR),%d0
789 + andl #(~ALLOWINT>>8)&0xff,%d0
790 + jne 2b
791 +
792 + /* check if we need to do software interrupts */
793 + tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
794 + jeq .Lret_from_exception
795 + pea ret_from_exception
796 + jra do_softirq
797 +
798 +ENTRY(user_inthandler)
799 + SAVE_ALL_INT
800 + GET_CURRENT(%d0)
801 + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
802 + /* put exception # in d0 */
803 + movel %sp@(PT_VECTOR),%d0
804 +user_irqvec_fixup = . + 2
805 + swap %d0 /* extract bits 25:18 */
806 + lsrl #2,%d0
807 + andl #0x0ff,%d0
808 +
809 + movel %sp,%sp@-
810 + movel %d0,%sp@- /* put vector # on stack */
811 +user_irqhandler_fixup = . + 2
812 + jbsr process_int /* process the IRQ */
813 + addql #8,%sp /* pop parameters off stack */
814 +
815 + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
816 + jeq ret_from_last_interrupt
817 + RESTORE_ALL
818 +
819 +/* Handler for uninitialized and spurious interrupts */
820 +
821 +ENTRY(bad_inthandler)
822 + SAVE_ALL_INT
823 + GET_CURRENT(%d0)
824 + addql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
825 +
826 + movel %sp,%sp@-
827 + jsr handle_badint
828 + addql #4,%sp
829 +
830 + subql #1,%curptr@(TASK_INFO+TINFO_PREEMPT)
831 + jeq ret_from_last_interrupt
832 + RESTORE_ALL
833 +
834 +ENTRY(sys_fork)
835 + SAVE_SWITCH_STACK
836 + pea %sp@(SWITCH_STACK_SIZE)
837 + jbsr m68k_fork
838 + addql #4,%sp
839 + RESTORE_SWITCH_STACK
840 + rts
841 +
842 +ENTRY(sys_clone)
843 + SAVE_SWITCH_STACK
844 + pea %sp@(SWITCH_STACK_SIZE)
845 + jbsr m68k_clone
846 + addql #4,%sp
847 + RESTORE_SWITCH_STACK
848 + rts
849 +
850 +ENTRY(sys_vfork)
851 + SAVE_SWITCH_STACK
852 + pea %sp@(SWITCH_STACK_SIZE)
853 + jbsr m68k_vfork
854 + addql #4,%sp
855 + RESTORE_SWITCH_STACK
856 + rts
857 +
858 +ENTRY(sys_sigsuspend)
859 + SAVE_SWITCH_STACK
860 + pea %sp@(SWITCH_STACK_SIZE)
861 + jbsr do_sigsuspend
862 + addql #4,%sp
863 + RESTORE_SWITCH_STACK
864 + rts
865 +
866 +ENTRY(sys_rt_sigsuspend)
867 + SAVE_SWITCH_STACK
868 + pea %sp@(SWITCH_STACK_SIZE)
869 + jbsr do_rt_sigsuspend
870 + addql #4,%sp
871 + RESTORE_SWITCH_STACK
872 + rts
873 +
874 +ENTRY(sys_sigreturn)
875 + SAVE_SWITCH_STACK
876 + jbsr do_sigreturn
877 + RESTORE_SWITCH_STACK
878 + rts
879 +
880 +ENTRY(sys_rt_sigreturn)
881 + SAVE_SWITCH_STACK
882 + jbsr do_rt_sigreturn
883 + RESTORE_SWITCH_STACK
884 + rts
885 +
886 +resume:
887 + /*
888 + * Beware - when entering resume, prev (the current task) is
889 + * in a0, next (the new task) is in a1,so don't change these
890 + * registers until their contents are no longer needed.
891 + */
892 +
893 + /* save sr */
894 + movew %sr,%d0
895 + movew %d0,%a0@(TASK_THREAD+THREAD_SR)
896 +
897 + /* save usp */
898 + /* Save USP via %a1 (which is saved/restored from %d0) */
899 + movel %a1,%d0
900 + movel %usp,%a1
901 + movel %a1,%a0@(TASK_THREAD+THREAD_USP)
902 + movel %d0,%a1
903 +
904 + /* save non-scratch registers on stack */
905 + SAVE_SWITCH_STACK
906 +
907 + /* save current kernel stack pointer */
908 + movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
909 +
910 + /* Return previous task in %d1 */
911 + movel %curptr,%d1
912 +
913 + /* switch to new task (a1 contains new task) */
914 + movel %a1,%curptr
915 +
916 + /* restore the kernel stack pointer */
917 + movel %a1@(TASK_THREAD+THREAD_KSP),%sp
918 +
919 + /* restore non-scratch registers */
920 + RESTORE_SWITCH_STACK
921 +
922 + /* restore user stack pointer */
923 + movel %a1@(TASK_THREAD+THREAD_USP),%a0
924 + movel %a0,%usp
925 +
926 + /* restore status register */
927 + movew %a1@(TASK_THREAD+THREAD_SR),%d0
928 + movew %d0,%sr
929 +
930 + rts
931 +
932 +.data
933 +ALIGN
934 +sys_call_table:
935 + .long sys_ni_syscall /* 0 - old "setup()" system call*/
936 + .long sys_exit
937 + .long sys_fork
938 + .long sys_read
939 + .long sys_write
940 + .long sys_open /* 5 */
941 + .long sys_close
942 + .long sys_waitpid
943 + .long sys_creat
944 + .long sys_link
945 + .long sys_unlink /* 10 */
946 + .long sys_execve
947 + .long sys_chdir
948 + .long sys_time
949 + .long sys_mknod
950 + .long sys_chmod /* 15 */
951 + .long sys_chown16
952 + .long sys_ni_syscall /* old break syscall holder */
953 + .long sys_stat
954 + .long sys_lseek
955 + .long sys_getpid /* 20 */
956 + .long sys_mount
957 + .long sys_oldumount
958 + .long sys_setuid16
959 + .long sys_getuid16
960 + .long sys_stime /* 25 */
961 + .long sys_ptrace
962 + .long sys_alarm
963 + .long sys_fstat
964 + .long sys_pause
965 + .long sys_utime /* 30 */
966 + .long sys_ni_syscall /* old stty syscall holder */
967 + .long sys_ni_syscall /* old gtty syscall holder */
968 + .long sys_access
969 + .long sys_nice
970 + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
971 + .long sys_sync
972 + .long sys_kill
973 + .long sys_rename
974 + .long sys_mkdir
975 + .long sys_rmdir /* 40 */
976 + .long sys_dup
977 + .long sys_pipe
978 + .long sys_times
979 + .long sys_ni_syscall /* old prof syscall holder */
980 + .long sys_brk /* 45 */
981 + .long sys_setgid16
982 + .long sys_getgid16
983 + .long sys_signal
984 + .long sys_geteuid16
985 + .long sys_getegid16 /* 50 */
986 + .long sys_acct
987 + .long sys_umount /* recycled never used phys() */
988 + .long sys_ni_syscall /* old lock syscall holder */
989 + .long sys_ioctl
990 + .long sys_fcntl /* 55 */
991 + .long sys_ni_syscall /* old mpx syscall holder */
992 + .long sys_setpgid
993 + .long sys_ni_syscall /* old ulimit syscall holder */
994 + .long sys_ni_syscall
995 + .long sys_umask /* 60 */
996 + .long sys_chroot
997 + .long sys_ustat
998 + .long sys_dup2
999 + .long sys_getppid
1000 + .long sys_getpgrp /* 65 */
1001 + .long sys_setsid
1002 + .long sys_sigaction
1003 + .long sys_sgetmask
1004 + .long sys_ssetmask
1005 + .long sys_setreuid16 /* 70 */
1006 + .long sys_setregid16
1007 + .long sys_sigsuspend
1008 + .long sys_sigpending
1009 + .long sys_sethostname
1010 + .long sys_setrlimit /* 75 */
1011 + .long sys_old_getrlimit
1012 + .long sys_getrusage
1013 + .long sys_gettimeofday
1014 + .long sys_settimeofday
1015 + .long sys_getgroups16 /* 80 */
1016 + .long sys_setgroups16
1017 + .long old_select
1018 + .long sys_symlink
1019 + .long sys_lstat
1020 + .long sys_readlink /* 85 */
1021 + .long sys_uselib
1022 + .long sys_swapon
1023 + .long sys_reboot
1024 + .long old_readdir
1025 + .long old_mmap /* 90 */
1026 + .long sys_munmap
1027 + .long sys_truncate
1028 + .long sys_ftruncate
1029 + .long sys_fchmod
1030 + .long sys_fchown16 /* 95 */
1031 + .long sys_getpriority
1032 + .long sys_setpriority
1033 + .long sys_ni_syscall /* old profil syscall holder */
1034 + .long sys_statfs
1035 + .long sys_fstatfs /* 100 */
1036 + .long sys_ni_syscall /* ioperm for i386 */
1037 + .long sys_socketcall
1038 + .long sys_syslog
1039 + .long sys_setitimer
1040 + .long sys_getitimer /* 105 */
1041 + .long sys_newstat
1042 + .long sys_newlstat
1043 + .long sys_newfstat
1044 + .long sys_ni_syscall
1045 + .long sys_ni_syscall /* 110 */ /* iopl for i386 */
1046 + .long sys_vhangup
1047 + .long sys_ni_syscall /* obsolete idle() syscall */
1048 + .long sys_ni_syscall /* vm86old for i386 */
1049 + .long sys_wait4
1050 + .long sys_swapoff /* 115 */
1051 + .long sys_sysinfo
1052 + .long sys_ipc
1053 + .long sys_fsync
1054 + .long sys_sigreturn
1055 + .long sys_clone /* 120 */
1056 + .long sys_setdomainname
1057 + .long sys_newuname
1058 + .long sys_cacheflush /* modify_ldt for i386 */
1059 + .long sys_adjtimex
1060 + .long sys_mprotect /* 125 */
1061 + .long sys_sigprocmask
1062 + .long sys_ni_syscall /* old "create_module" */
1063 + .long sys_init_module
1064 + .long sys_delete_module
1065 + .long sys_ni_syscall /* 130 - old "get_kernel_syms" */
1066 + .long sys_quotactl
1067 + .long sys_getpgid
1068 + .long sys_fchdir
1069 + .long sys_bdflush
1070 + .long sys_sysfs /* 135 */
1071 + .long sys_personality
1072 + .long sys_ni_syscall /* for afs_syscall */
1073 + .long sys_setfsuid16
1074 + .long sys_setfsgid16
1075 + .long sys_llseek /* 140 */
1076 + .long sys_getdents
1077 + .long sys_select
1078 + .long sys_flock
1079 + .long sys_msync
1080 + .long sys_readv /* 145 */
1081 + .long sys_writev
1082 + .long sys_getsid
1083 + .long sys_fdatasync
1084 + .long sys_sysctl
1085 + .long sys_mlock /* 150 */
1086 + .long sys_munlock
1087 + .long sys_mlockall
1088 + .long sys_munlockall
1089 + .long sys_sched_setparam
1090 + .long sys_sched_getparam /* 155 */
1091 + .long sys_sched_setscheduler
1092 + .long sys_sched_getscheduler
1093 + .long sys_sched_yield
1094 + .long sys_sched_get_priority_max
1095 + .long sys_sched_get_priority_min /* 160 */
1096 + .long sys_sched_rr_get_interval
1097 + .long sys_nanosleep
1098 + .long sys_mremap
1099 + .long sys_setresuid16
1100 + .long sys_getresuid16 /* 165 */
1101 + .long sys_getpagesize
1102 + .long sys_ni_syscall /* old sys_query_module */
1103 + .long sys_poll
1104 + .long sys_nfsservctl
1105 + .long sys_setresgid16 /* 170 */
1106 + .long sys_getresgid16
1107 + .long sys_prctl
1108 + .long sys_rt_sigreturn
1109 + .long sys_rt_sigaction
1110 + .long sys_rt_sigprocmask /* 175 */
1111 + .long sys_rt_sigpending
1112 + .long sys_rt_sigtimedwait
1113 + .long sys_rt_sigqueueinfo
1114 + .long sys_rt_sigsuspend
1115 + .long sys_pread64 /* 180 */
1116 + .long sys_pwrite64
1117 + .long sys_lchown16;
1118 + .long sys_getcwd
1119 + .long sys_capget
1120 + .long sys_capset /* 185 */
1121 + .long sys_sigaltstack
1122 + .long sys_sendfile
1123 + .long sys_ni_syscall /* streams1 */
1124 + .long sys_ni_syscall /* streams2 */
1125 + .long sys_vfork /* 190 */
1126 + .long sys_getrlimit
1127 + .long sys_mmap2
1128 + .long sys_truncate64
1129 + .long sys_ftruncate64
1130 + .long sys_stat64 /* 195 */
1131 + .long sys_lstat64
1132 + .long sys_fstat64
1133 + .long sys_chown
1134 + .long sys_getuid
1135 + .long sys_getgid /* 200 */
1136 + .long sys_geteuid
1137 + .long sys_getegid
1138 + .long sys_setreuid
1139 + .long sys_setregid
1140 + .long sys_getgroups /* 205 */
1141 + .long sys_setgroups
1142 + .long sys_fchown
1143 + .long sys_setresuid
1144 + .long sys_getresuid
1145 + .long sys_setresgid /* 210 */
1146 + .long sys_getresgid
1147 + .long sys_lchown
1148 + .long sys_setuid
1149 + .long sys_setgid
1150 + .long sys_setfsuid /* 215 */
1151 + .long sys_setfsgid
1152 + .long sys_pivot_root
1153 + .long sys_ni_syscall
1154 + .long sys_ni_syscall
1155 + .long sys_getdents64 /* 220 */
1156 + .long sys_gettid
1157 + .long sys_tkill
1158 + .long sys_setxattr
1159 + .long sys_lsetxattr
1160 + .long sys_fsetxattr /* 225 */
1161 + .long sys_getxattr
1162 + .long sys_lgetxattr
1163 + .long sys_fgetxattr
1164 + .long sys_listxattr
1165 + .long sys_llistxattr /* 230 */
1166 + .long sys_flistxattr
1167 + .long sys_removexattr
1168 + .long sys_lremovexattr
1169 + .long sys_fremovexattr
1170 + .long sys_futex /* 235 */
1171 + .long sys_sendfile64
1172 + .long sys_mincore
1173 + .long sys_madvise
1174 + .long sys_fcntl64
1175 + .long sys_readahead /* 240 */
1176 + .long sys_io_setup
1177 + .long sys_io_destroy
1178 + .long sys_io_getevents
1179 + .long sys_io_submit
1180 + .long sys_io_cancel /* 245 */
1181 + .long sys_fadvise64
1182 + .long sys_exit_group
1183 + .long sys_lookup_dcookie
1184 + .long sys_epoll_create
1185 + .long sys_epoll_ctl /* 250 */
1186 + .long sys_epoll_wait
1187 + .long sys_remap_file_pages
1188 + .long sys_set_tid_address
1189 + .long sys_timer_create
1190 + .long sys_timer_settime /* 255 */
1191 + .long sys_timer_gettime
1192 + .long sys_timer_getoverrun
1193 + .long sys_timer_delete
1194 + .long sys_clock_settime
1195 + .long sys_clock_gettime /* 260 */
1196 + .long sys_clock_getres
1197 + .long sys_clock_nanosleep
1198 + .long sys_statfs64
1199 + .long sys_fstatfs64
1200 + .long sys_tgkill /* 265 */
1201 + .long sys_utimes
1202 + .long sys_fadvise64_64
1203 + .long sys_mbind
1204 + .long sys_get_mempolicy
1205 + .long sys_set_mempolicy /* 270 */
1206 + .long sys_mq_open
1207 + .long sys_mq_unlink
1208 + .long sys_mq_timedsend
1209 + .long sys_mq_timedreceive
1210 + .long sys_mq_notify /* 275 */
1211 + .long sys_mq_getsetattr
1212 + .long sys_waitid
1213 + .long sys_ni_syscall /* for sys_vserver */
1214 + .long sys_add_key
1215 + .long sys_request_key /* 280 */
1216 + .long sys_keyctl
1217 + .long sys_ioprio_set
1218 + .long sys_ioprio_get
1219 + .long sys_inotify_init
1220 + .long sys_inotify_add_watch /* 285 */
1221 + .long sys_inotify_rm_watch
1222 + .long sys_migrate_pages
1223 + .long sys_openat
1224 + .long sys_mkdirat
1225 + .long sys_mknodat /* 290 */
1226 + .long sys_fchownat
1227 + .long sys_futimesat
1228 + .long sys_fstatat64
1229 + .long sys_unlinkat
1230 + .long sys_renameat /* 295 */
1231 + .long sys_linkat
1232 + .long sys_symlinkat
1233 + .long sys_readlinkat
1234 + .long sys_fchmodat
1235 + .long sys_faccessat /* 300 */
1236 + .long sys_ni_syscall /* Reserved for pselect6 */
1237 + .long sys_ni_syscall /* Reserved for ppoll */
1238 + .long sys_unshare
1239 + .long sys_set_robust_list
1240 + .long sys_get_robust_list /* 305 */
1241 + .long sys_splice
1242 + .long sys_sync_file_range
1243 + .long sys_tee
1244 + .long sys_vmsplice
1245 + .long sys_move_pages /* 310 */
1246 +
1247 --- /dev/null
1248 +++ b/arch/m68k/coldfire/head.S
1249 @@ -0,0 +1,661 @@
1250 +/*
1251 + * head.S is the MMU enabled ColdFire specific initial boot code
1252 + *
1253 + * Ported to ColdFire by
1254 + * Matt Waddel Matt.Waddel@freescale.com
1255 + * Kurt Mahan kmahan@freescale.com
1256 + * Copyright Freescale Semiconductor, Inc. 2007, 2008
1257 + * Phys kernel mapping Copyright Daniel Krueger, SYSTEC electornic GmbH 2008
1258 + *
1259 + * This program is free software; you can redistribute it and/or modify
1260 + * it under the terms of the GNU General Public License as published by
1261 + * the Free Software Foundation; either version 2 of the License, or
1262 + * (at your option) any later version.
1263 + *
1264 + * Parts of this code came from arch/m68k/kernel/head.S
1265 + */
1266 +#include <linux/linkage.h>
1267 +#include <linux/init.h>
1268 +#include <asm/bootinfo.h>
1269 +#include <asm/setup.h>
1270 +#include <asm/entry.h>
1271 +#include <asm/pgtable.h>
1272 +#include <asm/page.h>
1273 +#include <asm/coldfire.h>
1274 +#include <asm/mcfuart.h>
1275 +#include <asm/cfcache.h>
1276 +
1277 +#define DEBUG
1278 +
1279 +.globl kernel_pg_dir
1280 +.globl availmem
1281 +.globl set_context
1282 +.globl set_fpga
1283 +
1284 +#ifdef DEBUG
1285 +/* When debugging use readable names for labels */
1286 +#ifdef __STDC__
1287 +#define L(name) .head.S.##name
1288 +#else
1289 +#define L(name) .head.S./**/name
1290 +#endif
1291 +#else
1292 +#ifdef __STDC__
1293 +#define L(name) .L##name
1294 +#else
1295 +#define L(name) .L/**/name
1296 +#endif
1297 +#endif
1298 +
1299 +/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
1300 +#ifndef __INITDATA
1301 +#define __INITDATA .data
1302 +#define __FINIT .previous
1303 +#endif
1304 +
1305 +#if CONFIG_SDRAM_BASE != PAGE_OFFSET
1306 +/*
1307 + * Kernel mapped to virtual ram address.
1308 + *
1309 + * M5445x:
1310 + * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
1311 + * Data[1]: 0xA0000000 -> 0xAFFFFFFF PCI
1312 + * Code[0]: Not Mapped
1313 + * Code[1]: Not Mapped
1314 + *
1315 + * M547x/M548x
1316 + * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
1317 + * Data[1]: Not Mapped
1318 + * Code[0]: Not Mapped
1319 + * Code[1]: Not Mapped
1320 + */
1321 +#if defined(CONFIG_M5445X)
1322 +#define ACR0_DEFAULT #0xF00FA048 /* System regs */
1323 +#define ACR1_DEFAULT #0xA00FA048 /* PCI */
1324 +#define ACR2_DEFAULT #0x00000000 /* Not Mapped */
1325 +#define ACR3_DEFAULT #0x00000000 /* Not Mapped */
1326 +#elif defined(CONFIG_M547X_8X)
1327 +#define ACR0_DEFAULT #0xF00FA048 /* System Regs */
1328 +#define ACR1_DEFAULT #0x00000000 /* Not Mapped */
1329 +#define ACR2_DEFAULT #0x00000000 /* Not Mapped */
1330 +#define ACR3_DEFAULT #0x00000000 /* Not Mapped */
1331 +#endif
1332 +
1333 +#else /* CONFIG_SDRAM_BASE = PAGE_OFFSET */
1334 +/*
1335 + * Kernel mapped to physical ram address.
1336 + *
1337 + * M5445x:
1338 + * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
1339 + * Data[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - uncached
1340 + * Code[0]: Not Mapped
1341 + * Code[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
1342 + *
1343 + * M547x/M548x
1344 + * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
1345 + * Data[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - uncached
1346 + * Code[0]: Not Mapped
1347 + * Code[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - cached
1348 + */
1349 +#if defined(CONFIG_M5445X)
1350 +#define ACR0_DEFAULT #0xF00FA048 /* System Regs */
1351 +#define ACR1_DEFAULT #0x400FA048 /* SDRAM uncached */
1352 +#define ACR2_DEFAULT #0x00000000 /* Not mapped */
1353 +#define ACR3_DEFAULT #0x400FA008 /* SDRAM cached */
1354 +#elif defined(CONFIG_M547X_8X)
1355 +#define ACR0_DEFAULT #0xF00FA048 /* System Regs */
1356 +#define ACR1_DEFAULT #0x000FA048 /* SDRAM uncached */
1357 +#define ACR2_DEFAULT #0x00000000 /* Not mapped */
1358 +#define ACR3_DEFAULT #0x000FA008 /* SDRAM cached */
1359 +#endif
1360 +#endif
1361 +
1362 +/* Several macros to make the writing of subroutines easier:
1363 + * - func_start marks the beginning of the routine which setups the frame
1364 + * register and saves the registers, it also defines another macro
1365 + * to automatically restore the registers again.
1366 + * - func_return marks the end of the routine and simply calls the prepared
1367 + * macro to restore registers and jump back to the caller.
1368 + * - func_define generates another macro to automatically put arguments
1369 + * onto the stack call the subroutine and cleanup the stack again.
1370 + */
1371 +
1372 +.macro load_symbol_address symbol,register
1373 + movel #\symbol,\register
1374 +.endm
1375 +
1376 +.macro func_start name,saveregs,savesize,stack=0
1377 +L(\name):
1378 + linkw %a6,#-\stack
1379 + subal #(\savesize),%sp
1380 + moveml \saveregs,%sp@
1381 +.set stackstart,-\stack
1382 +
1383 +.macro func_return_\name
1384 + moveml %sp@,\saveregs
1385 + addal #(\savesize),%sp
1386 + unlk %a6
1387 + rts
1388 +.endm
1389 +.endm
1390 +
1391 +.macro func_return name
1392 + func_return_\name
1393 +.endm
1394 +
1395 +.macro func_call name
1396 + jbsr L(\name)
1397 +.endm
1398 +
1399 +.macro move_stack nr,arg1,arg2,arg3,arg4
1400 +.if \nr
1401 + move_stack "(\nr-1)",\arg2,\arg3,\arg4
1402 + movel \arg1,%sp@-
1403 +.endif
1404 +.endm
1405 +
1406 +.macro func_define name,nr=0
1407 +.macro \name arg1,arg2,arg3,arg4
1408 + move_stack \nr,\arg1,\arg2,\arg3,\arg4
1409 + func_call \name
1410 +.if \nr
1411 + lea %sp@(\nr*4),%sp
1412 +.endif
1413 +.endm
1414 +.endm
1415 +
1416 +func_define serial_putc,1
1417 +
1418 +.macro putc ch
1419 + pea \ch
1420 + func_call serial_putc
1421 + addql #4,%sp
1422 +.endm
1423 +
1424 +.macro dputc ch
1425 +#ifdef DEBUG
1426 + putc \ch
1427 +#endif
1428 +.endm
1429 +
1430 +func_define putn,1
1431 +
1432 +.macro dputn nr
1433 +#ifdef DEBUG
1434 + putn \nr
1435 +#endif
1436 +.endm
1437 +
1438 +#if CONFIG_SDRAM_BASE != PAGE_OFFSET
1439 +/*
1440 + mmu_map - creates a new TLB entry
1441 +
1442 + virt_addr Must be on proper boundary
1443 + phys_addr Must be on proper boundary
1444 + itlb MMUOR_ITLB if instruction TLB or 0
1445 + asid address space ID
1446 + shared_global MMUTR_SG if shared between different ASIDs or 0
1447 + size_code MMUDR_SZ1M 1 MB
1448 + MMUDR_SZ4K 4 KB
1449 + MMUDR_SZ8K 8 KB
1450 + MMUDR_SZ16M 16 MB
1451 + cache_mode MMUDR_INC instruction non-cacheable
1452 + MMUDR_IC instruction cacheable
1453 + MMUDR_DWT data writethrough
1454 + MMUDR_DCB data copyback
1455 + MMUDR_DNCP data non-cacheable, precise
1456 + MMUDR_DNCIP data non-cacheable, imprecise
1457 + super_prot MMUDR_SP if user mode generates exception or 0
1458 + readable MMUDR_R if permits read access (data TLB) or 0
1459 + writable MMUDR_W if permits write access (data TLB) or 0
1460 + executable MMUDR_X if permits execute access (instruction TLB) or 0
1461 + locked MMUDR_LK prevents TLB entry from being replaced or 0
1462 + temp_data_reg a data register to use for temporary values
1463 +*/
1464 +.macro mmu_map virt_addr,phys_addr,itlb,asid,shared_global,size_code,cache_mode,super_prot,readable,writable,executable,locked,temp_data_reg
1465 + /* Set up search of TLB. */
1466 + movel #(\virt_addr+1), \temp_data_reg
1467 + movel \temp_data_reg, MMUAR
1468 + /* Search. */
1469 + movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
1470 + movew \temp_data_reg, (MMUOR)
1471 + /* Set up tag value. */
1472 + movel #(\virt_addr + \asid + \shared_global + MMUTR_V), \temp_data_reg
1473 + movel \temp_data_reg, MMUTR
1474 + /* Set up data value. */
1475 + movel #(\phys_addr + \size_code + \cache_mode + \super_prot + \readable + \writable + \executable + \locked), \temp_data_reg
1476 + movel \temp_data_reg, MMUDR
1477 + /* Save it. */
1478 + movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
1479 + movew \temp_data_reg, (MMUOR)
1480 +.endm /* mmu_map */
1481 +
1482 +.macro mmu_unmap virt_addr,itlb,temp_data_reg
1483 + /* Set up search of TLB. */
1484 + movel #(\virt_addr+1), \temp_data_reg
1485 + movel \temp_data_reg, MMUAR
1486 + /* Search. */
1487 + movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
1488 + movew \temp_data_reg, (MMUOR)
1489 + /* Test for hit. */
1490 + movel MMUSR,\temp_data_reg
1491 + btst #MMUSR_HITN,\temp_data_reg
1492 + beq 1f
1493 + /* Read the TLB. */
1494 + movel #(MMUOR_RW + MMUOR_ACC +\itlb), \temp_data_reg
1495 + movew \temp_data_reg, (MMUOR)
1496 + movel MMUSR,\temp_data_reg
1497 + /* Set up tag value. */
1498 + movel #0, \temp_data_reg
1499 + movel \temp_data_reg, MMUTR
1500 + /* Set up data value. */
1501 + movel #0, \temp_data_reg
1502 + movel \temp_data_reg, MMUDR
1503 + /* Save it. */
1504 + movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
1505 + movew \temp_data_reg, (MMUOR)
1506 +1:
1507 +.endm /* mmu_unmap */
1508 +#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
1509 +
1510 +/* .text */
1511 +.section ".text.head","ax"
1512 +ENTRY(_stext)
1513 +/* Version numbers of the bootinfo interface -- if we later pass info
1514 + * from boot ROM we might want to put something real here.
1515 + *
1516 + * The area from _stext to _start will later be used as kernel pointer table
1517 + */
1518 + bras 1f /* Jump over bootinfo version numbers */
1519 +
1520 + .long BOOTINFOV_MAGIC
1521 + .long 0
1522 +#if CONFIG_SDRAM_BASE != PAGE_OFFSET
1523 +1: jmp __start-(0xc0000000-CONFIG_SDRAM_BASE)
1524 +#else
1525 +1: jmp __start
1526 +#endif
1527 +
1528 +.equ kernel_pg_dir,_stext
1529 +.equ .,_stext+0x1000
1530 +
1531 +ENTRY(_start)
1532 + jra __start
1533 +__INIT
1534 +ENTRY(__start)
1535 +/* Save the location of u-boot info - cmd line, bd_info, etc. */
1536 + movel %a7,%a4 /* Don't use %a4 before cf_early_init */
1537 + addl #0x00000004,%a4 /* offset past top */
1538 + addl #(PAGE_OFFSET-CONFIG_SDRAM_BASE),%a4 /* high mem offset */
1539 +
1540 +/* Setup initial stack pointer */
1541 + movel #CONFIG_SDRAM_BASE+0x1000,%sp
1542 +
1543 +/* Setup usp */
1544 + subl %a0,%a0
1545 + movel %a0,%usp
1546 +
1547 +#if defined(CONFIG_M5445X)
1548 + movel #0x80000000, %d0
1549 + movec %d0, %rambar1
1550 +#elif defined(CONFIG_M547X_8X)
1551 + movel #MCF_MBAR, %d0
1552 + movec %d0, %mbar
1553 + move.l #(MCF_RAMBAR0 + 0x21), %d0
1554 + movec %d0, %rambar0
1555 + move.l #(MCF_RAMBAR1 + 0x21), %d0
1556 + movec %d0, %rambar1
1557 +#endif
1558 +
1559 + movew #0x2700,%sr
1560 +
1561 +/* reset cache */
1562 + movel #(CF_CACR_ICINVA + CF_CACR_DCINVA),%d0
1563 + movecl %d0,%cacr
1564 +
1565 + movel #(MMU_BASE+1),%d0
1566 + movecl %d0,%mmubar
1567 + movel #MMUOR_CA,%a0 /* Clear tlb entries */
1568 + movew %a0,(MMUOR)
1569 + movel #(MMUOR_CA + MMUOR_ITLB),%a0 /* Use ITLB for searches */
1570 + movew %a0,(MMUOR)
1571 + movel #0,%a0 /* Clear Addr Space User ID */
1572 + movecl %a0,%asid
1573 +
1574 +/* setup ACRs */
1575 + movel ACR0_DEFAULT, %d0 /* ACR0 (DATA) setup */
1576 + movec %d0, %acr0
1577 + nop
1578 + movel ACR1_DEFAULT, %d0 /* ACR1 (DATA) setup */
1579 + movec %d0, %acr1
1580 + nop
1581 + movel ACR2_DEFAULT, %d0 /* ACR2 (CODE) setup */
1582 + movec %d0, %acr2
1583 + nop
1584 + movel ACR3_DEFAULT, %d0 /* ACR3 (CODE) setup */
1585 + movec %d0, %acr3
1586 + nop
1587 +
1588 + /* If you change the memory size to another value make a matching
1589 + change in paging_init(cf-mmu.c) to zones_size[]. */
1590 +
1591 +#if CONFIG_SDRAM_BASE != PAGE_OFFSET
1592 +#if defined(CONFIG_M5445X)
1593 + /* Map 256MB as code */
1594 + mmu_map (PAGE_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
1595 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1596 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1597 + mmu_map (PAGE_OFFSET+1*0x1000000), (PHYS_OFFSET+1*0x1000000), \
1598 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1599 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1600 + mmu_map (PAGE_OFFSET+2*0x1000000), (PHYS_OFFSET+2*0x1000000), \
1601 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1602 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1603 + mmu_map (PAGE_OFFSET+3*0x1000000), (PHYS_OFFSET+3*0x1000000), \
1604 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1605 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1606 + mmu_map (PAGE_OFFSET+4*0x1000000), (PHYS_OFFSET+4*0x1000000), \
1607 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1608 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1609 + mmu_map (PAGE_OFFSET+5*0x1000000), (PHYS_OFFSET+5*0x1000000), \
1610 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1611 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1612 + mmu_map (PAGE_OFFSET+6*0x1000000), (PHYS_OFFSET+6*0x1000000), \
1613 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1614 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1615 + mmu_map (PAGE_OFFSET+7*0x1000000), (PHYS_OFFSET+7*0x1000000), \
1616 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1617 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1618 + mmu_map (PAGE_OFFSET+8*0x1000000), (PHYS_OFFSET+8*0x1000000), \
1619 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1620 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1621 + mmu_map (PAGE_OFFSET+9*0x1000000), (PHYS_OFFSET+9*0x1000000), \
1622 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1623 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1624 + mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), \
1625 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1626 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1627 + mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), \
1628 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1629 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1630 + mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), \
1631 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1632 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1633 + mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), \
1634 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1635 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1636 + mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), \
1637 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1638 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1639 + mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), \
1640 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC, MMUDR_SP, \
1641 + 0, 0, MMUDR_X, MMUDR_LK, %d0
1642 +
1643 + /* Map 256MB as data also */
1644 + mmu_map (PAGE_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
1645 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1646 + 0, MMUDR_LK, %d0
1647 + mmu_map (PAGE_OFFSET+1*0x1000000), (PHYS_OFFSET+1*0x1000000), 0, 0, \
1648 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1649 + 0, MMUDR_LK, %d0
1650 + mmu_map (PAGE_OFFSET+2*0x1000000), (PHYS_OFFSET+2*0x1000000), 0, 0, \
1651 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1652 + 0, MMUDR_LK, %d0
1653 + mmu_map (PAGE_OFFSET+3*0x1000000), (PHYS_OFFSET+3*0x1000000), 0, 0, \
1654 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1655 + 0, MMUDR_LK, %d0
1656 + mmu_map (PAGE_OFFSET+4*0x1000000), (PHYS_OFFSET+4*0x1000000), 0, 0, \
1657 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1658 + 0, MMUDR_LK, %d0
1659 + mmu_map (PAGE_OFFSET+5*0x1000000), (PHYS_OFFSET+5*0x1000000), 0, 0, \
1660 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1661 + 0, MMUDR_LK, %d0
1662 + mmu_map (PAGE_OFFSET+6*0x1000000), (PHYS_OFFSET+6*0x1000000), 0, 0, \
1663 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1664 + 0, MMUDR_LK, %d0
1665 + mmu_map (PAGE_OFFSET+7*0x1000000), (PHYS_OFFSET+7*0x1000000), 0, 0, \
1666 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1667 + 0, MMUDR_LK, %d0
1668 + mmu_map (PAGE_OFFSET+8*0x1000000), (PHYS_OFFSET+8*0x1000000), 0, 0, \
1669 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1670 + 0, MMUDR_LK, %d0
1671 + mmu_map (PAGE_OFFSET+9*0x1000000), (PHYS_OFFSET+9*0x1000000), 0, 0, \
1672 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1673 + 0, MMUDR_LK, %d0
1674 + mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), 0, 0, \
1675 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1676 + 0, MMUDR_LK, %d0
1677 + mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), 0, 0, \
1678 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1679 + 0, MMUDR_LK, %d0
1680 + mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), 0, 0, \
1681 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1682 + 0, MMUDR_LK, %d0
1683 + mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), 0, 0, \
1684 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1685 + 0, MMUDR_LK, %d0
1686 + mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), 0, 0, \
1687 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1688 + 0, MMUDR_LK, %d0
1689 + mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), 0, 0, \
1690 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1691 + 0, MMUDR_LK, %d0
1692 +
1693 + /* Map ATA registers -- sacrifice a data TLB due to the hw design */
1694 + mmu_map (0x90000000), (0x90000000), 0, 0, \
1695 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1696 + 0, MMUDR_LK, %d0
1697 +
1698 +#elif defined(CONFIG_M547X_8X)
1699 +
1700 + /* Map first 8 MB as code */
1701 + mmu_map (PAGE_OFFSET+0*1024*1024), (0*1024*1024), MMUOR_ITLB, 0, \
1702 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1703 + MMUDR_LK, %d0
1704 + mmu_map (PAGE_OFFSET+1*1024*1024), (1*1024*1024), MMUOR_ITLB, 0, \
1705 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1706 + MMUDR_LK, %d0
1707 + mmu_map (PAGE_OFFSET+2*1024*1024), (2*1024*1024), MMUOR_ITLB, 0, \
1708 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1709 + MMUDR_LK, %d0
1710 + mmu_map (PAGE_OFFSET+3*1024*1024), (3*1024*1024), MMUOR_ITLB, 0, \
1711 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1712 + MMUDR_LK, %d0
1713 + mmu_map (PAGE_OFFSET+4*1024*1024), (4*1024*1024), MMUOR_ITLB, 0, \
1714 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1715 + MMUDR_LK, %d0
1716 + mmu_map (PAGE_OFFSET+5*1024*1024), (5*1024*1024), MMUOR_ITLB, 0, \
1717 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1718 + MMUDR_LK, %d0
1719 + mmu_map (PAGE_OFFSET+6*1024*1024), (6*1024*1024), MMUOR_ITLB, 0, \
1720 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1721 + MMUDR_LK, %d0
1722 + mmu_map (PAGE_OFFSET+7*1024*1024), (7*1024*1024), MMUOR_ITLB, 0, \
1723 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, MMUDR_X, \
1724 + MMUDR_LK, %d0
1725 +
1726 + /* Map first 8 MB as data */
1727 + mmu_map (PAGE_OFFSET+0*1024*1024), (0*1024*1024), 0, 0, \
1728 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1729 + MMUDR_W, 0, MMUDR_LK, %d0
1730 + mmu_map (PAGE_OFFSET+1*1024*1024), (1*1024*1024), 0, 0, \
1731 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1732 + MMUDR_W, 0, MMUDR_LK, %d0
1733 + mmu_map (PAGE_OFFSET+2*1024*1024), (2*1024*1024), 0, 0, \
1734 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1735 + MMUDR_W, 0, MMUDR_LK, %d0
1736 + mmu_map (PAGE_OFFSET+3*1024*1024), (3*1024*1024), 0, 0, \
1737 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1738 + MMUDR_W, 0, MMUDR_LK, %d0
1739 + mmu_map (PAGE_OFFSET+4*1024*1024), (4*1024*1024), 0, 0, \
1740 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1741 + MMUDR_W, 0, MMUDR_LK, %d0
1742 + mmu_map (PAGE_OFFSET+5*1024*1024), (5*1024*1024), 0, 0, \
1743 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1744 + MMUDR_W, 0, MMUDR_LK, %d0
1745 + mmu_map (PAGE_OFFSET+6*1024*1024), (6*1024*1024), 0, 0, \
1746 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1747 + MMUDR_W, 0, MMUDR_LK, %d0
1748 + mmu_map (PAGE_OFFSET+7*1024*1024), (7*1024*1024), 0, 0, \
1749 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
1750 + MMUDR_W, 0, MMUDR_LK, %d0
1751 +#endif
1752 + /*
1753 + * Do unity mapping to enable the MMU. Map first chunk of memory
1754 + * in place as code/data. The TLBs will be deleted after the MMU is
1755 + * enabled and we are executing in high memory.
1756 + */
1757 +
1758 +#if defined(CONFIG_M5445X)
1759 + /* Map first 16 MB as code */
1760 + mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
1761 + MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_INC, MMUDR_SP, 0, \
1762 + 0, MMUDR_X, 0, %d0
1763 + /* Map first 16 MB as data too */
1764 + mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
1765 + MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
1766 + 0, 0, %d0
1767 +#elif defined(CONFIG_M547X_8X)
1768 + /* Map first 4 MB as code */
1769 + mmu_map (0*1024*1024), (0*1024*1024), MMUOR_ITLB, 0, \
1770 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, \
1771 + MMUDR_X, 0, %d0
1772 + mmu_map (1*1024*1024), (1*1024*1024), MMUOR_ITLB, 0, \
1773 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, \
1774 + MMUDR_X, 0, %d0
1775 + mmu_map (2*1024*1024), (2*1024*1024), MMUOR_ITLB, 0, \
1776 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, \
1777 + MMUDR_X, 0, %d0
1778 + mmu_map (3*1024*1024), (3*1024*1024), MMUOR_ITLB, 0, \
1779 + MMUTR_SG, MMUDR_SZ1M, MMUDR_IC, MMUDR_SP, 0, 0, \
1780 + MMUDR_X, 0, %d0
1781 +
1782 + /* Map first 4 MB as data too */
1783 + mmu_map (0*1024*1024), (0*1024*1024), 0, 0, \
1784 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
1785 + MMUDR_W, 0, 0, %d0
1786 + mmu_map (1*1024*1024), (1*1024*1024), 0, 0, \
1787 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
1788 + MMUDR_W, 0, 0, %d0
1789 + mmu_map (2*1024*1024), (2*1024*1024), 0, 0, \
1790 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
1791 + MMUDR_W, 0, 0, %d0
1792 + mmu_map (3*1024*1024), (3*1024*1024), 0, 0, \
1793 + MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
1794 + MMUDR_W, 0, 0, %d0
1795 +#endif
1796 +#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
1797 +
1798 + /* Turn on MMU */
1799 + movel #(MMUCR_EN),%a0
1800 + movel %a0,MMUCR
1801 + nop /* This synchs the pipeline after a write to MMUCR */
1802 +
1803 + movel #__running_high,%a0 /* Get around PC-relative addressing. */
1804 + jmp %a0@
1805 +
1806 +ENTRY(__running_high)
1807 + load_symbol_address _stext,%sp
1808 + movel L(memory_start),%a0
1809 + movel %a0,availmem
1810 + load_symbol_address L(phys_kernel_start),%a0
1811 + load_symbol_address _stext,%a1
1812 + subl #_stext,%a1
1813 + addl #PAGE_OFFSET,%a1
1814 + movel %a1,%a0@
1815 +
1816 +/* zero bss */
1817 + lea _sbss,%a0
1818 + lea _ebss,%a1
1819 + clrl %d0
1820 +_loop_bss:
1821 + movel %d0,(%a0)+
1822 + cmpl %a0,%a1
1823 + bne _loop_bss
1824 +
1825 + /* Unmap unity mappings */
1826 +#if CONFIG_SDRAM_BASE != PAGE_OFFSET
1827 +#if defined(CONFIG_M5445X)
1828 + mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
1829 + mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
1830 +#elif defined(CONFIG_M547X_8X)
1831 + mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
1832 + mmu_unmap (PHYS_OFFSET+1*0x1000000), MMUOR_ITLB, %d0
1833 + mmu_unmap (PHYS_OFFSET+2*0x1000000), MMUOR_ITLB, %d0
1834 + mmu_unmap (PHYS_OFFSET+3*0x1000000), MMUOR_ITLB, %d0
1835 + mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
1836 + mmu_unmap (PHYS_OFFSET+1*0x1000000), 0, %d0
1837 + mmu_unmap (PHYS_OFFSET+2*0x1000000), 0, %d0
1838 + mmu_unmap (PHYS_OFFSET+3*0x1000000), 0, %d0
1839 +#endif
1840 +#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
1841 +
1842 +/* Setup initial stack pointer */
1843 + lea init_task,%a2
1844 + lea init_thread_union+THREAD_SIZE,%sp
1845 + subl %a6,%a6 /* clear a6 for gdb */
1846 +
1847 +#ifdef CONFIG_MCF_USER_HALT
1848 +/* Setup debug control reg to allow halts from user space */
1849 + lea wdbg_uhe,%a0
1850 + wdebug (%a0)
1851 +#endif
1852 +
1853 + movel %a4,uboot_info_stk /* save uboot info to variable */
1854 + jsr cf_early_init
1855 + jmp start_kernel
1856 +
1857 +.section ".text.head","ax"
1858 +set_context:
1859 +func_start set_context,%d0,(1*4)
1860 + movel 12(%sp),%d0
1861 + movec %d0,%asid
1862 +func_return set_context
1863 +
1864 +#ifdef CONFIG_M5445X
1865 +/*
1866 + * set_fpga(addr,val) on the M5445X
1867 + *
1868 + * Map in 0x00000000 -> 0x0fffffff and then do the write.
1869 + */
1870 +set_fpga:
1871 +#if 0
1872 + movew %sr,%d1
1873 + movew #0x2700,%sr
1874 + movel ACR0_FPGA, %d0
1875 + movec %d0, %acr0
1876 + nop
1877 + moveal 4(%sp),%a0
1878 + movel 8(%sp),%a0@
1879 + movel ACR0_DEFAULT, %d0
1880 + movec %d0, %acr0
1881 + nop
1882 + movew %d1,%sr
1883 +#endif
1884 + rts
1885 +#endif
1886 +
1887 + .data
1888 + .align 4
1889 +
1890 +availmem:
1891 + .long 0
1892 +L(phys_kernel_start):
1893 + .long PAGE_OFFSET
1894 +L(kernel_end):
1895 + .long 0
1896 +L(memory_start):
1897 + .long PAGE_OFFSET_RAW
1898 +
1899 +#ifdef CONFIG_MCF_USER_HALT
1900 +/*
1901 + * Enable User Halt Enable in the debug control register.
1902 + */
1903 +wdbg_uhe:
1904 + .word 0x2c80 /* DR0 */
1905 + .word 0x00b0 /* 31:16 */
1906 + .word 0x0400 /* 15:0 -- enable UHE */
1907 + .word 0x0000 /* unused */
1908 +#endif
1909 +
1910 +
1911 --- /dev/null
1912 +++ b/arch/m68k/coldfire/ints.c
1913 @@ -0,0 +1,463 @@
1914 +/*
1915 + * linux/arch/m68k/coldfire/ints.c -- General interrupt handling code
1916 + *
1917 + * Copyright (C) 1999-2002 Greg Ungerer (gerg@snapgear.com)
1918 + * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
1919 + * Kenneth Albanowski <kjahds@kjahds.com>,
1920 + * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
1921 + *
1922 + * Copyright Freescale Semiconductor, Inc. 2007, 2008
1923 + * Kurt Mahan kmahan@freescale.com
1924 + * Matt Waddel Matt.Waddel@freescale.com
1925 + *
1926 + * Based on:
1927 + * linux/arch/m68k/kernel/ints.c &
1928 + * linux/arch/m68knommu/5307/ints.c
1929 + *
1930 + * This file is subject to the terms and conditions of the GNU General Public
1931 + * License. See the file COPYING in the main directory of this archive
1932 + * for more details.
1933 + */
1934 +
1935 +#include <linux/module.h>
1936 +#include <linux/types.h>
1937 +#include <linux/init.h>
1938 +#include <linux/sched.h>
1939 +#include <linux/kernel_stat.h>
1940 +#include <linux/errno.h>
1941 +#include <linux/seq_file.h>
1942 +#include <linux/interrupt.h>
1943 +
1944 +#include <asm/system.h>
1945 +#include <asm/irq.h>
1946 +#include <asm/traps.h>
1947 +#include <asm/page.h>
1948 +#include <asm/machdep.h>
1949 +#include <asm/irq_regs.h>
1950 +
1951 +#include <asm/mcfsim.h>
1952 +
1953 +/*
1954 + * IRQ Handler lists.
1955 + */
1956 +static struct irq_node *irq_list[SYS_IRQS];
1957 +static struct irq_controller *irq_controller[SYS_IRQS];
1958 +static int irq_depth[SYS_IRQS];
1959 +
1960 +/*
1961 + * IRQ Controller
1962 + */
1963 +#if defined(CONFIG_M5445X)
1964 +void m5445x_irq_enable(unsigned int irq);
1965 +void m5445x_irq_disable(unsigned int irq);
1966 +static struct irq_controller m5445x_irq_controller = {
1967 + .name = "M5445X",
1968 + .lock = SPIN_LOCK_UNLOCKED,
1969 + .enable = m5445x_irq_enable,
1970 + .disable = m5445x_irq_disable,
1971 +};
1972 +#elif defined(CONFIG_M547X_8X)
1973 +void m547x_8x_irq_enable(unsigned int irq);
1974 +void m547x_8x_irq_disable(unsigned int irq);
1975 +static struct irq_controller m547x_8x_irq_controller = {
1976 + .name = "M547X_8X",
1977 + .lock = SPIN_LOCK_UNLOCKED,
1978 + .enable = m547x_8x_irq_enable,
1979 + .disable = m547x_8x_irq_disable,
1980 +};
1981 +#else
1982 +# error No IRQ controller defined
1983 +#endif
1984 +
1985 +#define POOL_SIZE SYS_IRQS
1986 +static struct irq_node pool[POOL_SIZE];
1987 +static struct irq_node *get_irq_node(void);
1988 +
1989 +/* The number of spurious interrupts */
1990 +unsigned int num_spurious;
1991 +asmlinkage void handle_badint(struct pt_regs *regs);
1992 +
1993 +/*
1994 + * void init_IRQ(void)
1995 + *
1996 + * This function should be called during kernel startup to initialize
1997 + * the IRQ handling routines.
1998 + */
1999 +void __init init_IRQ(void)
2000 +{
2001 + int i;
2002 +
2003 +#if defined(CONFIG_M5445X)
2004 + for (i = 0; i < SYS_IRQS; i++)
2005 + irq_controller[i] = &m5445x_irq_controller;
2006 +#elif defined(CONFIG_M547X_8X)
2007 + for (i = 0; i < SYS_IRQS; i++)
2008 + irq_controller[i] = &m547x_8x_irq_controller;
2009 +#endif
2010 +}
2011 +
2012 +/*
2013 + * process_int(unsigned long vec, struct pt_regs *fp)
2014 + *
2015 + * Process an interrupt. Called from entry.S.
2016 + */
2017 +asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
2018 +{
2019 + struct pt_regs *old_regs;
2020 + struct irq_node *node;
2021 + old_regs = set_irq_regs(fp);
2022 + kstat_cpu(0).irqs[vec]++;
2023 +
2024 + node = irq_list[vec];
2025 + if (!node)
2026 + handle_badint(fp);
2027 + else {
2028 + do {
2029 + node->handler(vec, node->dev_id);
2030 + node = node->next;
2031 + } while (node);
2032 + }
2033 +
2034 + set_irq_regs(old_regs);
2035 +}
2036 +
2037 +/*
2038 + * show_interrupts( struct seq_file *p, void *v)
2039 + *
2040 + * Called to show all the current interrupt information.
2041 + */
2042 +int show_interrupts(struct seq_file *p, void *v)
2043 +{
2044 + struct irq_controller *contr;
2045 + struct irq_node *node;
2046 + int i = *(loff_t *) v;
2047 +
2048 + if ((i < NR_IRQS) && (irq_list[i])) {
2049 + contr = irq_controller[i];
2050 + node = irq_list[i];
2051 + seq_printf(p, "%-8s %3u: %10u %s", contr->name, i,
2052 + kstat_cpu(0).irqs[i], node->devname);
2053 + while ((node = node->next))
2054 + seq_printf(p, ", %s", node->devname);
2055 +
2056 + seq_printf(p, "\n");
2057 + }
2058 +
2059 + return 0;
2060 +}
2061 +
2062 +/*
2063 + * get_irq_node(void)
2064 + *
2065 + * Get an irq node from the pool.
2066 + */
2067 +struct irq_node *get_irq_node(void)
2068 +{
2069 + struct irq_node *p = pool;
2070 + int i;
2071 +
2072 + for (i = 0; i < POOL_SIZE; i++, p++) {
2073 + if (!p->handler) {
2074 + memset(p, 0, sizeof(struct irq_node));
2075 + return p;
2076 + }
2077 + }
2078 + printk(KERN_INFO "%s(%s:%d): No more irq nodes, I suggest you \
2079 + increase POOL_SIZE", __FUNCTION__, __FILE__, __LINE__);
2080 + return NULL;
2081 +}
2082 +
2083 +void init_irq_proc(void)
2084 +{
2085 + /* Insert /proc/irq driver here */
2086 +}
2087 +
2088 +int setup_irq(unsigned int irq, struct irq_node *node)
2089 +{
2090 + struct irq_controller *contr;
2091 + struct irq_node **prev;
2092 + unsigned long flags;
2093 +
2094 + if (irq >= NR_IRQS || !irq_controller[irq]) {
2095 + printk("%s: Incorrect IRQ %d from %s\n",
2096 + __FUNCTION__, irq, node->devname);
2097 + return -ENXIO;
2098 + }
2099 +
2100 + contr = irq_controller[irq];
2101 + spin_lock_irqsave(&contr->lock, flags);
2102 +
2103 + prev = irq_list + irq;
2104 + if (*prev) {
2105 + /* Can't share interrupts unless both agree to */
2106 + if (!((*prev)->flags & node->flags & IRQF_SHARED)) {
2107 + spin_unlock_irqrestore(&contr->lock, flags);
2108 + printk(KERN_INFO "%s: -BUSY-Incorrect IRQ %d \n",
2109 + __FUNCTION__, irq);
2110 + return -EBUSY;
2111 + }
2112 + while (*prev)
2113 + prev = &(*prev)->next;
2114 + }
2115 +
2116 + if (!irq_list[irq]) {
2117 + if (contr->startup)
2118 + contr->startup(irq);
2119 + else
2120 + contr->enable(irq);
2121 + }
2122 + node->next = NULL;
2123 + *prev = node;
2124 +
2125 + spin_unlock_irqrestore(&contr->lock, flags);
2126 +
2127 + return 0;
2128 +}
2129 +
2130 +int request_irq(unsigned int irq,
2131 + irq_handler_t handler,
2132 + unsigned long flags, const char *devname, void *dev_id)
2133 +{
2134 + struct irq_node *node = get_irq_node();
2135 + int res;
2136 +
2137 + if (!node) {
2138 + printk(KERN_INFO "%s:get_irq_node error %x\n",
2139 + __FUNCTION__,(unsigned int) node);
2140 + return -ENOMEM;
2141 + }
2142 + node->handler = handler;
2143 + node->flags = flags;
2144 + node->dev_id = dev_id;
2145 + node->devname = devname;
2146 +
2147 + res = setup_irq(irq, node);
2148 + if (res)
2149 + node->handler = NULL;
2150 +
2151 + return res;
2152 +}
2153 +EXPORT_SYMBOL(request_irq);
2154 +
2155 +void free_irq(unsigned int irq, void *dev_id)
2156 +{
2157 + struct irq_controller *contr;
2158 + struct irq_node **p, *node;
2159 + unsigned long flags;
2160 +
2161 + if (irq >= NR_IRQS || !irq_controller[irq]) {
2162 + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
2163 + return;
2164 + }
2165 +
2166 + contr = irq_controller[irq];
2167 + spin_lock_irqsave(&contr->lock, flags);
2168 +
2169 + p = irq_list + irq;
2170 + while ((node = *p)) {
2171 + if (node->dev_id == dev_id)
2172 + break;
2173 + p = &node->next;
2174 + }
2175 +
2176 + if (node) {
2177 + *p = node->next;
2178 + node->handler = NULL;
2179 + } else
2180 + printk(KERN_DEBUG "%s: Removing probably wrong IRQ %d\n",
2181 + __FUNCTION__, irq);
2182 +
2183 + if (!irq_list[irq]) {
2184 + if (contr->shutdown)
2185 + contr->shutdown(irq);
2186 + else
2187 + contr->disable(irq);
2188 + }
2189 +
2190 + spin_unlock_irqrestore(&contr->lock, flags);
2191 +}
2192 +EXPORT_SYMBOL(free_irq);
2193 +
2194 +void enable_irq(unsigned int irq)
2195 +{
2196 + struct irq_controller *contr;
2197 + unsigned long flags;
2198 +
2199 + if (irq >= NR_IRQS || !irq_controller[irq]) {
2200 + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
2201 + return;
2202 + }
2203 +
2204 + contr = irq_controller[irq];
2205 + spin_lock_irqsave(&contr->lock, flags);
2206 + if (irq_depth[irq]) {
2207 + if (!--irq_depth[irq]) {
2208 + if (contr->enable)
2209 + contr->enable(irq);
2210 + }
2211 + } else
2212 + WARN_ON(1);
2213 + spin_unlock_irqrestore(&contr->lock, flags);
2214 +}
2215 +EXPORT_SYMBOL(enable_irq);
2216 +
2217 +void disable_irq(unsigned int irq)
2218 +{
2219 + struct irq_controller *contr;
2220 + unsigned long flags;
2221 +
2222 + if (irq >= NR_IRQS || !irq_controller[irq]) {
2223 + printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
2224 + return;
2225 + }
2226 +
2227 + contr = irq_controller[irq];
2228 + spin_lock_irqsave(&contr->lock, flags);
2229 + if (!irq_depth[irq]++) {
2230 + if (contr->disable)
2231 + contr->disable(irq);
2232 + }
2233 + spin_unlock_irqrestore(&contr->lock, flags);
2234 +}
2235 +EXPORT_SYMBOL(disable_irq);
2236 +
2237 +void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
2238 +EXPORT_SYMBOL(disable_irq_nosync);
2239 +
2240 +
2241 +unsigned long probe_irq_on(void)
2242 +{
2243 + return 0;
2244 +}
2245 +EXPORT_SYMBOL(probe_irq_on);
2246 +
2247 +int probe_irq_off(unsigned long irqs)
2248 +{
2249 + return 0;
2250 +}
2251 +EXPORT_SYMBOL(probe_irq_off);
2252 +
2253 +asmlinkage void handle_badint(struct pt_regs *regs)
2254 +{
2255 + kstat_cpu(0).irqs[0]++;
2256 + num_spurious++;
2257 + printk(KERN_DEBUG "unexpected interrupt from %u\n", regs->vector);
2258 +}
2259 +EXPORT_SYMBOL(handle_badint);
2260 +
2261 +#ifdef CONFIG_M5445X
2262 +/*
2263 + * M5445X Implementation
2264 + */
2265 +void m5445x_irq_enable(unsigned int irq)
2266 +{
2267 + /* enable the interrupt hardware */
2268 + if (irq < 64)
2269 + return;
2270 +
2271 + /* adjust past non-hardware ints */
2272 + irq -= 64;
2273 +
2274 + /* check for eport */
2275 + if ((irq > 0) && (irq < 8)) {
2276 + /* enable eport */
2277 + MCF_EPORT_EPPAR &= ~(3 << (irq*2)); /* level */
2278 + MCF_EPORT_EPDDR &= ~(1 << irq); /* input */
2279 + MCF_EPORT_EPIER |= 1 << irq; /* irq enabled */
2280 + }
2281 +
2282 + if (irq < 64) {
2283 + /* controller 0 */
2284 + MCF_INTC0_ICR(irq) = 0x02;
2285 + MCF_INTC0_CIMR = irq;
2286 + } else {
2287 + /* controller 1 */
2288 + irq -= 64;
2289 + MCF_INTC1_ICR(irq) = 0x02;
2290 + MCF_INTC1_CIMR = irq;
2291 + }
2292 +}
2293 +
2294 +void m5445x_irq_disable(unsigned int irq)
2295 +{
2296 + /* disable the interrupt hardware */
2297 + if (irq < 64)
2298 + return;
2299 +
2300 + /* adjust past non-hardware ints */
2301 + irq -= 64;
2302 +
2303 + /* check for eport */
2304 + if ((irq > 0) && (irq < 8)) {
2305 + /* disable eport */
2306 + MCF_EPORT_EPIER &= ~(1 << irq);
2307 + }
2308 +
2309 + if (irq < 64) {
2310 + /* controller 0 */
2311 + MCF_INTC0_ICR(irq) = 0x00;
2312 + MCF_INTC0_SIMR = irq;
2313 + } else {
2314 + /* controller 1 */
2315 + irq -= 64;
2316 + MCF_INTC1_ICR(irq) = 0x00;
2317 + MCF_INTC1_SIMR = irq;
2318 + }
2319 +}
2320 +#elif defined(CONFIG_M547X_8X)
2321 +/*
2322 + * M547X_8X Implementation
2323 + */
2324 +void m547x_8x_irq_enable(unsigned int irq)
2325 +{
2326 + /* enable the interrupt hardware */
2327 + if (irq < 64)
2328 + return;
2329 +
2330 + /* adjust past non-hardware ints */
2331 + irq -= 64;
2332 +
2333 +/* JKM -- re-add EPORT later */
2334 +#if 0
2335 + /* check for eport */
2336 + if ((irq > 0) && (irq < 8)) {
2337 + /* enable eport */
2338 + MCF_EPORT_EPPAR &= ~(3 << (irq*2)); /* level */
2339 + MCF_EPORT_EPDDR &= ~(1 << irq); /* input */
2340 + MCF_EPORT_EPIER |= 1 << irq; /* irq enabled */
2341 + }
2342 +#endif
2343 +
2344 + if (irq < 32) {
2345 + /* *grumble* don't set low bit of IMRL */
2346 + MCF_IMRL &= (~(1 << irq) & 0xfffffffe);
2347 + }
2348 + else {
2349 + MCF_IMRH &= ~(1 << (irq - 32));
2350 + }
2351 +}
2352 +
2353 +void m547x_8x_irq_disable(unsigned int irq)
2354 +{
2355 + /* disable the interrupt hardware */
2356 + if (irq < 64)
2357 + return;
2358 +
2359 + /* adjust past non-hardware ints */
2360 + irq -= 64;
2361 +
2362 +/* JKM -- re-add EPORT later */
2363 +#if 0
2364 + /* check for eport */
2365 + if ((irq > 0) && (irq < 8)) {
2366 + /* disable eport */
2367 + MCF_EPORT_EPIER &= ~(1 << irq);
2368 + }
2369 +#endif
2370 +
2371 + if (irq < 32)
2372 + MCF_IMRL |= (1 << irq);
2373 + else
2374 + MCF_IMRH |= (1 << (irq - 32));
2375 +}
2376 +#endif
2377 --- /dev/null
2378 +++ b/arch/m68k/coldfire/iomap.c
2379 @@ -0,0 +1,56 @@
2380 +/*
2381 + * arch/m68k/coldfire/iomap.c
2382 + *
2383 + * Generic coldfire iomap interface
2384 + *
2385 + * Based on the sh64 iomap.c by Paul Mundt.
2386 + *
2387 + * This file is subject to the terms and conditions of the GNU General Public
2388 + * License. See the file "COPYING" in the main directory of this archive
2389 + * for more details.
2390 + */
2391 +#include <linux/pci.h>
2392 +#include <asm/io.h>
2393 +
2394 +#if 0
2395 +void __iomem *__attribute__ ((weak))
2396 +ioport_map(unsigned long port, unsigned int len)
2397 +{
2398 + return (void __iomem *)port;
2399 +}
2400 +EXPORT_SYMBOL(pci_iomap);
2401 +
2402 +void ioport_unmap(void __iomem *addr)
2403 +{
2404 + /* Nothing .. */
2405 +}
2406 +EXPORT_SYMBOL(pci_iounmap);
2407 +
2408 +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
2409 +{
2410 + unsigned long start = pci_resource_start(dev, bar);
2411 + unsigned long len = pci_resource_len(dev, bar);
2412 + unsigned long flags = pci_resource_flags(dev, bar);
2413 +printk(KERN_INFO "PCI_IOMAP: BAR=%d START=0x%lx LEN=0x%lx FLAGS=0x%lx\n",
2414 + bar, start, len, flags);
2415 +
2416 + if (!len)
2417 + return NULL;
2418 + if (max && len > max)
2419 + len = max;
2420 + if (flags & IORESOURCE_IO)
2421 + return ioport_map(start, len);
2422 + if (flags & IORESOURCE_MEM)
2423 + return (void __iomem *)start;
2424 +
2425 + /* What? */
2426 + return NULL;
2427 +}
2428 +EXPORT_SYMBOL(ioport_map);
2429 +
2430 +void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
2431 +{
2432 + /* Nothing .. */
2433 +}
2434 +EXPORT_SYMBOL(ioport_unmap);
2435 +#endif
2436 --- /dev/null
2437 +++ b/arch/m68k/coldfire/m547x_8x-devices.c
2438 @@ -0,0 +1,163 @@
2439 +/*
2440 + * arch/m68k/coldfire/m547x_8x-devices.c
2441 + *
2442 + * Coldfire M547x/M548x Platform Device Configuration
2443 + *
2444 + * Copyright (c) 2008 Freescale Semiconductor, Inc.
2445 + * Kurt Mahan <kmahan@freescale.com>
2446 + */
2447 +#include <linux/module.h>
2448 +#include <linux/kernel.h>
2449 +#include <linux/init.h>
2450 +#include <linux/platform_device.h>
2451 +#include <linux/fsl_devices.h>
2452 +#include <linux/spi/spi.h>
2453 +
2454 +#include <asm/coldfire.h>
2455 +#include <asm/mcfsim.h>
2456 +#include <asm/mcfqspi.h>
2457 +
2458 +
2459 +#ifdef CONFIG_SPI
2460 +/*
2461 + *
2462 + * DSPI
2463 + *
2464 + */
2465 +
2466 +/* number of supported SPI selects */
2467 +#define SPI_NUM_CHIPSELECTS 8
2468 +
2469 +void coldfire_spi_cs_control(u8 cs, u8 command)
2470 +{
2471 + /* nothing special required */
2472 +}
2473 +
2474 +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
2475 +static struct coldfire_spi_chip spidev_chip_info = {
2476 + .bits_per_word = 8,
2477 +};
2478 +#endif
2479 +
2480 +static struct spi_board_info spi_board_info[] = {
2481 +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
2482 + {
2483 + .modalias = "spidev",
2484 + .max_speed_hz = 16000000, /* max clk (SCK) speed in HZ */
2485 + .bus_num = 1,
2486 + .chip_select = 0, /* CS0 */
2487 + .controller_data = &spidev_chip_info,
2488 + }
2489 +#endif
2490 +};
2491 +
2492 +static int spi_irq_list[] = {
2493 + /* IRQ, ICR Offset, ICR Val,Mask */
2494 + 64 + ISC_DSPI_OVRFW, ISC_DSPI_OVRFW, 0x18, 0,
2495 + 64 + ISC_DSPI_RFOF, ISC_DSPI_RFOF, 0x18, 0,
2496 + 64 + ISC_DSPI_RFDF, ISC_DSPI_RFDF, 0x18, 0,
2497 + 64 + ISC_DSPI_TFUF, ISC_DSPI_TFUF, 0x18, 0,
2498 + 64 + ISC_DSPI_TCF, ISC_DSPI_TCF, 0x18, 0,
2499 + 64 + ISC_DSPI_TFFF, ISC_DSPI_TFFF, 0x18, 0,
2500 + 64 + ISC_DSPI_EOQF, ISC_DSPI_EOQF, 0x18, 0,
2501 + 0,0,0,0,
2502 +};
2503 +
2504 +static struct coldfire_spi_master coldfire_master_info = {
2505 + .bus_num = 1,
2506 + .num_chipselect = SPI_NUM_CHIPSELECTS,
2507 + .irq_list = spi_irq_list,
2508 + .irq_source = 0, /* not used */
2509 + .irq_vector = 0, /* not used */
2510 + .irq_mask = 0, /* not used */
2511 + .irq_lp = 0, /* not used */
2512 + .par_val = 0, /* not used */
2513 + .cs_control = coldfire_spi_cs_control,
2514 +};
2515 +
2516 +static struct resource coldfire_spi_resources[] = {
2517 + [0] = {
2518 + .name = "spi-par",
2519 + .start = MCF_MBAR + 0x00000a50, /* PAR_DSPI */
2520 + .end = MCF_MBAR + 0x00000a50, /* PAR_DSPI */
2521 + .flags = IORESOURCE_MEM
2522 + },
2523 +
2524 + [1] = {
2525 + .name = "spi-module",
2526 + .start = MCF_MBAR + 0x00008a00, /* DSPI MCR Base */
2527 + .end = MCF_MBAR + 0x00008ab8, /* DSPI mem map end */
2528 + .flags = IORESOURCE_MEM
2529 + },
2530 +
2531 + [2] = {
2532 + .name = "spi-int-level",
2533 + .start = MCF_MBAR + 0x740, /* ICR start */
2534 + .end = MCF_MBAR + 0x740 + ISC_DSPI_EOQF, /* ICR end */
2535 + .flags = IORESOURCE_MEM
2536 + },
2537 +
2538 + [3] = {
2539 + .name = "spi-int-mask",
2540 + .start = MCF_MBAR + 0x70c, /* IMRL */
2541 + .end = MCF_MBAR + 0x70c, /* IMRL */
2542 + .flags = IORESOURCE_MEM
2543 + }
2544 +};
2545 +
2546 +static struct platform_device coldfire_spi = {
2547 + .name = "spi_coldfire",
2548 + .id = -1,
2549 + .resource = coldfire_spi_resources,
2550 + .num_resources = ARRAY_SIZE(coldfire_spi_resources),
2551 + .dev = {
2552 + .platform_data = &coldfire_master_info,
2553 + }
2554 +};
2555 +
2556 +/**
2557 + * m547x_8x_spi_init - Initialize SPI
2558 + */
2559 +static int __init m547x_8x_spi_init(void)
2560 +{
2561 + int retval;
2562 +
2563 + /* initialize the DSPI PAR */
2564 + MCF_GPIO_PAR_DSPI = (MCF_GPIO_PAR_DSPI_PAR_CS5 |
2565 + MCF_GPIO_PAR_DSPI_PAR_CS3_DSPICS |
2566 + MCF_GPIO_PAR_DSPI_PAR_CS2_DSPICS |
2567 + MCF_GPIO_PAR_DSPI_PAR_CS0_DSPICS |
2568 + MCF_GPIO_PAR_DSPI_PAR_SCK_SCK |
2569 + MCF_GPIO_PAR_DSPI_PAR_SIN_SIN |
2570 + MCF_GPIO_PAR_DSPI_PAR_SOUT_SOUT);
2571 +
2572 + /* register device */
2573 + retval = platform_device_register(&coldfire_spi);
2574 + if (retval < 0) {
2575 + goto out;
2576 + }
2577 +
2578 + /* register board info */
2579 + if (ARRAY_SIZE(spi_board_info))
2580 + retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
2581 +
2582 +out:
2583 + return retval;
2584 +}
2585 +#endif
2586 +
2587 +
2588 +/**
2589 + * m547x_8x_init_devices - Initialize M547X_8X devices
2590 + *
2591 + * Returns 0 on success.
2592 + */
2593 +static int __init m547x_8x_init_devices(void)
2594 +{
2595 +#ifdef CONFIG_SPI
2596 + m547x_8x_spi_init();
2597 +#endif
2598 +
2599 + return 0;
2600 +}
2601 +arch_initcall(m547x_8x_init_devices);
2602 --- /dev/null
2603 +++ b/arch/m68k/coldfire/m547x_8x-dma.c
2604 @@ -0,0 +1,516 @@
2605 +/*
2606 + * arch/m68k/coldfire/m547x_8x-dma.c
2607 + *
2608 + * Coldfire M547x/M548x DMA
2609 + *
2610 + * Copyright (c) 2008 Freescale Semiconductor, Inc.
2611 + * Kurt Mahan <kmahan@freescale.com>
2612 + *
2613 + * This code is based on patches from the Freescale M547x_8x BSP
2614 + * release mcf547x_8x-20070107-ltib.iso
2615 + *
2616 + * This program is free software; you can redistribute it and/or modify
2617 + * it under the terms of the GNU General Public License as published by
2618 + * the Free Software Foundation; either version 2 of the License, or
2619 + * (at your option) any later version.
2620 + *
2621 + * This program is distributed in the hope that it will be useful,
2622 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2623 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2624 + * GNU General Public License for more details.
2625 + *
2626 + * You should have received a copy of the GNU General Public License
2627 + * along with this program; if not, write to the Free Software
2628 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2629 + */
2630 +#include <linux/kernel.h>
2631 +#include <linux/sched.h>
2632 +#include <linux/mm.h>
2633 +#include <linux/init.h>
2634 +#include <linux/interrupt.h>
2635 +#include <asm/io.h>
2636 +#include <asm/irq.h>
2637 +#include <asm/dma.h>
2638 +#include <asm/coldfire.h>
2639 +#include <asm/m5485sram.h>
2640 +#include <asm/mcfsim.h>
2641 +
2642 +/*
2643 + * This global keeps track of which initiators have been
2644 + * used of the available assignments. Initiators 0-15 are
2645 + * hardwired. Initiators 16-31 are multiplexed and controlled
2646 + * via the Initiatior Mux Control Registe (IMCR). The
2647 + * assigned requestor is stored with the associated initiator
2648 + * number.
2649 + */
2650 +static int used_reqs[32] = {
2651 + DMA_ALWAYS, DMA_DSPI_RX, DMA_DSPI_TX, DMA_DREQ0,
2652 + DMA_PSC0_RX, DMA_PSC0_TX, DMA_USBEP0, DMA_USBEP1,
2653 + DMA_USBEP2, DMA_USBEP3, DMA_PCI_TX, DMA_PCI_RX,
2654 + DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX,
2655 + 0, 0, 0, 0,
2656 + 0, 0, 0, 0,
2657 + 0, 0, 0, 0,
2658 + 0, 0, 0, 0
2659 +};
2660 +
2661 +/*
2662 + * This global keeps track of which channels have been assigned
2663 + * to tasks. This methology assumes that no single initiator
2664 + * will be tied to more than one task/channel
2665 + */
2666 +static char used_channel[16] = {
2667 + -1, -1, -1, -1, -1, -1, -1, -1,
2668 + -1, -1, -1, -1, -1, -1, -1, -1
2669 +};
2670 +
2671 +unsigned int connected_channel[16] = {
2672 + 0, 0, 0, 0, 0, 0, 0, 0,
2673 + 0, 0, 0, 0, 0, 0, 0, 0
2674 +};
2675 +
2676 +/**
2677 + * dma_set_initiator - enable initiator
2678 + * @initiator: initiator identifier
2679 + *
2680 + * Returns 0 of successful, non-zero otherwise
2681 + *
2682 + * Attempt to enable the provided Initiator in the Initiator
2683 + * Mux Control Register.
2684 + */
2685 +int dma_set_initiator(int initiator)
2686 +{
2687 + switch (initiator) {
2688 + case DMA_ALWAYS:
2689 + case DMA_DSPI_RX:
2690 + case DMA_DSPI_TX:
2691 + case DMA_DREQ0:
2692 + case DMA_PSC0_RX:
2693 + case DMA_PSC0_TX:
2694 + case DMA_USBEP0:
2695 + case DMA_USBEP1:
2696 + case DMA_USBEP2:
2697 + case DMA_USBEP3:
2698 + case DMA_PCI_TX:
2699 + case DMA_PCI_RX:
2700 + case DMA_PSC1_RX:
2701 + case DMA_PSC1_TX:
2702 + case DMA_I2C_RX:
2703 + case DMA_I2C_TX:
2704 + /*
2705 + * These initiators are always active
2706 + */
2707 + break;
2708 +
2709 + case DMA_FEC0_RX:
2710 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC16(3))
2711 + | MCF_DMA_IMCR_SRC16_FEC0RX;
2712 + used_reqs[16] = DMA_FEC0_RX;
2713 + break;
2714 +
2715 + case DMA_FEC0_TX:
2716 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC17(3))
2717 + | MCF_DMA_IMCR_SRC17_FEC0TX;
2718 + used_reqs[17] = DMA_FEC0_TX;
2719 + break;
2720 +
2721 + case DMA_FEC1_RX:
2722 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC20(3))
2723 + | MCF_DMA_IMCR_SRC20_FEC1RX;
2724 + used_reqs[20] = DMA_FEC1_RX;
2725 + break;
2726 +
2727 + case DMA_FEC1_TX:
2728 + if (used_reqs[21] == 0) {
2729 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3))
2730 + | MCF_DMA_IMCR_SRC21_FEC1TX;
2731 + used_reqs[21] = DMA_FEC1_TX;
2732 + } else if (used_reqs[25] == 0) {
2733 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3))
2734 + | MCF_DMA_IMCR_SRC25_FEC1TX;
2735 + used_reqs[25] = DMA_FEC1_TX;
2736 + } else if (used_reqs[31] == 0) {
2737 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
2738 + | MCF_DMA_IMCR_SRC31_FEC1TX;
2739 + used_reqs[31] = DMA_FEC1_TX;
2740 + } else /* No empty slots */
2741 + return 1;
2742 + break;
2743 +
2744 + case DMA_DREQ1:
2745 + if (used_reqs[29] == 0) {
2746 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
2747 + | MCF_DMA_IMCR_SRC29_DREQ1;
2748 + used_reqs[29] = DMA_DREQ1;
2749 + } else if (used_reqs[21] == 0) {
2750 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3))
2751 + | MCF_DMA_IMCR_SRC21_DREQ1;
2752 + used_reqs[21] = DMA_DREQ1;
2753 + } else /* No empty slots */
2754 + return 1;
2755 + break;
2756 +
2757 + case DMA_CTM0:
2758 + if (used_reqs[24] == 0) {
2759 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC24(3))
2760 + | MCF_DMA_IMCR_SRC24_CTM0;
2761 + used_reqs[24] = DMA_CTM0;
2762 + } else /* No empty slots */
2763 + return 1;
2764 + break;
2765 +
2766 + case DMA_CTM1:
2767 + if (used_reqs[25] == 0) {
2768 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3))
2769 + | MCF_DMA_IMCR_SRC25_CTM1;
2770 + used_reqs[25] = DMA_CTM1;
2771 + } else /* No empty slots */
2772 + return 1;
2773 + break;
2774 +
2775 + case DMA_CTM2:
2776 + if (used_reqs[26] == 0) {
2777 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3))
2778 + | MCF_DMA_IMCR_SRC26_CTM2;
2779 + used_reqs[26] = DMA_CTM2;
2780 + } else /* No empty slots */
2781 + return 1;
2782 + break;
2783 +
2784 + case DMA_CTM3:
2785 + if (used_reqs[27] == 0) {
2786 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3))
2787 + | MCF_DMA_IMCR_SRC27_CTM3;
2788 + used_reqs[27] = DMA_CTM3;
2789 + } else /* No empty slots */
2790 + return 1;
2791 + break;
2792 +
2793 + case DMA_CTM4:
2794 + if (used_reqs[28] == 0) {
2795 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
2796 + | MCF_DMA_IMCR_SRC28_CTM4;
2797 + used_reqs[28] = DMA_CTM4;
2798 + } else /* No empty slots */
2799 + return 1;
2800 + break;
2801 +
2802 + case DMA_CTM5:
2803 + if (used_reqs[29] == 0) {
2804 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
2805 + | MCF_DMA_IMCR_SRC29_CTM5;
2806 + used_reqs[29] = DMA_CTM5;
2807 + } else /* No empty slots */
2808 + return 1;
2809 + break;
2810 +
2811 + case DMA_CTM6:
2812 + if (used_reqs[30] == 0) {
2813 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3))
2814 + | MCF_DMA_IMCR_SRC30_CTM6;
2815 + used_reqs[30] = DMA_CTM6;
2816 + } else /* No empty slots */
2817 + return 1;
2818 + break;
2819 +
2820 + case DMA_CTM7:
2821 + if (used_reqs[31] == 0) {
2822 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
2823 + | MCF_DMA_IMCR_SRC31_CTM7;
2824 + used_reqs[31] = DMA_CTM7;
2825 + } else /* No empty slots */
2826 + return 1;
2827 + break;
2828 +
2829 + case DMA_USBEP4:
2830 + if (used_reqs[26] == 0) {
2831 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3))
2832 + | MCF_DMA_IMCR_SRC26_USBEP4;
2833 + used_reqs[26] = DMA_USBEP4;
2834 + } else /* No empty slots */
2835 + return 1;
2836 + break;
2837 +
2838 + case DMA_USBEP5:
2839 + if (used_reqs[27] == 0) {
2840 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3))
2841 + | MCF_DMA_IMCR_SRC27_USBEP5;
2842 + used_reqs[27] = DMA_USBEP5;
2843 + } else /* No empty slots */
2844 + return 1;
2845 + break;
2846 +
2847 + case DMA_USBEP6:
2848 + if (used_reqs[28] == 0) {
2849 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
2850 + | MCF_DMA_IMCR_SRC28_USBEP6;
2851 + used_reqs[28] = DMA_USBEP6;
2852 + } else /* No empty slots */
2853 + return 1;
2854 + break;
2855 +
2856 + case DMA_PSC2_RX:
2857 + if (used_reqs[28] == 0) {
2858 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3))
2859 + | MCF_DMA_IMCR_SRC28_PSC2RX;
2860 + used_reqs[28] = DMA_PSC2_RX;
2861 + } else /* No empty slots */
2862 + return 1;
2863 + break;
2864 +
2865 + case DMA_PSC2_TX:
2866 + if (used_reqs[29] == 0) {
2867 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3))
2868 + | MCF_DMA_IMCR_SRC29_PSC2TX;
2869 + used_reqs[29] = DMA_PSC2_TX;
2870 + } else /* No empty slots */
2871 + return 1;
2872 + break;
2873 +
2874 + case DMA_PSC3_RX:
2875 + if (used_reqs[30] == 0) {
2876 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3))
2877 + | MCF_DMA_IMCR_SRC30_PSC3RX;
2878 + used_reqs[30] = DMA_PSC3_RX;
2879 + } else /* No empty slots */
2880 + return 1;
2881 + break;
2882 +
2883 + case DMA_PSC3_TX:
2884 + if (used_reqs[31] == 0) {
2885 + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3))
2886 + | MCF_DMA_IMCR_SRC31_PSC3TX;
2887 + used_reqs[31] = DMA_PSC3_TX;
2888 + } else /* No empty slots */
2889 + return 1;
2890 + break;
2891 +
2892 + default:
2893 + return 1;
2894 + }
2895 + return 0;
2896 +}
2897 +
2898 +/**
2899 + * dma_get_initiator - get the initiator for the given requestor
2900 + * @requestor: initiator identifier
2901 + *
2902 + * Returns initiator number (0-31) if assigned or just 0
2903 + */
2904 +unsigned int dma_get_initiator(int requestor)
2905 +{
2906 + u32 i;
2907 +
2908 + for (i = 0; i < sizeof(used_reqs); ++i) {
2909 + if (used_reqs[i] == requestor)
2910 + return i;
2911 + }
2912 + return 0;
2913 +}
2914 +
2915 +/**
2916 + * dma_remove_initiator - remove the given initiator from active list
2917 + * @requestor: requestor to remove
2918 + */
2919 +void dma_remove_initiator(int requestor)
2920 +{
2921 + u32 i;
2922 +
2923 + for (i = 0; i < sizeof(used_reqs); ++i) {
2924 + if (used_reqs[i] == requestor) {
2925 + used_reqs[i] = -1;
2926 + break;
2927 + }
2928 + }
2929 +}
2930 +
2931 +/**
2932 + * dma_set_channel_fec: find available channel for fec and mark
2933 + * @requestor: initiator/requestor identifier
2934 + *
2935 + * Returns first avaialble channel (0-5) or -1 if all occupied
2936 + */
2937 +int dma_set_channel_fec(int requestor)
2938 +{
2939 + u32 i, t;
2940 +
2941 +#ifdef CONFIG_FEC_548x_ENABLE_FEC2
2942 + t = 4;
2943 +#else
2944 + t = 2;
2945 +#endif
2946 +
2947 + for (i = 0; i < t ; ++i) {
2948 + if (used_channel[i] == -1) {
2949 + used_channel[i] = requestor;
2950 + return i;
2951 + }
2952 + }
2953 + /* All channels taken */
2954 + return -1;
2955 +}
2956 +
2957 +/**
2958 + * dma_set_channel - find an available channel and mark as used
2959 + * @requestor: initiator/requestor identifier
2960 + *
2961 + * Returns first available channel (6-15) or -1 if all occupied
2962 + */
2963 +int dma_set_channel(int requestor)
2964 +{
2965 + u32 i;
2966 +#ifdef CONFIG_NET_FEC2
2967 + i = 4;
2968 +#else
2969 + i = 2;
2970 +#endif
2971 +
2972 + for (; i < 16; ++i)
2973 + if (used_channel[i] == -1) {
2974 + used_channel[i] = requestor;
2975 + return i;
2976 + }
2977 +
2978 + /* All channels taken */
2979 + return -1;
2980 +}
2981 +
2982 +/**
2983 + * dma_get_channel - get the channel being initiated by the requestor
2984 + * @requestor: initiator/requestor identifier
2985 + *
2986 + * Returns Initiator for requestor or -1 if not found
2987 + */
2988 +int dma_get_channel(int requestor)
2989 +{
2990 + u32 i;
2991 +
2992 + for (i = 0; i < sizeof(used_channel); ++i) {
2993 + if (used_channel[i] == requestor)
2994 + return i;
2995 + }
2996 + return -1;
2997 +}
2998 +
2999 +/**
3000 + * dma_connect - connect a channel with reference on data
3001 + * @channel: channel number
3002 + * @address: reference address of data
3003 + *
3004 + * Returns 0 if success or -1 if invalid channel
3005 + */
3006 +int dma_connect(int channel, int address)
3007 +{
3008 + if ((channel < 16) && (channel >= 0)) {
3009 + connected_channel[channel] = address;
3010 + return 0;
3011 + }
3012 + return -1;
3013 +}
3014 +
3015 +/**
3016 + * dma_disconnect - disconnect a channel
3017 + * @channel: channel number
3018 + *
3019 + * Returns 0 if success or -1 if invalid channel
3020 + */
3021 +int dma_disconnect(int channel)
3022 +{
3023 + if ((channel < 16) && (channel >= 0)) {
3024 + connected_channel[channel] = 0;
3025 + return 0;
3026 + }
3027 + return -1;
3028 +}
3029 +
3030 +/**
3031 + * dma_remove_channel - remove channel from the active list
3032 + * @requestor: initiator/requestor identifier
3033 + */
3034 +void dma_remove_channel(int requestor)
3035 +{
3036 + u32 i;
3037 +
3038 + for (i = 0; i < sizeof(used_channel); ++i) {
3039 + if (used_channel[i] == requestor) {
3040 + used_channel[i] = -1;
3041 + break;
3042 + }
3043 + }
3044 +}
3045 +
3046 +/**
3047 + * dma_interrupt_handler - dma interrupt handler
3048 + * @irq: interrupt number
3049 + * @dev_id: data
3050 + *
3051 + * Returns IRQ_HANDLED
3052 + */
3053 +irqreturn_t dma_interrupt_handler(int irq, void *dev_id)
3054 +{
3055 + u32 i, interrupts;
3056 +
3057 + /*
3058 + * Determine which interrupt(s) triggered by AND'ing the
3059 + * pending interrupts with those that aren't masked.
3060 + */
3061 + interrupts = MCF_DMA_DIPR;
3062 + MCF_DMA_DIPR = interrupts;
3063 +
3064 + for (i = 0; i < 16; ++i, interrupts >>= 1) {
3065 + if (interrupts & 0x1)
3066 + if (connected_channel[i] != 0)
3067 + ((void (*)(void)) (connected_channel[i])) ();
3068 + }
3069 +
3070 + return IRQ_HANDLED;
3071 +}
3072 +
3073 +/**
3074 + * dma_remove_channel_by_number - clear dma channel
3075 + * @channel: channel number to clear
3076 + */
3077 +void dma_remove_channel_by_number(int channel)
3078 +{
3079 + if ((channel < sizeof(used_channel)) && (channel >= 0))
3080 + used_channel[channel] = -1;
3081 +}
3082 +
3083 +/**
3084 + * dma_init - initialize the dma subsystem
3085 + *
3086 + * Returns 0 if success non-zero if failure
3087 + *
3088 + * Handles the DMA initialization during device setup.
3089 + */
3090 +int __devinit dma_init()
3091 +{
3092 + int result;
3093 + char *dma_version_str;
3094 +
3095 + MCD_getVersion(&dma_version_str);
3096 + printk(KERN_INFO "m547x_8x DMA: Initialize %s\n", dma_version_str);
3097 +
3098 + /* attempt to setup dma interrupt handler */
3099 + if (request_irq(64 + ISC_DMA, dma_interrupt_handler, IRQF_DISABLED,
3100 + "MCD-DMA", NULL)) {
3101 + printk(KERN_ERR "MCD-DMA: Cannot allocate the DMA IRQ(48)\n");
3102 + return 1;
3103 + }
3104 +
3105 + MCF_DMA_DIMR = 0;
3106 + MCF_DMA_DIPR = 0xFFFFFFFF;
3107 +
3108 + MCF_ICR(ISC_DMA) = ILP_DMA;
3109 +
3110 + result = MCD_initDma((dmaRegs *) (MCF_MBAR + 0x8000),
3111 + (void *) SYS_SRAM_DMA_START, MCD_RELOC_TASKS);
3112 + if (result != MCD_OK) {
3113 + printk(KERN_ERR "MCD-DMA: Cannot perform DMA initialization\n");
3114 + free_irq(64 + ISC_DMA, NULL);
3115 + return 1;
3116 + }
3117 +
3118 + return 0;
3119 +}
3120 +device_initcall(dma_init);
3121 --- /dev/null
3122 +++ b/arch/m68k/coldfire/Makefile
3123 @@ -0,0 +1,20 @@
3124 +#
3125 +# Makefile for Linux arch/m68k/coldfire source directory
3126 +#
3127 +
3128 +obj-y:= entry.o config.o cache.o signal.o muldi3.o traps.o ints.o
3129 +ifdef CONFIG_M5445X
3130 +ifneq ($(strip $(CONFIG_USB) $(CONFIG_USB_GADGET_MCF5445X)),)
3131 + obj-y += usb.o usb/
3132 +endif
3133 +endif
3134 +
3135 +ifdef CONFIG_M547X_8X
3136 +obj-$(CONFIG_PCI) += mcf548x-pci.o
3137 +else
3138 +obj-$(CONFIG_PCI) += pci.o mcf5445x-pci.o iomap.o
3139 +endif
3140 +obj-$(CONFIG_M5445X) += mcf5445x-devices.o
3141 +obj-$(CONFIG_M547X_8X) += m547x_8x-devices.o
3142 +obj-$(CONFIG_M547X_8X) += mcf548x-devices.o
3143 +obj-$(CONFIG_MCD_DMA) += m547x_8x-dma.o
3144 --- /dev/null
3145 +++ b/arch/m68k/coldfire/mcf5445x-devices.c
3146 @@ -0,0 +1,136 @@
3147 +/*
3148 + * arch/m68k/coldfire/mcf5445x-devices.c
3149 + *
3150 + * Coldfire M5445x Platform Device Configuration
3151 + *
3152 + * Based on the Freescale MXC devices.c
3153 + *
3154 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
3155 + * Kurt Mahan <kmahan@freescale.com>
3156 + */
3157 +#include <linux/module.h>
3158 +#include <linux/kernel.h>
3159 +#include <linux/init.h>
3160 +#include <linux/platform_device.h>
3161 +#include <linux/fsl_devices.h>
3162 +
3163 +#include <asm/coldfire.h>
3164 +#include <asm/mcfsim.h>
3165 +
3166 +/* ATA Interrupt */
3167 +#define IRQ_ATA (64 + 64 + 54)
3168 +
3169 +/* ATA Base */
3170 +#define BASE_IO_ATA 0x90000000
3171 +
3172 +#define ATA_IER MCF_REG08(BASE_IO_ATA+0x2c) /* int enable reg */
3173 +#define ATA_ICR MCF_REG08(BASE_IO_ATA+0x30) /* int clear reg */
3174 +
3175 +/*
3176 + * On-chip PATA
3177 + */
3178 +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
3179 +static int ata_init(struct platform_device *pdev)
3180 +{
3181 + /* clear ints */
3182 + ATA_IER = 0x00;
3183 + ATA_ICR = 0xff;
3184 +
3185 + /* setup shared pins */
3186 + MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC & MCF_GPIO_PAR_FEC_FEC1_MASK) |
3187 + MCF_GPIO_PAR_FEC_FEC1_ATA;
3188 +
3189 + MCF_GPIO_PAR_FECI2C = (MCF_GPIO_PAR_FECI2C &
3190 + (MCF_GPIO_PAR_FECI2C_MDC1_MASK &
3191 + MCF_GPIO_PAR_FECI2C_MDIO1_MASK)) |
3192 + MCF_GPIO_PAR_FECI2C_MDC1_ATA_DIOR |
3193 + MCF_GPIO_PAR_FECI2C_MDIO1_ATA_DIOW;
3194 +
3195 + MCF_GPIO_PAR_ATA = MCF_GPIO_PAR_ATA_BUFEN |
3196 + MCF_GPIO_PAR_ATA_CS1 |
3197 + MCF_GPIO_PAR_ATA_CS0 |
3198 + MCF_GPIO_PAR_ATA_DA2 |
3199 + MCF_GPIO_PAR_ATA_DA1 |
3200 + MCF_GPIO_PAR_ATA_DA0 |
3201 + MCF_GPIO_PAR_ATA_RESET_RESET |
3202 + MCF_GPIO_PAR_ATA_DMARQ_DMARQ |
3203 + MCF_GPIO_PAR_ATA_IORDY_IORDY;
3204 +
3205 + MCF_GPIO_PAR_PCI = (MCF_GPIO_PAR_PCI &
3206 + (MCF_GPIO_PAR_PCI_GNT3_MASK &
3207 + MCF_GPIO_PAR_PCI_REQ3_MASK)) |
3208 + MCF_GPIO_PAR_PCI_GNT3_ATA_DMACK |
3209 + MCF_GPIO_PAR_PCI_REQ3_ATA_INTRQ;
3210 +
3211 + return 0;
3212 +}
3213 +
3214 +static void ata_exit(void)
3215 +{
3216 + printk(KERN_INFO "** ata_exit\n");
3217 +}
3218 +
3219 +static int ata_get_clk_rate(void)
3220 +{
3221 + return MCF_BUSCLK;
3222 +}
3223 +
3224 +/* JKM -- move these to a header file */
3225 +#define MCF_IDE_DMA_WATERMARK 32 /* DMA watermark level in bytes */
3226 +#define MCF_IDE_DMA_BD_NR (512/3/4) /* number of BDs per channel */
3227 +
3228 +static struct fsl_ata_platform_data ata_data = {
3229 + .init = ata_init,
3230 + .exit = ata_exit,
3231 + .get_clk_rate = ata_get_clk_rate,
3232 +#ifdef CONFIG_PATA_FSL_USE_DMA
3233 + .udma_mask = 0x0F, /* the board handles up to UDMA3 */
3234 + .fifo_alarm = MCF_IDE_DMA_WATERMARK / 2,
3235 + .max_sg = MCF_IDE_DMA_BD_NR,
3236 +#endif
3237 +};
3238 +
3239 +static struct resource pata_fsl_resources[] = {
3240 + [0] = { /* I/O */
3241 + .start = BASE_IO_ATA,
3242 + .end = BASE_IO_ATA + 0x000000d8,
3243 + .flags = IORESOURCE_MEM,
3244 + },
3245 + [2] = { /* IRQ */
3246 + .start = IRQ_ATA,
3247 + .end = IRQ_ATA,
3248 + .flags = IORESOURCE_IRQ,
3249 + },
3250 +};
3251 +
3252 +static struct platform_device pata_fsl_device = {
3253 + .name = "pata_fsl",
3254 + .id = -1,
3255 + .num_resources = ARRAY_SIZE(pata_fsl_resources),
3256 + .resource = pata_fsl_resources,
3257 + .dev = {
3258 + .platform_data = &ata_data,
3259 + .coherent_dma_mask = ~0, /* $$$ REVISIT */
3260 + },
3261 +};
3262 +
3263 +static inline void mcf5445x_init_pata(void)
3264 +{
3265 + (void)platform_device_register(&pata_fsl_device);
3266 +}
3267 +#else
3268 +static inline void mcf5445x_init_pata(void)
3269 +{
3270 +}
3271 +#endif
3272 +
3273 +static int __init mcf5445x_init_devices(void)
3274 +{
3275 + printk(KERN_INFO "MCF5445x INIT_DEVICES\n");
3276 +#if 0
3277 + mcf5445x_init_pata();
3278 +#endif
3279 +
3280 + return 0;
3281 +}
3282 +arch_initcall(mcf5445x_init_devices);
3283 --- /dev/null
3284 +++ b/arch/m68k/coldfire/mcf5445x-pci.c
3285 @@ -0,0 +1,431 @@
3286 +/*
3287 + * arch/m68k/coldfire/mcf5445x-pci.c
3288 + *
3289 + * Coldfire M5445x specific PCI implementation.
3290 + *
3291 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
3292 + * Kurt Mahan <kmahan@freescale.com>
3293 + */
3294 +
3295 +#include <linux/delay.h>
3296 +#include <linux/interrupt.h>
3297 +#include <linux/pci.h>
3298 +
3299 +#include <asm/mcfsim.h>
3300 +#include <asm/pci.h>
3301 +#include <asm/irq.h>
3302 +
3303 +/*
3304 + * Layout MCF5445x to PCI memory mappings:
3305 + *
3306 + * WIN MCF5445x PCI TYPE
3307 + * --- -------- --- ----
3308 + * [0] 0xA0000000 -> 0xA7FFFFFF 0xA0000000 -> 0xA7FFFFFF MEM
3309 + * [1] 0xA8000000 -> 0xABFFFFFF 0xA8000000 -> 0xABFFFFFF MEM
3310 + * [2] 0xAC000000 -> 0xAFFFFFFF 0xAC000000 -> 0xAFFFFFFF IO
3311 + */
3312 +
3313 +#define MCF5445X_PCI_MEM_BASE 0xA0000000
3314 +#define MCF5445X_PCI_MEM_SIZE 0x0C000000
3315 +
3316 +#define MCF5445X_PCI_CONFIG_BASE 0xAC000000
3317 +#define MCF5445X_PCI_CONFIG_SIZE 0x04000000
3318 +
3319 +#define MCF5445X_PCI_IO_BASE 0xAC000000
3320 +#define MCF5445X_PCI_IO_SIZE 0x04000000
3321 +
3322 +/* PCI Bus memory resource block */
3323 +struct resource pci_iomem_resource = {
3324 + .name = "PCI memory space",
3325 + .start = MCF5445X_PCI_MEM_BASE,
3326 + .flags = IORESOURCE_MEM,
3327 + .end = MCF5445X_PCI_MEM_BASE + MCF5445X_PCI_MEM_SIZE - 1
3328 +};
3329 +
3330 +/* PCI Bus ioport resource block */
3331 +struct resource pci_ioport_resource = {
3332 + .name = "PCI I/O space",
3333 + .start = MCF5445X_PCI_IO_BASE,
3334 + .flags = IORESOURCE_IO,
3335 + .end = MCF5445X_PCI_IO_BASE + MCF5445X_PCI_IO_SIZE - 1
3336 +};
3337 +
3338 +/*
3339 + * The M54455EVB multiplexes all the PCI interrupts via
3340 + * the FPGA and routes them to a single interrupt. The
3341 + * PCI spec requires all PCI interrupt routines be smart
3342 + * enough to sort out their own interrupts.
3343 + * The interrupt source from the FPGA is configured
3344 + * to EPORT 3.
3345 + */
3346 +#define MCF5445X_PCI_IRQ 0x43
3347 +
3348 +#define PCI_SLOTS 4
3349 +
3350 +/*
3351 + * FPGA Info
3352 + */
3353 +#define FPGA_PCI_IRQ_ENABLE (u32 *)0x09000000
3354 +#define FPGA_PCI_IRQ_STATUS (u32 *)0x09000004
3355 +#define FPGA_PCI_IRQ_ROUTE (u32 *)0x0900000c
3356 +#define FPGA_SEVEN_LED (u32 *)0x09000014
3357 +
3358 +extern void set_fpga(u32 *addr, u32 val);
3359 +
3360 +#ifdef DEBUG
3361 +void mcf5445x_pci_dumpregs(void);
3362 +#endif
3363 +
3364 +/*
3365 + * mcf5445x_conf_device(struct pci_dev *dev)
3366 + *
3367 + * Machine dependent Configure the given device.
3368 + *
3369 + * Parameters:
3370 + *
3371 + * dev - the pci device.
3372 + */
3373 +void
3374 +mcf5445x_conf_device(struct pci_dev *dev)
3375 +{
3376 + set_fpga(FPGA_PCI_IRQ_ENABLE, 0x0f);
3377 +}
3378 +
3379 +/*
3380 + * int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus,
3381 + * unsigned int devfn, int reg,
3382 + * u32 *value)
3383 + *
3384 + * Read from PCI configuration space.
3385 + *
3386 + */
3387 +int mcf5445x_pci_config_read(unsigned int seg, unsigned int bus,
3388 + unsigned int devfn, int reg, int len, u32 *value)
3389 +{
3390 + u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) |
3391 + MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) |
3392 + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) |
3393 + MCF_PCI_PCICAR_DWORD(reg) |
3394 + MCF_PCI_PCICAR_E;
3395 +
3396 + if ((bus > 255) || (devfn > 255) || (reg > 255)) {
3397 + *value = -1;
3398 + return -EINVAL;
3399 + }
3400 +
3401 + /* setup for config mode */
3402 + MCF_PCI_PCICAR = addr;
3403 + __asm__ __volatile__("nop");
3404 +
3405 + switch (len) {
3406 + case 1:
3407 + *value = *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3));
3408 + break;
3409 + case 2:
3410 + *value = le16_to_cpu(*(volatile u16 *)
3411 + (MCF5445X_PCI_CONFIG_BASE + (reg&2)));
3412 + break;
3413 + case 4:
3414 + *value = le32_to_cpu(*(volatile u32 *)
3415 + (MCF5445X_PCI_CONFIG_BASE));
3416 + break;
3417 + }
3418 +
3419 + /* clear config mode */
3420 + MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E;
3421 + __asm__ __volatile__("nop");
3422 +
3423 + return 0;
3424 +}
3425 +
3426 +/*
3427 + * int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus,
3428 + * unsigned int devfn, int reg,
3429 + * u32 *value)
3430 + *
3431 + * Write to PCI configuration space
3432 + */
3433 +int mcf5445x_pci_config_write(unsigned int seg, unsigned int bus,
3434 + unsigned int devfn, int reg, int len, u32 value)
3435 +{
3436 + u32 addr = MCF_PCI_PCICAR_BUSNUM(bus) |
3437 + MCF_PCI_PCICAR_DEVNUM(PCI_SLOT(devfn)) |
3438 + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNC(devfn)) |
3439 + MCF_PCI_PCICAR_DWORD(reg) |
3440 + MCF_PCI_PCICAR_E;
3441 +
3442 + if ((bus > 255) || (devfn > 255) || (reg > 255))
3443 + return -EINVAL;
3444 +
3445 + /* setup for config mode */
3446 + MCF_PCI_PCICAR = addr;
3447 + __asm__ __volatile__("nop");
3448 +
3449 + switch (len) {
3450 + case 1:
3451 + *(volatile u8 *)(MCF5445X_PCI_CONFIG_BASE+(reg&3)) = (u8)value;
3452 + break;
3453 + case 2:
3454 + *(volatile u16 *)(MCF5445X_PCI_CONFIG_BASE+(reg&2)) =
3455 + cpu_to_le16((u16)value);
3456 + break;
3457 + case 4:
3458 + *(volatile u32 *)(MCF5445X_PCI_CONFIG_BASE) =
3459 + cpu_to_le32(value);
3460 + break;
3461 + }
3462 +
3463 + /* clear config mode */
3464 + MCF_PCI_PCICAR = ~MCF_PCI_PCICAR_E;
3465 + __asm__ __volatile__("nop");
3466 +
3467 + return 0;
3468 +}
3469 +
3470 +/* hardware operations */
3471 +static struct pci_raw_ops mcf5445x_pci_ops = {
3472 + .read = mcf5445x_pci_config_read,
3473 + .write = mcf5445x_pci_config_write,
3474 +};
3475 +
3476 +/*
3477 + * irqreturn_t mcf5445x_pci_interrupt( int irq, void *dev)
3478 + *
3479 + * PCI controller interrupt handler.
3480 + */
3481 +static irqreturn_t
3482 +mcf5445x_pci_interrupt(int irq, void *dev)
3483 +{
3484 + u32 status = MCF_PCI_PCIGSCR;
3485 +#ifdef DEBUG
3486 + printk(KERN_INFO "PCI: Controller irq status=0x%08x\n", status);
3487 +#endif
3488 + /* clear */
3489 + MCF_PCI_PCIGSCR = status;
3490 +
3491 + return IRQ_HANDLED;
3492 +}
3493 +
3494 +/*
3495 + * irqreturn_t mcf5445x_pci_arb_interrupt( int irq, void *dev)
3496 + *
3497 + * PCI Arbiter interrupt handler.
3498 + */
3499 +static irqreturn_t
3500 +mcf5445x_pci_arb_interrupt(int irq, void *dev)
3501 +{
3502 + u32 status = MCF_PCIARB_PASR;
3503 +#ifdef DEBUG
3504 + printk(KERN_INFO "PCI: Arbiter irq status=0x%08x\n", status);
3505 +#endif
3506 + /* clear */
3507 + MCF_PCIARB_PASR = status;
3508 + return IRQ_HANDLED;
3509 +}
3510 +
3511 +/*
3512 + * struct pci_bus_info *init_mcf5445x_pci(void)
3513 + *
3514 + * Machine specific initialisation:
3515 + *
3516 + * - Allocate and initialise a 'pci_bus_info' structure
3517 + * - Initialize hardware
3518 + *
3519 + * Result: pointer to 'pci_bus_info' structure.
3520 + */
3521 +int __init
3522 +init_mcf5445x_pci(void)
3523 +{
3524 + return 0;
3525 +#if 0
3526 + /*
3527 + * Initialize the PCI core
3528 + */
3529 +
3530 + /* arbitration controller */
3531 + MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI |
3532 + MCF_PCIARB_PACR_EXTMPRI(0x0f) |
3533 + MCF_PCIARB_PACR_INTMINTEN |
3534 + MCF_PCIARB_PACR_EXTMINTEN(0x0f);
3535 +
3536 + /* pci pin assignment regs */
3537 + MCF_GPIO_PAR_PCI = MCF_GPIO_PAR_PCI_GNT0 |
3538 + MCF_GPIO_PAR_PCI_GNT1 |
3539 + MCF_GPIO_PAR_PCI_GNT2 |
3540 + MCF_GPIO_PAR_PCI_GNT3_GNT3 |
3541 + MCF_GPIO_PAR_PCI_REQ0 |
3542 + MCF_GPIO_PAR_PCI_REQ1 |
3543 + MCF_GPIO_PAR_PCI_REQ2 |
3544 + MCF_GPIO_PAR_PCI_REQ3_REQ3;
3545 +
3546 + /* target control reg */
3547 + MCF_PCI_PCITCR = MCF_PCI_PCITCR_P |
3548 + MCF_PCI_PCITCR_WCT(8);
3549 +
3550 + /* PCI MEM address */
3551 + MCF_PCI_PCIIW0BTAR = 0xA007A000;
3552 +
3553 + /* PCI MEM address */
3554 + MCF_PCI_PCIIW1BTAR = 0xA803A800;
3555 +
3556 + /* PCI IO address */
3557 + MCF_PCI_PCIIW2BTAR = 0xAC03AC00;
3558 +
3559 + /* window control */
3560 + MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_ENABLE |
3561 + MCF_PCI_PCIIWCR_WINCTRL0_MEMREAD |
3562 + MCF_PCI_PCIIWCR_WINCTRL1_ENABLE |
3563 + MCF_PCI_PCIIWCR_WINCTRL1_MEMREAD |
3564 + MCF_PCI_PCIIWCR_WINCTRL2_ENABLE |
3565 + MCF_PCI_PCIIWCR_WINCTRL2_IO;
3566 +
3567 + /* initiator control reg */
3568 + MCF_PCI_PCIICR = 0x00ff;
3569 +
3570 + /* type 0 - command */
3571 + MCF_PCI_PCISCR = MCF_PCI_PCISCR_MW | /* mem write/inval */
3572 + MCF_PCI_PCISCR_B | /* bus master enable */
3573 + MCF_PCI_PCISCR_M; /* mem access enable */
3574 +
3575 + /* type 0 - config reg */
3576 + MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(8) |
3577 + MCF_PCI_PCICR1_LATTIMER(0xff);
3578 +
3579 + /* type 0 - config 2 reg */
3580 + MCF_PCI_PCICR2 = 0;
3581 +
3582 + /* target control reg */
3583 + MCF_PCI_PCITCR2 = MCF_PCI_PCITCR2_B0E |
3584 + MCF_PCI_PCITCR2_B4E;
3585 +
3586 + /* translate addresses from PCI[0] to CF[SDRAM] */
3587 + MCF_PCI_PCITBATR0 = MCF_RAMBAR1 | MCF_PCI_PCITBATR0_EN;
3588 + MCF_PCI_PCITBATR4 = MCF_RAMBAR1 | MCF_PCI_PCITBATR4_EN;
3589 +
3590 + /* setup controller interrupt handlers */
3591 + if (request_irq(55+128, mcf5445x_pci_interrupt, IRQF_SHARED,
3592 + "PCI Controller", NULL))
3593 + printk(KERN_ERR "PCI: Unable to register controller irq\n");
3594 +
3595 + if (request_irq (56+128, mcf5445x_pci_arb_interrupt, IRQF_SHARED, "PCI Arbiter", NULL))
3596 + printk(KERN_ERR "PCI: Unable to register arbiter irq\n");
3597 +
3598 + /* global control - clear reset bit */
3599 + MCF_PCI_PCIGSCR = MCF_PCI_PCIGSCR_SEE |
3600 + MCF_PCI_PCIGSCR_PEE;
3601 +
3602 + /* let everything settle */
3603 + udelay(1000);
3604 +
3605 + /* allocate bus ioport resource */
3606 + if (request_resource(&ioport_resource, &pci_ioport_resource) < 0)
3607 + printk(KERN_ERR "PCI: Unable to alloc ioport resource\n");
3608 +
3609 + /* allocate bus iomem resource */
3610 + if (request_resource(&iomem_resource, &pci_iomem_resource) < 0)
3611 + printk(KERN_ERR "PCI: Unable to alloc iomem resource\n");
3612 +
3613 + /* setup FPGA to route PCI to IRQ3(67), SW7 to IRQ7, SW6 to IRQ4 */
3614 + set_fpga(FPGA_PCI_IRQ_ENABLE, 0x00000000);
3615 + set_fpga(FPGA_PCI_IRQ_ROUTE, 0x00000039);
3616 + set_fpga(FPGA_SEVEN_LED, 0x000000FF);
3617 +
3618 + raw_pci_ops = &mcf5445x_pci_ops;
3619 +
3620 + return 0;
3621 +#endif
3622 +}
3623 +
3624 +/*
3625 + * DEBUGGING
3626 + */
3627 +
3628 +#ifdef DEBUG
3629 +struct regdump {
3630 + u32 addr;
3631 + char regname[16];
3632 +};
3633 +
3634 +struct regdump type0regs[] = {
3635 + { 0xfc0a8000, "PCIIDR" },
3636 + { 0xfc0a8004, "PCISCR" },
3637 + { 0xfc0a8008, "PCICCRIR" },
3638 + { 0xfc0a800c, "PCICR1" },
3639 + { 0xfc0a8010, "PCIBAR0" },
3640 + { 0xfc0a8014, "PCIBAR1" },
3641 + { 0xfc0a8018, "PCIBAR2" },
3642 + { 0xfc0a801c, "PCIBAR3" },
3643 + { 0xfc0a8020, "PCIBAR4" },
3644 + { 0xfc0a8024, "PCIBAR5" },
3645 + { 0xfc0a8028, "PCICCPR" },
3646 + { 0xfc0a802c, "PCISID" },
3647 + { 0xfc0a8030, "PCIERBAR" },
3648 + { 0xfc0a8034, "PCICPR" },
3649 + { 0xfc0a803c, "PCICR2" },
3650 + { 0, "" }
3651 +};
3652 +
3653 +struct regdump genregs[] = {
3654 + { 0xfc0a8060, "PCIGSCR" },
3655 + { 0xfc0a8064, "PCITBATR0" },
3656 + { 0xfc0a8068, "PCITBATR1" },
3657 + { 0xfc0a806c, "PCITCR1" },
3658 + { 0xfc0a8070, "PCIIW0BTAR" },
3659 + { 0xfc0a8074, "PCIIW1BTAR" },
3660 + { 0xfc0a8078, "PCIIW2BTAR" },
3661 + { 0xfc0a8080, "PCIIWCR" },
3662 + { 0xfc0a8084, "PCIICR" },
3663 + { 0xfc0a8088, "PCIISR" },
3664 + { 0xfc0a808c, "PCITCR2" },
3665 + { 0xfc0a8090, "PCITBATR0" },
3666 + { 0xfc0a8094, "PCITBATR1" },
3667 + { 0xfc0a8098, "PCITBATR2" },
3668 + { 0xfc0a809c, "PCITBATR3" },
3669 + { 0xfc0a80a0, "PCITBATR4" },
3670 + { 0xfc0a80a4, "PCITBATR5" },
3671 + { 0xfc0a80a8, "PCIINTR" },
3672 + { 0xfc0a80f8, "PCICAR" },
3673 + { 0, "" }
3674 +};
3675 +
3676 +struct regdump arbregs[] = {
3677 + { 0xfc0ac000, "PACR" },
3678 + { 0xfc0ac004, "PASR" }, /* documentation error */
3679 + { 0, "" }
3680 +};
3681 +
3682 +/*
3683 + * void mcf5445x_pci_dumpregs()
3684 + *
3685 + * Dump out all the PCI registers
3686 + */
3687 +void
3688 +mcf5445x_pci_dumpregs(void)
3689 +{
3690 + struct regdump *reg;
3691 +
3692 + printk(KERN_INFO "*** MCF5445x PCI TARGET 0 REGISTERS ***\n");
3693 +
3694 + reg = type0regs;
3695 + while (reg->addr) {
3696 + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
3697 + *((u32 *)reg->addr), reg->regname);
3698 + reg++;
3699 + }
3700 +
3701 + printk(KERN_INFO "\n*** MCF5445x PCI GENERAL REGISTERS ***\n");
3702 + reg = genregs;
3703 + while (reg->addr) {
3704 + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
3705 + *((u32 *)reg->addr), reg->regname);
3706 + reg++;
3707 + }
3708 + printk(KERN_INFO "\n*** MCF5445x PCI ARBITER REGISTERS ***\n");
3709 + reg = arbregs;
3710 + while (reg->addr) {
3711 + printk(KERN_INFO "0x%08x 0x%08x %s\n", reg->addr,
3712 + *((u32 *)reg->addr), reg->regname);
3713 + reg++;
3714 + }
3715 +}
3716 +#endif /* DEBUG */
3717 --- /dev/null
3718 +++ b/arch/m68k/coldfire/mcf548x-devices.c
3719 @@ -0,0 +1,94 @@
3720 +/*
3721 + * arch/m68k/coldfire/mcf5445x-devices.c
3722 + *
3723 + * Coldfire M5445x Platform Device Configuration
3724 + *
3725 + * Based on the Freescale MXC devices.c
3726 + *
3727 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
3728 + * Kurt Mahan <kmahan@freescale.com>
3729 + */
3730 +#include <linux/module.h>
3731 +#include <linux/kernel.h>
3732 +#include <linux/init.h>
3733 +#include <linux/mtd/physmap.h>
3734 +#include <linux/platform_device.h>
3735 +#include <linux/fsl_devices.h>
3736 +
3737 +#include <asm/coldfire.h>
3738 +#include <asm/mcfsim.h>
3739 +
3740 +static struct resource coldfire_i2c_resources[] = {
3741 + [0] = { /* I/O */
3742 + .start = MCF_MBAR + 0x008F00,
3743 + .end = MCF_MBAR + 0x008F20,
3744 + .flags = IORESOURCE_MEM,
3745 + },
3746 + [2] = { /* IRQ */
3747 + .start = 40,
3748 + .end = 40,
3749 + .flags = IORESOURCE_IRQ,
3750 + },
3751 +};
3752 +
3753 +static struct platform_device coldfire_i2c_device = {
3754 + .name = "MCF548X-i2c",
3755 + .id = -1,
3756 + .num_resources = ARRAY_SIZE(coldfire_i2c_resources),
3757 + .resource = coldfire_i2c_resources,
3758 +};
3759 +
3760 +static struct resource coldfire_sec_resources[] = {
3761 + [0] = { /* I/O */
3762 + .start = MCF_MBAR + 0x00020000,
3763 + .end = MCF_MBAR + 0x00033000,
3764 + .flags = IORESOURCE_MEM,
3765 + },
3766 + [2] = { /* IRQ */
3767 + .start = ISC_SEC,
3768 + .end = ISC_SEC,
3769 + .flags = IORESOURCE_IRQ,
3770 + },
3771 +};
3772 +
3773 +static struct platform_device coldfire_sec_device = {
3774 + .name = "fsl-sec1",
3775 + .id = -1,
3776 + .num_resources = ARRAY_SIZE(coldfire_sec_resources),
3777 + .resource = coldfire_sec_resources,
3778 +};
3779 +
3780 +#if defined(CONFIG_MTD_PHYSMAP)
3781 +static struct physmap_flash_data mcf5485_flash_data = {
3782 + .width = 2,
3783 +};
3784 +
3785 +static struct resource mcf5485_flash_resource = {
3786 + .start = 0xf8000000,
3787 + .end = 0xf80fffff,
3788 + .flags = IORESOURCE_MEM,
3789 +};
3790 +
3791 +static struct platform_device mcf5485_flash_device = {
3792 + .name = "physmap-flash",
3793 + .id = 0,
3794 + .dev = {
3795 + .platform_data = &mcf5485_flash_data,
3796 + },
3797 + .num_resources = 1,
3798 + .resource = &mcf5485_flash_resource,
3799 +};
3800 +#endif
3801 +
3802 +static int __init mcf5485_init_devices(void)
3803 +{
3804 + printk(KERN_INFO "MCF5485x INIT_DEVICES\n");
3805 +
3806 + platform_device_register(&coldfire_i2c_device);
3807 + platform_device_register(&coldfire_sec_device);
3808 +/*#if defined(CONFIG_MTD_PHYSMAP)
3809 + platform_device_register(&mcf5485_flash_device);
3810 +#endif*/
3811 + return 0;
3812 +}
3813 +arch_initcall(mcf5485_init_devices);
3814 --- /dev/null
3815 +++ b/arch/m68k/coldfire/mcf548x-pci.c
3816 @@ -0,0 +1,959 @@
3817 +/*
3818 + * ColdFire 547x/548x PCI Host Controller functions
3819 + *
3820 + * Copyright (c) 2005-2008 Freescale Semiconductor, Inc.
3821 + *
3822 + * This code is based on the 2.6.10 version of pci.c
3823 + *
3824 + * This program is free software; you can redistribute it and/or modify
3825 + * it under the terms of the GNU General Public License as published by
3826 + * the Free Software Foundation; either version 2 of the License, or
3827 + * (at your option) any later version.
3828 + *
3829 + * This program is distributed in the hope that it will be useful,
3830 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3831 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3832 + * GNU General Public License for more details.
3833 + *
3834 + * You should have received a copy of the GNU General Public License
3835 + * along with this program; if not, write to the Free Software
3836 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
3837 + */
3838 +#include <linux/kernel.h>
3839 +#include <linux/types.h>
3840 +#include <linux/init.h>
3841 +#include <linux/mm.h>
3842 +#include <linux/string.h>
3843 +#include <linux/pci.h>
3844 +#include <linux/ioport.h>
3845 +#include <linux/slab.h>
3846 +#include <linux/version.h>
3847 +#include <linux/interrupt.h>
3848 +
3849 +#include <linux/dma-mapping.h>
3850 +#include <asm/coldfire.h>
3851 +#include <asm/io.h>
3852 +#include <asm/m5485sim.h>
3853 +#include <asm/m5485pci.h>
3854 +#include <asm/irq.h>
3855 +#include <asm/pci.h>
3856 +#include <asm/virtconvert.h>
3857 +
3858 +
3859 +#undef DEBUG
3860 +//#define DEBUG
3861 +
3862 +#ifdef DEBUG
3863 +//#define DBG(x...) printk(KERN_DEBUG x)
3864 +#define DBG(x...) printk(x)
3865 +#else
3866 +#define DBG(x...)
3867 +#endif
3868 +
3869 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,75))
3870 +# define irqreturn_t void
3871 +# define IRQ_HANDLED
3872 +# define IRQ_NONE
3873 +#endif
3874 +
3875 +/*
3876 + * Bridge configration dafaults
3877 + */
3878 +#define PCI_RETRIES 0
3879 +#define PCI_CACHE_LINE 8
3880 +#define PCI_MINGNT 1
3881 +#define PCI_MAXLAT 42
3882 +
3883 +
3884 +/*
3885 + * Initiator windows setting
3886 + */
3887 +#define HOST_MEM_BASE 0xD0000000 /* ColdFire Memory window base */
3888 +#define PCI_MEM_BASE 0xD0000000 /* PCI Memory window base */
3889 +#define PCI_MEM_SIZE 0x08000000 /* Memory window size (128M) */
3890 +#define HOST_IO_BASE 0xD8000000 /* ColdFire I/O window base */
3891 +#define PCI_IO_BASE_ADDR 0x00000000 /* PCI I/O window base */