diff options
Diffstat (limited to 'target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch')
-rw-r--r-- | target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch | 4000 |
1 files changed, 4000 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch b/target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch new file mode 100644 index 000000000..269d13c05 --- /dev/null +++ b/target/linux/coldfire/patches-2.6.31/001-coldfire_support.patch @@ -0,0 +1,4000 @@ +--- a/arch/m68k/include/asm/atomic_mm.h ++++ b/arch/m68k/include/asm/atomic_mm.h +@@ -20,12 +20,20 @@ + + 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) +@@ -45,6 +53,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; +@@ -155,7 +171,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/arch/m68k/include/asm/bitops_mm.h ++++ b/arch/m68k/include/asm/bitops_mm.h +@@ -8,6 +8,10 @@ + * for more details. + */ + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_bitops.h> ++#else ++ + #ifndef _LINUX_BITOPS_H + #error only <linux/bitops.h> can be included directly + #endif +@@ -461,4 +465,6 @@ static inline int ext2_find_next_bit(con + + #endif /* __KERNEL__ */ + ++#endif /* CONFIG_COLDFIRE */ ++ + #endif /* _M68K_BITOPS_H */ +--- a/arch/m68k/include/asm/bootinfo.h ++++ b/arch/m68k/include/asm/bootinfo.h +@@ -25,6 +25,51 @@ + #define _M68K_BOOTINFO_H + + ++#ifndef __ASSEMBLY__ ++/* ++ * UBoot Support ++ * ++ * bd_info structure from uboot1.3.2/arch/m68k/include/asm/u-boot.h ++ */ ++ ++struct bd_info { ++ unsigned long bi_memstart; /* start of DRAM memory */ ++ unsigned long bi_memsize; /* size of DRAM memory in bytes */ ++ unsigned long bi_flashstart; /* start of FLASH memory */ ++ unsigned long bi_flashsize; /* size of FLASH memory */ ++ unsigned long bi_flashoffset; /* reserved area for startup monitor */ ++ unsigned long bi_sramstart; /* start of SRAM memory */ ++ unsigned long bi_sramsize; /* size of SRAM memory */ ++ unsigned long bi_mbar_base; /* base of internal registers */ ++ unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ ++ unsigned long bi_boot_params; /* where this board expects params */ ++ unsigned long bi_ip_addr; /* IP Address */ ++ unsigned char bi_enet0addr[6]; /* Ethernet 0 mac address */ ++ unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ ++ unsigned long bi_intfreq; /* Internal Freq, in MHz */ ++ unsigned long bi_busfreq; /* Bus Freq, in MHz */ ++#ifdef UBOOT_EXTRA_CLOCK ++ unsigned long bi_inpfreq; /* input Freq in MHz */ ++ unsigned long bi_vcofreq; /* vco Freq in MHz */ ++ unsigned long bi_flbfreq; /* Flexbus Freq in MHz */ ++#endif ++ unsigned long bi_baudrate; /* Console Baudrate */ ++ unsigned char bi_enet1addr[6]; /* eth1 mac address */ ++ unsigned char bi_enet2addr[6]; /* eth2 mac address */ ++ unsigned char bi_enet3addr[6]; /* eth3 mac address */ ++}; ++ ++struct uboot_record { ++ struct bd_info *bdi; ++ unsigned long initrd_start; ++ unsigned long initrd_end; ++ unsigned long cmd_line_start; ++ unsigned long cmd_line_stop; ++}; ++ ++#endif /* __ASSEMBLY__ */ ++ ++ + /* + * Bootinfo definitions + * +--- a/arch/m68k/include/asm/cacheflush_mm.h ++++ b/arch/m68k/include/asm/cacheflush_mm.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/arch/m68k/include/asm/checksum_mm.h ++++ b/arch/m68k/include/asm/checksum_mm.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/arch/m68k/include/asm/coldfire.h ++++ b/arch/m68k/include/asm/coldfire.h +@@ -5,6 +5,9 @@ + * + * (C) Copyright 1999-2006, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo (www.lineo.com) ++ * ++ * Shrek Wu b16972@freescale.com ++ * Copyright Freescale Semiconductor, Inc. 2009 + */ + + /****************************************************************************/ +@@ -19,25 +22,78 @@ + * here. Also the peripheral clock (bus clock) divide ratio is set + * at config time too. + */ ++/*FIXME Jason*/ ++#if 0 + #ifdef CONFIG_CLOCK_SET + #define MCF_CLK CONFIG_CLOCK_FREQ + #define MCF_BUSCLK (CONFIG_CLOCK_FREQ / CONFIG_CLOCK_DIV) + #else + #error "Don't know what your ColdFire CPU clock frequency is??" + #endif ++#endif ++ ++ ++#define MCF_CLK CONFIG_MCFCLK ++#define MCF_BUSCLK (CONFIG_MCFCLK/2) ++ ++ ++#if defined(CONFIG_M520x) ++#define MCF_IPSBAR 0xFC000000 ++#else ++#define MCF_IPSBAR 0x40000000 ++#endif + ++#if defined(CONFIG_M5445X) ++#define MCF_MBAR 0x0 ++/* ++ * Even though RAMBAR1 macro should be in the 0x8xxxxxxx range, ++ * here set the CONFIG_SDRAM_BASE value to it to use ++ * SDRAM memory, not SRAM memory. ++ */ ++#define MCF_RAMBAR1 (CONFIG_SDRAM_BASE) ++#elif defined(CONFIG_M547X_8X) ++#define MCF_MBAR 0xF0000000 ++#define MCF_MMUBAR 0xF1000000 ++#define MCF_RAMBAR0 0xF3000000 ++#define MCF_RAMBAR1 0xF3001000 ++#else + /* + * Define the processor support peripherals base address. + * This is generally setup by the boards start up code. + */ + #define MCF_MBAR 0x10000000 + #define MCF_MBAR2 0x80000000 +-#if defined(CONFIG_M520x) +-#define MCF_IPSBAR 0xFC000000 +-#else +-#define MCF_IPSBAR 0x40000000 + #endif + ++#ifdef __ASSEMBLY__ ++#define REG32 ++#define REG16 ++#define REG08 ++#else /* __ASSEMBLY__ */ ++#define REG32(x) ((volatile unsigned long *)(x)) ++#define REG16(x) ((volatile unsigned short *)(x)) ++#define REG08(x) ((volatile unsigned char *)(x)) ++ ++#define MCF_REG32(x) *(volatile unsigned long *)(MCF_MBAR+(x)) ++#define MCF_REG16(x) *(volatile unsigned short *)(MCF_MBAR+(x)) ++#define MCF_REG08(x) *(volatile unsigned char *)(MCF_MBAR+(x)) ++ ++void cacr_set(unsigned long); ++unsigned long cacr_get(void); ++ ++#define coldfire_enable_irq0(irq) MCF_INTC0_CIMR = (irq); ++ ++#define coldfire_enable_irq1(irq) MCF_INTC1_CIMR = (irq); ++ ++#define coldfire_disable_irq0(irq) MCF_INTC0_SIMR = (irq); ++ ++#define coldfire_disable_irq1(irq) MCF_INTC1_SIMR = (irq); ++ ++#define getiprh() MCF_INTC0_IPRH ++ ++#endif /* __ASSEMBLY__ */ ++ ++ + #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) + #undef MCF_MBAR +--- a/arch/m68k/include/asm/delay_mm.h ++++ b/arch/m68k/include/asm/delay_mm.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/arch/m68k/include/asm/div64.h ++++ b/arch/m68k/include/asm/div64.h +@@ -1,7 +1,7 @@ + #ifndef _M68K_DIV64_H + #define _M68K_DIV64_H + +-#ifdef CONFIG_MMU ++#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) + + #include <linux/types.h> + +--- a/arch/m68k/include/asm/dma_mm.h ++++ b/arch/m68k/include/asm/dma_mm.h +@@ -4,13 +4,126 @@ + + /* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ ++/*#ifdef CONFIG_COLDFIRE*/ ++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X) ++#define MAX_DMA_ADDRESS 0xefffffff ++#else + #define MAX_DMA_ADDRESS PAGE_OFFSET ++#endif + ++#ifndef CONFIG_COLDFIRE + #define MAX_DMA_CHANNELS 8 + + extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ + extern void free_dma(unsigned int dmanr); /* release it again */ + ++#else /* not (defined(CONFIG_MCF5474) || defined(CONFIG_MCF5484) ++ || defined(CONFIG_MCF5475) || defined(CONFIG_MCF5485)) */ ++/************************************************ ++ * Multichannel DMA definitions * ++ ************************************************/ ++#ifdef CONFIG_MCD_DMA ++#include <asm/MCD_dma.h> ++#include <asm/m5485dma.h> ++ ++struct scatterlist; ++ ++#define MAX_DMA_CHANNELS NCHANNELS ++/* ++ * identifiers for each initiator/requestor ++ */ ++#define DMA_ALWAYS (0) ++#define DMA_DSPI_RX (1) ++#define DMA_DSPI_TX (2) ++#define DMA_DREQ0 (3) ++#define DMA_PSC0_RX (4) ++#define DMA_PSC0_TX (5) ++#define DMA_USBEP0 (6) ++#define DMA_USBEP1 (7) ++#define DMA_USBEP2 (8) ++#define DMA_USBEP3 (9) ++#define DMA_PCI_TX (10) ++#define DMA_PCI_RX (11) ++#define DMA_PSC1_RX (12) ++#define DMA_PSC1_TX (13) ++#define DMA_I2C_RX (14) ++#define DMA_I2C_TX (15) ++#define DMA_FEC0_RX (16) ++#define DMA_FEC0_TX (17) ++#define DMA_FEC1_RX (18) ++#define DMA_FEC1_TX (19) ++#define DMA_DREQ1 (20) ++#define DMA_CTM0 (21) ++#define DMA_CTM1 (22) ++#define DMA_CTM2 (23) ++#define DMA_CTM3 (24) ++#define DMA_CTM4 (25) ++#define DMA_CTM5 (26) ++#define DMA_CTM6 (27) ++#define DMA_CTM7 (28) ++#define DMA_USBEP4 (29) ++#define DMA_USBEP5 (30) ++#define DMA_USBEP6 (31) ++#define DMA_PSC2_RX (32) ++#define DMA_PSC2_TX (33) ++#define DMA_PSC3_RX (34) ++#define DMA_PSC3_TX (35) ++#define DMA_FEC_RX(x) ((x == 0) ? DMA_FEC0_RX : DMA_FEC1_RX) ++#define DMA_FEC_TX(x) ((x == 0) ? DMA_FEC0_TX : DMA_FEC1_TX) ++ ++int dma_set_initiator(int); ++unsigned int dma_get_initiator(int); ++void dma_remove_initiator(int); ++int dma_set_channel(int); ++int dma_get_channel(int); ++void dma_remove_channel(int); ++int dma_set_channel_fec(int requestor); ++int dma_connect(int channel, int address); ++int dma_disconnect(int channel); ++void dma_remove_channel_by_number(int channel); ++int dma_init(void); ++#endif /* CONFIG_MCD_DMA */ ++ ++extern spinlock_t dma_spin_lock; ++ ++static __inline__ unsigned long claim_dma_lock(void) ++{ ++ unsigned long flags; ++ spin_lock_irqsave(&dma_spin_lock, flags); ++ return flags; ++} ++ ++static __inline__ void release_dma_lock(unsigned long flags) ++{ ++ spin_unlock_irqrestore(&dma_spin_lock, flags); ++} ++ ++ ++/* ++ * Linux standard DMA stuff ++ */ ++#if 0 ++int request_dma(unsigned int channel, const char * device_id); ++void free_dma(unsigned int channel); ++void enable_dma(unsigned int channel); ++void disable_dma(unsigned int channel); ++int dma_channel_active(unsigned int channel); ++void set_dma_sg(unsigned int channel, struct scatterlist *sg, int nr_sg); ++void set_dma_page(unsigned int channel, char pagenr); ++void set_dma_addr(unsigned int channel, unsigned long physaddr); ++void set_dma_count(unsigned int channel, unsigned long count); ++void set_dma_mode(unsigned int channel, unsigned int mode); ++void set_dma_speed(unsigned int channel, int cycle_ns); ++int get_dma_residue(unsigned int channel); ++#endif ++#define clear_dma_ff(channel) ++ ++#endif ++ ++#ifdef CONFIG_PCI ++extern int isa_dma_bridge_buggy; ++#else + #define isa_dma_bridge_buggy (0) ++#endif + + #endif /* _M68K_DMA_H */ +--- a/arch/m68k/include/asm/elf.h ++++ b/arch/m68k/include/asm/elf.h +@@ -35,6 +35,27 @@ + #define R_68K_JMP_SLOT 21 + #define R_68K_RELATIVE 22 + ++/* TLS static relocations */ ++#define R_68K_TLS_GD32 25 ++#define R_68K_TLS_GD16 26 ++#define R_68K_TLS_GD8 27 ++#define R_68K_TLS_LDM32 28 ++#define R_68K_TLS_LDM16 29 ++#define R_68K_TLS_LDM8 30 ++#define R_68K_TLS_LDO32 31 ++#define R_68K_TLS_LDO16 32 ++#define R_68K_TLS_LDO8 33 ++#define R_68K_TLS_IE32 34 ++#define R_68K_TLS_IE16 35 ++#define R_68K_TLS_IE8 36 ++#define R_68K_TLS_LE32 37 ++#define R_68K_TLS_LE16 38 ++#define R_68K_TLS_LE8 39 ++/* TLS dynamic relocations */ ++#define R_68K_TLS_DTPMOD32 40 ++#define R_68K_TLS_DTPREL32 41 ++#define R_68K_TLS_TPREL32 42 ++ + typedef unsigned long elf_greg_t; + + #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +@@ -60,7 +81,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 +@@ -71,8 +92,10 @@ typedef struct user_m68kfp_struct elf_fp + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + #define ELF_ET_DYN_BASE 0xD0000000UL ++#elif defined(CONFIG_COLDFIRE) ++#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x10000000) + #else + #define ELF_ET_DYN_BASE 0x0D800000UL + #endif +@@ -116,4 +139,35 @@ typedef struct user_m68kfp_struct elf_fp + + #define SET_PERSONALITY(ex) set_personality(PER_LINUX) + ++/* ++ * VDSO ++ */ ++#ifdef CONFIG_VDSO ++extern unsigned int vdso_enabled; ++ ++#define VDSO_BASE ((unsigned long)current->mm->context.vdso) ++#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) ++ ++#define VDSO_AUX_ENT \ ++ if (vdso_enabled) \ ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); ++ ++/* additional pages */ ++#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 ++ ++struct linux_binprm; ++extern int arch_setup_additional_pages(struct linux_binprm *bprm, ++ int executable_stack); ++ ++#else ++/* no VDSO_AUX_ENT */ ++#define VDSO_AUX_ENT ++#endif ++ ++#define ARCH_DLINFO \ ++do { \ ++ /* vdso entry */ \ ++ VDSO_AUX_ENT; \ ++} while (0); ++ + #endif +--- a/arch/m68k/include/asm/io_mm.h ++++ b/arch/m68k/include/asm/io_mm.h +@@ -7,17 +7,24 @@ + * - added skeleton for GG-II and Amiga PCMCIA + * 2/3/01 RZ: - moved a few more defs into raw_io.h + * +- * inX/outX should not be used by any driver unless it does +- * ISA access. Other drivers should use function defined in raw_io.h ++ * inX/outX/readX/writeX should not be used by any driver unless it does ++ * ISA or PCI access. Other drivers should use function defined in raw_io.h + * or define its own macros on top of these. + * +- * inX(),outX() are for ISA I/O ++ * inX(),outX() are for PCI and ISA I/O ++ * readX(),writeX() are for PCI memory + * isa_readX(),isa_writeX() are for ISA memory ++ * ++ * moved mem{cpy,set}_*io inside CONFIG_PCI + */ + + #ifndef _IO_H + #define _IO_H + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_io.h> ++#else ++ + #ifdef __KERNEL__ + + #include <linux/compiler.h> +@@ -88,20 +95,20 @@ extern unsigned long gg2_isa_base; + #undef MULTI_ISA + #endif + +-#define ISA_TYPE_Q40 (1) +-#define ISA_TYPE_GG2 (2) +-#define ISA_TYPE_AG (3) ++#define Q40_ISA (1) ++#define GG2_ISA (2) ++#define AG_ISA (3) + + #if defined(CONFIG_Q40) && !defined(MULTI_ISA) +-#define ISA_TYPE ISA_TYPE_Q40 ++#define ISA_TYPE Q40_ISA + #define ISA_SEX 0 + #endif + #if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) +-#define ISA_TYPE ISA_TYPE_AG ++#define ISA_TYPE AG_ISA + #define ISA_SEX 1 + #endif + #if defined(CONFIG_GG2) && !defined(MULTI_ISA) +-#define ISA_TYPE ISA_TYPE_GG2 ++#define ISA_TYPE GG2_ISA + #define ISA_SEX 0 + #endif + +@@ -123,13 +130,13 @@ static inline u8 __iomem *isa_itb(unsign + switch(ISA_TYPE) + { + #ifdef CONFIG_Q40 +- case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr); ++ case Q40_ISA: return (u8 __iomem *)Q40_ISA_IO_B(addr); + #endif + #ifdef CONFIG_GG2 +- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr); ++ case GG2_ISA: return (u8 __iomem *)GG2_ISA_IO_B(addr); + #endif + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr); ++ case AG_ISA: return (u8 __iomem *)AG_ISA_IO_B(addr); + #endif + default: return NULL; /* avoid warnings, just in case */ + } +@@ -139,13 +146,13 @@ static inline u16 __iomem *isa_itw(unsig + switch(ISA_TYPE) + { + #ifdef CONFIG_Q40 +- case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr); ++ case Q40_ISA: return (u16 __iomem *)Q40_ISA_IO_W(addr); + #endif + #ifdef CONFIG_GG2 +- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr); ++ case GG2_ISA: return (u16 __iomem *)GG2_ISA_IO_W(addr); + #endif + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr); ++ case AG_ISA: return (u16 __iomem *)AG_ISA_IO_W(addr); + #endif + default: return NULL; /* avoid warnings, just in case */ + } +@@ -155,7 +162,7 @@ static inline u32 __iomem *isa_itl(unsig + switch(ISA_TYPE) + { + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: return (u32 __iomem *)AG_ISA_IO_W(addr); ++ case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr); + #endif + default: return 0; /* avoid warnings, just in case */ + } +@@ -165,13 +172,13 @@ static inline u8 __iomem *isa_mtb(unsign + switch(ISA_TYPE) + { + #ifdef CONFIG_Q40 +- case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr); ++ case Q40_ISA: return (u8 __iomem *)Q40_ISA_MEM_B(addr); + #endif + #ifdef CONFIG_GG2 +- case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr); ++ case GG2_ISA: return (u8 __iomem *)GG2_ISA_MEM_B(addr); + #endif + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: return (u8 __iomem *)addr; ++ case AG_ISA: return (u8 __iomem *)addr; + #endif + default: return NULL; /* avoid warnings, just in case */ + } +@@ -181,13 +188,13 @@ static inline u16 __iomem *isa_mtw(unsig + switch(ISA_TYPE) + { + #ifdef CONFIG_Q40 +- case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr); ++ case Q40_ISA: return (u16 __iomem *)Q40_ISA_MEM_W(addr); + #endif + #ifdef CONFIG_GG2 +- case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr); ++ case GG2_ISA: return (u16 __iomem *)GG2_ISA_MEM_W(addr); + #endif + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: return (u16 __iomem *)addr; ++ case AG_ISA: return (u16 __iomem *)addr; + #endif + default: return NULL; /* avoid warnings, just in case */ + } +@@ -201,30 +208,29 @@ static inline u16 __iomem *isa_mtw(unsig + #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) + #define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) + +-#define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) +-#define isa_readw(p) \ +- (ISA_SEX ? in_be16(isa_mtw((unsigned long)(p))) \ +- : in_le16(isa_mtw((unsigned long)(p)))) +-#define isa_writeb(val,p) out_8(isa_mtb((unsigned long)(p)),(val)) +-#define isa_writew(val,p) \ +- (ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val)) \ +- : out_le16(isa_mtw((unsigned long)(p)),(val))) +- ++#define isa_readb(p) in_8(isa_mtb(p)) ++#define isa_readw(p) (ISA_SEX ? in_be16(isa_mtw(p)) : in_le16(isa_mtw(p))) ++#define isa_writeb(val,p) out_8(isa_mtb(p),(val)) ++#define isa_writew(val,p) (ISA_SEX ? out_be16(isa_mtw(p),(val)) : out_le16(isa_mtw(p),(val))) + static inline void isa_delay(void) + { +- switch(ISA_TYPE) +- { ++ switch (ISA_TYPE) { + #ifdef CONFIG_Q40 +- case ISA_TYPE_Q40: isa_outb(0,0x80); break; ++ case Q40_ISA: ++ isa_outb(0, 0x80); ++ break; + #endif + #ifdef CONFIG_GG2 +- case ISA_TYPE_GG2: break; ++ case GG2_ISA: ++ break; + #endif + #ifdef CONFIG_AMIGA_PCMCIA +- case ISA_TYPE_AG: break; ++ case AG_ISA: ++ break; + #endif +- default: break; /* avoid warnings */ +- } ++ default: ++ break; /* avoid warnings */ ++ } + } + + #define isa_inb_p(p) ({u8 v=isa_inb(p);isa_delay();v;}) +@@ -253,7 +259,10 @@ static inline void isa_delay(void) + (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ + raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) + ++#endif /* CONFIG_ISA */ + ++ ++#if defined(CONFIG_ISA) && !defined(CONFIG_PCI) + #define inb isa_inb + #define inb_p isa_inb_p + #define outb isa_outb +@@ -276,9 +285,80 @@ static inline void isa_delay(void) + #define readw isa_readw + #define writeb isa_writeb + #define writew isa_writew ++#endif /* CONFIG_ISA */ ++ ++#if defined(CONFIG_PCI) ++ ++#define readl(addr) in_le32(addr) ++#define writel(val, addr) out_le32((addr), (val)) ++ ++/* those can be defined for both ISA and PCI - it won't work though */ ++#define readb(addr) in_8(addr) ++#define readw(addr) in_le16(addr) ++#define writeb(val, addr) out_8((addr), (val)) ++#define writew(val, addr) out_le16((addr), (val)) ++ ++#define readb_relaxed(addr) readb(addr) ++#define readw_relaxed(addr) readw(addr) ++#define readl_relaxed(addr) readl(addr) ++ ++#ifndef CONFIG_ISA ++#define inb(port) in_8(port) ++#define outb(val, port) out_8((port), (val)) ++#define inw(port) in_le16(port) ++#define outw(val, port) out_le16((port), (val)) ++#define inl(port) in_le32(port) ++#define outl(val, port) out_le32((port), (val)) ++#define insb(port, buf, nr) \ ++ raw_insb((u8 *)(port), (u8 *)(buf), (nr)) ++#define outsb(port, buf, nr) \ ++ raw_outsb((u8 *)(port), (u8 *)(buf), (nr)) ++#define insw(port, buf, nr) \ ++ raw_insw_swapw((u16 *)(port), (u16 *)(buf), (nr)) ++#define outsw(port, buf, nr) \ ++ raw_outsw_swapw((u16 *)(port), (u16 *)(buf), (nr)) ++#define insl(port, buf, nr) \ ++ raw_insw_swapw((u16 *)(port), (u16 *)(buf), (nr)<<1) ++#define outsl(port, buf, nr) \ ++ raw_outsw_swapw((u16 *)(port), (u16 *)(buf), (nr)<<1) ++ ++#define __raw_readb readb ++#define __raw_readw readw ++#define __raw_readl readl ++#define __raw_writeb writeb ++#define __raw_writew writew ++#define __raw_writel writel + +-#else /* CONFIG_ISA */ ++#else ++/* ++ * kernel with both ISA and PCI compiled in, those have ++ * conflicting defs for in/out. Simply consider port < 1024 ++ * ISA and everything else PCI. read,write not defined ++ * in this case ++ */ ++#define inb(port) ((port) < 1024 ? isa_inb(port) : in_8(port)) ++#define inb_p(port) ((port) < 1024 ? isa_inb_p(port) : in_8(port)) ++#define inw(port) ((port) < 1024 ? isa_inw(port) : in_le16(port)) ++#define inw_p(port) ((port) < 1024 ? isa_inw_p(port) : in_le16(port)) ++#define inl(port) ((port) < 1024 ? isa_inl(port) : in_le32(port)) ++#define inl_p(port) ((port) < 1024 ? isa_inl_p(port) : in_le32(port)) ++ ++#define outb(val, port) (((port) < 1024) ? isa_outb((val), (port)) ++ : out_8((port), (val))) ++#define outb_p(val, port) (((port) < 1024) ? isa_outb_p((val), (port)) ++ : out_8((port), (val))) ++#define outw(val, port) (((port) < 1024) ? isa_outw((val), (port)) ++ : out_le16((port), (val))) ++#define outw_p(val, port) (((port) < 1024) ? isa_outw_p((val), (port)) ++ : out_le16((port), (val))) ++#define outl(val, port) (((port) < 1024) ? isa_outl((val), (port)) ++ : out_le32((port), (val))) ++#define outl_p(val, port) (((port) < 1024) ? isa_outl_p((val), (port)) ++ : out_le32((port), (val))) ++#endif ++#endif /* CONFIG_PCI */ + ++#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) + /* + * We need to define dummy functions for GENERIC_IOMAP support. + */ +@@ -305,11 +385,11 @@ static inline void isa_delay(void) + #define writeb(val,addr) out_8((addr),(val)) + #define readw(addr) in_le16(addr) + #define writew(val,addr) out_le16((addr),(val)) +- +-#endif /* CONFIG_ISA */ +- ++#endif ++#if !defined(CONFIG_PCI) + #define readl(addr) in_le32(addr) + #define writel(val,addr) out_le32((addr),(val)) ++#endif + + #define mmiowb() + +@@ -345,10 +425,10 @@ 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 ++#else ++#define IO_SPACE_LIMIT 0xffff + #endif + + #endif /* __KERNEL__ */ +@@ -366,4 +446,5 @@ static inline void memcpy_toio(volatile + */ + #define xlate_dev_kmem_ptr(p) p + ++#endif /* CONFIG_COLDFIRE */ + #endif /* _IO_H */ +--- a/arch/m68k/include/asm/irq_mm.h ++++ b/arch/m68k/include/asm/irq_mm.h +@@ -12,7 +12,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/arch/m68k/include/asm/machdep_mm.h ++++ b/arch/m68k/include/asm/machdep_mm.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/arch/m68k/include/asm/mcfsim.h ++++ b/arch/m68k/include/asm/mcfsim.h +@@ -39,6 +39,25 @@ + #include <asm/m5407sim.h> + #endif + ++#if defined(CONFIG_COLDFIRE) ++#include <asm/coldfire.h> ++#endif ++ ++#if defined(CONFIG_M5445X) ++#include <asm/mcf5445x_intc.h> ++#include <asm/mcf5445x_gpio.h> ++#include <asm/mcf5445x_ccm.h> ++#include <asm/mcf5445x_eport.h> ++#include <asm/mcf5445x_fbcs.h> ++#include <asm/mcf5445x_xbs.h> ++#include <asm/mcf5445x_dtim.h> ++#include <asm/mcf5445x_rtc.h> ++#include <asm/mcf5445x_scm.h> ++#elif defined(CONFIG_M547X_8X) ++#include <asm/m5485sim.h> ++#include <asm/m5485gpio.h> ++#include <asm/m5485gpt.h> ++#endif + + /* + * Define the base address of the SIM within the MBAR address space. +--- a/arch/m68k/include/asm/mmu_context.h ++++ b/arch/m68k/include/asm/mmu_context.h +@@ -8,7 +8,7 @@ static inline void enter_lazy_tlb(struct + } + + #ifdef CONFIG_MMU +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + + #include <asm/setup.h> + #include <asm/page.h> +@@ -103,7 +103,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> + +@@ -151,7 +151,179 @@ static inline void activate_mm(struct mm + activate_context(next_mm); + } + ++#else /* CONFIG_COLDFIRE */ ++ ++#include <asm/coldfire.h> ++#include <asm/atomic.h> ++#include <asm/bitops.h> ++#include <asm/mmu.h> ++ ++#define NO_CONTEXT 256 ++#define LAST_CONTEXT 255 ++#define FIRST_CONTEXT 1 ++ ++#ifdef CONFIG_VDSO ++#define cpu_context(mm) ((mm)->context.id) ++#else ++#define cpu_context(mm) ((mm)->context) ++#endif ++ ++#ifdef CONFIG_VDSO ++extern void set_context(unsigned long context, pgd_t *pgd); ++#else ++extern void set_context(mm_context_t context, pgd_t *pgd); ++#endif ++extern unsigned long context_map[]; ++#ifdef CONFIG_VDSO ++extern unsigned long next_mmu_context; ++#else ++extern mm_context_t next_mmu_context; ++#endif ++ ++ ++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) ++{ ++#ifdef CONFIG_VDSO ++ unsigned long ctx; ++#else ++ mm_context_t ctx; + #endif ++ ++ if (cpu_context(mm) != 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; ++ cpu_context(mm) = ctx; ++ context_mm[ctx] = mm; ++} ++ ++/* ++ * Set up the context for a new address space. ++ */ ++#define init_new_context(tsk, mm) ((cpu_context(mm) = NO_CONTEXT), 0) ++/* #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 (cpu_context(mm) != NO_CONTEXT) { ++ clear_bit(cpu_context(mm), context_map); ++ cpu_context(mm) = 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(cpu_context(tsk->mm), 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(cpu_context(mm), mm->pgd); ++} ++ ++#define deactivate_mm(tsk, mm) do { } while (0) ++ ++extern void mmu_context_init(void); ++#if defined(CONFIG_M547X_8X) ++#define prepare_arch_switch(next) load_ksp_mmu(next) ++ ++static inline void load_ksp_mmu(struct task_struct *task) ++{ ++ int flags; ++ struct mm_struct *mm; ++ int asid; ++ pgd_t *pgd; ++ pmd_t *pmd; ++ pte_t *pte; ++ unsigned long mmuar; ++ ++ local_irq_save(flags); ++ mmuar = task->thread.ksp; ++ ++ /* Search for a valid TLB entry, if one is found, don't remap */ ++ *MMUAR = mmuar; ++ *MMUOR = MMUOR_STLB | MMUOR_ADR; ++ if ((*MMUSR) & MMUSR_HIT) ++ goto end; ++ ++ if (mmuar >= PAGE_OFFSET) { ++ mm = &init_mm; ++ } else { ++ printk(KERN_INFO "load_ksp_mmu: non-kernel" ++ " mm found: 0x%08x\n", (unsigned int) task->mm); ++ mm = task->mm; ++ } ++ ++ if (!mm) ++ goto bug; ++ ++ pgd = pgd_offset(mm, mmuar); ++ if (pgd_none(*pgd)) ++ goto bug; ++ ++ pmd = pmd_offset(pgd, mmuar); ++ if (pmd_none(*pmd)) ++ goto bug; ++ ++ pte = (mmuar >= PAGE_OFFSET) ? pte_offset_kernel(pmd, mmuar) ++ : pte_offset_map(pmd, mmuar); ++ if (pte_none(*pte) || !pte_present(*pte)) ++ goto bug; ++ ++ set_pte(pte, pte_mkyoung(*pte)); ++ asid = cpu_context(mm) & 0xff; ++ if (!pte_dirty(*pte) && mmuar <= PAGE_OFFSET) ++ set_pte(pte, pte_wrprotect(*pte)); ++ ++ *MMUTR = (mmuar & PAGE_MASK) | (asid << CF_ASID_MMU_SHIFT) ++ | (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK) ++ >> CF_PAGE_MMUTR_SHIFT) ++ | MMUTR_V; ++ ++ *MMUDR = (pte_val(*pte) & PAGE_MASK) ++ | ((pte->pte) & CF_PAGE_MMUDR_MASK) ++ | MMUDR_SZ8K | MMUDR_X; ++ ++ *MMUOR = MMUOR_ACC | MMUOR_UAA; ++ asm ("nop"); ++ ++ goto end; ++ ++bug: ++ printk(KERN_ERR "ksp load failed: mm=0x%08x ksp=0x%08x\n", ++ (unsigned int) mm, (unsigned int) mmuar); ++end: ++ local_irq_restore(flags); ++} ++#endif /* CONFIG_M547X_8X */ ++ ++#endif /* CONFIG_COLDFIRE */ ++ + #else /* !CONFIG_MMU */ + + static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +--- a/arch/m68k/include/asm/page_mm.h ++++ b/arch/m68k/include/asm/page_mm.h +@@ -1,10 +1,15 @@ + #ifndef _M68K_PAGE_H + #define _M68K_PAGE_H + ++/*#if defined(CONFIG_COLDFIRE)*/ ++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X) ++#include <asm/cf_page.h> ++#else ++ + #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) +@@ -113,10 +118,31 @@ 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) ++{ ++#if CONFIG_SDRAM_BASE != PAGE_OFFSET ++ return (((unsigned long)vaddr & 0x0fffffff) + CONFIG_SDRAM_BASE); ++#else ++ return (unsigned long)vaddr; ++#endif ++} ++#define __pa(vaddr) ___pa((void *)(vaddr)) ++ ++static inline void *__va(unsigned long paddr) ++{ ++#if CONFIG_SDRAM_BASE != PAGE_OFFSET ++ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET); ++#else ++ return (void *)paddr; ++#endif ++} ++ ++#else + static inline unsigned long ___pa(void *vaddr) + { + unsigned long paddr; +@@ -138,6 +164,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 */ +@@ -169,6 +196,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) +@@ -225,4 +254,10 @@ static inline __attribute_const__ int __ + + #include <asm-generic/getorder.h> + ++#ifdef CONFIG_VDSO ++/* vDSO support */ ++#define __HAVE_ARCH_GATE_AREA ++#endif ++ ++#endif /* !CONFIG_COLDFIRE */ + #endif /* _M68K_PAGE_H */ +--- a/arch/m68k/include/asm/page_offset.h ++++ b/arch/m68k/include/asm/page_offset.h +@@ -1,10 +1,13 @@ + /* This handles the memory map.. */ + + #ifdef CONFIG_MMU +-#ifndef CONFIG_SUN3 +-#define PAGE_OFFSET_RAW 0x00000000 +-#else ++#if defined(CONFIG_SUN3) + #define PAGE_OFFSET_RAW 0x0E000000 ++#elif defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X) ++#define PHYS_OFFSET CONFIG_SDRAM_BASE ++#define PAGE_OFFSET_RAW (PHYS_OFFSET) ++#else ++#define PAGE_OFFSET_RAW 0x00000000 + #endif + #else + #define PAGE_OFFSET_RAW CONFIG_RAMBASE +--- a/arch/m68k/include/asm/pgalloc.h ++++ b/arch/m68k/include/asm/pgalloc.h +@@ -7,8 +7,10 @@ + + #ifdef CONFIG_MMU + #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/arch/m68k/include/asm/pgtable_mm.h ++++ b/arch/m68k/include/asm/pgtable_mm.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,11 @@ + #ifdef CONFIG_SUN3 + #define KMAP_START 0x0DC00000 + #define KMAP_END 0x0E000000 ++#elif defined(CONFIG_COLDFIRE) ++#define VMALLOC_START 0xc0000000 ++#define VMALLOC_END 0xcfffffff ++#define KMAP_START (VMALLOC_END + 1) ++#define KMAP_END 0xe8000000 + #else + #define KMAP_START 0xd0000000 + #define KMAP_END 0xf0000000 +@@ -79,9 +90,11 @@ + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ ++#if !defined(CONFIG_COLDFIRE) + #define VMALLOC_OFFSET (8*1024*1024) + #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) + #define VMALLOC_END KMAP_START ++#endif + #else + extern unsigned long vmalloc_end; + #define VMALLOC_START 0x0f800000 +@@ -130,6 +143,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 +@@ -138,6 +153,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 +@@ -152,6 +170,7 @@ static inline void update_mmu_cache(stru + ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ + : (prot))) + ++#endif /* CONFIG_COLDFIRE */ + #include <asm-generic/pgtable.h> + #endif /* !__ASSEMBLY__ */ + +--- a/arch/m68k/include/asm/processor_mm.h ++++ b/arch/m68k/include/asm/processor_mm.h +@@ -2,6 +2,7 @@ + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald ++ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + + #ifndef __ASM_M68K_PROCESSOR_H +@@ -22,24 +23,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 +64,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 0x60000000UL ++#else /* CONFIG_SUN3 */ + #define TASK_UNMAPPED_BASE 0x0A000000UL + #endif + #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) +@@ -60,7 +77,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 +102,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 +113,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/arch/m68k/include/asm/ptrace.h ++++ b/arch/m68k/include/asm/ptrace.h +@@ -39,10 +39,21 @@ struct pt_regs { + long orig_d0; + long stkadj; + #ifdef CONFIG_COLDFIRE ++#if 0 + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ + unsigned short sr; + unsigned long pc; ++#endif ++/*FROM BSP*/ ++ 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; + #else + unsigned short sr; + unsigned long pc; +@@ -71,6 +82,8 @@ struct switch_stack { + #define PTRACE_GETFPREGS 14 + #define PTRACE_SETFPREGS 15 + ++#define PTRACE_GET_THREAD_AREA 25 ++ + #ifdef __KERNEL__ + + #ifndef PS_S +--- a/arch/m68k/include/asm/raw_io.h ++++ b/arch/m68k/include/asm/raw_io.h +@@ -8,6 +8,10 @@ + #ifndef _RAW_IO_H + #define _RAW_IO_H + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_raw_io.h> ++#else ++ + #ifdef __KERNEL__ + + #include <asm/types.h> +@@ -60,6 +64,9 @@ extern void __iounmap(void *addr, unsign + #define __raw_writew(val,addr) out_be16((addr),(val)) + #define __raw_writel(val,addr) out_be32((addr),(val)) + ++#define swap_inw(port) in_le16((port)) ++#define swap_outw(val,port) out_le16((port),(val)) ++ + static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) + { + unsigned int i; +@@ -344,4 +351,6 @@ static inline void raw_outsw_swapw(volat + + #endif /* __KERNEL__ */ + ++#endif /* CONFIG_COLDFIRE */ ++ + #endif /* _RAW_IO_H */ +--- a/arch/m68k/include/asm/segment.h ++++ b/arch/m68k/include/asm/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) + { + #ifdef CONFIG_MMU +@@ -56,6 +57,15 @@ static inline void set_fs(mm_segment_t v + #endif + } + ++#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/arch/m68k/include/asm/setup.h ++++ b/arch/m68k/include/asm/setup.h +@@ -2,6 +2,7 @@ + ** asm/setup.h -- Definition of the Linux/m68k setup information + ** + ** Copyright 1992 by Greg Harp ++ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + ** + ** This file is subject to the terms and conditions of the GNU General Public + ** License. See the file COPYING in the main directory of this archive +@@ -40,6 +41,7 @@ + #define MACH_HP300 9 + #define MACH_Q40 10 + #define MACH_SUN3X 11 ++#define MACH_CFMMU 12 + + #define COMMAND_LINE_SIZE 256 + +@@ -189,6 +191,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 +221,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) ++#ifdef CONFIG_M547X_8X ++#define FPU_CFV4E (1<<FPUB_CFV4E) ++#else ++#define FPU_CFV4E 0 ++#endif + + #define MMUB_68851 0 + #define MMUB_68030 1 /* Internal MMU */ +@@ -235,6 +253,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 +261,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 +361,14 @@ extern int m68k_is040or060; + # endif + #endif + ++#if !defined(CONFIG_CFV4E) ++# define CPU_IS_COLDFIRE (0) ++#else ++# define CPU_IS_COLDFIRE (m68k_cputype & CPU_CFV4E) ++# define CPU_IS_CFV4E (m68k_cputype & CPU_CFV4E) ++# define MMU_IS_CFV4E (m68k_mmutype & MMU_CFV4E) ++#endif ++ + #define CPU_TYPE (m68k_cputype) + + #ifdef CONFIG_M68KFPU_EMU +@@ -371,6 +399,14 @@ extern int m68k_realnum_memory; /* real + extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ + #endif + ++#ifdef CONFIG_CFV4E ++#define QCHIP_RESTORE_DIRECTIVE ".chip 547x" ++#define CHIP_RESTORE_DIRECTIVE .chip 547x ++#else ++#define QCHIP_RESTORE_DIRECTIVE ".chip 68k" ++#define CHIP_RESTORE_DIRECTIVE .chip 68k ++#endif ++ + #endif /* __KERNEL__ */ + + #endif /* _M68K_SETUP_H */ +--- a/arch/m68k/include/asm/sigcontext.h ++++ b/arch/m68k/include/asm/sigcontext.h +@@ -15,9 +15,15 @@ struct sigcontext { + unsigned long sc_pc; + unsigned short sc_formatvec; + #ifndef __uClinux__ ++# ifdef __mcoldfire__ ++ unsigned long sc_fpregs[2][2]; /* room for two fp registers */ ++ unsigned long sc_fpcntl[3]; ++ unsigned char sc_fpstate[16+6*8]; ++# else + unsigned long sc_fpregs[2*3]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[216]; ++# endif + #endif + }; + +--- a/arch/m68k/include/asm/siginfo.h ++++ b/arch/m68k/include/asm/siginfo.h +@@ -29,7 +29,8 @@ typedef struct siginfo { + struct { + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ +- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; ++ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int) ++ + sizeof(__kernel_uid_t)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; +@@ -38,18 +39,18 @@ typedef struct siginfo { + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ +- sigval_t _sigval; + __kernel_uid32_t _uid32; /* sender's uid */ ++ sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + __kernel_pid_t _pid; /* which child */ + __kernel_uid_t _uid; /* backwards compatibility */ +- int _status; /* exit code */ ++ __kernel_uid32_t _uid32; /* sender's uid */ + clock_t _utime; + clock_t _stime; +- __kernel_uid32_t _uid32; /* sender's uid */ ++ int _status; /* exit code */ + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ +--- a/arch/m68k/include/asm/signal.h ++++ b/arch/m68k/include/asm/signal.h +@@ -150,7 +150,8 @@ typedef struct sigaltstack { + #ifdef __KERNEL__ + #include <asm/sigcontext.h> + +-#ifndef __uClinux__ ++//#ifndef __uClinux__ ++#ifndef CONFIG_COLDFIRE /*FIXME Jason*/ + #define __HAVE_ARCH_SIG_BITOPS + + static inline void sigaddset(sigset_t *set, int _sig) +@@ -201,7 +202,6 @@ static inline int sigfindinword(unsigned + + struct pt_regs; + extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +- + #else + + #undef __HAVE_ARCH_SIG_BITOPS +--- a/arch/m68k/include/asm/string_mm.h ++++ b/arch/m68k/include/asm/string_mm.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/arch/m68k/include/asm/swab.h ++++ b/arch/m68k/include/asm/swab.h +@@ -4,7 +4,7 @@ + #include <linux/types.h> + #include <linux/compiler.h> + +-#define __SWAB_64_THRU_32__ ++/*#define __SWAB_64_THRU_32__ + + #if defined (__mcfisaaplus__) || defined (__mcfisac__) + static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +@@ -23,5 +23,29 @@ static inline __attribute_const__ __u32 + } + #define __arch_swab32 __arch_swab32 + #endif ++*/ ++#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)); ++ return val; ++} ++#define __arch__swab32(x) ___arch__swab32(x) ++ ++#endif ++#endif ++ ++#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) ++# define __BYTEORDER_HAS_U64__ ++# define __SWAB_64_THRU_32__ ++#endif + + #endif /* _M68K_SWAB_H */ +--- a/arch/m68k/include/asm/system_mm.h ++++ b/arch/m68k/include/asm/system_mm.h +@@ -5,9 +5,24 @@ + #include <linux/kernel.h> + #include <asm/segment.h> + #include <asm/entry.h> ++#include <asm/cfcache.h> + + #ifdef __KERNEL__ + ++#ifdef CONFIG_COLDFIRE ++#define FLUSH_BC (0x00040000) ++ ++#define finish_arch_switch(prev) do { \ ++ unsigned long tmpreg; \ ++ asm volatile ( "move.l %2,%0\n" \ ++ "orl %1,%0\n" \ ++ "movec %0,%%cacr" \ ++ : "=&d" (tmpreg) \ ++ : "id" (FLUSH_BC), "m" (shadow_cacr)); \ ++ } while(0) ++ ++#endif ++ + /* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This +@@ -63,16 +78,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/arch/m68k/include/asm/thread_info_mm.h ++++ b/arch/m68k/include/asm/thread_info_mm.h +@@ -10,6 +10,7 @@ struct thread_info { + struct exec_domain *exec_domain; /* execution domain */ + int preempt_count; /* 0 => preemptable, <0 => BUG */ + __u32 cpu; /* should always be 0 on m68k */ ++ unsigned long tp_value; + struct restart_block restart_block; + }; + +--- a/arch/m68k/include/asm/tlbflush.h ++++ b/arch/m68k/include/asm/tlbflush.h +@@ -2,7 +2,7 @@ + #define _M68K_TLBFLUSH_H + + #ifdef CONFIG_MMU +-#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,15 @@ 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 + + #else /* !CONFIG_MMU */ +--- a/arch/m68k/include/asm/uaccess_mm.h ++++ b/arch/m68k/include/asm/uaccess_mm.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 + */ +@@ -371,4 +374,5 @@ unsigned long __clear_user(void __user * + + #define strlen_user(str) strnlen_user(str, 32767) + ++#endif /* CONFIG_COLDFIRE */ + #endif /* _M68K_UACCESS_H */ +--- a/arch/m68k/include/asm/ucontext.h ++++ b/arch/m68k/include/asm/ucontext.h +@@ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG]; + + typedef struct fpregset { + int f_fpcntl[3]; ++#ifdef __mcoldfire__ ++ int f_fpregs[8][2]; ++#else + int f_fpregs[8*3]; ++#endif + } fpregset_t; + + struct mcontext { +--- a/arch/m68k/include/asm/unistd.h ++++ b/arch/m68k/include/asm/unistd.h +@@ -336,10 +336,14 @@ + #define __NR_pwritev 330 + #define __NR_rt_tgsigqueueinfo 331 + #define __NR_perf_counter_open 332 ++#define __NR_read_tp 333 ++#define __NR_write_tp 334 ++#define __NR_atomic_cmpxchg_32 335 ++#define __NR_atomic_barrier 336 + + #ifdef __KERNEL__ + +-#define NR_syscalls 333 ++#define NR_syscalls 337 + + #define __ARCH_WANT_IPC_PARSE_VERSION + #define __ARCH_WANT_OLD_READDIR +--- a/arch/m68k/include/asm/virtconvert.h ++++ b/arch/m68k/include/asm/virtconvert.h +@@ -1,6 +1,10 @@ + #ifndef __VIRT_CONVERT__ + #define __VIRT_CONVERT__ + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cf_virtconvert.h> ++#else ++ + /* + * Macros used for converting between virtual and physical mappings. + */ +@@ -46,3 +50,4 @@ static inline void *phys_to_virt(unsigne + + #endif + #endif ++#endif +--- a/arch/m68k/Kconfig ++++ b/arch/m68k/Kconfig +@@ -12,6 +12,14 @@ config MMU + bool + default y + ++config GENERIC_TIME ++ bool "Enable generic timer" ++ default n ++ ++config GENERIC_CLOCKEVENTS ++ bool "Enable generic clockevents" ++ default n ++ + config RWSEM_GENERIC_SPINLOCK + bool + default y +@@ -37,7 +45,7 @@ config GENERIC_CALIBRATE_DELAY + + config TIME_LOW_RES + bool +- default y ++ default n + + config GENERIC_IOMAP + bool +@@ -49,7 +57,7 @@ config ARCH_MAY_HAVE_PC_FDC + default y + + config NO_IOPORT +- def_bool y ++ def_bool !(M5445X || M547X_8X) + + config NO_DMA + def_bool SUN3 +@@ -107,6 +115,35 @@ config PCMCIA + To compile this driver as modules, choose M here: the + modules will be called pcmcia_core and ds. + ++config COLDFIRE ++ bool "ColdFire V4e support" ++ default y ++ select CFV4E ++ help ++ Say Y if you want to build a kernel to run on one of the ColdFire ++ V4e boards. ++ ++config CFV4E ++ bool ++ depends on COLDFIRE ++ select MMU_CFV4E if MMU ++ default y ++ ++config FPU ++ bool "ColdFire V4e FPU support" ++ default n ++ help ++ This enables support for CFV4E FPU feature. ++ ++config MCD_DMA ++ bool "ColdFire MCD DMA support" ++ depends on M547X_8X ++ default y ++ help ++ This enables support for the ColdFire 547x/548x family ++ multichannel DMA support. Many drivers need it. ++ If you want it, say Y ++ + config AMIGA + bool "Amiga support" + select MMU_MOTOROLA if MMU +@@ -124,6 +161,16 @@ config ATARI + this kernel on an Atari, say Y here and browse the material + available in <file:Documentation/m68k>; otherwise say N. + ++config PCI ++ bool "PCI bus support" ++ depends on M54455 || M547X_8X ++ default n ++ help ++ Find out whether you have a PCI motherboard. PCI is the name of a ++ bus system, i.e. the way the CPU talks to the other stuff inside ++ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or ++ VESA. If you have PCI, say Y, otherwise N. ++ + config MAC + bool "Macintosh support" + select MMU_MOTOROLA if MMU +@@ -278,6 +325,118 @@ config M68060 + If you anticipate running this kernel on a computer with a MC68060 + processor, say Y. Otherwise, say N. + ++config M5445X ++ bool "MCF5445x support" ++ depends on COLDFIRE ++ select GENERIC_TIME ++ select USB_EHCI_FSL ++ select HAVE_FSL_USB_DR ++ help ++ This option will add support for the MCF544x processor with mmu. ++ ++config M54451 ++ bool ++ depends on M5445X ++ default n ++ ++config M54455 ++ bool ++ depends on M5445X ++ default n ++ ++choice ++ prompt "Model" ++ depends on M5445X ++ default M54451EVB ++ config M54451EVB ++ bool "M54451EVB" ++ select M54451 ++ config M54455EVB ++ bool "M54455EVB" ++ select M54455 ++endchoice ++ ++config HAVE_FSL_USB_DR ++ bool ++ default n ++ ++config M547X_8X ++ bool "MCF547x/MCF548x support" ++ depends on COLDFIRE ++ help ++ This option will add support for the MCF547x/MCF548x processor with mmu. ++ ++config M547X ++ bool ++ depends on M547X_8X ++ default n ++ ++config M548X ++ bool ++ depends on M547X_8X ++ default n ++ ++choice ++ prompt "Model" ++ depends on M547X_8X ++ default M5485CFE ++ ++config M5475AFE ++ bool "MCF5475AFE" ++ select M547X ++config M5475BFE ++ bool "MCF5475BFE" ++ select M547X ++config M5475CFE ++ bool "MCF5475CFE" ++ select M547X ++config M5475DFE ++ bool "MCF5475DFE" ++ select M547X ++config M5475EFE ++ bool "MCF5475EFE" ++ select M547X ++config M5475FFE ++ bool "MCF5475FFE" ++ select M547X ++config M5485AFE ++ bool "MCF5485AFE" ++ select M548X ++config M5485BFE ++ bool "MCF5485BFE" ++ select M548X ++config M5485CFE ++ bool "MCF5485CFE" ++ select M548X ++config M5485DFE ++ bool "MCF5485DFE" ++ select M548X ++config M5485EFE ++ bool "MCF5485EFE" ++ select M548X ++config M5485FFE ++ bool "MCF5485FFE" ++ select M548X ++ ++endchoice ++ ++ ++config MCFCLK ++ int ++ default 240000000 if M54451EVB ++ default 266666666 if M54455EVB ++ default 266000000 if M547X ++ default 200000000 if M548X ++ help ++ Coldfire System clock. ++ ++config MCF_USER_HALT ++ bool "Coldfire User Halt Enable" ++ depends on M5445X || M547X_8X ++ default n ++ help ++ Enables the HALT instruction in User Mode. ++ + config MMU_MOTOROLA + bool + +@@ -285,6 +444,70 @@ config MMU_SUN3 + bool + depends on MMU && !MMU_MOTOROLA + ++config MMU_CFV4E ++ bool ++ ++config SDRAM_BASE ++ hex ++ depends on COLDFIRE ++ default 0x40000000 if M5445X ++ default 0x00000000 if M547X_8X ++ ++config SDRAM_SIZE ++ hex ++ depends on COLDFIRE ++ default 0x08000000 if M54451EVB ++ default 0x10000000 if M54455EVB ++ default 0x04000000 if M547X_8X ++ ++config NOR_FLASH_BASE ++ hex "NOR Flash Base Address" ++ depends on COLDFIRE ++ default 0x00000000 if M54451EVB ++ default 0x00000000 if M54455EVB ++ default 0xE0000000 if M547X_8X ++ ++config DMA_BASE ++ hex ++ depends on COLDFIRE ++ default 0xef000000 ++ ++config DMA_SIZE ++ hex ++ depends on COLDFIRE ++ default 0x1000000 if M5445X ++ default 0x800000 if M547X_8X ++ ++config SRAM ++ bool "SRAM allocation APIs support on mcfv4 platform" ++ depends on COLDFIRE && M5445X ++ default y ++ select GENERIC_ALLOCATOR ++ ++config SRAM_BASE ++ hex ++ depends on COLDFIRE && SRAM ++ default 0x8ff00000 if M5445X ++ ++config SRAM_SIZE ++ hex ++ depends on COLDFIRE && SRAM ++ default 0x8000 if M5445X ++ ++config SRAM_ALLOC_GRANULARITY ++ hex ++ depends on SRAM ++ default 0x200 if M5445X ++ ++config VDSO ++ bool "Support VDSO page" ++ depends on MMU ++ default n ++ help ++ This will enable support for the kernel mapping a vDSO page ++ in process space, and subsequently handing down the entry point ++ to the libc through the ELF auxiliary vector. ++ + config M68KFPU_EMU + bool "Math emulation support (EXPERIMENTAL)" + depends on EXPERIMENTAL +@@ -451,6 +674,14 @@ config ZONE_DMA + source "drivers/pci/Kconfig" + + source "drivers/zorro/Kconfig" ++endmenu ++ ++menu "Power management options" ++ ++config PM ++ bool "Power Management support" ++ help ++ Support processor power management modes + + endmenu + +@@ -589,7 +820,7 @@ config DN_SERIAL + + config SERIAL_CONSOLE + bool "Support for serial port console" +- depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL) ++ depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO || COLDFIRE) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL || SERIAL_COLDFIRE) + ---help--- + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all +@@ -612,6 +843,8 @@ config SERIAL_CONSOLE + + endmenu + ++source "kernel/time/Kconfig" ++ + source "fs/Kconfig" + + source "arch/m68k/Kconfig.debug" +--- a/arch/m68k/kernel/asm-offsets.c ++++ b/arch/m68k/kernel/asm-offsets.c +@@ -2,6 +2,11 @@ + * This program is used to generate definitions needed by + * assembly language modules. + * ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com ++ * Add Codlfire support ++ * + * We use the technique used in the OSF Mach kernel code: + * generate asm statements containing #defines, + * compile this file to assembler, and then extract the +@@ -56,8 +61,15 @@ int main(void) + DEFINE(PT_A2, offsetof(struct pt_regs, a2)); + DEFINE(PT_PC, offsetof(struct pt_regs, pc)); + DEFINE(PT_SR, offsetof(struct pt_regs, sr)); ++#ifdef CONFIG_COLDFIRE ++ /* Need to get the context out of struct mm for ASID setting */ ++ DEFINE(MM_CONTEXT, offsetof(struct mm_struct, context)); ++ /* Coldfire exception frame has vector *before* pc */ ++ DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) - 4); ++#else + /* bitfields are a bit difficult */ + DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); ++#endif + + /* offsets into the irq_handler struct */ + DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler)); +--- a/arch/m68k/kernel/dma.c ++++ b/arch/m68k/kernel/dma.c +@@ -1,4 +1,7 @@ + /* ++ * Copyright Freescale Semiconductor, Inc. 2008, 2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. +@@ -11,12 +14,24 @@ + #include <linux/kernel.h> + #include <linux/scatterlist.h> + #include <linux/vmalloc.h> +- ++#include <linux/pci.h> + #include <asm/pgalloc.h> + + void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *handle, gfp_t flag) + { ++#if defined(CONFIG_M5445X) | defined(CONFIG_M547X_8X) ++ /* ++ * On the M5445x platform the memory allocated with GFP_DMA ++ * is guaranteed to be DMA'able. ++ */ ++ void *addr; ++ ++ size = PAGE_ALIGN(size); ++ addr = kmalloc(size, GFP_DMA); ++ *handle = virt_to_phys(addr); ++ return addr; ++#else + struct page *page, **map; + pgprot_t pgprot; + void *addr; +@@ -55,6 +70,7 @@ void *dma_alloc_coherent(struct device * + kfree(map); + + return addr; ++#endif + } + EXPORT_SYMBOL(dma_alloc_coherent); + +@@ -62,7 +78,11 @@ void dma_free_coherent(struct device *de + void *addr, dma_addr_t handle) + { + pr_debug("dma_free_coherent: %p, %x\n", addr, handle); ++#if defined(CONFIG_M5445X) | defined(CONFIG_M547X_8X) ++ kfree(addr); ++#else + vfree(addr); ++#endif + } + EXPORT_SYMBOL(dma_free_coherent); + +@@ -88,9 +108,16 @@ void dma_sync_sg_for_device(struct devic + enum dma_data_direction dir) + { + int i; ++#ifdef CONFIG_COLDFIRE ++ struct scatterlist *_sg; + ++ for_each_sg(sg, _sg, nents, i) ++ dma_sync_single_for_device(dev, _sg->dma_address, ++ _sg->length, dir); ++#else + for (i = 0; i < nents; sg++, i++) + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); ++#endif + } + EXPORT_SYMBOL(dma_sync_sg_for_device); + +@@ -119,10 +146,19 @@ int dma_map_sg(struct device *dev, struc + enum dma_data_direction dir) + { + int i; +- ++#ifdef CONFIG_COLDFIRE ++ struct scatterlist *_sg; ++#endif ++#ifndef CONFIG_COLDFIRE + for (i = 0; i < nents; sg++, i++) { + sg->dma_address = sg_phys(sg); + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); ++#else ++ for_each_sg(sg, _sg, nents, i) { ++ _sg->dma_address = sg_phys(_sg); ++ dma_sync_single_for_device(dev, _sg->dma_address, ++ _sg->length, dir); ++#endif + } + return nents; + } +--- a/arch/m68k/kernel/Makefile ++++ b/arch/m68k/kernel/Makefile +@@ -2,16 +2,26 @@ + # Makefile for the linux kernel. + # + +-ifndef CONFIG_SUN3 +- extra-y := head.o ++ifdef CONFIG_SUN3 ++ extra-y := sun3-head.o vmlinux.lds ++ obj-y := entry.o signal.o ints.o time.o + else +- extra-y := sun3-head.o ++ifndef CONFIG_COLDFIRE ++ extra-y := head.o vmlinux.lds ++ obj-y := entry.o signal.o traps.o ints.o time.o ++else # CONFIG_COLDFIRE ++ extra-y := vmlinux.lds ++ ifdef CONFIG_M547X_8X ++ obj-$(CONFIG_PCI) += bios32_mcf548x.o ++ endif ++endif + endif +-extra-y += vmlinux.lds + +-obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ +- sys_m68k.o time.o setup.o m68k_ksyms.o devres.o ++obj-y += process.o ptrace.o module.o \ ++ sys_m68k.o setup.o m68k_ksyms.o devres.o# semaphore.o + + devres-y = ../../../kernel/irq/devres.o + + obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo ++ ++EXTRA_AFLAGS := -traditional +--- a/arch/m68k/kernel/process.c ++++ b/arch/m68k/kernel/process.c +@@ -4,6 +4,11 @@ + * Copyright (C) 1995 Hamish Macdonald + * + * 68060 fixes by Jesper Skov ++ * ++ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. ++ * Kurt.Mahan@freescale.com ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + */ + + /* +@@ -186,12 +191,21 @@ EXPORT_SYMBOL(kernel_thread); + void flush_thread(void) + { + unsigned long zero = 0; ++#if !defined(CONFIG_COLDFIRE) + set_fs(USER_DS); + current->thread.fs = __USER_DS; + if (!FPU_IS_EMU) + asm volatile (".chip 68k/68881\n\t" + "frestore %0@\n\t" + ".chip 68k" : : "a" (&zero)); ++#else ++ set_fs(USER_DS); ++ current->thread.fs = USER_DS; ++#if defined(CONFIG_FPU) ++ if (!FPU_IS_EMU) ++ asm volatile ("frestore %0@\n\t" : : "a" (&zero)); ++#endif ++#endif + } + + /* +@@ -251,10 +265,15 @@ int copy_thread(unsigned long clone_flag + + p->thread.usp = usp; + p->thread.ksp = (unsigned long)childstack; ++ ++ if (clone_flags & CLONE_SETTLS) ++ task_thread_info(p)->tp_value = regs->d5; ++ + /* + * Must save the current SFC/DFC value, NOT the value when + * the parent was last descheduled - RGH 10-08-96 + */ ++#if !defined(CONFIG_COLDFIRE) + p->thread.fs = get_fs().seg; + + if (!FPU_IS_EMU) { +@@ -266,9 +285,34 @@ int copy_thread(unsigned long clone_flag + "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" + : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) + : "memory"); ++#else ++ p->thread.fs = get_fs(); ++ ++#if defined(CONFIG_FPU) ++ if (!FPU_IS_EMU) { ++ /* Copy the current fpu state */ ++ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) ++ : "memory"); ++ ++ if (p->thread.fpstate[0]) { ++ asm volatile ("fmovemd %/fp0-%/fp7,%0" ++ : : "m" (p->thread.fp[0]) ++ : "memory"); ++ asm volatile ("fmovel %/fpiar,%0" ++ : : "m" (p->thread.fpcntl[0]) ++ : "memory"); ++ asm volatile ("fmovel %/fpcr,%0" ++ : : "m" (p->thread.fpcntl[1]) ++ : "memory"); ++ asm volatile ("fmovel %/fpsr,%0" ++ : : "m" (p->thread.fpcntl[2]) ++ : "memory"); ++ } + /* Restore the state in case the fpu was busy */ + asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); + } ++#endif ++#endif + + return 0; + } +@@ -277,7 +321,9 @@ int copy_thread(unsigned long clone_flag + + int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) + { ++#if !defined(CONFIG_COLDFIRE) || defined(CONFIG_FPU) + char fpustate[216]; ++#endif + + if (FPU_IS_EMU) { + int i; +@@ -294,6 +340,7 @@ int dump_fpu (struct pt_regs *regs, stru + } + + /* First dump the fpu context to avoid protocol violation. */ ++#if !defined(CONFIG_COLDFIRE) + asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); + if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) + return 0; +@@ -304,6 +351,25 @@ int dump_fpu (struct pt_regs *regs, stru + asm volatile ("fmovemx %/fp0-%/fp7,%0" + :: "m" (fpu->fpregs[0]) + : "memory"); ++#elif defined(CONFIG_FPU) ++ asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); ++ if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) ++ return 0; ++ ++ asm volatile ("fmovel %/fpiar,%0" ++ : : "m" (fpu->fpcntl[0]) ++ : "memory"); ++ asm volatile ("fmovel %/fpcr,%0" ++ : : "m" (fpu->fpcntl[1]) ++ : "memory"); ++ asm volatile ("fmovel %/fpsr,%0" ++ : : "m" (fpu->fpcntl[2]) ++ : "memory"); ++ asm volatile ("fmovemd %/fp0-%/fp7,%0" ++ : : "m" (fpu->fpregs[0]) ++ : "memory"); ++#endif ++ + return 1; + } + EXPORT_SYMBOL(dump_fpu); +--- a/arch/m68k/kernel/ptrace.c ++++ b/arch/m68k/kernel/ptrace.c +@@ -265,6 +265,11 @@ long arch_ptrace(struct task_struct *chi + ret = -EFAULT; + break; + ++ case PTRACE_GET_THREAD_AREA: ++ ret = put_user(task_thread_info(child)->tp_value, ++ (unsigned long __user *) data); ++ break; ++ + default: + ret = ptrace_request(child, request, addr, data); + break; +--- a/arch/m68k/kernel/setup.c ++++ b/arch/m68k/kernel/setup.c +@@ -2,6 +2,9 @@ + * linux/arch/m68k/kernel/setup.c + * + * Copyright (C) 1995 Hamish Macdonald ++ * Copyright Freescale Semiconductor, Inc. 2008, 2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + */ + + /* +@@ -75,13 +78,24 @@ EXPORT_SYMBOL(m68k_memory); + + struct mem_info m68k_ramdisk; + ++#if !defined(CONFIG_COLDFIRE) + static char m68k_command_line[CL_SIZE]; ++#else ++char m68k_command_line[CL_SIZE]; ++unsigned long uboot_info_stk; ++EXPORT_SYMBOL(uboot_info_stk); ++#endif + + void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; + /* machine dependent irq functions */ + void (*mach_init_IRQ) (void) __initdata = NULL; + void (*mach_get_model) (char *model); + void (*mach_get_hardware_list) (struct seq_file *m); ++ ++#ifdef CONFIG_COLDFIRE ++void (*mach_tick)(void); ++#endif ++ + /* machine dependent timer functions */ + unsigned long (*mach_gettimeoffset) (void); + int (*mach_hwclk) (int, struct rtc_time*); +@@ -137,13 +151,17 @@ extern void config_hp300(void); + extern void config_q40(void); + extern void config_sun3x(void); + ++#ifdef CONFIG_COLDFIRE ++void coldfire_sort_memrec(void); ++#endif ++ + #define MASK_256K 0xfffc0000 + + extern void paging_init(void); + + static void __init m68k_parse_bootinfo(const struct bi_record *record) + { +- while (record->tag != BI_LAST) { ++ while ((record->tag != BI_LAST)) { + int unknown = 0; + const unsigned long *data = record->data; + +@@ -203,6 +221,10 @@ static void __init m68k_parse_bootinfo(c + record->size); + } + ++#ifdef CONFIG_COLDFIRE ++ coldfire_sort_memrec(); ++#endif ++ + m68k_realnum_memory = m68k_num_memory; + #ifdef CONFIG_SINGLE_MEMORY_CHUNK + if (m68k_num_memory > 1) { +@@ -215,8 +237,11 @@ static void __init m68k_parse_bootinfo(c + + void __init setup_arch(char **cmdline_p) + { +- int i; + ++#if !defined(CONFIG_SUN3) ++ int i; ++#endif ++ + /* The bootinfo is located right after the kernel bss */ + m68k_parse_bootinfo((const struct bi_record *)_end); + +@@ -230,9 +255,10 @@ void __init setup_arch(char **cmdline_p) + * We should really do our own FPU check at startup. + * [what do we do with buggy 68LC040s? if we have problems + * with them, we should add a test to check_bugs() below] */ +-#ifndef CONFIG_M68KFPU_EMU_ONLY ++#if !defined(CONFIG_M68KFPU_EMU_ONLY) && defined(CONFIG_FPU) + /* clear the fpu if we have one */ +- if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { ++ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060| ++ FPU_CFV4E)) { + volatile int zero = 0; + asm volatile ("frestore %0" : : "m" (zero)); + } +@@ -320,13 +346,18 @@ void __init setup_arch(char **cmdline_p) + config_sun3x(); + break; + #endif ++#ifdef CONFIG_COLDFIRE ++ case MACH_CFMMU: ++ config_coldfire(); ++ break; ++#endif + default: + panic("No configuration setup"); + } + + paging_init(); + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) + for (i = 1; i < m68k_num_memory; i++) + free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, + m68k_memory[i].size); +@@ -353,6 +384,10 @@ void __init setup_arch(char **cmdline_p) + + #endif /* !CONFIG_SUN3 */ + ++#ifdef CONFIG_COLDFIRE ++ mmu_context_init(); ++#endif ++ + /* set ISA defs early as possible */ + #if defined(CONFIG_ISA) && defined(MULTI_ISA) + if (MACH_IS_Q40) { +@@ -383,6 +418,7 @@ static int show_cpuinfo(struct seq_file + #define LOOP_CYCLES_68030 (8) + #define LOOP_CYCLES_68040 (3) + #define LOOP_CYCLES_68060 (1) ++#define LOOP_CYCLES_COLDFIRE (2) + + if (CPU_IS_020) { + cpu = "68020"; +@@ -396,6 +432,9 @@ static int show_cpuinfo(struct seq_file + } else if (CPU_IS_060) { + cpu = "68060"; + clockfactor = LOOP_CYCLES_68060; ++ } else if (CPU_IS_CFV4E) { ++ cpu = "ColdFire V4e"; ++ clockfactor = LOOP_CYCLES_COLDFIRE; + } else { + cpu = "680x0"; + clockfactor = 0; +@@ -414,6 +453,8 @@ static int show_cpuinfo(struct seq_file + fpu = "68060"; + else if (m68k_fputype & FPU_SUNFPA) + fpu = "Sun FPA"; ++ else if (m68k_fputype & FPU_CFV4E) ++ fpu = "ColdFire V4e"; + else + fpu = "none"; + #endif +@@ -430,6 +471,8 @@ static int show_cpuinfo(struct seq_file + mmu = "Sun-3"; + else if (m68k_mmutype & MMU_APOLLO) + mmu = "Apollo"; ++ else if (m68k_mmutype & MMU_CFV4E) ++ mmu = "ColdFire"; + else + mmu = "unknown"; + +@@ -512,7 +555,7 @@ module_init(proc_hardware_init); + + void check_bugs(void) + { +-#ifndef CONFIG_M68KFPU_EMU ++#if !defined(CONFIG_M68KFPU_EMU) && !defined(CONFIG_M5445X) + if (m68k_fputype == 0) { + printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " + "WHICH IS REQUIRED BY LINUX/M68K ***\n"); +--- a/arch/m68k/kernel/sys_m68k.c ++++ b/arch/m68k/kernel/sys_m68k.c +@@ -1,5 +1,8 @@ + /* + * linux/arch/m68k/kernel/sys_m68k.c ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * + * This file contains various random system calls that + * have a non-standard calling sequence on the Linux/m68k +@@ -29,6 +32,14 @@ + #include <asm/traps.h> + #include <asm/page.h> + #include <asm/unistd.h> ++#include <linux/elf.h> ++#include <asm/tlb.h> ++#ifdef CONFIG_COLDFIRE ++#include <asm/cacheflush.h> ++#endif ++ ++asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, ++ unsigned long error_code); + + /* common code for old and new mmaps */ + static inline long do_mmap2( +@@ -240,6 +251,7 @@ asmlinkage int sys_ipc (uint call, int f + return -EINVAL; + } + ++#ifndef CONFIG_COLDFIRE + /* Convert virtual (user) address VADDR to physical address PADDR */ + #define virt_to_phys_040(vaddr) \ + ({ \ +@@ -563,6 +575,7 @@ cache_flush_060 (unsigned long addr, int + } + return 0; + } ++#endif /* CONFIG_COLDFIRE */ + + /* sys_cacheflush -- flush (part of) the processor cache. */ + asmlinkage int +@@ -595,6 +608,7 @@ sys_cacheflush (unsigned long addr, int + goto out; + } + ++#ifndef CONFIG_COLDFIRE + if (CPU_IS_020_OR_030) { + if (scope == FLUSH_SCOPE_LINE && len < 256) { + unsigned long cacr; +@@ -639,6 +653,16 @@ sys_cacheflush (unsigned long addr, int + ret = cache_flush_060 (addr, scope, cache, len); + } + } ++#else /* CONFIG_COLDFIRE */ ++ if ((cache & FLUSH_CACHE_INSN) && (cache & FLUSH_CACHE_DATA)) ++ flush_bcache(); ++ else if (cache & FLUSH_CACHE_INSN) ++ flush_icache(); ++ else ++ flush_dcache(); ++ ++ ret = 0; ++#endif /* CONFIG_COLDFIRE */ + out: + unlock_kernel(); + return ret; +@@ -663,3 +687,79 @@ int kernel_execve(const char *filename, + : "d" (__a), "d" (__b), "d" (__c)); + return __res; + } ++ ++asmlinkage unsigned long ++sys_read_tp(void) ++{ ++ return current_thread_info()->tp_value; ++} ++ ++asmlinkage int ++sys_write_tp(unsigned long tp) ++{ ++ current_thread_info()->tp_value = tp; ++ return 0; ++} ++ ++/* This syscall gets its arguments in A0 (mem), D2 (oldval) and ++ D1 (newval). */ ++asmlinkage int ++sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, ++ unsigned long __user *mem) ++{ ++ /* This was borrowed from ARM's implementation. */ ++ for (;;) { ++ struct mm_struct *mm = current->mm; ++ pgd_t *pgd; pmd_t *pmd; pte_t *pte; ++ spinlock_t *ptl; ++ unsigned long mem_value; ++ ++ down_read(&mm->mmap_sem); ++ pgd = pgd_offset(mm, (unsigned long)mem); ++ if (!pgd_present(*pgd)) ++ goto bad_access; ++ pmd = pmd_offset(pgd, (unsigned long)mem); ++ if (!pmd_present(*pmd)) ++ goto bad_access; ++ pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); ++ if (!pte_present(*pte) || !pte_dirty(*pte)) { ++ pte_unmap_unlock(pte, ptl); ++ goto bad_access; ++ } ++ ++ mem_value = *mem; ++ if (mem_value == oldval) ++ *mem = newval; ++ ++ pte_unmap_unlock(pte, ptl); ++ up_read(&mm->mmap_sem); ++ return mem_value; ++ ++bad_access: ++ up_read(&mm->mmap_sem); ++ /* This is not necessarily a bad access, we can get here if ++ a memory we're trying to write to should be copied-on-write. ++ Make the kernel do the necessary page stuff, then re-iterate. ++ Simulate a write access fault to do that. */ ++ { ++ /* The first argument of the function corresponds to ++ D1, which is the first field of struct pt_regs. */ ++ struct pt_regs *fp = (struct pt_regs *)&newval; ++ ++ /* '3' is an RMW flag. */ ++ if (do_page_fault(fp, (unsigned long)mem, 3)) ++ /* If the do_page_fault() failed, we don't ++ have anything meaningful to return. ++ There should be a SIGSEGV pending for ++ the process. */ ++ return 0xdeadbeef; ++ } ++ } ++} ++ ++asmlinkage int ++sys_atomic_barrier(void) ++{ ++ /* no code needed for uniprocs */ ++ return 0; ++} +--- a/arch/m68k/kernel/time.c ++++ b/arch/m68k/kernel/time.c +@@ -2,6 +2,9 @@ + * linux/arch/m68k/kernel/time.c + * + * Copyright (C) 1991, 1992, 1995 Linus Torvalds ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * + * This file contains the m68k-specific time handling details. + * Most of the stuff is located in the machine specific files. +@@ -41,6 +44,11 @@ static inline int set_rtc_mmss(unsigned + */ + static irqreturn_t timer_interrupt(int irq, void *dummy) + { ++#ifdef CONFIG_COLDFIRE ++ /* kick hardware timer if necessary */ ++ if (mach_tick) ++ mach_tick(); ++#endif + do_timer(1); + #ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); +--- a/arch/m68k/kernel/vmlinux.lds.S ++++ b/arch/m68k/kernel/vmlinux.lds.S +@@ -1,10 +1,13 @@ + PHDRS + { +- text PT_LOAD FILEHDR PHDRS FLAGS (7); ++ headers PT_PHDR PHDRS ; ++ text PT_LOAD FILEHDR PHDRS FLAGS (5); + data PT_LOAD FLAGS (7); + } + #ifdef CONFIG_SUN3 + #include "vmlinux-sun3.lds" ++#elif CONFIG_COLDFIRE ++#include "vmlinux-cf.lds" + #else + #include "vmlinux-std.lds" + #endif +--- a/arch/m68k/lib/checksum.c ++++ b/arch/m68k/lib/checksum.c +@@ -30,6 +30,10 @@ + * 1998/8/31 Andreas Schwab: + * Zero out rest of buffer on exception in + * csum_partial_copy_from_user. ++ * ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + */ + + #include <linux/module.h> +@@ -39,8 +43,131 @@ + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + ++#ifdef CONFIG_COLDFIRE ++ ++static inline unsigned short from32to16(unsigned long x) ++{ ++ /* add up 16-bit and 16-bit for 16+c bit */ ++ x = (x & 0xffff) + (x >> 16); ++ /* add up carry.. */ ++ x = (x & 0xffff) + (x >> 16); ++ return x; ++} ++ ++static unsigned long do_csum(const unsigned char *buff, int len) ++{ ++ int odd, count; ++ unsigned long result = 0; ++ ++ if (len <= 0) ++ goto out; ++ odd = 1 & (unsigned long) buff; ++ if (odd) { ++ result = *buff; ++ len--; ++ buff++; ++ } ++ count = len >> 1; /* nr of 16-bit words.. */ ++ if (count) { ++ if (2 & (unsigned long) buff) { ++ result += *(unsigned short *) buff; ++ count--; ++ len -= 2; ++ buff += 2; ++ } ++ count >>= 1; /* nr of 32-bit words.. */ ++ if (count) { ++ unsigned long carry = 0; ++ do { ++ unsigned long w = *(unsigned long *) buff; ++ count--; ++ buff += 4; ++ result += carry; ++ result += w; ++ carry = (w > result); ++ } while (count); ++ result += carry; ++ result = (result & 0xffff) + (result >> 16); ++ } ++ if (len & 2) { ++ result += *(unsigned short *) buff; ++ buff += 2; ++ } ++ } ++ if (len & 1) ++ result += (*buff << 8); ++ result = from32to16(result); ++ if (odd) ++ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); ++out: ++ return result; ++} ++ ++/* ++ * This is a version of ip_compute_csum() optimized for IP headers, ++ * which always checksum on 4 octet boundaries. ++ */ ++__sum16 ip_fast_csum(const void *iph, unsigned int ihl) ++{ ++ return ~do_csum(iph, ihl*4); ++} ++EXPORT_SYMBOL(ip_fast_csum); ++ ++/* ++ * computes the checksum of a memory block at buff, length len, ++ * and adds in "sum" (32-bit) ++ * ++ * returns a 32-bit number suitable for feeding into itself ++ * or csum_tcpudp_magic ++ * ++ * this function must be called with even lengths, except ++ * for the last fragment, which may be odd ++ * ++ * it's best to have buff aligned on a 32-bit boundary ++ */ + __wsum csum_partial(const void *buff, int len, __wsum sum) + { ++ unsigned int result = do_csum(buff, len); ++ ++ /* add in old sum, and carry.. */ ++ result += sum; ++ if (sum > result) ++ result += 1; ++ return result; ++} ++EXPORT_SYMBOL(csum_partial); ++ ++/* ++ * copy from fs while checksumming, otherwise like csum_partial ++ */ ++ ++__wsum ++csum_partial_copy_from_user(const void __user *src, void *dst, int len, ++ __wsum sum, int *csum_err) ++{ ++ if (csum_err) *csum_err = 0; ++ memcpy(dst, src, len); ++ return csum_partial(dst, len, sum); ++} ++EXPORT_SYMBOL(csum_partial_copy_from_user); ++ ++/* ++ * copy from ds while checksumming, otherwise like csum_partial ++ */ ++ ++__wsum ++csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) ++{ ++ memcpy(dst, src, len); ++ return csum_partial(dst, len, sum); ++} ++EXPORT_SYMBOL(csum_partial_copy_nocheck); ++ ++#else /* !CONFIG_COLDFIRE */ ++ ++unsigned int ++csum_partial(const unsigned char *buff, int len, unsigned int sum) ++{ + unsigned long tmp1, tmp2; + /* + * Experiments with ethernet and slip connections show that buff +@@ -423,3 +550,4 @@ csum_partial_copy_nocheck(const void *sr + return(sum); + } + EXPORT_SYMBOL(csum_partial_copy_nocheck); ++#endif /* CONFIG_COLDFIRE */ +--- a/arch/m68k/lib/muldi3.c ++++ b/arch/m68k/lib/muldi3.c +@@ -1,6 +1,9 @@ + /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and + gcc-2.7.2.3/longlong.h which is: */ + /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. ++ Copyright Freescale Semiconductor, Inc. 2008-2009 ++ Jason Jin Jason.Jin@freescale.com ++ Shrek Wu B16972@freescale.com + + This file is part of GNU CC. + +@@ -21,12 +24,22 @@ Boston, MA 02111-1307, USA. */ + + #define BITS_PER_UNIT 8 + ++#ifdef CONFIG_COLDFIRE ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ unsigned long long x; \ ++ x = (unsigned long long)u * v; \ ++ w0 = (unsigned long)(x & 0x00000000ffffffff); \ ++ w1 = (unsigned long)(x & 0xffffffff00000000) >> 32; \ ++ } while (0) ++#else /* CONFIG_COLDFIRE */ + #define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "dmi" ((USItype)(v))) ++#endif /* CONFIG_COLDFIRE */ + + #define __umulsidi3(u, v) \ + ({DIunion __w; \ +--- a/arch/m68k/lib/string.c ++++ b/arch/m68k/lib/string.c +@@ -1,4 +1,8 @@ + /* ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com ++ * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. +@@ -21,6 +25,7 @@ char *strcat(char *dest, const char *src + } + EXPORT_SYMBOL(strcat); + ++#ifndef CONFIG_COLDFIRE + void *memset(void *s, int c, size_t count) + { + void *xs = s; +@@ -149,6 +154,69 @@ void *memcpy(void *to, const void *from, + } + EXPORT_SYMBOL(memcpy); + ++#else /* CONFIG_COLDFIRE */ ++ ++void *memset(void *s, int c, size_t count) ++{ ++ unsigned long x; ++ void *originalTo = s; ++ ++ for (x = 0; x < count; x++) ++ *(unsigned char *)s++ = (unsigned char)c; ++ ++ return originalTo; ++} ++EXPORT_SYMBOL(memset); ++ ++void *memcpy(void *to, const void *from, size_t n) ++{ ++ void *xto = to; ++ size_t temp; ++ ++ if (!n) ++ return xto; ++ if ((long) to & 1) { ++ char *cto = to; ++ const char *cfrom = from; ++ *cto++ = *cfrom++; ++ to = cto; ++ from = cfrom; ++ n--; ++ } ++ if (n > 2 && (long) to & 2) { ++ short *sto = to; ++ const short *sfrom = from; ++ *sto++ = *sfrom++; ++ to = sto; ++ from = sfrom; ++ n -= 2; ++ } ++ temp = n >> 2; ++ if (temp) { ++ long *lto = to; ++ const long *lfrom = from; ++ for (; temp; temp--) ++ *lto++ = *lfrom++; ++ to = lto; ++ from = lfrom; ++ } ++ if (n & 2) { ++ short *sto = to; ++ const short *sfrom = from; ++ *sto++ = *sfrom++; ++ to = sto; ++ from = sfrom; ++ } ++ if (n & 1) { ++ char *cto = to; ++ const char *cfrom = from; ++ *cto = *cfrom; ++ } ++ return xto; ++} ++EXPORT_SYMBOL(memcpy); ++#endif /* CONFIG_COLDFIRE */ ++ + void *memmove(void *dest, const void *src, size_t n) + { + void *xdest = dest; +--- a/arch/m68k/lib/uaccess.c ++++ b/arch/m68k/lib/uaccess.c +@@ -1,10 +1,15 @@ + /* ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com ++ * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + #include <linux/module.h> ++#ifndef CONFIG_COLDFIRE + #include <asm/uaccess.h> + + unsigned long __generic_copy_from_user(void *to, const void __user *from, +@@ -220,3 +225,244 @@ unsigned long __clear_user(void __user * + return res; + } + EXPORT_SYMBOL(__clear_user); ++ ++#else /* CONFIG_COLDFIRE */ ++ ++#include <asm/cf_uaccess.h> ++ ++unsigned long __generic_copy_from_user(void *to, const void *from, ++ unsigned long n) ++{ ++ unsigned long tmp; ++ __asm__ __volatile__ ++ (" tstl %2\n" ++ " jeq 2f\n" ++ "1: movel (%1)+,%3\n" ++ " movel %3,(%0)+\n" ++ " subql #1,%2\n" ++ " jne 1b\n" ++ "2: movel %4,%2\n" ++ " bclr #1,%2\n" ++ " jeq 4f\n" ++ "3: movew (%1)+,%3\n" ++ " movew %3,(%0)+\n" ++ "4: bclr #0,%2\n" ++ " jeq 6f\n" ++ "5: moveb (%1)+,%3\n" ++ " moveb %3,(%0)+\n" ++ "6:\n" ++ ".section .fixup,\"ax\"\n" ++ " .even\n" ++ "7: movel %2,%%d0\n" ++ "71:clrl (%0)+\n" ++ " subql #1,%%d0\n" ++ " jne 71b\n" ++ " lsll #2,%2\n" ++ " addl %4,%2\n" ++ " btst #1,%4\n" ++ " jne 81f\n" ++ " btst #0,%4\n" ++ " jne 91f\n" ++ " jra 6b\n" ++ "8: addql #2,%2\n" ++ "81:clrw (%0)+\n" ++ " btst #0,%4\n" ++ " jne 91f\n" ++ " jra 6b\n" ++ "9: addql #1,%2\n" ++ "91:clrb (%0)+\n" ++ " jra 6b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ " .align 4\n" ++ " .long 1b,7b\n" ++ " .long 3b,8b\n" ++ " .long 5b,9b\n" ++ ".previous" ++ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) ++ : "d"(n & 3), "0"(to), "1"(from), "2"(n/4) ++ : "d0", "memory"); ++ return n; ++} ++EXPORT_SYMBOL(__generic_copy_from_user); ++ ++ ++unsigned long __generic_copy_to_user(void *to, const void *from, ++ unsigned long n) ++{ ++ unsigned long tmp; ++ __asm__ __volatile__ ++ (" tstl %2\n" ++ " jeq 3f\n" ++ "1: movel (%1)+,%3\n" ++ "22:movel %3,(%0)+\n" ++ "2: subql #1,%2\n" ++ " jne 1b\n" ++ "3: movel %4,%2\n" ++ " bclr #1,%2\n" ++ " jeq 4f\n" ++ " movew (%1)+,%3\n" ++ "24:movew %3,(%0)+\n" ++ "4: bclr #0,%2\n" ++ " jeq 5f\n" ++ " moveb (%1)+,%3\n" ++ "25:moveb %3,(%0)+\n" ++ "5:\n" ++ ".section .fixup,\"ax\"\n" ++ " .even\n" ++ "60:addql #1,%2\n" ++ "6: lsll #2,%2\n" ++ " addl %4,%2\n" ++ " jra 5b\n" ++ "7: addql #2,%2\n" ++ " jra 5b\n" ++ "8: addql #1,%2\n" ++ " jra 5b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ " .align 4\n" ++ " .long 1b,60b\n" ++ " .long 22b,6b\n" ++ " .long 2b,6b\n" ++ " .long 24b,7b\n" ++ " .long 3b,60b\n" ++ " .long 4b,7b\n" ++ " .long 25b,8b\n" ++ " .long 5b,8b\n" ++ ".previous" ++ : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) ++ : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4) ++ : "memory"); ++ return n; ++} ++EXPORT_SYMBOL(__generic_copy_to_user); ++ ++/* ++ * Copy a null terminated string from userspace. ++ */ ++ ++long strncpy_from_user(char *dst, const char *src, long count) ++{ ++ long res = -EFAULT; ++ if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */ ++ return res; ++ if (count == 0) return count; ++ __asm__ __volatile__ ++ ("1: moveb (%2)+,%%d0\n" ++ "12:moveb %%d0,(%1)+\n" ++ " jeq 2f\n" ++ " subql #1,%3\n" ++ " jne 1b\n" ++ "2: subl %3,%0\n" ++ "3:\n" ++ ".section .fixup,\"ax\"\n" ++ " .even\n" ++ "4: movel %4,%0\n" ++ " jra 3b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ " .align 4\n" ++ " .long 1b,4b\n" ++ " .long 12b,4b\n" ++ ".previous" ++ : "=d"(res), "=a"(dst), "=a"(src), "=d"(count) ++ : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count) ++ : "d0", "memory"); ++ return res; ++} ++EXPORT_SYMBOL(strncpy_from_user); ++ ++/* ++ * Return the size of a string (including the ending 0) ++ * ++ * Return 0 on exception, a value greater than N if too long ++ */ ++long strnlen_user(const char *src, long n) ++{ ++ long res = -EFAULT; ++ if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */ ++ return res; ++ ++ res = -(long)src; ++ __asm__ __volatile__ ++ ("1:\n" ++ " tstl %2\n" ++ " jeq 3f\n" ++ "2: moveb (%1)+,%%d0\n" ++ "22:\n" ++ " subql #1,%2\n" ++ " tstb %%d0\n" ++ " jne 1b\n" ++ " jra 4f\n" ++ "3:\n" ++ " addql #1,%0\n" ++ "4:\n" ++ " addl %1,%0\n" ++ "5:\n" ++ ".section .fixup,\"ax\"\n" ++ " .even\n" ++ "6: moveq %3,%0\n" ++ " jra 5b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ " .align 4\n" ++ " .long 2b,6b\n" ++ " .long 22b,6b\n" ++ ".previous" ++ : "=d"(res), "=a"(src), "=d"(n) ++ : "i"(0), "0"(res), "1"(src), "2"(n) ++ : "d0"); ++ return res; ++} ++EXPORT_SYMBOL(strnlen_user); ++ ++ ++/* ++ * Zero Userspace ++ */ ++ ++unsigned long __clear_user(void *to, unsigned long n) ++{ ++ __asm__ __volatile__ ++ (" tstl %1\n" ++ " jeq 3f\n" ++ "1: movel %3,(%0)+\n" ++ "2: subql #1,%1\n" ++ " jne 1b\n" ++ "3: movel %2,%1\n" ++ " bclr #1,%1\n" ++ " jeq 4f\n" ++ "24:movew %3,(%0)+\n" ++ "4: bclr #0,%1\n" ++ " jeq 5f\n" ++ "25:moveb %3,(%0)+\n" ++ "5:\n" ++ ".section .fixup,\"ax\"\n" ++ " .even\n" ++ "61:addql #1,%1\n" ++ "6: lsll #2,%1\n" ++ " addl %2,%1\n" ++ " jra 5b\n" ++ "7: addql #2,%1\n" ++ " jra 5b\n" ++ "8: addql #1,%1\n" ++ " jra 5b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ " .align 4\n" ++ " .long 1b,61b\n" ++ " .long 2b,6b\n" ++ " .long 3b,61b\n" ++ " .long 24b,7b\n" ++ " .long 4b,7b\n" ++ " .long 25b,8b\n" ++ " .long 5b,8b\n" ++ ".previous" ++ : "=a"(to), "=d"(n) ++ : "r"(n & 3), "d"(0), "0"(to), "1"(n/4)); ++ return n; ++} ++EXPORT_SYMBOL(__clear_user); ++ ++#endif /* CONFIG_COLDFIRE */ ++ +--- a/arch/m68k/Makefile ++++ b/arch/m68k/Makefile +@@ -1,6 +1,8 @@ + # + # m68k/Makefile + # ++# Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. ++# + # This file is included by the global makefile so that you can add your own + # architecture-specific flags and dependencies. Remember to do have actions + # for "archclean" and "archdep" for cleaning up and making dependencies for +@@ -10,13 +12,13 @@ + # License. See the file "COPYING" in the main directory of this archive + # for more details. + # +-# Copyright (C) 1994 by Hamish Macdonald +-# + +-KBUILD_DEFCONFIG := multi_defconfig ++KBUILD_DEFCONFIG := amiga_defconfig#multi_defconfig + + # override top level makefile ++ifndef CONFIG_COLDFIRE + AS += -m68020 ++endif + LDFLAGS := -m m68kelf + LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds + ifneq ($(SUBARCH),$(ARCH)) +@@ -30,12 +32,18 @@ ifdef CONFIG_SUN3 + LDFLAGS_vmlinux = -N + endif + ++ifdef CONFIG_COLDFIRE ++OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment -S ++# LDFLAGS_vmlinux = --verbose ++endif ++ + CHECKFLAGS += -D__mc68000__ + + # without -fno-strength-reduce the 53c7xx.c driver fails ;-( + KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 + + # enable processor switch if compiled only for a single cpu ++ifndef CONFIG_COLDFIRE + ifndef CONFIG_M68020 + ifndef CONFIG_M68030 + +@@ -49,6 +57,17 @@ endif + + endif + endif ++endif ++ ++ifdef CONFIG_M5445X ++KBUILD_CFLAGS += -march=isac -mcpu=54455 -msoft-float -g ++KBUILD_AFLAGS += -march=isac -mcpu=54455 -msoft-float ++endif ++ ++ifdef CONFIG_M547X_8X ++KBUILD_CFLAGS += -mcfv4e -g ++KBUILD_AFLAGS += -mcfv4e ++endif + + ifdef CONFIG_KGDB + # If configured for kgdb support, include debugging infos and keep the +@@ -57,8 +76,12 @@ KBUILD_CFLAGS := $(subst -fomit-frame-po + endif + + ifndef CONFIG_SUN3 ++ifndef CONFIG_COLDFIRE + head-y := arch/m68k/kernel/head.o + else ++head-y := arch/m68k/coldfire/common/head.o ++endif ++else + head-y := arch/m68k/kernel/sun3-head.o + endif + +@@ -79,7 +102,20 @@ core-$(CONFIG_SUN3) += arch/m68k/sun3/ + core-$(CONFIG_M68040) += arch/m68k/fpsp040/ + core-$(CONFIG_M68060) += arch/m68k/ifpsp060/ + core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/ ++core-$(CONFIG_COLDFIRE) += arch/m68k/coldfire/ ++ ++ifdef CONFIG_COLDFIRE ++boot := arch/m68k/boot ++ ++all: uImage ++ ++zImage zImage.srec uImage uImage.srec vmlinux.srec: vmlinux ++ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + ++archclean: ++ $(Q)$(MAKE) $(clean)=$(boot) ++ ++else + all: zImage + + lilo: vmlinux +@@ -117,6 +153,7 @@ endif + + archclean: + rm -f vmlinux.gz vmlinux.bz2 ++endif + + install: + sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" +--- a/arch/m68k/mm/cache.c ++++ b/arch/m68k/mm/cache.c +@@ -4,13 +4,20 @@ + * Instruction cache handling + * + * Copyright (C) 1995 Hamish Macdonald ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + */ + + #include <linux/module.h> + #include <asm/pgalloc.h> + #include <asm/traps.h> + ++#ifdef CONFIG_COLDFIRE ++#include <asm/cfcache.h> ++#endif /* CONFIG_COLDFIRE */ + ++#ifndef CONFIG_COLDFIRE + static unsigned long virt_to_phys_slow(unsigned long vaddr) + { + if (CPU_IS_060) { +@@ -69,11 +76,18 @@ static unsigned long virt_to_phys_slow(u + } + return 0; + } ++#endif /* CONFIG_COLDFIRE */ ++ + + /* Push n pages at kernel virtual address and clear the icache */ + /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ + void flush_icache_range(unsigned long address, unsigned long endaddr) + { ++#ifdef CONFIG_COLDFIRE ++// JKM -- hack until new cpushl stuff is in ++// cf_icache_flush_range(address, endaddr); ++ flush_icache(); ++#else /* !CONFIG_COLDFIRE */ + + if (CPU_IS_040_OR_060) { + address &= PAGE_MASK; +@@ -94,9 +108,11 @@ void flush_icache_range(unsigned long ad + : "=&d" (tmp) + : "di" (FLUSH_I)); + } ++#endif /* CONFIG_COLDFIRE */ + } + EXPORT_SYMBOL(flush_icache_range); + ++#ifndef CONFIG_COLDFIRE + void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) + { +@@ -115,4 +131,5 @@ void flush_icache_user_range(struct vm_a + : "di" (FLUSH_I)); + } + } ++#endif /* CONFIG_COLDFIRE */ + +--- a/arch/m68k/mm/hwtest.c ++++ b/arch/m68k/mm/hwtest.c +@@ -12,6 +12,10 @@ + * them here complete with the comments from the original atari + * config.c... + * -- PMM <pmaydell@chiark.greenend.org.uk>, 05/1998 ++ * ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + */ + + /* This function tests for the presence of an address, specially a +@@ -25,6 +29,7 @@ + + #include <linux/module.h> + ++#ifndef CONFIG_COLDFIRE + int hwreg_present( volatile void *regp ) + { + int ret = 0; +@@ -82,4 +87,5 @@ int hwreg_write( volatile void *regp, un + return( ret ); + } + EXPORT_SYMBOL(hwreg_write); ++#endif + +--- a/arch/m68k/mm/init.c ++++ b/arch/m68k/mm/init.c +@@ -2,6 +2,9 @@ + * linux/arch/m68k/mm/init.c + * + * Copyright (C) 1995 Hamish Macdonald ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * + * Contains common initialization routines, specific init code moved + * to motorola.c and sun3mmu.c +@@ -31,6 +34,10 @@ + #include <asm/sections.h> + #include <asm/tlb.h> + ++#ifdef CONFIG_VDSO ++int vdso_init(void); ++#endif ++ + DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + + pg_data_t pg_data_map[MAX_NUMNODES]; +@@ -88,7 +95,6 @@ void __init mem_init(void) + if (MACH_IS_ATARI) + atari_stram_mem_init_hook(); + #endif +- + /* this will put all memory onto the freelists */ + totalram_pages = num_physpages = 0; + for_each_online_pgdat(pgdat) { +@@ -112,7 +118,7 @@ void __init mem_init(void) + } + } + +-#ifndef CONFIG_SUN3 ++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + /* insert pointer tables allocated so far into the tablelist */ + init_pointer_table((unsigned long)kernel_pg_dir); + for (i = 0; i < PTRS_PER_PGD; i++) { +@@ -131,6 +137,11 @@ void __init mem_init(void) + codepages << (PAGE_SHIFT-10), + datapages << (PAGE_SHIFT-10), + initpages << (PAGE_SHIFT-10)); ++ ++#ifdef CONFIG_VDSO ++ /* init the vdso page */ ++ vdso_init(); ++#endif + } + + #ifdef CONFIG_BLK_DEV_INITRD +--- a/arch/m68k/mm/kmap.c ++++ b/arch/m68k/mm/kmap.c +@@ -2,6 +2,9 @@ + * linux/arch/m68k/mm/kmap.c + * + * Copyright (C) 1997 Roman Hodek ++ * Copyright Freescale Semiconductor, Inc. 2008, 2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * + * 10/01/99 cleaned up the code and changing to the same interface + * used by other architectures /Roman Zippel +@@ -24,7 +27,11 @@ + + #undef DEBUG + ++#ifndef CONFIG_COLDFIRE + #define PTRTREESIZE (256*1024) ++#else ++#define PTRTREESIZE PAGE_SIZE ++#endif + + /* + * For 040/060 we can use the virtual memory area like other architectures, +@@ -50,7 +57,11 @@ static inline void free_io_area(void *ad + + #else + ++#ifdef CONFIG_COLDFIRE ++#define IO_SIZE PAGE_SIZE ++#else + #define IO_SIZE (256*1024) ++#endif + + static struct vm_struct *iolist; + +@@ -127,8 +138,41 @@ void __iomem *__ioremap(unsigned long ph + } + #endif + ++#ifdef CONFIG_M5445X ++ if (physaddr >= 0xf0000000) { ++ /* ++ * On the M5445x processors an ACR is setup to map ++ * the 0xF0000000 range into kernel memory as ++ * non-cacheable. ++ */ ++ return (void __iomem *)physaddr; ++ } ++ if ((physaddr >= KMAP_START) && (physaddr <= KMAP_END)) { ++ /* if physaddr belongs to virtual address range for ioremap, ++ * then return physaddr because it has been ioremapped ++ */ ++ return (void __iomem *)physaddr; ++ } ++#endif ++#ifdef CONFIG_M547X_8X ++ if (physaddr >= 0xf0000000) { ++ /* ++ * On the M547x/M548x processors an ACR is setup to map ++ * the 0xF0000000 range into kernel memory as ++ * non-cacheable. ++ */ ++ return (void __iomem *)physaddr; ++ } ++ ++ if ((physaddr >= 0xd0000000) && (physaddr + size < 0xd800ffff)) { ++ printk(KERN_ERR "ioremap:PCI 0x%lx,0x%lx(%d)" ++ " - PCI area hit\n", physaddr, size, cacheflag); ++ return (void *)physaddr; ++ } ++#endif + #ifdef DEBUG +- printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); ++ printk(KERN_ERR "ioremap: paddr=0x%lx,size=0x%lx(%d) - ", ++ physaddr, size, cacheflag); + #endif + /* + * Mappings have to be aligned +@@ -147,7 +191,8 @@ void __iomem *__ioremap(unsigned long ph + virtaddr = (unsigned long)area->addr; + retaddr = virtaddr + offset; + #ifdef DEBUG +- printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); ++ printk(KERN_ERR " paddr=0x%lx,vaddr=0x%lx,retaddr=0x%lx", ++ physaddr, virtaddr, retaddr); + #endif + + /* +@@ -172,7 +217,12 @@ void __iomem *__ioremap(unsigned long ph + break; + } + } else { ++#ifndef CONFIG_COLDFIRE + physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); ++#else ++ physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY | \ ++ _PAGE_READWRITE); ++#endif + switch (cacheflag) { + case IOMAP_NOCACHE_SER: + case IOMAP_NOCACHE_NONSER: +@@ -252,6 +302,13 @@ void __iounmap(void *addr, unsigned long + pmd_t *pmd_dir; + pte_t *pte_dir; + ++#ifdef CONFIG_M547X_8X ++ if ((addr >= (void *)0xd0000000) ++ && (addr + size < (void *)0xd800ffff)) { ++ printk(KERN_ERR "%s: PCI address\n", __func__); ++ return; ++ } ++#endif + while ((long)size > 0) { + pgd_dir = pgd_offset_k(virtaddr); + if (pgd_bad(*pgd_dir)) { +--- a/arch/m68k/mm/Makefile ++++ b/arch/m68k/mm/Makefile +@@ -6,3 +6,5 @@ obj-y := cache.o init.o fault.o hwtest. + + obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o + obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o ++obj-$(CONFIG_MMU_CFV4E) += cf-mmu.o kmap.o memory.o ++obj-$(CONFIG_SRAM) += cf-sram.o +--- a/arch/m68k/mm/memory.c ++++ b/arch/m68k/mm/memory.c +@@ -2,6 +2,10 @@ + * linux/arch/m68k/mm/memory.c + * + * Copyright (C) 1995 Hamish Macdonald ++ * Copyright Freescale Semiconductor, Inc. 2008-2009 ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com ++ * + */ + + #include <linux/module.h> +@@ -127,6 +131,7 @@ int free_pointer_table (pmd_t *ptable) + return 0; + } + ++#ifndef CONFIG_COLDFIRE + /* invalidate page in both caches */ + static inline void clear040(unsigned long paddr) + { +@@ -173,6 +178,7 @@ static inline void pushcl040(unsigned lo + clear040(paddr); + local_irq_restore(flags); + } ++#endif /* CONFIG_COLDFIRE */ + + /* + * 040: Hit every page containing an address in the range paddr..paddr+len-1. +@@ -203,6 +209,11 @@ static inline void pushcl040(unsigned lo + + void cache_clear (unsigned long paddr, int len) + { ++#ifdef CONFIG_COLDFIRE ++// JKM -- revise to use proper caching ++// cf_cache_clear(paddr, len); ++ flush_bcache(); ++#else + if (CPU_IS_040_OR_060) { + int tmp; + +@@ -237,6 +248,7 @@ void cache_clear (unsigned long paddr, i + if(mach_l2_flush) + mach_l2_flush(0); + #endif ++#endif /* CONFIG_COLDFIRE */ + } + EXPORT_SYMBOL(cache_clear); + +@@ -250,6 +262,11 @@ EXPORT_SYMBOL(cache_clear); + + void cache_push (unsigned long paddr, int len) + { ++#ifdef CONFIG_COLDFIRE ++// JKM -- revise to use proper caching ++// cf_cache_push(paddr, len); ++ flush_bcache(); ++#else + if (CPU_IS_040_OR_060) { + int tmp = PAGE_SIZE; + +@@ -290,6 +307,7 @@ void cache_push (unsigned long paddr, in + if(mach_l2_flush) + mach_l2_flush(1); + #endif ++#endif /* CONFIG_COLDFIRE */ + } + EXPORT_SYMBOL(cache_push); + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -3,6 +3,10 @@ + * + * (C) Copyright Al Viro 2000, 2001 + * Released under GPL v2. ++ * (c) Copyright Freescale Semiconductor, Inc. 2008, 2009 ++ * Change to align on page size for coldfire ++ * Jason Jin Jason.Jin@freescale.com ++ * Shrek Wu B16972@freescale.com + * + * Based on code from fs/super.c, copyright Linus Torvalds and others. + * Heavily rewritten. +@@ -1858,7 +1862,11 @@ int copy_mount_options(const void __user + /* copy_from_user cannot cross TASK_SIZE ! */ + size = TASK_SIZE - (unsigned long)data; + if (size > PAGE_SIZE) ++#ifndef CONFIG_COLDFIRE + size = PAGE_SIZE; ++#else ++ size = PAGE_SIZE - ((unsigned long)data & ~PAGE_MASK); ++#endif + + i = size - exact_copy_from_user((void *)page, data, size); + if (!i) { +--- a/include/linux/fsl_devices.h ++++ b/include/linux/fsl_devices.h +@@ -6,7 +6,7 @@ + * + * Maintainer: Kumar Gala <galak@kernel.crashing.org> + * +- * Copyright 2004 Freescale Semiconductor, Inc ++ * Copyright 2004-2008 Freescale Semiconductor, Inc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the +@@ -18,6 +18,7 @@ + #define _FSL_DEVICE_H_ + + #include <linux/types.h> ++#include <linux/interrupt.h> + + /* + * Some conventions on how we handle peripherals on Freescale chips +@@ -58,11 +59,42 @@ enum fsl_usb2_phy_modes { + FSL_USB2_PHY_SERIAL, + }; + ++struct platform_device; + struct fsl_usb2_platform_data { + /* board specific information */ + enum fsl_usb2_operating_modes operating_mode; + enum fsl_usb2_phy_modes phy_mode; + unsigned int port_enables; ++ ++ char *name; /* pretty print */ ++ int (*platform_init) (struct platform_device *); ++ void (*platform_uninit) (struct fsl_usb2_platform_data *); ++ void __iomem *regs; /* ioremap'd register base */ ++ u32 xcvr_type; /* PORTSC_PTS_* */ ++ char *transceiver; /* transceiver name */ ++ unsigned power_budget; /* for hcd->power_budget */ ++ struct platform_device *pdev; ++ struct fsl_xcvr_ops *xcvr_ops; ++ int (*gpio_usb_active) (void); ++ void (*gpio_usb_inactive) (void); ++ unsigned big_endian_mmio : 1; ++ unsigned big_endian_desc : 1; ++ unsigned es : 1; /* need USBMODE:ES */ ++ unsigned have_sysif_regs : 1; ++ unsigned le_setup_buf : 1; ++ unsigned suspended : 1; ++ unsigned already_suspended : 1; ++ ++ /* register save area for suspend/resume */ ++ u32 pm_command; ++ u32 pm_status; ++ u32 pm_intr_enable; ++ u32 pm_frame_index; ++ u32 pm_segment; ++ u32 pm_frame_list; ++ u32 pm_async_next; ++ u32 pm_configured_flag; ++ u32 pm_portsc; + }; + + /* Flags in fsl_usb2_mph_platform_data */ +@@ -92,4 +124,30 @@ struct mpc8xx_pcmcia_ops { + */ + int fsl_deep_sleep(void); + ++struct fsl_ata_platform_data { ++#ifdef CONFIG_FSL_PATA_USE_DMA ++ int udma_mask; /* UDMA modes h/w can handle */ ++ int fifo_alarm; /* value for fifo_alarm reg */ ++ int max_sg; /* longest sglist h/w can handle */ ++#endif ++ int (*init)(struct platform_device *pdev); ++ void (*exit)(void); ++ int (*get_clk_rate)(void); ++}; ++ ++struct coldfire_fec_platform_data { ++ int hash_table; ++ unsigned int *fec_hw; ++ void (*request_intrs)(struct net_device *dev, ++ irqreturn_t (*)(int, void *), ++ void *irq_privatedata); ++ void (*set_mii)(struct net_device *dev); ++ void (*get_mac)(struct net_device *dev); ++ void (*enable_phy_intr)(void); ++ void (*disable_phy_intr)(void); ++ void (*phy_ack_intr)(void); ++ void (*localhw_setup)(void); ++ void (*uncache)(unsigned long addr); ++ void (*platform_flush_cache)(void); ++}; + #endif /* _FSL_DEVICE_H_ */ |