diff options
Diffstat (limited to 'target/linux/coldfire/patches/002-mcfv4e_coldfire_headers.patch')
-rw-r--r-- | target/linux/coldfire/patches/002-mcfv4e_coldfire_headers.patch | 1646 |
1 files changed, 1646 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/002-mcfv4e_coldfire_headers.patch b/target/linux/coldfire/patches/002-mcfv4e_coldfire_headers.patch new file mode 100644 index 000000000..a31b28817 --- /dev/null +++ b/target/linux/coldfire/patches/002-mcfv4e_coldfire_headers.patch @@ -0,0 +1,1646 @@ +From 127797e5cf8a036825007586b914b75897aba554 Mon Sep 17 00:00:00 2001 +From: Kurt Mahan <kmahan@freescale.com> +Date: Wed, 31 Oct 2007 16:39:31 -0600 +Subject: [PATCH] Add Coldfire Support into existing headers. + +Modifications to the various M68k header files to add +Coldfire processor support. + +LTIBName: mcfv4e-coldfire-headers +Signed-off-by: Kurt Mahan <kmahan@freescale.com> +--- + include/asm-m68k/atomic.h | 23 ++- + include/asm-m68k/bitops.h | 426 ++++++++++++++++++++++++++++++++++++++++ + include/asm-m68k/bootinfo.h | 13 ++ + include/asm-m68k/byteorder.h | 12 +- + include/asm-m68k/cacheflush.h | 4 + + include/asm-m68k/checksum.h | 10 + + include/asm-m68k/delay.h | 26 +++ + include/asm-m68k/div64.h | 4 + + include/asm-m68k/elf.h | 2 +- + include/asm-m68k/fpu.h | 2 + + include/asm-m68k/io.h | 26 +++- + include/asm-m68k/irq.h | 5 +- + include/asm-m68k/machdep.h | 7 + + include/asm-m68k/mmu_context.h | 84 ++++++++- + include/asm-m68k/page.h | 20 ++- + include/asm-m68k/page_offset.h | 7 +- + include/asm-m68k/pci.h | 99 ++++++---- + include/asm-m68k/pgalloc.h | 4 +- + include/asm-m68k/pgtable.h | 15 ++ + include/asm-m68k/processor.h | 46 ++++- + include/asm-m68k/ptrace.h | 11 + + include/asm-m68k/raw_io.h | 58 ++++++ + include/asm-m68k/segment.h | 10 + + include/asm-m68k/setup.h | 27 +++ + include/asm-m68k/signal.h | 5 + + include/asm-m68k/string.h | 2 + + include/asm-m68k/system.h | 17 ++- + include/asm-m68k/thread_info.h | 1 + + include/asm-m68k/tlbflush.h | 16 ++- + include/asm-m68k/uaccess.h | 4 + + 30 files changed, 925 insertions(+), 61 deletions(-) + +--- a/include/asm-m68k/atomic.h ++++ b/include/asm-m68k/atomic.h +@@ -2,7 +2,7 @@ + #define __ARCH_M68K_ATOMIC__ + + +-#include <asm/system.h> ++#include <asm/system.h> /* local_irq_XXX() */ + + /* + * Atomic operations that C can't guarantee us. Useful for +@@ -21,12 +21,20 @@ typedef struct { int counter; } atomic_t + + static inline void atomic_add(int i, atomic_t *v) + { ++#ifndef CONFIG_COLDFIRE + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); ++#else ++ __asm__ __volatile__("addl %1,%0" : "=m" (*v) : "d" (i), "m" (*v)); ++#endif + } + + static inline void atomic_sub(int i, atomic_t *v) + { ++#ifndef CONFIG_COLDFIRE + __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i)); ++#else ++ __asm__ __volatile__("subl %1,%0" : "=m" (*v) : "d" (i), "m" (*v)); ++#endif + } + + static inline void atomic_inc(atomic_t *v) +@@ -46,6 +54,14 @@ static inline int atomic_dec_and_test(at + return c != 0; + } + ++static __inline__ int atomic_dec_and_test_lt(volatile atomic_t *v) ++{ ++ char c; ++ __asm__ __volatile__("subql #1,%1; slt %0" : "=d" (c), "=m" (*v) ++ : "m" (*v)); ++ return c != 0 ; ++} ++ + static inline int atomic_inc_and_test(atomic_t *v) + { + char c; +@@ -156,7 +172,12 @@ static inline int atomic_sub_and_test(in + static inline int atomic_add_negative(int i, atomic_t *v) + { + char c; ++#ifndef CONFIG_COLDFIRE + __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); ++#else ++ __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "=m" (*v) ++ : "d" (i) , "m" (*v)); ++#endif + return c != 0; + } + +--- a/include/asm-m68k/bitops.h ++++ b/include/asm-m68k/bitops.h +@@ -19,6 +19,7 @@ + * + * They use the standard big-endian m680x0 bit ordering. + */ ++#ifndef CONFIG_COLDFIRE + + #define test_and_set_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ +@@ -457,4 +458,429 @@ static inline int ext2_find_next_bit(con + + #endif /* __KERNEL__ */ + ++#else /* CONFIG_COLDFIRE */ ++ ++#define test_and_set_bit(nr,vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_test_and_set_bit(nr, vaddr) : \ ++ __generic_coldfire_test_and_set_bit(nr, vaddr)) ++ ++ ++static __inline__ int __constant_coldfire_test_and_set_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ ++ __asm__ __volatile__ ("bset %2,%1; sne %0" ++ : "=d" (retval), "+QUd" (*p) ++ : "di" (nr & 7)); ++ return retval; ++} ++ ++static __inline__ int __generic_coldfire_test_and_set_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ ++ __asm__ __volatile__ ("bset %2,%1; sne %0" ++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "d" (nr) ++ : "memory"); ++ return retval; ++} ++#define __test_and_set_bit(nr, vaddr) test_and_set_bit(nr, vaddr) ++ ++#define set_bit(nr,vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_set_bit(nr, vaddr) : \ ++ __generic_coldfire_set_bit(nr, vaddr)) ++ ++static __inline__ void __constant_coldfire_set_bit(int nr, ++ volatile void *vaddr) ++{ ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ __asm__ __volatile__ ("bset %1,%0" ++ : "+QUd" (*p) : "di" (nr & 7)); ++} ++ ++static __inline__ void __generic_coldfire_set_bit(int nr, volatile void *vaddr) ++{ ++ __asm__ __volatile__ ("bset %1,%0" ++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "d" (nr) ++ : "memory"); ++} ++#define __set_bit(nr, vaddr) set_bit(nr, vaddr) ++ ++#define test_and_clear_bit(nr, vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_test_and_clear_bit(nr, vaddr) : \ ++ __generic_coldfire_test_and_clear_bit(nr, vaddr)) ++ ++static __inline__ int __constant_coldfire_test_and_clear_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ ++ __asm__ __volatile__ ("bclr %2,%1; sne %0" ++ : "=d" (retval), "+QUd" (*p) ++ : "id" (nr & 7)); ++ ++ return retval; ++} ++ ++static __inline__ int __generic_coldfire_test_and_clear_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ ++ __asm__ __volatile__ ("bclr %2,%1; sne %0" ++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "d" (nr & 7) ++ : "memory"); ++ ++ return retval; ++} ++#define __test_and_clear_bit(nr, vaddr) test_and_clear_bit(nr, vaddr) ++ ++/* ++ * clear_bit() doesn't provide any barrier for the compiler. ++ */ ++#define smp_mb__before_clear_bit() barrier() ++#define smp_mb__after_clear_bit() barrier() ++ ++#define clear_bit(nr,vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_clear_bit(nr, vaddr) : \ ++ __generic_coldfire_clear_bit(nr, vaddr)) ++ ++static __inline__ void __constant_coldfire_clear_bit(int nr, ++ volatile void *vaddr) ++{ ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ __asm__ __volatile__ ("bclr %1,%0" ++ : "+QUd" (*p) : "id" (nr & 7)); ++} ++ ++static __inline__ void __generic_coldfire_clear_bit(int nr, ++ volatile void *vaddr) ++{ ++ __asm__ __volatile__ ("bclr %1,%0" ++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "d" (nr) ++ : "memory"); ++} ++#define __clear_bit(nr, vaddr) clear_bit(nr, vaddr) ++ ++#define test_and_change_bit(nr, vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_test_and_change_bit(nr, vaddr) : \ ++ __generic_coldfire_test_and_change_bit(nr, vaddr)) ++ ++static __inline__ int __constant_coldfire_test_and_change_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ ++ __asm__ __volatile__ ("bchg %2,%1; sne %0" ++ : "=d" (retval), "+QUd" (*p) ++ : "id" (nr & 7)); ++ ++ return retval; ++} ++ ++static __inline__ int __generic_coldfire_test_and_change_bit(int nr, ++ volatile void *vaddr) ++{ ++ char retval; ++ ++ __asm__ __volatile__ ("bchg %2,%1; sne %0" ++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "id" (nr) ++ : "memory"); ++ ++ return retval; ++} ++#define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr) ++#define __change_bit(nr, vaddr) change_bit(nr, vaddr) ++ ++#define change_bit(nr,vaddr) \ ++ (__builtin_constant_p(nr) ? \ ++ __constant_coldfire_change_bit(nr, vaddr) : \ ++ __generic_coldfire_change_bit(nr, vaddr)) ++ ++static __inline__ void __constant_coldfire_change_bit(int nr, ++ volatile void *vaddr) ++{ ++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; ++ __asm__ __volatile__ ("bchg %1,%0" ++ : "+QUd" (*p) : "id" (nr & 7)); ++} ++ ++static __inline__ void __generic_coldfire_change_bit(int nr, ++ volatile void *vaddr) ++{ ++ __asm__ __volatile__ ("bchg %1,%0" ++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3]) ++ : "d" (nr) ++ : "memory"); ++} ++ ++static inline int test_bit(int nr, const unsigned long *vaddr) ++{ ++ return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; ++} ++ ++static __inline__ unsigned long ffz(unsigned long word) ++{ ++ unsigned long result = 0; ++ ++ while (word & 1) { ++ result++; ++ word >>= 1; ++ } ++ return result; ++} ++ ++/* find_next_zero_bit() finds the first zero bit in a bit string of length ++ * 'size' bits, starting the search at bit 'offset'. This is largely based ++ * on Linus's ALPHA routines. ++ */ ++static __inline__ unsigned long find_next_zero_bit(void *addr, ++ unsigned long size, unsigned long offset) ++{ ++ unsigned long *p = ((unsigned long *) addr) + (offset >> 5); ++ unsigned long result = offset & ~31UL; ++ unsigned long tmp; ++ ++ if (offset >= size) ++ return size; ++ size -= result; ++ offset &= 31UL; ++ if (offset) { ++ tmp = *(p++); ++ tmp |= ~0UL >> (32-offset); ++ if (size < 32) ++ goto found_first; ++ if (~tmp) ++ goto found_middle; ++ size -= 32; ++ result += 32; ++ } ++ while (size & ~31UL) { ++ tmp = *(p++); ++ if (~tmp) ++ goto found_middle; ++ result += 32; ++ size -= 32; ++ } ++ if (!size) ++ return result; ++ tmp = *p; ++ ++found_first: ++ tmp |= ~0UL >> size; ++found_middle: ++ return result + ffz(tmp); ++} ++ ++#define find_first_zero_bit(addr, size) find_next_zero_bit(((void *)addr), \ ++ (size), 0) ++ ++/* Ported from included/linux/bitops.h */ ++static __inline__ int ffs(int x) ++{ ++ int r = 1; ++ ++ if (!x) ++ return 0; ++ if (!(x & 0xffff)) { ++ x >>= 16; ++ r += 16; ++ } ++ if (!(x & 0xff)) { ++ x >>= 8; ++ r += 8; ++ } ++ if (!(x & 0xf)) { ++ x >>= 4; ++ r += 4; ++ } ++ if (!(x & 3)) { ++ x >>= 2; ++ r += 2; ++ } ++ if (!(x & 1)) { ++ x >>= 1; ++ r += 1; ++ } ++ return r; ++} ++#define __ffs(x) (ffs(x) - 1) ++ ++/* find_next_bit - find the next set bit in a memory region ++ * (from asm-ppc/bitops.h) ++ */ ++static __inline__ unsigned long find_next_bit(const unsigned long *addr, ++ unsigned long size, unsigned long offset) ++{ ++ unsigned int *p = ((unsigned int *) addr) + (offset >> 5); ++ unsigned int result = offset & ~31UL; ++ unsigned int tmp; ++ ++ if (offset >= size) ++ return size; ++ size -= result; ++ offset &= 31UL; ++ if (offset) { ++ tmp = *p++; ++ tmp &= ~0UL << offset; ++ if (size < 32) ++ goto found_first; ++ if (tmp) ++ goto found_middle; ++ size -= 32; ++ result += 32; ++ } ++ while (size >= 32) { ++ tmp = *p++; ++ if (tmp != 0) ++ goto found_middle; ++ result += 32; ++ size -= 32; ++ } ++ if (!size) ++ return result; ++ tmp = *p; ++ ++found_first: ++ tmp &= ~0UL >> (32 - size); ++ if (tmp == 0UL) /* Are any bits set? */ ++ return result + size; /* Nope. */ ++found_middle: ++ return result + __ffs(tmp); ++} ++ ++#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) ++ ++#ifdef __KERNEL__ ++ ++/* Ported from include/linux/bitops.h */ ++static __inline__ int fls(int x) ++{ ++ int r = 32; ++ ++ if (!x) ++ return 0; ++ if (!(x & 0xffff0000u)) { ++ x <<= 16; ++ r -= 16; ++ } ++ if (!(x & 0xff000000u)) { ++ x <<= 8; ++ r -= 8; ++ } ++ if (!(x & 0xf0000000u)) { ++ x <<= 4; ++ r -= 4; ++ } ++ if (!(x & 0xc0000000u)) { ++ x <<= 2; ++ r -= 2; ++ } ++ if (!(x & 0x80000000u)) { ++ x <<= 1; ++ r -= 1; ++ } ++ return r; ++} ++ ++#include <asm-generic/bitops/fls64.h> ++#include <asm-generic/bitops/sched.h> ++#include <asm-generic/bitops/hweight.h> ++ ++#define minix_find_first_zero_bit(addr, size) find_next_zero_bit((addr), \ ++ (size), 0) ++#define minix_test_and_set_bit(nr, addr) test_and_set_bit((nr), \ ++ (unsigned long *)(addr)) ++#define minix_set_bit(nr, addr) set_bit((nr), \ ++ (unsigned long *)(addr)) ++#define minix_test_and_clear_bit(nr, addr) test_and_clear_bit((nr), \ ++ (unsigned long *)(addr)) ++ ++static inline int minix_test_bit(int nr, const volatile unsigned long *vaddr) ++{ ++ int *a = (int *)vaddr; ++ int mask; ++ ++ a += nr >> 5; ++ mask = 1 << (nr & 0x1f); ++ return ((mask & *a) != 0); ++} ++ ++#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 24, \ ++ (unsigned long *)(addr)) ++#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, \ ++ (unsigned long *)(addr)) ++#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 24, \ ++ (unsigned long *)(addr)) ++#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, \ ++ (unsigned long *)(addr)) ++ ++static inline int ext2_test_bit(int nr, const void *vaddr) ++{ ++ const unsigned char *p = vaddr; ++ return (p[nr >> 3] & (1U << (nr & 7))) != 0; ++} ++ ++static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size) ++{ ++ const unsigned long *p = vaddr, *addr = vaddr; ++ int res; ++ ++ if (!size) ++ return 0; ++ ++ size = (size >> 5) + ((size & 31) > 0); ++ while (*p++ == ~0UL) { ++ if (--size == 0) ++ return (p - addr) << 5; ++ } ++ ++ --p; ++ for (res = 0; res < 32; res++) ++ if (!ext2_test_bit (res, p)) ++ break; ++ return (p - addr) * 32 + res; ++} ++ ++static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, ++ unsigned offset) ++{ ++ const unsigned long *addr = vaddr; ++ const unsigned long *p = addr + (offset >> 5); ++ int bit = offset & 31UL, res; ++ ++ if (offset >= size) ++ return size; ++ ++ if (bit) { ++ /* Look for zero in first longword */ ++ for (res = bit; res < 32; res++) ++ if (!ext2_test_bit (res, p)) ++ return (p - addr) * 32 + res; ++ p++; ++ } ++ /* No zero yet, search remaining full bytes for a zero */ ++ res = ext2_find_first_zero_bit(p, size - 32 * (p - addr)); ++ return (p - addr) * 32 + res; ++} ++ ++#endif /* KERNEL */ ++ ++#endif /* CONFIG_COLDFIRE */ ++ + #endif /* _M68K_BITOPS_H */ +--- a/include/asm-m68k/bootinfo.h ++++ b/include/asm-m68k/bootinfo.h +@@ -49,6 +49,19 @@ struct bi_record { + #endif /* __ASSEMBLY__ */ + + ++#ifndef __ASSEMBLY__ ++ ++struct uboot_record { ++ unsigned long bd_info; ++ unsigned long initrd_start; ++ unsigned long initrd_end; ++ unsigned long cmd_line_start; ++ unsigned long cmd_line_stop; ++}; ++ ++#endif /* __ASSEMBLY__ */ ++ ++ + /* + * Tag Definitions + * +--- a/include/asm-m68k/byteorder.h ++++ b/include/asm-m68k/byteorder.h +@@ -4,8 +4,15 @@ + #include <asm/types.h> + #include <linux/compiler.h> + +-#ifdef __GNUC__ +- ++#if defined(__GNUC__) ++#if defined(__mcfisaaplus__) || defined(__mcfisac__) ++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val) ++{ ++ __asm__ ("byterev %0" : "=d" (val) : "0" (val)); ++ return val; ++} ++#define __arch__swab32(x) ___arch__swab32(x) ++#elif !defined(__mcoldfire__) + static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val) + { + __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); +@@ -14,6 +21,7 @@ static __inline__ __attribute_const__ __ + #define __arch__swab32(x) ___arch__swab32(x) + + #endif ++#endif + + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) + # define __BYTEORDER_HAS_U64__ +--- a/include/asm-m68k/cacheflush.h ++++ b/include/asm-m68k/cacheflush.h +@@ -6,6 +6,9 @@ + /* cache code */ + #define FLUSH_I_AND_D (0x00000808) + #define FLUSH_I (0x00000008) ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_cacheflush.h> ++#else /* !CONFIG_COLDFIRE */ + + /* + * Cache handling functions +@@ -153,4 +156,5 @@ static inline void copy_from_user_page(s + memcpy(dst, src, len); + } + ++#endif /* !CONFIG_COLDFIRE */ + #endif /* _M68K_CACHEFLUSH_H */ +--- a/include/asm-m68k/checksum.h ++++ b/include/asm-m68k/checksum.h +@@ -34,6 +34,7 @@ extern __wsum csum_partial_copy_nocheck( + void *dst, int len, + __wsum sum); + ++#ifndef CONFIG_COLDFIRE /* CF has own copy in arch/m68k/lib/checksum.c */ + /* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. +@@ -59,6 +60,9 @@ static inline __sum16 ip_fast_csum(const + : "memory"); + return (__force __sum16)~sum; + } ++#else ++extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); ++#endif + + /* + * Fold a partial checksum +@@ -67,6 +71,11 @@ static inline __sum16 ip_fast_csum(const + static inline __sum16 csum_fold(__wsum sum) + { + unsigned int tmp = (__force u32)sum; ++#ifdef CONFIG_COLDFIRE ++ tmp = (tmp & 0xffff) + (tmp >> 16); ++ tmp = (tmp & 0xffff) + (tmp >> 16); ++ return (__force __sum16) ~tmp; ++#else + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" +@@ -74,6 +83,7 @@ static inline __sum16 csum_fold(__wsum s + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (tmp)); + return (__force __sum16)~sum; ++#endif + } + + +--- a/include/asm-m68k/delay.h ++++ b/include/asm-m68k/delay.h +@@ -11,8 +11,25 @@ + + static inline void __delay(unsigned long loops) + { ++#if defined(CONFIG_COLDFIRE) ++ /* The coldfire runs this loop at significantly different speeds ++ * depending upon long word alignment or not. We'll pad it to ++ * long word alignment which is the faster version. ++ * The 0x4a8e is of course a 'tstl %fp' instruction. This is better ++ * than using a NOP (0x4e71) instruction because it executes in one ++ * cycle not three and doesn't allow for an arbitary delay waiting ++ * for bus cycles to finish. Also fp/a6 isn't likely to cause a ++ * stall waiting for the register to become valid if such is added ++ * to the coldfire at some stage. ++ */ ++ __asm__ __volatile__ (".balignw 4, 0x4a8e\n\t" ++ "1: subql #1, %0\n\t" ++ "jcc 1b" ++ : "=d" (loops) : "0" (loops)); ++#else + __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" + : "=d" (loops) : "0" (loops)); ++#endif + } + + extern void __bad_udelay(void); +@@ -26,12 +43,17 @@ extern void __bad_udelay(void); + */ + static inline void __const_udelay(unsigned long xloops) + { ++#if defined(CONFIG_COLDFIRE) ++ ++ __delay(((((unsigned long long) xloops * loops_per_jiffy))>>32)*HZ); ++#else + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1" + : "=d" (xloops), "=d" (tmp) + : "d" (xloops), "1" (loops_per_jiffy)); + __delay(xloops * HZ); ++#endif + } + + static inline void __udelay(unsigned long usecs) +@@ -46,12 +68,16 @@ static inline void __udelay(unsigned lon + static inline unsigned long muldiv(unsigned long a, unsigned long b, + unsigned long c) + { ++#if defined(CONFIG_COLDFIRE) ++ return (long)(((unsigned long long)a * b)/c); ++#else + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1; divul %3,%0:%1" + : "=d" (tmp), "=d" (a) + : "d" (b), "d" (c), "1" (a)); + return a; ++#endif + } + + #endif /* defined(_M68K_DELAY_H) */ +--- a/include/asm-m68k/div64.h ++++ b/include/asm-m68k/div64.h +@@ -5,6 +5,7 @@ + + /* n = n / base; return rem; */ + ++#ifndef CONFIG_COLDFIRE + #define do_div(n, base) ({ \ + union { \ + unsigned long n32[2]; \ +@@ -24,6 +25,9 @@ + (n) = __n.n64; \ + __rem; \ + }) ++#else ++# include <asm-generic/div64.h> ++#endif + + extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); + #endif /* _M68K_DIV64_H */ +--- a/include/asm-m68k/elf.h ++++ b/include/asm-m68k/elf.h +@@ -60,7 +60,7 @@ typedef struct user_m68kfp_struct elf_fp + #define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 + + #define USE_ELF_CORE_DUMP +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + #define ELF_EXEC_PAGESIZE 4096 + #else + #define ELF_EXEC_PAGESIZE 8192 +--- a/include/asm-m68k/fpu.h ++++ b/include/asm-m68k/fpu.h +@@ -12,6 +12,8 @@ + #define FPSTATESIZE (96/sizeof(unsigned char)) + #elif defined(CONFIG_M68KFPU_EMU) + #define FPSTATESIZE (28/sizeof(unsigned char)) ++#elif defined(CONFIG_CFV4E) ++#define FPSTATESIZE (16/sizeof(unsigned char)) + #elif defined(CONFIG_M68060) + #define FPSTATESIZE (12/sizeof(unsigned char)) + #else +--- a/include/asm-m68k/io.h ++++ b/include/asm-m68k/io.h +@@ -397,10 +397,12 @@ static inline void memcpy_toio(volatile + __builtin_memcpy((void __force *) dst, src, count); + } + +-#ifndef CONFIG_SUN3 +-#define IO_SPACE_LIMIT 0xffff +-#else ++#if defined(CONFIG_SUN3) + #define IO_SPACE_LIMIT 0x0fffffff ++#elif defined(CONFIG_COLDFIRE) ++#define IO_SPACE_LIMIT 0xffffffff ++#else ++#define IO_SPACE_LIMIT 0xffff + #endif + + #endif /* __KERNEL__ */ +@@ -418,4 +420,22 @@ static inline void memcpy_toio(volatile + */ + #define xlate_dev_kmem_ptr(p) p + ++#ifdef CONFIG_COLDFIRE ++ ++#define memset_io(a, b, c) memset((void *)(a), (b), (c)) ++#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) ++#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) ++#if !defined(readb) ++#define readb(addr) \ ++ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) ++#define readw(addr) \ ++ ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) ++#define readl(addr) \ ++ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) ++#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b)) ++#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b)) ++#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b)) ++#endif /* readb */ ++#endif /* CONFIG_COLDFIRE */ ++ + #endif /* _IO_H */ +--- a/include/asm-m68k/irq.h ++++ b/include/asm-m68k/irq.h +@@ -11,7 +11,10 @@ + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +-#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) ++#if defined(CONFIG_COLDFIRE) ++#define SYS_IRQS 256 ++#define NR_IRQS SYS_IRQS ++#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) + #define NR_IRQS 200 + #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) + #define NR_IRQS 72 +--- a/include/asm-m68k/machdep.h ++++ b/include/asm-m68k/machdep.h +@@ -32,4 +32,11 @@ extern void (*mach_heartbeat) (int); + extern void (*mach_l2_flush) (int); + extern void (*mach_beep) (unsigned int, unsigned int); + ++#ifdef CONFIG_COLDFIRE ++extern void __init config_coldfire(void); ++extern void __init mmu_context_init(void); ++extern irq_handler_t mach_default_handler; ++extern void (*mach_tick)(void); ++#endif ++ + #endif /* _M68K_MACHDEP_H */ +--- a/include/asm-m68k/mmu_context.h ++++ b/include/asm-m68k/mmu_context.h +@@ -7,7 +7,7 @@ static inline void enter_lazy_tlb(struct + { + } + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + + #include <asm/setup.h> + #include <asm/page.h> +@@ -102,7 +102,7 @@ static inline void activate_mm(struct mm + switch_mm_0460(next_mm); + } + +-#else /* CONFIG_SUN3 */ ++#elif defined(CONFIG_SUN3) + #include <asm/sun3mmu.h> + #include <linux/sched.h> + +@@ -150,5 +150,83 @@ static inline void activate_mm(struct mm + activate_context(next_mm); + } + +-#endif ++#else /* CONFIG_COLDFIRE */ ++ ++#include <asm/atomic.h> ++#include <asm/bitops.h> ++#include <asm/mmu.h> ++ ++#define NO_CONTEXT 256 ++#define LAST_CONTEXT 255 ++#define FIRST_CONTEXT 1 ++ ++extern void set_context(mm_context_t context, pgd_t *pgd); ++extern unsigned long context_map[]; ++extern mm_context_t next_mmu_context; ++ ++extern atomic_t nr_free_contexts; ++extern struct mm_struct *context_mm[LAST_CONTEXT+1]; ++extern void steal_context(void); ++ ++static inline void get_mmu_context(struct mm_struct *mm) ++{ ++ mm_context_t ctx; ++ ++ if (mm->context != NO_CONTEXT) ++ return; ++ while (atomic_dec_and_test_lt(&nr_free_contexts)) { ++ atomic_inc(&nr_free_contexts); ++ steal_context(); ++ } ++ ctx = next_mmu_context; ++ while (test_and_set_bit(ctx, context_map)) { ++ ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx); ++ if (ctx > LAST_CONTEXT) ++ ctx = 0; ++ } ++ next_mmu_context = (ctx + 1) & LAST_CONTEXT; ++ mm->context = ctx; ++ context_mm[ctx] = mm; ++} ++ ++/* ++ * Set up the context for a new address space. ++ */ ++#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0) ++ ++/* ++ * We're finished using the context for an address space. ++ */ ++static inline void destroy_context(struct mm_struct *mm) ++{ ++ if (mm->context != NO_CONTEXT) { ++ clear_bit(mm->context, context_map); ++ mm->context = NO_CONTEXT; ++ atomic_inc(&nr_free_contexts); ++ } ++} ++ ++static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ++ struct task_struct *tsk) ++{ ++ get_mmu_context(tsk->mm); ++ set_context(tsk->mm->context, next->pgd); ++} ++ ++/* ++ * After we have set current->mm to a new value, this activates ++ * the context for the new mm so we see the new mappings. ++ */ ++static inline void activate_mm(struct mm_struct *active_mm, ++ struct mm_struct *mm) ++{ ++ get_mmu_context(mm); ++ set_context(mm->context, mm->pgd); ++} ++ ++#define deactivate_mm(tsk, mm) do { } while (0) ++ ++extern void mmu_context_init(void); ++ ++#endif /* CONFIG_COLDFIRE */ + #endif +--- a/include/asm-m68k/page.h ++++ b/include/asm-m68k/page.h +@@ -4,7 +4,7 @@ + #include <linux/const.h> + + /* PAGE_SHIFT determines the page size */ +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + #define PAGE_SHIFT (12) + #else + #define PAGE_SHIFT (13) +@@ -116,10 +116,23 @@ typedef struct page *pgtable_t; + + extern unsigned long m68k_memoffset; + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) + + #define WANT_PAGE_VIRTUAL + ++#if defined(CONFIG_COLDFIRE) ++static inline unsigned long ___pa(void *vaddr) ++{ ++ return (((unsigned long)vaddr & 0x0fffffff) + CONFIG_SDRAM_BASE); ++} ++#define __pa(vaddr) ___pa((void *)(vaddr)) ++ ++static inline void *__va(unsigned long paddr) ++{ ++ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET); ++} ++ ++#else + static inline unsigned long ___pa(void *vaddr) + { + unsigned long paddr; +@@ -141,6 +154,7 @@ static inline void *__va(unsigned long p + : "0" (paddr), "i" (m68k_fixup_memoffset)); + return vaddr; + } ++#endif + + #else /* !CONFIG_SUN3 */ + /* This #define is a horrible hack to suppress lots of warnings. --m */ +@@ -172,6 +186,8 @@ static inline void *__va(unsigned long x + * memory node, but we have no highmem, so that works for now. + * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots + * of the shifts unnecessary. ++ * ++ * PFNs are used to map physical pages. So PFN[0] maps to the base phys addr. + */ + #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) + #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +--- a/include/asm-m68k/page_offset.h ++++ b/include/asm-m68k/page_offset.h +@@ -1,8 +1,11 @@ + + /* This handles the memory map.. */ +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + #define PAGE_OFFSET_RAW 0x00000000 +-#else ++#elif defined(CONFIG_SUN3) + #define PAGE_OFFSET_RAW 0x0E000000 ++#else /* CONFIG_COLDFIRE */ ++#define PAGE_OFFSET_RAW 0xC0000000 ++#define PHYS_OFFSET 0x40000000 + #endif + +--- a/include/asm-m68k/pci.h ++++ b/include/asm-m68k/pci.h +@@ -1,57 +1,86 @@ +-#ifndef _ASM_M68K_PCI_H +-#define _ASM_M68K_PCI_H +- + /* +- * asm-m68k/pci_m68k.h - m68k specific PCI declarations. ++ * asm-m68k/pci.h - m68k specific PCI declarations. + * +- * Written by Wout Klaren. ++ * Coldfire Implementation Copyright (c) 2007 Freescale Semiconductor, Inc. ++ * Kurt Mahan <kmahan@freescale.com> + */ ++#ifndef _ASM_M68K_PCI_H ++#define _ASM_M68K_PCI_H + +-#include <asm/scatterlist.h> ++#ifdef CONFIG_PCI + +-struct pci_ops; ++#include <asm-generic/pci-dma-compat.h> + + /* +- * Structure with hardware dependent information and functions of the +- * PCI bus. ++ * The PCI address space does equal the physical memory ++ * address space. The networking and block device layers use ++ * this boolean for bounce buffer decisions. + */ ++#define PCI_DMA_BUS_IS_PHYS (1) + +-struct pci_bus_info +-{ +- /* +- * Resources of the PCI bus. +- */ +- +- struct resource mem_space; +- struct resource io_space; ++#define PCIBIOS_MIN_IO 0x00004000 ++#define PCIBIOS_MIN_MEM 0x02000000 + +- /* +- * System dependent functions. +- */ ++#define pcibios_assign_all_busses() 0 ++#define pcibios_scan_all_fns(a, b) 0 + +- struct pci_ops *m68k_pci_ops; ++static inline void ++pcibios_set_master(struct pci_dev *dev) ++{ ++ /* no special bus mastering setup handling */ ++} + +- void (*fixup)(int pci_modify); +- void (*conf_device)(struct pci_dev *dev); +-}; ++static inline void ++pcibios_penalize_isa_irq(int irq, int active) ++{ ++ /* no dynamic PCI IRQ allocation */ ++} + +-#define pcibios_assign_all_busses() 0 +-#define pcibios_scan_all_fns(a, b) 0 ++static inline void ++pcibios_add_platform_entries(struct pci_dev *dev) ++{ ++ /* no special handling */ ++} + +-static inline void pcibios_set_master(struct pci_dev *dev) ++static inline void ++pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, ++ struct resource *res) + { +- /* No special bus mastering setup handling */ ++#ifdef CONFIG_M54455 ++ if ((res->start == 0xa0000000) || (res->start == 0xa8000000)) { ++ /* HACK! FIX! kludge to fix bridge mapping */ ++ region->start = res->start & 0x0fffffff; ++ region->end = res->end & 0x0fffffff; ++ } else { ++ region->start = res->start; ++ region->end = res->end; ++ } ++#else ++ region->start = res->start; ++ region->end = res->end; ++#endif + } + +-static inline void pcibios_penalize_isa_irq(int irq, int active) ++static inline void ++pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, ++ struct pci_bus_region *region) + { +- /* We don't do dynamic PCI IRQ allocation */ ++ res->start = region->start; ++ res->end = region->end; + } + +-/* The PCI address space does equal the physical memory +- * address space. The networking and block device layers use +- * this boolean for bounce buffer decisions. +- */ +-#define PCI_DMA_BUS_IS_PHYS (1) ++static inline struct resource * ++pcibios_select_root(struct pci_dev *pdev, struct resource *res) ++{ ++ struct resource *root = NULL; ++ ++ if (res->flags & IORESOURCE_IO) ++ root = &ioport_resource; ++ if (res->flags & IORESOURCE_MEM) ++ root = &iomem_resource; ++ ++ return root; ++} + ++#endif /* CONFIG_PCI */ + #endif /* _ASM_M68K_PCI_H */ +--- a/include/asm-m68k/pgalloc.h ++++ b/include/asm-m68k/pgalloc.h +@@ -8,8 +8,10 @@ + #include <asm/virtconvert.h> + + +-#ifdef CONFIG_SUN3 ++#if defined(CONFIG_SUN3) + #include <asm/sun3_pgalloc.h> ++#elif defined(CONFIG_COLDFIRE) ++#include <asm/cf_pgalloc.h> + #else + #include <asm/motorola_pgalloc.h> + #endif +--- a/include/asm-m68k/pgtable.h ++++ b/include/asm-m68k/pgtable.h +@@ -40,6 +40,8 @@ + /* PGDIR_SHIFT determines what a third-level page table entry can map */ + #ifdef CONFIG_SUN3 + #define PGDIR_SHIFT 17 ++#elif defined(CONFIG_COLDFIRE) ++#define PGDIR_SHIFT 22 + #else + #define PGDIR_SHIFT 25 + #endif +@@ -54,6 +56,10 @@ + #define PTRS_PER_PTE 16 + #define PTRS_PER_PMD 1 + #define PTRS_PER_PGD 2048 ++#elif defined(CONFIG_COLDFIRE) ++#define PTRS_PER_PTE 512 ++#define PTRS_PER_PMD 1 ++#define PTRS_PER_PGD 1024 + #else + #define PTRS_PER_PTE 1024 + #define PTRS_PER_PMD 8 +@@ -66,6 +72,9 @@ + #ifdef CONFIG_SUN3 + #define KMAP_START 0x0DC00000 + #define KMAP_END 0x0E000000 ++#elif defined(CONFIG_COLDFIRE) ++#define KMAP_START 0xe0000000 ++#define KMAP_END 0xf0000000 + #else + #define KMAP_START 0xd0000000 + #define KMAP_END 0xf0000000 +@@ -130,6 +139,8 @@ static inline void update_mmu_cache(stru + + #ifdef CONFIG_SUN3 + #include <asm/sun3_pgtable.h> ++#elif defined(CONFIG_COLDFIRE) ++#include <asm/cf_pgtable.h> + #else + #include <asm/motorola_pgtable.h> + #endif +@@ -140,6 +151,9 @@ static inline void update_mmu_cache(stru + /* + * Macro to mark a page protection value as "uncacheable". + */ ++#ifdef CONFIG_COLDFIRE ++# define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | CF_PAGE_NOCACHE)) ++#else /* CONFIG_COLDFIRE */ + #ifdef SUN3_PAGE_NOCACHE + # define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE + #else +@@ -154,6 +168,7 @@ static inline void update_mmu_cache(stru + ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ + : (prot))) + ++#endif /* CONFIG_COLDFIRE */ + #endif /* !__ASSEMBLY__ */ + + /* +--- a/include/asm-m68k/processor.h ++++ b/include/asm-m68k/processor.h +@@ -22,24 +22,38 @@ static inline unsigned long rdusp(void) + { + unsigned long usp; + ++#ifndef CONFIG_COLDFIRE + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); ++#else ++ __asm__ __volatile__("movel %/usp,%0" : "=a" (usp)); ++#endif + return usp; + } + + static inline void wrusp(unsigned long usp) + { ++#ifndef CONFIG_COLDFIRE + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); ++#else ++ __asm__ __volatile__("movel %0,%/usp" : : "a" (usp)); ++#endif + } + + /* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + #define TASK_SIZE (0xF0000000UL) ++#elif defined(CONFIG_COLDFIRE) ++#define TASK_SIZE (0xC0000000UL) ++#else /* CONFIG_SUN3 */ ++#ifdef __ASSEMBLY__ ++#define TASK_SIZE (0x0E000000) + #else + #define TASK_SIZE (0x0E000000UL) + #endif ++#endif + + #ifdef __KERNEL__ + #define STACK_TOP TASK_SIZE +@@ -49,9 +63,11 @@ static inline void wrusp(unsigned long u + /* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +-#ifndef CONFIG_SUN3 +-#define TASK_UNMAPPED_BASE 0xC0000000UL +-#else ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) ++#define TASK_UNMAPPED_BASE 0xC0000000UL ++#elif defined(CONFIG_COLDFIRE) ++#define TASK_UNMAPPED_BASE 0x80000000UL ++#else /* CONFIG_SUN3 */ + #define TASK_UNMAPPED_BASE 0x0A000000UL + #endif + #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) +@@ -60,7 +76,11 @@ struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ ++#ifndef CONFIG_COLDFIRE + unsigned short fs; /* saved fs (sfc, dfc) */ ++#else ++ mm_segment_t fs; ++#endif + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long faddr; /* info about last fault */ +@@ -81,6 +101,7 @@ struct thread_struct { + /* + * Do necessary setup to start up a newly executed thread. + */ ++#ifndef CONFIG_COLDFIRE + static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) + { +@@ -91,6 +112,23 @@ static inline void start_thread(struct p + regs->sr &= ~0x2000; + wrusp(usp); + } ++#else ++/* ++ * Do necessary setup to start up a newly executed thread. ++ * ++ * pass the data segment into user programs if it exists, ++ * it can't hurt anything as far as I can tell ++ */ ++#define start_thread(_regs, _pc, _usp) \ ++do { \ ++ set_fs(USER_DS); /* reads from user space */ \ ++ (_regs)->pc = (_pc); \ ++ if (current->mm) \ ++ (_regs)->d5 = current->mm->start_data; \ ++ (_regs)->sr &= ~0x2000; \ ++ wrusp(_usp); \ ++} while (0) ++#endif + + /* Forward declaration, a strange C thing */ + struct task_struct; +--- a/include/asm-m68k/ptrace.h ++++ b/include/asm-m68k/ptrace.h +@@ -38,10 +38,21 @@ struct pt_regs { + long d0; + long orig_d0; + long stkadj; ++#ifndef CONFIG_COLDFIRE + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ ++#else ++ unsigned long mmuar; ++ unsigned long mmusr; ++ unsigned format : 4; /* frame format specifier */ ++ unsigned fs2 : 2; ++ unsigned vector: 8; ++ unsigned fs1 : 2; ++ unsigned short sr; ++ unsigned long pc; ++#endif + }; + + /* +--- a/include/asm-m68k/raw_io.h ++++ b/include/asm-m68k/raw_io.h +@@ -77,6 +77,7 @@ static inline void raw_outsb(volatile u8 + out_8(port, *buf++); + } + ++#ifndef CONFIG_COLDFIRE + static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) + { + unsigned int tmp; +@@ -342,6 +343,63 @@ static inline void raw_outsw_swapw(volat + : "d0", "a0", "a1", "d6"); + } + ++ ++#else /*CONFIG_COLDFIRE */ ++ ++static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++) ++ *buf++ = raw_inw(port); ++} ++ ++static inline void raw_outsw(volatile u16 *port, const u16 *buf, ++ unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++, buf++) ++ raw_outw(*buf, port); ++} ++ ++static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++) ++ *buf++ = raw_inl(port); ++} ++ ++static inline void raw_outsl(volatile u32 *port, const u32 *buf, ++ unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++, buf++) ++ raw_outl(*buf, port); ++} ++ ++static inline void raw_insw_swapw(volatile u16 *port, u16 *buf, ++ unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++) ++ *buf++ = in_le16(port); ++ ++} ++ ++static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, ++ unsigned int nr) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < nr; i++, buf++) ++ out_le16(port, *buf); ++} ++#endif /*CONFIG_COLDFIRE */ ++ + #endif /* __KERNEL__ */ + + #endif /* _RAW_IO_H */ +--- a/include/asm-m68k/segment.h ++++ b/include/asm-m68k/segment.h +@@ -29,6 +29,7 @@ typedef struct { + * Get/set the SFC/DFC registers for MOVES instructions + */ + ++#ifndef CONFIG_COLDFIRE + static inline mm_segment_t get_fs(void) + { + mm_segment_t _v; +@@ -50,6 +51,15 @@ static inline void set_fs(mm_segment_t v + : /* no outputs */ : "r" (val.seg) : "memory"); + } + ++#else /* CONFIG_COLDFIRE */ ++ ++#include <asm/current.h> ++#define get_fs() (current->thread.fs) ++#define set_fs(val) (current->thread.fs = (val)) ++#define get_ds() (KERNEL_DS) ++ ++#endif /* CONFIG_COLDFIRE */ ++ + #define segment_eq(a,b) ((a).seg == (b).seg) + + #endif /* __ASSEMBLY__ */ +--- a/include/asm-m68k/setup.h ++++ b/include/asm-m68k/setup.h +@@ -40,6 +40,7 @@ + #define MACH_HP300 9 + #define MACH_Q40 10 + #define MACH_SUN3X 11 ++#define MACH_CFMMU 12 + + #define COMMAND_LINE_SIZE 256 + +@@ -189,6 +190,14 @@ extern unsigned long m68k_machtype; + # define MACH_TYPE (MACH_SUN3X) + #endif + ++#if !defined(CONFIG_COLDFIRE) ++# define MACH_IS_COLDFIRE (0) ++#else ++# define CONFIG_COLDFIRE_ONLY ++# define MACH_IS_COLDFIRE (1) ++# define MACH_TYPE (MACH_CFMMU) ++#endif ++ + #ifndef MACH_TYPE + # define MACH_TYPE (m68k_machtype) + #endif +@@ -211,23 +220,31 @@ extern unsigned long m68k_machtype; + #define CPUB_68030 1 + #define CPUB_68040 2 + #define CPUB_68060 3 ++#define CPUB_CFV4E 4 + + #define CPU_68020 (1<<CPUB_68020) + #define CPU_68030 (1<<CPUB_68030) + #define CPU_68040 (1<<CPUB_68040) + #define CPU_68060 (1<<CPUB_68060) ++#define CPU_CFV4E (1<<CPUB_CFV4E) + + #define FPUB_68881 0 + #define FPUB_68882 1 + #define FPUB_68040 2 /* Internal FPU */ + #define FPUB_68060 3 /* Internal FPU */ + #define FPUB_SUNFPA 4 /* Sun-3 FPA */ ++#define FPUB_CFV4E 5 + + #define FPU_68881 (1<<FPUB_68881) + #define FPU_68882 (1<<FPUB_68882) + #define FPU_68040 (1<<FPUB_68040) + #define FPU_68060 (1<<FPUB_68060) + #define FPU_SUNFPA (1<<FPUB_SUNFPA) ++#ifndef CONFIG_M54455 ++#define FPU_CFV4E (1<<FPUB_CFV4E) ++#else ++#define FPU_CFV4E 0 ++#endif + + #define MMUB_68851 0 + #define MMUB_68030 1 /* Internal MMU */ +@@ -235,6 +252,7 @@ extern unsigned long m68k_machtype; + #define MMUB_68060 3 /* Internal MMU */ + #define MMUB_APOLLO 4 /* Custom Apollo */ + #define MMUB_SUN3 5 /* Custom Sun-3 */ ++#define MMUB_CFV4E 6 + + #define MMU_68851 (1<<MMUB_68851) + #define MMU_68030 (1<<MMUB_68030) +@@ -242,6 +260,7 @@ extern unsigned long m68k_machtype; + #define MMU_68060 (1<<MMUB_68060) + #define MMU_SUN3 (1<<MMUB_SUN3) + #define MMU_APOLLO (1<<MMUB_APOLLO) ++#define MMU_CFV4E (1<<MMUB_CFV4E) + + #ifdef __KERNEL__ + +@@ -341,6 +360,14 @@ extern int m68k_is040or060; + # endif + #endif + ++#if !defined(CONFIG_CFV4E) ++# define CPU_IS_COLDFIRE (0) ++#else ++# define CPU_IS_COLDFIRE (1) ++# define CPU_IS_CFV4E (1) ++# define MMU_IS_CFV4E (1) ++#endif ++ + #define CPU_TYPE (m68k_cputype) + + #ifdef CONFIG_M68KFPU_EMU +--- a/include/asm-m68k/signal.h ++++ b/include/asm-m68k/signal.h +@@ -150,6 +150,7 @@ typedef struct sigaltstack { + #ifdef __KERNEL__ + #include <asm/sigcontext.h> + ++#ifndef CONFIG_COLDFIRE + #define __HAVE_ARCH_SIG_BITOPS + + static inline void sigaddset(sigset_t *set, int _sig) +@@ -200,6 +201,10 @@ static inline int sigfindinword(unsigned + + struct pt_regs; + extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); ++#else ++ ++#define ptrace_signal_deliver(regs, cookie) do { } while (0) ++#endif /* CONFIG_COLDFIRE */ + + #endif /* __KERNEL__ */ + +--- a/include/asm-m68k/string.h ++++ b/include/asm-m68k/string.h +@@ -93,6 +93,7 @@ static inline char *strchr(const char *s + return (char *)s - 1; + } + ++#ifndef CONFIG_COLDFIRE + #define __HAVE_ARCH_STRCMP + static inline int strcmp(const char *cs, const char *ct) + { +@@ -110,6 +111,7 @@ static inline int strcmp(const char *cs, + : "+a" (cs), "+a" (ct), "=d" (res)); + return res; + } ++#endif + + #define __HAVE_ARCH_MEMSET + extern void *memset(void *, int, __kernel_size_t); +--- a/include/asm-m68k/system.h ++++ b/include/asm-m68k/system.h +@@ -63,16 +63,25 @@ asmlinkage void resume(void); + #define smp_read_barrier_depends() ((void)0) + + /* interrupt control.. */ +-#if 0 +-#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") +-#else + #include <linux/hardirq.h> ++#ifndef CONFIG_COLDFIRE + #define local_irq_enable() ({ \ + if (MACH_IS_Q40 || !hardirq_count()) \ + asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \ + }) +-#endif + #define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") ++#else /* CONFIG_COLDFIRE */ ++#define local_irq_enable() \ ++ asm volatile ("move.w %%sr, %%d0\n\t" \ ++ "andil #0xf8ff,%%d0\n\t" \ ++ "move.w %%d0, %%sr\n" \ ++ : : : "cc", "d0", "memory") ++#define local_irq_disable() \ ++ asm volatile ("move %/sr,%%d0\n\t" \ ++ "ori.l #0x0700,%%d0\n\t" \ ++ "move %%d0,%/sr\n" \ ++ : : : "cc", "%d0", "memory") ++#endif + #define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") + #define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") + +--- a/include/asm-m68k/thread_info.h ++++ b/include/asm-m68k/thread_info.h +@@ -58,5 +58,6 @@ struct thread_info { + #define TIF_DELAYED_TRACE 14 /* single step a syscall */ + #define TIF_SYSCALL_TRACE 15 /* syscall trace active */ + #define TIF_MEMDIE 16 ++#define TIF_FREEZE 17 /* freezing processes */ + + #endif /* _ASM_M68K_THREAD_INFO_H */ +--- a/include/asm-m68k/tlbflush.h ++++ b/include/asm-m68k/tlbflush.h +@@ -2,7 +2,7 @@ + #define _M68K_TLBFLUSH_H + + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + + #include <asm/current.h> + +@@ -92,7 +92,12 @@ static inline void flush_tlb_kernel_rang + flush_tlb_all(); + } + +-#else ++static inline void flush_tlb_pgtables(struct mm_struct *mm, ++ unsigned long start, unsigned long end) ++{ ++} ++ ++#elif defined(CONFIG_SUN3) + + + /* Reserved PMEGs. */ +@@ -214,6 +219,13 @@ static inline void flush_tlb_kernel_page + sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); + } + ++static inline void flush_tlb_pgtables(struct mm_struct *mm, ++ unsigned long start, unsigned long end) ++{ ++} ++ ++#else /* CONFIG_COLDFIRE */ ++#include <asm/cf_tlbflush.h> + #endif + + #endif /* _M68K_TLBFLUSH_H */ +--- a/include/asm-m68k/uaccess.h ++++ b/include/asm-m68k/uaccess.h +@@ -1,6 +1,9 @@ + #ifndef __M68K_UACCESS_H + #define __M68K_UACCESS_H + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_uaccess.h> ++#else + /* + * User space memory access functions + */ +@@ -367,4 +370,5 @@ unsigned long __clear_user(void __user * + + #define strlen_user(str) strnlen_user(str, 32767) + ++#endif /* CONFIG_COLDFIRE */ + #endif /* _M68K_UACCESS_H */ |