aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch')
-rw-r--r--target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch11199
1 files changed, 11199 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch b/target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch
new file mode 100644
index 000000000..6b889914a
--- /dev/null
+++ b/target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch
@@ -0,0 +1,11199 @@
+From c462e1a613c8f84bb503189b0796d036dd1e5376 Mon Sep 17 00:00:00 2001
+From: Jason Jin <jason.jin@freescale.com>
+Date: Thu, 4 Aug 2011 09:59:35 +0800
+Subject: [PATCH 01/52] Coldfire architecture support in Linux 2.6.38
+
+Coldfire architecture support in Linux 2.6.38.
+
+Signed-off-by: Alison Wang <b18965@freescale.com>
+Signed-off-by: Jason Jin <jason.jin@freescale.com>
+---
+ arch/m68k/Kconfig | 279 +++++++++-
+ arch/m68k/Kconfig.debug | 9 +
+ arch/m68k/Makefile | 48 ++-
+ arch/m68k/boot/Makefile | 68 +++
+ arch/m68k/coldfire/Makefile | 10 +
+ arch/m68k/coldfire/common/Makefile | 7 +
+ arch/m68k/coldfire/common/cache.c | 45 ++
+ arch/m68k/coldfire/common/clk.c | 51 ++
+ arch/m68k/coldfire/common/entry.S | 745 ++++++++++++++++++++++++
+ arch/m68k/coldfire/common/head.S | 466 +++++++++++++++
+ arch/m68k/coldfire/common/ints.c | 544 ++++++++++++++++++
+ arch/m68k/coldfire/common/muldi3.S | 73 +++
+ arch/m68k/coldfire/common/signal.c | 991 ++++++++++++++++++++++++++++++++
+ arch/m68k/coldfire/common/traps.c | 457 +++++++++++++++
+ arch/m68k/include/asm/atomic.h | 33 +-
+ arch/m68k/include/asm/bitops_mm.h | 12 +-
+ arch/m68k/include/asm/bootinfo.h | 42 ++
+ arch/m68k/include/asm/cacheflush_mm.h | 14 +-
+ arch/m68k/include/asm/cf-sram.h | 21 +
+ arch/m68k/include/asm/cf_bitops.h | 443 ++++++++++++++
+ arch/m68k/include/asm/cf_cacheflush.h | 20 +
+ arch/m68k/include/asm/cf_entry.h | 153 +++++
+ arch/m68k/include/asm/cf_io.h | 185 ++++++
+ arch/m68k/include/asm/cf_pgalloc.h | 112 ++++
+ arch/m68k/include/asm/cf_pgtable.h | 364 ++++++++++++
+ arch/m68k/include/asm/cf_raw_io.h | 188 ++++++
+ arch/m68k/include/asm/cf_tlbflush.h | 66 +++
+ arch/m68k/include/asm/cf_uaccess.h | 262 +++++++++
+ arch/m68k/include/asm/cf_virtconvert.h | 63 ++
+ arch/m68k/include/asm/cfcache.h | 146 +++++
+ arch/m68k/include/asm/cfmmu.h | 112 ++++
+ arch/m68k/include/asm/coldfire.h | 70 ++-
+ arch/m68k/include/asm/delay_mm.h | 42 ++-
+ arch/m68k/include/asm/div64.h | 11 +-
+ arch/m68k/include/asm/dma.h | 109 ++++-
+ arch/m68k/include/asm/elf.h | 70 +++-
+ arch/m68k/include/asm/io_mm.h | 234 ++++++--
+ arch/m68k/include/asm/irq.h | 14 +-
+ arch/m68k/include/asm/machdep.h | 15 +-
+ arch/m68k/include/asm/mcfdspi.h | 59 ++
+ arch/m68k/include/asm/mcfsim.h | 121 ++++
+ arch/m68k/include/asm/mcfuart.h | 64 ++
+ arch/m68k/include/asm/mmu.h | 15 +-
+ arch/m68k/include/asm/mmu_context.h | 184 ++++++-
+ arch/m68k/include/asm/page.h | 10 +-
+ arch/m68k/include/asm/page_mm.h | 61 ++
+ arch/m68k/include/asm/page_offset.h | 21 +-
+ arch/m68k/include/asm/pgalloc.h | 12 +-
+ arch/m68k/include/asm/pgtable_mm.h | 36 ++-
+ arch/m68k/include/asm/processor.h | 45 ++-
+ arch/m68k/include/asm/ptrace.h | 48 ++-
+ arch/m68k/include/asm/raw_io.h | 15 +-
+ arch/m68k/include/asm/segment.h | 17 +
+ arch/m68k/include/asm/setup.h | 36 ++
+ arch/m68k/include/asm/signal.h | 10 +-
+ arch/m68k/include/asm/string.h | 20 +-
+ arch/m68k/include/asm/swab.h | 15 +-
+ arch/m68k/include/asm/system_mm.h | 23 +-
+ arch/m68k/include/asm/tlbflush.h | 24 +-
+ arch/m68k/include/asm/uaccess_mm.h | 80 ++--
+ arch/m68k/include/asm/unistd.h | 11 +-
+ arch/m68k/include/asm/virtconvert.h | 11 +
+ arch/m68k/kernel/Makefile | 23 +-
+ arch/m68k/kernel/asm-offsets.c | 28 +
+ arch/m68k/kernel/dma.c | 47 ++-
+ arch/m68k/kernel/process.c | 66 +++
+ arch/m68k/kernel/setup.c | 72 ++-
+ arch/m68k/kernel/sys_m68k.c | 80 +++
+ arch/m68k/kernel/time.c | 142 +++++-
+ arch/m68k/kernel/vmlinux-cf.lds | 142 +++++
+ arch/m68k/kernel/vmlinux.lds.S | 12 +-
+ arch/m68k/lib/checksum.c | 129 +++++
+ arch/m68k/lib/muldi3.c | 13 +
+ arch/m68k/lib/string.c | 68 +++
+ arch/m68k/lib/uaccess.c | 247 ++++++++
+ arch/m68k/mm/Makefile | 2 +
+ arch/m68k/mm/cache.c | 19 +
+ arch/m68k/mm/cf-mmu.c | 311 ++++++++++
+ arch/m68k/mm/cf-sram.c | 80 +++
+ arch/m68k/mm/hwtest.c | 10 +
+ arch/m68k/mm/init.c | 15 +-
+ arch/m68k/mm/kmap.c | 82 +++-
+ arch/m68k/mm/memory.c | 17 +
+ fs/namespace.c | 8 +
+ include/linux/fsl_devices.h | 14 +-
+ 85 files changed, 8962 insertions(+), 197 deletions(-)
+ create mode 100644 arch/m68k/boot/Makefile
+ create mode 100644 arch/m68k/coldfire/Makefile
+ create mode 100644 arch/m68k/coldfire/common/Makefile
+ create mode 100644 arch/m68k/coldfire/common/cache.c
+ create mode 100644 arch/m68k/coldfire/common/clk.c
+ create mode 100644 arch/m68k/coldfire/common/entry.S
+ create mode 100644 arch/m68k/coldfire/common/head.S
+ create mode 100644 arch/m68k/coldfire/common/ints.c
+ create mode 100644 arch/m68k/coldfire/common/muldi3.S
+ create mode 100644 arch/m68k/coldfire/common/signal.c
+ create mode 100644 arch/m68k/coldfire/common/traps.c
+ create mode 100644 arch/m68k/include/asm/cf-sram.h
+ create mode 100644 arch/m68k/include/asm/cf_bitops.h
+ create mode 100644 arch/m68k/include/asm/cf_cacheflush.h
+ create mode 100644 arch/m68k/include/asm/cf_entry.h
+ create mode 100644 arch/m68k/include/asm/cf_io.h
+ create mode 100644 arch/m68k/include/asm/cf_pgalloc.h
+ create mode 100644 arch/m68k/include/asm/cf_pgtable.h
+ create mode 100644 arch/m68k/include/asm/cf_raw_io.h
+ create mode 100644 arch/m68k/include/asm/cf_tlbflush.h
+ create mode 100644 arch/m68k/include/asm/cf_uaccess.h
+ create mode 100644 arch/m68k/include/asm/cf_virtconvert.h
+ create mode 100644 arch/m68k/include/asm/cfcache.h
+ create mode 100644 arch/m68k/include/asm/cfmmu.h
+ create mode 100644 arch/m68k/include/asm/mcfdspi.h
+ create mode 100644 arch/m68k/kernel/vmlinux-cf.lds
+ create mode 100644 arch/m68k/mm/cf-mmu.c
+ create mode 100644 arch/m68k/mm/cf-sram.c
+
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -9,6 +9,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
+@@ -34,7 +42,7 @@ config GENERIC_CALIBRATE_DELAY
+
+ config TIME_LOW_RES
+ bool
+- default y
++ default n
+
+ config GENERIC_IOMAP
+ bool
+@@ -46,7 +54,7 @@ config ARCH_MAY_HAVE_PC_FDC
+ default y
+
+ config NO_IOPORT
+- def_bool y
++ def_bool !(M5445X || M547X_8X || M5441X)
+
+ config NO_DMA
+ def_bool SUN3
+@@ -105,6 +113,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
+@@ -122,6 +159,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
+@@ -276,6 +323,147 @@ 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 M5474LITE
++ bool "MCF5474LITE"
++ select M547X
++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 M5484LITE
++ bool "MCF5484LITE"
++ select M548X
++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 M5441X
++ bool "MCF5441x support"
++ depends on COLDFIRE
++ select GENERIC_TIME
++ select USB_EHCI_FSL
++ select HAVE_FSL_USB_DR
++ help
++ This option will add support for the MCF5441x processor with mmu.
++
++config M54418
++ bool
++ depends on M5441X
++ default n
++choice
++ prompt "Model"
++ depends on M5441X
++ default M54418EVB
++ config M54418EVB
++ bool "M54418EVB"
++ select M54418
++endchoice
++
++config MCFCLK
++ int
++ default 240000000 if M54451EVB
++ default 266666666 if M54455EVB
++ default 266000000 if M547X
++ default 200000000 if M548X
++ default 250000000 if M54418EVB && !USB_M5441X_PLLCLK
++ default 150000000 if M54418EVB && USB_M5441X_PLLCLK
++ help
++ Coldfire System clock.
++
++config MCF_USER_HALT
++ bool "Coldfire User Halt Enable"
++ depends on M5445X || M547X_8X || M5441X
++ default n
++ help
++ Enables the HALT instruction in User Mode.
++
+ config MMU_MOTOROLA
+ bool
+
+@@ -283,6 +471,81 @@ 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
++ default 0x40000000 if M5441X
++
++config SDRAM_SIZE
++ hex
++ depends on COLDFIRE
++ default 0x08000000 if M54451EVB
++ default 0x10000000 if M54455EVB
++ default 0x04000000 if M547X_8X
++ default 0x08000000 if M54418EVB
++
++config NOR_FLASH_BASE
++ hex "NOR Flash Base Address"
++ depends on COLDFIRE
++ default 0x00000000 if M54451EVB
++ default 0x00000000 if M54455EVB
++ default 0xE0000000 if M5475CFE
++ default 0xE0000000 if M5485CFE
++ default 0xFF800000 if M5484LITE
++ default 0xFF800000 if M5474LITE
++ default 0x00000000 if M54418EVB
++
++config DMA_BASE
++ hex
++ depends on COLDFIRE
++ default 0xef000000 if M5445X
++ default 0xef000000 if M547X_8X
++ default 0xdf000000 if M5441X
++
++config DMA_SIZE
++ hex
++ depends on COLDFIRE
++ default 0x1000000 if M5445X
++ default 0x800000 if M547X_8X
++ default 0x1000000 if M5441X
++
++config SRAM
++ bool "SRAM allocation APIs support on mcfv4 platform"
++ depends on COLDFIRE && (M5445X || M5441X)
++ default y
++ select GENERIC_ALLOCATOR
++
++config SRAM_BASE
++ hex
++ depends on COLDFIRE && SRAM
++ default 0x8ff00000 if M5445X
++ default 0x8ff00000 if M5441X
++
++config SRAM_SIZE
++ hex
++ depends on COLDFIRE && SRAM
++ default 0x8000 if M5445X
++ default 0x10000 if M5441X
++
++config SRAM_ALLOC_GRANULARITY
++ hex
++ depends on SRAM
++ default 0x200 if (M5445X || M5441X)
++
++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
+@@ -449,6 +712,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
+
+@@ -583,7 +854,7 @@ config DN_SERIAL
+
+ config SERIAL_CONSOLE
+ bool "Support for serial port console"
+- depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=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 || SUN3 || SUN3X || VME || APOLLO || COLDFIRE) && (ATARI_MFPSER=y || ATARI_MIDI=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
+@@ -606,6 +877,8 @@ config SERIAL_CONSOLE
+
+ endmenu
+
++source "kernel/time/Kconfig"
++
+ source "fs/Kconfig"
+
+ source "arch/m68k/Kconfig.debug"
+--- a/arch/m68k/Kconfig.debug
++++ b/arch/m68k/Kconfig.debug
+@@ -2,4 +2,13 @@ menu "Kernel hacking"
+
+ source "lib/Kconfig.debug"
+
++config BOOTPARAM
++ bool 'Compiled-in Kernel Boot Parameter'
++ depends on COLDFIRE
++
++config BOOTPARAM_STRING
++ string 'Kernel Boot Parameter'
++ default 'console=ttyS0,115200'
++ depends on BOOTPARAM
++
+ endmenu
+--- a/arch/m68k/Makefile
++++ b/arch/m68k/Makefile
+@@ -1,6 +1,8 @@
+ #
+ # m68k/Makefile
+ #
++# Copyright (C) 2007-2011 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
+ KBUILD_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,22 @@ 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_M5441X
++KBUILD_CFLAGS += -march=isac -mcpu=54418 -msoft-float -g
++KBUILD_AFLAGS += -march=isac -mcpu=54418 -msoft-float
++endif
+
+ ifdef CONFIG_KGDB
+ # If configured for kgdb support, include debugging infos and keep the
+@@ -57,8 +81,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 +107,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 +158,7 @@ endif
+
+ archclean:
+ rm -f vmlinux.gz vmlinux.bz2
++endif
+
+ install:
+ sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
+--- /dev/null
++++ b/arch/m68k/boot/Makefile
+@@ -0,0 +1,68 @@
++#
++# arch/m68k/boot/Makefile
++#
++# Based on arch/sh/boot/Makefile by Stuart Menefy
++#
++# Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++# by Kurt Mahan <kmahan@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.
++#
++
++MKIMAGE := $(srctree)/scripts/mkuboot.sh
++
++#
++# Assign safe dummy values if these variables are not defined,
++# in order to suppress error message.
++#
++CONFIG_SDRAM_BASE ?= 0x40000000
++CONFIG_IMG_START ?= 0x00020000
++
++export CONFIG_SDRAM_BASE CONFIG_IMG_START
++
++targets := zImage zImage.srec vmlinux.srec uImage uImage.srec
++
++$(obj)/zImage: $(obj)/vmlinux.bin FORCE
++ $(call if_changed,gzip)
++ @echo ' Image $@ is ready'
++
++OBJCOPYFLAGS_zImage.srec := -I binary -O srec
++$(obj)/zImage.srec: $(obj)/zImage
++ $(call if_changed,objcopy)
++
++KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
++ $$[$(CONFIG_SDRAM_BASE) + \
++ $(CONFIG_IMG_START)]')
++
++KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
++ $$[$(CONFIG_SDRAM_BASE) + \
++ $(CONFIG_IMG_START)]')
++
++quiet_cmd_uimage = UIMAGE $@
++ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A m68k -O linux -T kernel \
++ -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
++ -n 'Linux-$(KERNELRELEASE)' -d $< $@
++
++$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
++ $(call if_changed,uimage)
++ @echo ' Image $@ is ready'
++
++$(obj)/vmlinux.bin: vmlinux FORCE
++ $(call if_changed,objcopy)
++
++$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
++ $(call if_changed,gzip)
++
++OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
++$(obj)/vmlinux.srec: $(obj)/vmlinux.bin
++ $(call if_changed,objcopy)
++
++OBJCOPYFLAGS_uImage.srec := -I binary -O srec
++$(obj)/uImage.srec: $(obj)/uImage
++ $(call if_changed,objcopy)
++
++clean-files += uImage uImage.srec \
++ zImage zImage.srec \
++ vmlinux.srec vmlinux.bin vmlinux.bin.gz
+--- /dev/null
++++ b/arch/m68k/coldfire/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for Linux arch/m68k/coldfire source directory
++#
++
++obj-y += common/
++obj-$(CONFIG_VDSO) += vdso/
++
++obj-$(CONFIG_M5445X) += m5445x/
++obj-$(CONFIG_M547X_8X) += m547x/
++obj-$(CONFIG_M5441X) += m5441x/
+--- /dev/null
++++ b/arch/m68k/coldfire/common/Makefile
+@@ -0,0 +1,7 @@
++#
++# Makefile for Linux arch/m68k/coldfire/common source directory
++#
++
++obj-y:= entry.o cache.o signal.o muldi3.o traps.o ints.o clk.o
++extra-y:= head.o
++
+--- /dev/null
++++ b/arch/m68k/coldfire/common/cache.c
+@@ -0,0 +1,45 @@
++/*
++ * linux/arch/m68k/coldfire/cache.c
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Matt Waddel Matt.Waddel@freescale.com
++ * Kurt Mahan kmahan@freescale.com
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/interrupt.h>
++#include <asm/cfcache.h>
++#include <asm/coldfire.h>
++#include <asm/system.h>
++
++/* Cache Control Reg shadow reg */
++unsigned long shadow_cacr;
++
++/**
++ * cacr_set - Set the Cache Control Register
++ * @x Value to set
++ */
++void cacr_set(unsigned long x)
++{
++ shadow_cacr = x;
++
++ __asm__ __volatile__ ("movec %0, %%cacr"
++ : /* no outputs */
++ : "r" (shadow_cacr));
++}
++
++/**
++ * cacr_get - Get the current value of the Cache Control Register
++ *
++ * @return CACR value
++ */
++unsigned long cacr_get(void)
++{
++ return shadow_cacr;
++}
+--- /dev/null
++++ b/arch/m68k/coldfire/common/clk.c
+@@ -0,0 +1,51 @@
++/***************************************************************************/
++
++/*
++ * clk.c -- general ColdFire CPU kernel clk handling
++ *
++ * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
++ * Copyright (C) 2011 Freescale Semiconductore, Inc. All Rights Reserved.
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++*/
++
++/***************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/clk.h>
++#include <asm/coldfire.h>
++
++/***************************************************************************/
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++ return NULL;
++}
++EXPORT_SYMBOL(clk_get);
++
++int clk_enable(struct clk *clk)
++{
++ return 0;
++}
++EXPORT_SYMBOL(clk_enable);
++
++void clk_disable(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_disable);
++
++void clk_put(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_put);
++
++unsigned long clk_get_rate(struct clk *clk)
++{
++ return MCF_CLK;
++}
++EXPORT_SYMBOL(clk_get_rate);
++/***************************************************************************/
+--- /dev/null
++++ b/arch/m68k/coldfire/common/entry.S
+@@ -0,0 +1,745 @@
++/*
++ * arch/m68k/coldfire/entry.S
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Matt Waddel Matt.Waddel@freescale.com
++ * Kurt Mahan kmahan@freescale.com
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ *
++ * Based on:
++ *
++ * arch/m68knommu/platform/5307/entry.S &
++ * arch/m68k/kernel/entry.S
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file README.legal in the main directory of this archive
++ * for more details.
++ */
++
++#include <linux/sys.h>
++#include <linux/linkage.h>
++#include <asm/cf_entry.h>
++#include <asm/errno.h>
++#include <asm/setup.h>
++#include <asm/segment.h>
++#include <asm/traps.h>
++#include <asm/unistd.h>
++#include <asm/asm-offsets.h>
++
++/*
++ * TASK_INFO:
++ *
++ * - TINFO_PREEMPT (struct thread_info / preempt_count)
++ * Used to keep track of preemptability
++ * - TINFO_FLAGS (struct thread_info / flags - include/asm-m68k/thread_info.h)
++ * Various bit flags that are checked for scheduling/tracing
++ * Bits 0-7 are checked every exception exit
++ * 8-15 are checked every syscall exit
++ *
++ * TIF_SIGPENDING 6
++ * TIF_NEED_RESCHED 7
++ * TIF_DELAYED_TRACE 14
++ * TIF_SYSCALL_TRACE 15
++ * TIF_MEMDIE 16 (never checked here)
++ */
++
++.bss
++
++sw_ksp:
++.long 0
++
++sw_usp:
++.long 0
++
++.text
++
++.globl system_call
++.globl buserr
++.globl trap
++.globl resume
++.globl ret_from_exception
++.globl ret_from_signal
++.globl sys_call_table
++.globl ret_from_interrupt
++.globl inthandler
++
++ENTRY(buserr)
++#ifdef CONFIG_COLDFIRE_FOO
++ movew #0x2700,%sr /* lock interrupts */
++#endif
++ SAVE_ALL_INT
++#ifdef CONFIG_COLDFIRE_FOO
++ movew PT_0FF_SR(%sp),%d3 /* get original %sr */
++ oril #0x2000,%d3 /* set supervisor mode in it */
++ movew %d3,%sr /* recover irq state */
++#endif
++ GET_CURRENT(%d0)
++ movel %sp,%sp@- /* stack frame pointer argument */
++ jsr buserr_c
++ addql #4,%sp
++ jra .Lret_from_exception
++
++ENTRY(trap)
++ SAVE_ALL_INT
++ GET_CURRENT(%d0)
++ movel %sp,%sp@- /* stack frame pointer argument */
++ jsr trap_c
++ addql #4,%sp
++ jra .Lret_from_exception
++
++ /* After a fork we jump here directly from resume,
++ %d1 contains the previous task schedule_tail */
++ENTRY(ret_from_fork)
++ movel %d1,%sp@-
++ jsr schedule_tail
++ addql #4,%sp
++ jra .Lret_from_exception
++
++do_trace_entry:
++ movel #-ENOSYS,%d1 /* needed for strace */
++ movel %d1,%sp@(PT_OFF_D0)
++ subql #4,%sp
++ SAVE_SWITCH_STACK
++ jbsr syscall_trace
++ RESTORE_SWITCH_STACK
++ addql #4,%sp
++ movel %sp@(PT_OFF_ORIG_D0),%d0
++ cmpl #NR_syscalls,%d0
++ jcs syscall
++badsys:
++ movel #-ENOSYS,%d1
++ movel %d1,%sp@(PT_OFF_D0)
++ jra ret_from_exception
++
++do_trace_exit:
++ subql #4,%sp
++ SAVE_SWITCH_STACK
++ jbsr syscall_trace
++ RESTORE_SWITCH_STACK
++ addql #4,%sp
++ jra .Lret_from_exception
++
++ENTRY(ret_from_signal)
++ RESTORE_SWITCH_STACK
++ addql #4,%sp
++ jra .Lret_from_exception
++
++ENTRY(system_call)
++ SAVE_ALL_SYS
++
++ GET_CURRENT(%d1)
++ /* save top of frame */
++ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
++
++ /* syscall trace */
++ tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
++ jmi do_trace_entry /* SYSCALL_TRACE is set */
++ cmpl #NR_syscalls,%d0
++ jcc badsys
++syscall:
++ movel #sys_call_table,%a0
++ asll #2,%d0
++ addl %d0,%a0
++ movel %a0@,%a0
++ jsr %a0@
++ movel %d0,%sp@(PT_OFF_D0) /* save the return value */
++ret_from_syscall:
++ movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
++ jne syscall_exit_work /* flags set so process */
++1: RESTORE_ALL
++
++syscall_exit_work:
++ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
++ bnes 1b /* if so, skip resched, signals */
++
++ btstl #15,%d0 /* check if SYSCALL_TRACE */
++ jne do_trace_exit
++ btstl #14,%d0 /* check if DELAYED_TRACE */
++ jne do_delayed_trace
++ btstl #6,%d0 /* check if SIGPENDING */
++ jne do_signal_return
++ pea resume_userspace
++ jra schedule
++
++ENTRY(ret_from_exception)
++.Lret_from_exception:
++ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
++ bnes 1f /* if so, skip resched, signals */
++ movel %d0,%sp@- /* Only allow interrupts when we are */
++ move %sr,%d0 /* last one on the kernel stack, */
++ andl #ALLOWINT,%d0 /* otherwise stack overflow can occur */
++ move %d0,%sr /* during heavy interrupt load. */
++ movel %sp@+,%d0
++
++resume_userspace:
++ moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
++ jne exit_work /* SIGPENDING and/or NEED_RESCHED set */
++1: RESTORE_ALL
++
++exit_work:
++ /* save top of frame */
++ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
++ btstl #6,%d0 /* check for SIGPENDING in flags */
++ jne do_signal_return
++ pea resume_userspace
++ jra schedule
++
++do_signal_return:
++ subql #4,%sp /* dummy return address */
++ SAVE_SWITCH_STACK
++ pea %sp@(SWITCH_STACK_SIZE)
++ clrl %sp@-
++ bsrl do_signal
++ addql #8,%sp
++ RESTORE_SWITCH_STACK
++ addql #4,%sp
++ jbra resume_userspace
++
++do_delayed_trace:
++ bclr #7,%sp@(PT_OFF_SR) /* clear trace bit in SR */
++ pea 1 /* send SIGTRAP */
++ movel %curptr,%sp@-
++ pea LSIGTRAP
++ jbsr send_sig
++ addql #8,%sp
++ addql #4,%sp
++ jbra resume_userspace
++
++/*
++ * This is the interrupt handler (for all hardware interrupt
++ * sources). It figures out the vector number and calls the appropriate
++ * interrupt service routine directly.
++ */
++ENTRY(inthandler)
++ SAVE_ALL_INT
++ GET_CURRENT(%d0)
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ addil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++ /* put exception # in d0 */
++ movel %sp@(PT_VECTOR),%d0
++ swap %d0 /* extract bits 25:18 */
++ lsrl #2,%d0
++ andl #0x0ff,%d0
++
++ movel %sp,%sp@-
++ movel %d0,%sp@- /* put vector # on stack */
++auto_irqhandler_fixup = . + 2
++ jbsr process_int /* process the IRQ */
++ addql #8,%sp /* pop parameters off stack */
++
++ret_from_interrupt:
++
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ subil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++ jeq ret_from_last_interrupt
++2: RESTORE_ALL
++
++ ALIGN
++ret_from_last_interrupt:
++ moveb %sp@(PT_OFF_SR),%d0
++ andl #(~ALLOWINT>>8)&0xff,%d0
++ jne 2b
++
++ /* check if we need to do software interrupts */
++ tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
++ jeq .Lret_from_exception
++ pea ret_from_exception
++ jra do_softirq
++
++ENTRY(user_inthandler)
++ SAVE_ALL_INT
++ GET_CURRENT(%d0)
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ addil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++ /* put exception # in d0 */
++ movel %sp@(PT_VECTOR),%d0
++user_irqvec_fixup = . + 2
++ swap %d0 /* extract bits 25:18 */
++ lsrl #2,%d0
++ andl #0x0ff,%d0
++
++ movel %sp,%sp@-
++ movel %d0,%sp@- /* put vector # on stack */
++user_irqhandler_fixup = . + 2
++ jbsr process_int /* process the IRQ */
++ addql #8,%sp /* pop parameters off stack */
++
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ subil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++ jeq ret_from_last_interrupt
++ RESTORE_ALL
++
++/* Handler for uninitialized and spurious interrupts */
++
++ENTRY(bad_inthandler)
++ SAVE_ALL_INT
++ GET_CURRENT(%d0)
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ addil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++
++ movel %sp,%sp@-
++ jsr handle_badint
++ addql #4,%sp
++
++ movel %curptr@(TASK_INFO+TINFO_PREEMPT),%d0
++ subil #0x10000,%d0
++ movel %d0,%curptr@(TASK_INFO+TINFO_PREEMPT)
++ jeq ret_from_last_interrupt
++ RESTORE_ALL
++
++ENTRY(sys_fork)
++ SAVE_SWITCH_STACK
++ pea %sp@(SWITCH_STACK_SIZE)
++ jbsr m68k_fork
++ addql #4,%sp
++ RESTORE_SWITCH_STACK
++ rts
++
++ENTRY(sys_clone)
++ SAVE_SWITCH_STACK
++ pea %sp@(SWITCH_STACK_SIZE)
++ jbsr m68k_clone
++ addql #4,%sp
++ RESTORE_SWITCH_STACK
++ rts
++
++ENTRY(sys_vfork)
++ SAVE_SWITCH_STACK
++ pea %sp@(SWITCH_STACK_SIZE)
++ jbsr m68k_vfork
++ addql #4,%sp
++ RESTORE_SWITCH_STACK
++ rts
++
++ENTRY(sys_sigsuspend)
++ SAVE_SWITCH_STACK
++ pea %sp@(SWITCH_STACK_SIZE)
++ jbsr do_sigsuspend
++ addql #4,%sp
++ RESTORE_SWITCH_STACK
++ rts
++
++ENTRY(sys_sigreturn)
++ SAVE_SWITCH_STACK
++ jbsr do_sigreturn
++ RESTORE_SWITCH_STACK
++ rts
++
++ENTRY(sys_rt_sigreturn)
++ SAVE_SWITCH_STACK
++ jbsr do_rt_sigreturn
++ RESTORE_SWITCH_STACK
++ rts
++
++resume:
++ /*
++ * Beware - when entering resume, prev (the current task) is
++ * in a0, next (the new task) is in a1,so don't change these
++ * registers until their contents are no longer needed.
++ */
++
++ /* save sr */
++ movew %sr,%d0
++ movew %d0,%a0@(TASK_THREAD+THREAD_SR)
++
++ /* save usp */
++ /* Save USP via %a1 (which is saved/restored from %d0) */
++ movel %a1,%d0
++ movel %usp,%a1
++ movel %a1,%a0@(TASK_THREAD+THREAD_USP)
++ movel %d0,%a1
++
++ /* save non-scratch registers on stack */
++ SAVE_SWITCH_STACK
++
++ /* save current kernel stack pointer */
++ movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
++#ifdef CONFIG_FPU
++ /* save floating point context */
++ fsave %a0@(TASK_THREAD+THREAD_FPSTATE)
++
++1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)
++ jeq 3f
++2:
++ fmovemd %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)
++3:
++#endif
++ /* Return previous task in %d1 */
++ movel %curptr,%d1
++
++ /* switch to new task (a1 contains new task) */
++ movel %a1,%curptr
++#ifdef CONFIG_FPU
++ /* restore floating point context */
++1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)
++ jeq 3f
++2:
++ fmovemd %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7
++/* frestore %a1@(TASK_THREAD+THREAD_FPCNTL)*/
++3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)
++#endif
++ /* restore the kernel stack pointer */
++ movel %a1@(TASK_THREAD+THREAD_KSP),%sp
++
++ /* restore non-scratch registers */
++ RESTORE_SWITCH_STACK
++
++ /* restore user stack pointer */
++ movel %a1@(TASK_THREAD+THREAD_USP),%a0
++ movel %a0,%usp
++
++ /* restore status register */
++ movew %a1@(TASK_THREAD+THREAD_SR),%d0
++ movew %d0,%sr
++
++ rts
++
++.data
++ALIGN
++sys_call_table:
++ .long sys_ni_syscall /* 0 - old "setup()" system call*/
++ .long sys_exit
++ .long sys_fork
++ .long sys_read
++ .long sys_write
++ .long sys_open /* 5 */
++ .long sys_close
++ .long sys_waitpid
++ .long sys_creat
++ .long sys_link
++ .long sys_unlink /* 10 */
++ .long sys_execve
++ .long sys_chdir
++ .long sys_time
++ .long sys_mknod
++ .long sys_chmod /* 15 */
++ .long sys_chown16
++ .long sys_ni_syscall /* old break syscall holder */
++ .long sys_stat
++ .long sys_lseek
++ .long sys_getpid /* 20 */
++ .long sys_mount
++ .long sys_oldumount
++ .long sys_setuid16
++ .long sys_getuid16
++ .long sys_stime /* 25 */
++ .long sys_ptrace
++ .long sys_alarm
++ .long sys_fstat
++ .long sys_pause
++ .long sys_utime /* 30 */
++ .long sys_ni_syscall /* old stty syscall holder */
++ .long sys_ni_syscall /* old gtty syscall holder */
++ .long sys_access
++ .long sys_nice
++ .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
++ .long sys_sync
++ .long sys_kill
++ .long sys_rename
++ .long sys_mkdir
++ .long sys_rmdir /* 40 */
++ .long sys_dup
++ .long sys_pipe
++ .long sys_times
++ .long sys_ni_syscall /* old prof syscall holder */
++ .long sys_brk /* 45 */
++ .long sys_setgid16
++ .long sys_getgid16
++ .long sys_signal
++ .long sys_geteuid16
++ .long sys_getegid16 /* 50 */
++ .long sys_acct
++ .long sys_umount /* recycled never used phys() */
++ .long sys_ni_syscall /* old lock syscall holder */
++ .long sys_ioctl
++ .long sys_fcntl /* 55 */
++ .long sys_ni_syscall /* old mpx syscall holder */
++ .long sys_setpgid
++ .long sys_ni_syscall /* old ulimit syscall holder */
++ .long sys_ni_syscall
++ .long sys_umask /* 60 */
++ .long sys_chroot
++ .long sys_ustat
++ .long sys_dup2
++ .long sys_getppid
++ .long sys_getpgrp /* 65 */
++ .long sys_setsid
++ .long sys_sigaction
++ .long sys_sgetmask
++ .long sys_ssetmask
++ .long sys_setreuid16 /* 70 */
++ .long sys_setregid16
++ .long sys_sigsuspend
++ .long sys_sigpending
++ .long sys_sethostname
++ .long sys_setrlimit /* 75 */
++ .long sys_old_getrlimit
++ .long sys_getrusage
++ .long sys_gettimeofday
++ .long sys_settimeofday
++ .long sys_getgroups16 /* 80 */
++ .long sys_setgroups16
++ .long old_select
++ .long sys_symlink
++ .long sys_lstat
++ .long sys_readlink /* 85 */
++ .long sys_uselib
++ .long sys_swapon
++ .long sys_reboot
++ .long sys_old_readdir
++ .long old_mmap /* 90 */
++ .long sys_munmap
++ .long sys_truncate
++ .long sys_ftruncate
++ .long sys_fchmod
++ .long sys_fchown16 /* 95 */
++ .long sys_getpriority
++ .long sys_setpriority
++ .long sys_ni_syscall /* old profil syscall holder */
++ .long sys_statfs
++ .long sys_fstatfs /* 100 */
++ .long sys_ni_syscall /* ioperm for i386 */
++ .long sys_socketcall
++ .long sys_syslog
++ .long sys_setitimer
++ .long sys_getitimer /* 105 */
++ .long sys_newstat
++ .long sys_newlstat
++ .long sys_newfstat
++ .long sys_ni_syscall
++ .long sys_ni_syscall /* 110 */ /* iopl for i386 */
++ .long sys_vhangup
++ .long sys_ni_syscall /* obsolete idle() syscall */
++ .long sys_ni_syscall /* vm86old for i386 */
++ .long sys_wait4
++ .long sys_swapoff /* 115 */
++ .long sys_sysinfo
++ .long sys_ipc
++ .long sys_fsync
++ .long sys_sigreturn
++ .long sys_clone /* 120 */
++ .long sys_setdomainname
++ .long sys_newuname
++ .long sys_cacheflush /* modify_ldt for i386 */
++ .long sys_adjtimex
++ .long sys_mprotect /* 125 */
++ .long sys_sigprocmask
++ .long sys_ni_syscall /* old "create_module" */
++ .long sys_init_module
++ .long sys_delete_module
++ .long sys_ni_syscall /* 130 - old "get_kernel_syms" */
++ .long sys_quotactl
++ .long sys_getpgid
++ .long sys_fchdir
++ .long sys_bdflush
++ .long sys_sysfs /* 135 */
++ .long sys_personality
++ .long sys_ni_syscall /* for afs_syscall */
++ .long sys_setfsuid16
++ .long sys_setfsgid16
++ .long sys_llseek /* 140 */
++ .long sys_getdents
++ .long sys_select
++ .long sys_flock
++ .long sys_msync
++ .long sys_readv /* 145 */
++ .long sys_writev
++ .long sys_getsid
++ .long sys_fdatasync
++ .long sys_sysctl
++ .long sys_mlock /* 150 */
++ .long sys_munlock
++ .long sys_mlockall
++ .long sys_munlockall
++ .long sys_sched_setparam
++ .long sys_sched_getparam /* 155 */
++ .long sys_sched_setscheduler
++ .long sys_sched_getscheduler
++ .long sys_sched_yield
++ .long sys_sched_get_priority_max
++ .long sys_sched_get_priority_min /* 160 */
++ .long sys_sched_rr_get_interval
++ .long sys_nanosleep
++ .long sys_mremap
++ .long sys_setresuid16
++ .long sys_getresuid16 /* 165 */
++ .long sys_getpagesize
++ .long sys_ni_syscall /* old sys_query_module */
++ .long sys_poll
++ .long sys_nfsservctl
++ .long sys_setresgid16 /* 170 */
++ .long sys_getresgid16
++ .long sys_prctl
++ .long sys_rt_sigreturn
++ .long sys_rt_sigaction
++ .long sys_rt_sigprocmask /* 175 */
++ .long sys_rt_sigpending
++ .long sys_rt_sigtimedwait
++ .long sys_rt_sigqueueinfo
++ .long sys_rt_sigsuspend
++ .long sys_pread64 /* 180 */
++ .long sys_pwrite64
++ .long sys_lchown16;
++ .long sys_getcwd
++ .long sys_capget
++ .long sys_capset /* 185 */
++ .long sys_sigaltstack
++ .long sys_sendfile
++ .long sys_ni_syscall /* streams1 */
++ .long sys_ni_syscall /* streams2 */
++ .long sys_vfork /* 190 */
++ .long sys_getrlimit
++ .long sys_mmap2
++ .long sys_truncate64
++ .long sys_ftruncate64
++ .long sys_stat64 /* 195 */
++ .long sys_lstat64
++ .long sys_fstat64
++ .long sys_chown
++ .long sys_getuid
++ .long sys_getgid /* 200 */
++ .long sys_geteuid
++ .long sys_getegid
++ .long sys_setreuid
++ .long sys_setregid
++ .long sys_getgroups /* 205 */
++ .long sys_setgroups
++ .long sys_fchown
++ .long sys_setresuid
++ .long sys_getresuid
++ .long sys_setresgid /* 210 */
++ .long sys_getresgid
++ .long sys_lchown
++ .long sys_setuid
++ .long sys_setgid
++ .long sys_setfsuid /* 215 */
++ .long sys_setfsgid
++ .long sys_pivot_root
++ .long sys_ni_syscall
++ .long sys_ni_syscall
++ .long sys_getdents64 /* 220 */
++ .long sys_gettid
++ .long sys_tkill
++ .long sys_setxattr
++ .long sys_lsetxattr
++ .long sys_fsetxattr /* 225 */
++ .long sys_getxattr
++ .long sys_lgetxattr
++ .long sys_fgetxattr
++ .long sys_listxattr
++ .long sys_llistxattr /* 230 */
++ .long sys_flistxattr
++ .long sys_removexattr
++ .long sys_lremovexattr
++ .long sys_fremovexattr
++ .long sys_futex /* 235 */
++ .long sys_sendfile64
++ .long sys_mincore
++ .long sys_madvise
++ .long sys_fcntl64
++ .long sys_readahead /* 240 */
++ .long sys_io_setup
++ .long sys_io_destroy
++ .long sys_io_getevents
++ .long sys_io_submit
++ .long sys_io_cancel /* 245 */
++ .long sys_fadvise64
++ .long sys_exit_group
++ .long sys_lookup_dcookie
++ .long sys_epoll_create
++ .long sys_epoll_ctl /* 250 */
++ .long sys_epoll_wait
++ .long sys_remap_file_pages
++ .long sys_set_tid_address
++ .long sys_timer_create
++ .long sys_timer_settime /* 255 */
++ .long sys_timer_gettime
++ .long sys_timer_getoverrun
++ .long sys_timer_delete
++ .long sys_clock_settime
++ .long sys_clock_gettime /* 260 */
++ .long sys_clock_getres
++ .long sys_clock_nanosleep
++ .long sys_statfs64
++ .long sys_fstatfs64
++ .long sys_tgkill /* 265 */
++ .long sys_utimes
++ .long sys_fadvise64_64
++ .long sys_mbind
++ .long sys_get_mempolicy
++ .long sys_set_mempolicy /* 270 */
++ .long sys_mq_open
++ .long sys_mq_unlink
++ .long sys_mq_timedsend
++ .long sys_mq_timedreceive
++ .long sys_mq_notify /* 275 */
++ .long sys_mq_getsetattr
++ .long sys_waitid
++ .long sys_ni_syscall /* for sys_vserver */
++ .long sys_add_key
++ .long sys_request_key /* 280 */
++ .long sys_keyctl
++ .long sys_ioprio_set
++ .long sys_ioprio_get
++ .long sys_inotify_init
++ .long sys_inotify_add_watch /* 285 */
++ .long sys_inotify_rm_watch
++ .long sys_migrate_pages
++ .long sys_openat
++ .long sys_mkdirat
++ .long sys_mknodat /* 290 */
++ .long sys_fchownat
++ .long sys_futimesat
++ .long sys_fstatat64
++ .long sys_unlinkat
++ .long sys_renameat /* 295 */
++ .long sys_linkat
++ .long sys_symlinkat
++ .long sys_readlinkat
++ .long sys_fchmodat
++ .long sys_faccessat /* 300 */
++ .long sys_ni_syscall /* Reserved for pselect6 */
++ .long sys_ni_syscall /* Reserved for ppoll */
++ .long sys_unshare
++ .long sys_set_robust_list
++ .long sys_get_robust_list /* 305 */
++ .long sys_splice
++ .long sys_sync_file_range
++ .long sys_tee
++ .long sys_vmsplice
++ .long sys_move_pages /* 310 */
++ .long sys_sched_setaffinity
++ .long sys_sched_getaffinity
++ .long sys_kexec_load
++ .long sys_getcpu
++ .long sys_epoll_pwait /* 315 */
++ .long sys_utimensat
++ .long sys_signalfd
++ .long sys_timerfd_create
++ .long sys_eventfd
++ .long sys_fallocate /* 320 */
++ .long sys_timerfd_settime
++ .long sys_timerfd_gettime
++ .long sys_signalfd4
++ .long sys_eventfd2
++ .long sys_epoll_create1 /* 325 */
++ .long sys_dup3
++ .long sys_pipe2
++ .long sys_inotify_init1
++ .long sys_preadv
++ .long sys_pwritev /* 330 */
++ .long sys_rt_tgsigqueueinfo
++ .long sys_perf_event_open
++ .long sys_get_thread_area
++ .long sys_set_thread_area
++ .long sys_atomic_cmpxchg_32 /* 335 */
++ .long sys_atomic_barrier
++ .long sys_fanotify_init
++ .long sys_fanotify_mark
++ .long sys_prlimit64
+--- /dev/null
++++ b/arch/m68k/coldfire/common/head.S
+@@ -0,0 +1,466 @@
++/*
++ * head.S is the MMU enabled ColdFire specific initial boot code
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Matt Waddel Matt.Waddel@freescale.com
++ * Kurt Mahan kmahan@freescale.com
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * Parts of this code came from arch/m68k/kernel/head.S
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/bootinfo.h>
++#include <asm/setup.h>
++#include <asm/entry.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/coldfire.h>
++#include <asm/cfcache.h>
++
++#define DEBUG
++
++.globl kernel_pg_dir
++.globl availmem
++.globl set_context
++.globl set_fpga
++
++#ifdef DEBUG
++/* When debugging use readable names for labels */
++#ifdef __STDC__
++#define L(name) .head.S.##name
++#else
++#define L(name) .head.S./**/name
++#endif
++#else
++#ifdef __STDC__
++#define L(name) .L##name
++#else
++#define L(name) .L/**/name
++#endif
++#endif
++
++/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
++#ifndef __INITDATA
++#define __INITDATA .data
++#define __FINIT .previous
++#endif
++
++/*
++ * Kernel mapped to physical ram address.
++ *
++ * M5445x:
++ * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
++ * Data[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
++ * Code[0]: Not Mapped
++ * Code[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
++ *
++ * M547x/M548x
++ * Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
++ * Data[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - uncached
++ * Code[0]: Not Mapped
++ * Code[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - cached
++ *
++ * M5441X:
++ * Data[0]: 0xE0000000 -> 0xFFFFFFFF System regs
++ * Data[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
++ * Code[0]: Not Mapped
++ * Code[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
++ */
++#if defined(CONFIG_M5445X)
++#define ACR0_DEFAULT #0xF00FA048 /* System Regs uncached/precise */
++#define ACR1_DEFAULT #0x400FA028 /* SDRAM cached/copyback */
++#define ACR2_DEFAULT #0x00000000 /* Not mapped */
++#define ACR3_DEFAULT #0x400FA028 /* SDRAM cached/copyback */
++#elif defined(CONFIG_M547X_8X)
++#define ACR0_DEFAULT #0xF00FA048 /* System Regs */
++#define ACR1_DEFAULT #0x000FA028 /* SDRAM cached/copy-back */
++#define ACR2_DEFAULT #0x00000000 /* Not mapped */
++#define ACR3_DEFAULT #0x000FA028 /* Instruction cached/copy-back */
++#elif defined(CONFIG_M5441X)
++#define ACR0_DEFAULT #0xE01FA048 /* System Regs */
++#define ACR1_DEFAULT #0x400FA028 /* SDRAM cached/copyback */
++#define ACR4_DEFAULT #0x00000000 /* Not mapped */
++#define ACR5_DEFAULT #0x00000000 /* Not mapped */
++#define ACR2_DEFAULT #0x00000000 /* Not mapped */
++#define ACR3_DEFAULT #0x400FA028 /* Instruction cached/copy-back */
++#define ACR6_DEFAULT #0x00000000 /* Not mapped */
++#define ACR7_DEFAULT #0x00000000 /* Not mapped */
++#endif
++
++/* ACR mapping for FPGA (maps 0) */
++#define ACR0_FPGA #0x000FA048 /* ACR0 enable FPGA */
++
++/* Several macros to make the writing of subroutines easier:
++ * - func_start marks the beginning of the routine which setups the frame
++ * register and saves the registers, it also defines another macro
++ * to automatically restore the registers again.
++ * - func_return marks the end of the routine and simply calls the prepared
++ * macro to restore registers and jump back to the caller.
++ * - func_define generates another macro to automatically put arguments
++ * onto the stack call the subroutine and cleanup the stack again.
++ */
++
++.macro load_symbol_address symbol,register
++ movel #\symbol,\register
++.endm
++
++.macro func_start name,saveregs,savesize,stack=0
++L(\name):
++ linkw %a6,#-\stack
++ subal #(\savesize),%sp
++ moveml \saveregs,%sp@
++.set stackstart,-\stack
++
++.macro func_return_\name
++ moveml %sp@,\saveregs
++ addal #(\savesize),%sp
++ unlk %a6
++ rts
++.endm
++.endm
++
++.macro func_return name
++ func_return_\name
++.endm
++
++.macro func_call name
++ jbsr L(\name)
++.endm
++
++.macro move_stack nr,arg1,arg2,arg3,arg4
++.if \nr
++ move_stack "(\nr-1)",\arg2,\arg3,\arg4
++ movel \arg1,%sp@-
++.endif
++.endm
++
++.macro func_define name,nr=0
++.macro \name arg1,arg2,arg3,arg4
++ move_stack \nr,\arg1,\arg2,\arg3,\arg4
++ func_call \name
++.if \nr
++ lea %sp@(\nr*4),%sp
++.endif
++.endm
++.endm
++
++func_define serial_putc,1
++
++.macro putc ch
++ pea \ch
++ func_call serial_putc
++ addql #4,%sp
++.endm
++
++.macro dputc ch
++#ifdef DEBUG
++ putc \ch
++#endif
++.endm
++
++func_define putn,1
++
++.macro dputn nr
++#ifdef DEBUG
++ putn \nr
++#endif
++.endm
++
++/*
++ mmu_map - creates a new TLB entry
++
++ virt_addr Must be on proper boundary
++ phys_addr Must be on proper boundary
++ itlb MMUOR_ITLB if instruction TLB or 0
++ asid address space ID
++ shared_global MMUTR_SG if shared between different ASIDs or 0
++ size_code MMUDR_SZ1M 1 MB
++ MMUDR_SZ4K 4 KB
++ MMUDR_SZ8K 8 KB
++ MMUDR_SZ16M 16 MB
++ cache_mode MMUDR_INC instruction non-cacheable
++ MMUDR_IC instruction cacheable
++ MMUDR_DWT data writethrough
++ MMUDR_DCB data copyback
++ MMUDR_DNCP data non-cacheable, precise
++ MMUDR_DNCIP data non-cacheable, imprecise
++ super_prot MMUDR_SP if user mode generates exception or 0
++ readable MMUDR_R if permits read access (data TLB) or 0
++ writable MMUDR_W if permits write access (data TLB) or 0
++ executable MMUDR_X if permits execute access (instruction TLB) or 0
++ locked MMUDR_LK prevents TLB entry from being replaced or 0
++ temp_data_reg a data register to use for temporary values
++*/
++.macro mmu_map virt_addr,phys_addr,itlb,asid,shared_global,size_code, \
++ cache_mode,super_prot,readable,writable,executable,locked,temp_data_reg
++ /* Set up search of TLB. */
++ movel #(\virt_addr+1), \temp_data_reg
++ movel \temp_data_reg, MMUAR
++ /* Search. */
++ movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
++ movew \temp_data_reg, (MMUOR)
++ /* Set up tag value. */
++ movel #(\virt_addr + \asid + \shared_global + MMUTR_V), \temp_data_reg
++ movel \temp_data_reg, MMUTR
++ /* Set up data value. */
++ movel #(\phys_addr + \size_code + \cache_mode + \super_prot + \
++ \readable + \writable + \executable + \locked), \temp_data_reg
++ movel \temp_data_reg, MMUDR
++ /* Save it. */
++ movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
++ movew \temp_data_reg, (MMUOR)
++.endm /* mmu_map */
++
++.macro mmu_unmap virt_addr,itlb,temp_data_reg
++ /* Set up search of TLB. */
++ movel #(\virt_addr+1), \temp_data_reg
++ movel \temp_data_reg, MMUAR
++ /* Search. */
++ movel #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
++ movew \temp_data_reg, (MMUOR)
++ /* Test for hit. */
++ movel MMUSR,\temp_data_reg
++ btst #MMUSR_HITN,\temp_data_reg
++ beq 1f
++ /* Read the TLB. */
++ movel #(MMUOR_RW + MMUOR_ACC +\itlb), \temp_data_reg
++ movew \temp_data_reg, (MMUOR)
++ movel MMUSR,\temp_data_reg
++ /* Set up tag value. */
++ movel #0, \temp_data_reg
++ movel \temp_data_reg, MMUTR
++ /* Set up data value. */
++ movel #0, \temp_data_reg
++ movel \temp_data_reg, MMUDR
++ /* Save it. */
++ movel #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
++ movew \temp_data_reg, (MMUOR)
++1:
++.endm /* mmu_unmap */
++
++/* .text */
++.section ".text.head","ax"
++ENTRY(_stext)
++/* Version numbers of the bootinfo interface -- if we later pass info
++ * from boot ROM we might want to put something real here.
++ *
++ * The area from _stext to _start will later be used as kernel pointer table
++ */
++ bras 1f /* Jump over bootinfo version numbers */
++
++ .long BOOTINFOV_MAGIC
++ .long 0
++1: jmp __start
++
++.equ kernel_pg_dir,_stext
++.equ .,_stext+0x1000
++
++ENTRY(_start)
++ jra __start
++__INIT
++ENTRY(__start)
++/* Save the location of u-boot info - cmd line, bd_info, etc. */
++ movel %a7,%a4 /* Don't use %a4 before cf_early_init */
++ addl #0x00000004,%a4 /* offset past top */
++ addl #(PAGE_OFFSET-CONFIG_SDRAM_BASE),%a4 /* high mem offset */
++
++/* Setup initial stack pointer */
++ movel #CONFIG_SDRAM_BASE+0x1000,%sp
++
++/* Setup usp */
++ subl %a0,%a0
++ movel %a0,%usp
++
++#if defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
++#if defined(CONFIG_SRAM)
++ movel #(CONFIG_SRAM_BASE+0x221), %d0
++#else
++ movel #0x80000000, %d0
++#endif
++
++#ifdef CONFIG_M5441X
++ movec %d0, %rambar
++#else
++ movec %d0, %rambar1
++#endif
++#elif defined(CONFIG_M547X_8X)
++ movel #MCF_MBAR, %d0
++ movec %d0, %mbar
++ move.l #(MCF_RAMBAR0 + 0x21), %d0
++ movec %d0, %rambar0
++ move.l #(MCF_RAMBAR1 + 0x21), %d0
++ movec %d0, %rambar1
++#endif
++
++ movew #0x2700,%sr
++
++/* reset cache */
++ movel #(CF_CACR_ICINVA + CF_CACR_DCINVA),%d0
++ movecl %d0,%cacr
++
++ movel #(MMU_BASE+1),%d0
++ movecl %d0,%mmubar
++ movel #MMUOR_CA,%a0 /* Clear tlb entries */
++ movew %a0,(MMUOR)
++ movel #(MMUOR_CA + MMUOR_ITLB),%a0 /* Use ITLB for searches */
++ movew %a0,(MMUOR)
++ movel #0,%a0 /* Clear Addr Space User ID */
++ movecl %a0,%asid
++
++/* setup ACRs */
++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X) || defined(CONFIG_M5441X)
++ movel ACR0_DEFAULT, %d0 /* ACR0 (DATA) setup */
++ movec %d0, %acr0
++ nop
++ movel ACR1_DEFAULT, %d0 /* ACR1 (DATA) setup */
++ movec %d0, %acr1
++ nop
++ movel ACR2_DEFAULT, %d0 /* ACR2 (CODE) setup */
++ movec %d0, %acr2
++ nop
++ movel ACR3_DEFAULT, %d0 /* ACR3 (CODE) setup */
++ movec %d0, %acr3
++ nop
++#endif
++ /* Turn on MMU */
++ movel #(MMUCR_EN),%a0
++ movel %a0,MMUCR
++ nop /* This synchs the pipeline after a write to MMUCR */
++
++ movel #__running_high,%a0 /* Get around PC-relative addressing. */
++ jmp %a0@
++
++ENTRY(__running_high)
++ load_symbol_address _stext,%sp
++ movel L(memory_start),%a0
++ movel %a0,availmem
++ load_symbol_address L(phys_kernel_start),%a0
++ load_symbol_address _stext,%a1
++ subl #_stext,%a1
++ addl #PAGE_OFFSET,%a1
++ movel %a1,%a0@
++
++/* zero bss */
++ lea _sbss,%a0
++ lea _ebss,%a1
++ clrl %d0
++_loop_bss:
++ movel %d0,(%a0)+
++ cmpl %a0,%a1
++ bne _loop_bss
++
++/* create dma memory mirror TLB mapping */
++#if defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
++ mmu_map CONFIG_DMA_BASE, \
++ CONFIG_SDRAM_BASE, 0, 0, \
++ MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
++ 0, MMUDR_LK, %d0
++#elif defined(CONFIG_M547X_8X)
++ mmu_map (CONFIG_DMA_BASE + 0*1024*1024), \
++ (CONFIG_SDRAM_BASE + 0*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 1*1024*1024), \
++ (CONFIG_SDRAM_BASE + 1*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 2*1024*1024), \
++ (CONFIG_SDRAM_BASE + 2*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 3*1024*1024), \
++ (CONFIG_SDRAM_BASE + 3*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 4*1024*1024), \
++ (CONFIG_SDRAM_BASE + 4*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 5*1024*1024), \
++ (CONFIG_SDRAM_BASE + 5*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 6*1024*1024), \
++ (CONFIG_SDRAM_BASE + 6*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++ mmu_map (CONFIG_DMA_BASE + 7*1024*1024), \
++ (CONFIG_SDRAM_BASE + 7*1024*1024), 0, 0, \
++ MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
++ MMUDR_W, 0, MMUDR_LK, %d0
++#endif
++
++/* Setup initial stack pointer */
++ lea init_task,%a2
++ lea init_thread_union+THREAD_SIZE,%sp
++ subl %a6,%a6 /* clear a6 for gdb */
++
++#ifdef CONFIG_MCF_USER_HALT
++/* Setup debug control reg to allow halts from user space */
++ lea wdbg_uhe,%a0
++ wdebug (%a0)
++#endif
++
++ movel %a4,uboot_info_stk /* save uboot info to variable */
++ jsr cf_early_init
++ jmp start_kernel
++
++.section ".text.head","ax"
++set_context:
++func_start set_context,%d0,(1*4)
++ movel 12(%sp),%d0
++ movec %d0,%asid
++func_return set_context
++
++#ifdef CONFIG_M54455
++/*
++ * set_fpga(addr,val) on the M5445X
++ *
++ * Map in 0x00000000 -> 0x0fffffff and then do the write.
++ */
++set_fpga:
++ movew %sr,%d1
++ movew #0x2700,%sr
++ movel ACR0_FPGA, %d0
++ movec %d0, %acr0
++ nop
++ moveal 4(%sp),%a0
++ movel 8(%sp),%a0@
++ movel ACR0_DEFAULT, %d0
++ movec %d0, %acr0
++ nop
++ movew %d1,%sr
++ rts
++#endif
++
++ .data
++ .align 4
++
++availmem:
++ .long 0
++L(phys_kernel_start):
++ .long PAGE_OFFSET
++L(kernel_end):
++ .long 0
++L(memory_start):
++ .long PAGE_OFFSET_RAW
++
++#ifdef CONFIG_MCF_USER_HALT
++/*
++ * Enable User Halt Enable in the debug control register.
++ */
++wdbg_uhe:
++ .word 0x2c80 /* DR0 */
++ .word 0x00b0 /* 31:16 */
++ .word 0x0400 /* 15:0 -- enable UHE */
++ .word 0x0000 /* unused */
++#endif
++
++
+--- /dev/null
++++ b/arch/m68k/coldfire/common/ints.c
+@@ -0,0 +1,544 @@
++/*
++ * linux/arch/m68k/coldfire/ints.c -- General interrupt handling code
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Matt Waddel Matt.Waddel@freescale.com
++ * Kurt Mahan kmahan@freescale.com
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ *
++ * Based on:
++ * linux/arch/m68k/kernel/ints.c &
++ * linux/arch/m68knommu/5307/ints.c
++ *
++ * 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>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/kernel_stat.h>
++#include <linux/errno.h>
++#include <linux/seq_file.h>
++#include <linux/interrupt.h>
++
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/traps.h>
++#include <asm/page.h>
++#include <asm/machdep.h>
++#include <asm/irq_regs.h>
++
++#include <asm/mcfsim.h>
++
++/*
++ * IRQ Handler lists.
++ */
++static struct irq_node *irq_list[SYS_IRQS];
++static struct irq_controller *irq_controller[SYS_IRQS];
++static int irq_depth[SYS_IRQS];
++
++#define POOL_SIZE SYS_IRQS
++static struct irq_node pool[POOL_SIZE];
++static struct irq_node *get_irq_node(void);
++
++/* The number of spurious interrupts */
++unsigned int num_spurious;
++asmlinkage void handle_badint(struct pt_regs *regs);
++
++/*
++ * process_int(unsigned long vec, struct pt_regs *fp)
++ *
++ * Process an interrupt. Called from entry.S.
++ */
++asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
++{
++ struct pt_regs *old_regs;
++ struct irq_node *node;
++ old_regs = set_irq_regs(fp);
++ kstat_cpu(0).irqs[vec]++;
++
++ node = irq_list[vec];
++ if (!node)
++ handle_badint(fp);
++ else {
++ do {
++ node->handler(vec, node->dev_id);
++ node = node->next;
++ } while (node);
++ }
++
++ set_irq_regs(old_regs);
++}
++
++/*
++ * show_interrupts( struct seq_file *p, void *v)
++ *
++ * Called to show all the current interrupt information.
++ */
++int show_interrupts(struct seq_file *p, void *v)
++{
++ struct irq_controller *contr;
++ struct irq_node *node;
++ int i = *(loff_t *) v;
++
++ if ((i < NR_IRQS) && (irq_list[i])) {
++ contr = irq_controller[i];
++ node = irq_list[i];
++ seq_printf(p, "%-8s %3u: %10u %s", contr->name, i,
++ kstat_cpu(0).irqs[i], node->devname);
++ while ((node = node->next))
++ seq_printf(p, ", %s", node->devname);
++
++ seq_printf(p, "\n");
++ }
++
++ return 0;
++}
++
++/*
++ * get_irq_node(void)
++ *
++ * Get an irq node from the pool.
++ */
++struct irq_node *get_irq_node(void)
++{
++ struct irq_node *p = pool;
++ int i;
++
++ for (i = 0; i < POOL_SIZE; i++, p++) {
++ if (!p->handler) {
++ memset(p, 0, sizeof(struct irq_node));
++ return p;
++ }
++ }
++ printk(KERN_INFO "%s(%s:%d): No more irq nodes, I suggest you \
++ increase POOL_SIZE", __func__, __FILE__, __LINE__);
++ return NULL;
++}
++
++void init_irq_proc(void)
++{
++ /* Insert /proc/irq driver here */
++}
++
++int setup_irq(unsigned int irq, struct irq_node *node)
++{
++ struct irq_controller *contr;
++ struct irq_node **prev;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS || !irq_controller[irq]) {
++ printk("%s: Incorrect IRQ %d from %s\n",
++ __func__, irq, node->devname);
++ return -ENXIO;
++ }
++
++ contr = irq_controller[irq];
++ spin_lock_irqsave(&contr->lock, flags);
++
++ prev = irq_list + irq;
++ if (*prev) {
++ /* Can't share interrupts unless both agree to */
++ if (!((*prev)->flags & node->flags & IRQF_SHARED)) {
++ spin_unlock_irqrestore(&contr->lock, flags);
++ printk(KERN_INFO "%s: -BUSY-Incorrect IRQ %d\n",
++ __func__, irq);
++ return -EBUSY;
++ }
++ while (*prev)
++ prev = &(*prev)->next;
++ }
++
++ if (!irq_list[irq]) {
++ if (contr->startup)
++ contr->startup(irq);
++ else
++ contr->enable(irq);
++ }
++ node->next = NULL;
++ *prev = node;
++
++ spin_unlock_irqrestore(&contr->lock, flags);
++
++ return 0;
++}
++
++int request_irq(unsigned int irq,
++ irq_handler_t handler,
++ unsigned long flags, const char *devname, void *dev_id)
++{
++ struct irq_node *node = get_irq_node();
++ int res;
++
++ if (!node) {
++ printk(KERN_INFO "%s:get_irq_node error %x\n",
++ __func__, (unsigned int) node);
++ return -ENOMEM;
++ }
++ node->handler = handler;
++ node->flags = flags;
++ node->dev_id = dev_id;
++ node->devname = devname;
++
++ res = setup_irq(irq, node);
++ if (res)
++ node->handler = NULL;
++
++ return res;
++}
++EXPORT_SYMBOL(request_irq);
++
++void free_irq(unsigned int irq, void *dev_id)
++{
++ struct irq_controller *contr;
++ struct irq_node **p, *node;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS || !irq_controller[irq]) {
++ printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __func__, irq);
++ return;
++ }
++
++ contr = irq_controller[irq];
++ spin_lock_irqsave(&contr->lock, flags);
++
++ p = irq_list + irq;
++ while ((node = *p)) {
++ if (node->dev_id == dev_id)
++ break;
++ p = &node->next;
++ }
++
++ if (node) {
++ *p = node->next;
++ node->handler = NULL;
++ } else
++ printk(KERN_DEBUG "%s: Removing probably wrong IRQ %d\n",
++ __func__, irq);
++
++ if (!irq_list[irq]) {
++ if (contr->shutdown)
++ contr->shutdown(irq);
++ else
++ contr->disable(irq);
++ }
++
++ spin_unlock_irqrestore(&contr->lock, flags);
++}
++EXPORT_SYMBOL(free_irq);
++
++void enable_irq(unsigned int irq)
++{
++ struct irq_controller *contr;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS || !irq_controller[irq]) {
++ printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __func__, irq);
++ return;
++ }
++
++ contr = irq_controller[irq];
++ spin_lock_irqsave(&contr->lock, flags);
++ if (irq_depth[irq]) {
++ if (!--irq_depth[irq]) {
++ if (contr->enable)
++ contr->enable(irq);
++ }
++ } else
++ WARN_ON(1);
++ spin_unlock_irqrestore(&contr->lock, flags);
++}
++EXPORT_SYMBOL(enable_irq);
++
++void disable_irq(unsigned int irq)
++{
++ struct irq_controller *contr;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS || !irq_controller[irq]) {
++ printk(KERN_DEBUG "%s: Incorrect IRQ %d\n", __func__, irq);
++ return;
++ }
++
++ contr = irq_controller[irq];
++ spin_lock_irqsave(&contr->lock, flags);
++ if (!irq_depth[irq]++) {
++ if (contr->disable)
++ contr->disable(irq);
++ }
++ spin_unlock_irqrestore(&contr->lock, flags);
++}
++EXPORT_SYMBOL(disable_irq);
++
++void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
++EXPORT_SYMBOL(disable_irq_nosync);
++
++
++unsigned long probe_irq_on(void)
++{
++ return 0;
++}
++EXPORT_SYMBOL(probe_irq_on);
++
++int probe_irq_off(unsigned long irqs)
++{
++ return 0;
++}
++EXPORT_SYMBOL(probe_irq_off);
++
++asmlinkage void handle_badint(struct pt_regs *regs)
++{
++ kstat_cpu(0).irqs[0]++;
++ num_spurious++;
++ printk(KERN_DEBUG "unexpected interrupt from %u\n", regs->vector);
++}
++EXPORT_SYMBOL(handle_badint);
++
++unsigned int irq_canonicalize(unsigned int irq)
++{
++#ifdef CONFIG_Q40
++ if (MACH_IS_Q40 && irq == 11)
++ irq = 10;
++#endif
++ return irq;
++}
++EXPORT_SYMBOL(irq_canonicalize);
++
++#ifdef CONFIG_M5445X
++/*
++ * M5445X Implementation
++ */
++void m5445x_irq_enable(unsigned int irq)
++{
++ /* enable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* enable eport */
++ MCF_EPORT_EPPAR &= ~(3 << (irq*2)); /* level */
++ MCF_EPORT_EPDDR &= ~(1 << irq); /* input */
++ MCF_EPORT_EPIER |= 1 << irq; /* irq enabled */
++ }
++
++ if (irq < 64) {
++ /* controller 0 */
++ MCF_INTC0_ICR(irq) = 0x02;
++ MCF_INTC0_CIMR = irq;
++ } else {
++ /* controller 1 */
++ irq -= 64;
++ MCF_INTC1_ICR(irq) = 0x02;
++ MCF_INTC1_CIMR = irq;
++ }
++}
++
++void m5445x_irq_disable(unsigned int irq)
++{
++ /* disable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* disable eport */
++ MCF_EPORT_EPIER &= ~(1 << irq);
++ }
++
++ if (irq < 64) {
++ /* controller 0 */
++ MCF_INTC0_ICR(irq) = 0x00;
++ MCF_INTC0_SIMR = irq;
++ } else {
++ /* controller 1 */
++ irq -= 64;
++ MCF_INTC1_ICR(irq) = 0x00;
++ MCF_INTC1_SIMR = irq;
++ }
++}
++#elif defined(CONFIG_M547X_8X)
++/*
++ * M547X_8X Implementation
++ */
++void m547x_8x_irq_enable(unsigned int irq)
++{
++ /* enable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* enable eport */
++ MCF_EPPAR &= ~(3 << (irq*2));
++ /* level */
++ MCF_EPDDR &= ~(1 << irq);
++ /* input */
++ MCF_EPIER |= 1 << irq;
++ /* irq enabled */
++ }
++
++ if (irq < 32) {
++ /* *grumble* don't set low bit of IMRL */
++ MCF_IMRL &= (~(1 << irq) & 0xfffffffe);
++ } else {
++ MCF_IMRH &= ~(1 << (irq - 32));
++ }
++}
++
++void m547x_8x_irq_disable(unsigned int irq)
++{
++ /* disable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* disable eport */
++ MCF_EPIER &= ~(1 << irq);
++ }
++
++ if (irq < 32)
++ MCF_IMRL |= (1 << irq);
++ else
++ MCF_IMRH |= (1 << (irq - 32));
++}
++
++#elif defined(CONFIG_M5441X)
++/*
++ * M5441X Implementation
++ */
++void m5441x_irq_enable(unsigned int irq)
++{
++ /* enable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* enable eport */
++ MCF_EPORT_EPPAR &= ~(3 << (irq*2)); /* level */
++ MCF_EPORT_EPIER |= 1 << irq; /* irq enabled */
++ }
++
++ if (irq < 64) {
++ /* controller 0 */
++ MCF_INTC0_ICR(irq) = 0x02;
++ MCF_INTC0_CIMR = irq;
++ } else if (irq >= 64 && irq < 128) {
++ /* controller 1 */
++ irq -= 64;
++ MCF_INTC1_ICR(irq) = 0x02;
++ MCF_INTC1_CIMR = irq;
++ } else if (irq >= 128 && irq < 192) {
++ /* controller 2 */
++ irq -= 128;
++ MCF_INTC2_ICR(irq) = 0x02;
++ MCF_INTC2_CIMR = irq;
++ } else {
++ /* invalid irq number */
++ return;
++ }
++}
++
++void m5441x_irq_disable(unsigned int irq)
++{
++ /* disable the interrupt hardware */
++ if (irq < 64)
++ return;
++
++ /* adjust past non-hardware ints */
++ irq -= 64;
++
++ /* check for eport */
++ if ((irq > 0) && (irq < 8)) {
++ /* disable eport */
++ MCF_EPORT_EPIER &= ~(1 << irq);
++ }
++
++ if (irq < 64) {
++ /* controller 0 */
++ MCF_INTC0_ICR(irq) = 0x00;
++ MCF_INTC0_SIMR = irq;
++ } else if (irq >= 64 && irq < 128) {
++ /* controller 1 */
++ irq -= 64;
++ MCF_INTC1_ICR(irq) = 0x00;
++ MCF_INTC1_SIMR = irq;
++ } else if (irq >= 128 && irq < 192) {
++ /* controller 2 */
++ irq -= 128;
++ MCF_INTC2_ICR(irq) = 0x00;
++ MCF_INTC2_SIMR = irq;
++ }
++}
++#endif
++
++/*
++ * IRQ Controller
++ */
++#if defined(CONFIG_M5445X)
++static struct irq_controller m5445x_irq_controller = {
++ .name = "M5445X",
++ .lock = __SPIN_LOCK_UNLOCKED(m5445x_irq_controller.lock),
++ .enable = m5445x_irq_enable,
++ .disable = m5445x_irq_disable,
++};
++#elif defined(CONFIG_M547X_8X)
++static struct irq_controller m547x_8x_irq_controller = {
++ .name = "M547X_8X",
++ .lock = __SPIN_LOCK_UNLOCKED(m547x_8x_irq_controller.lock),
++ .enable = m547x_8x_irq_enable,
++ .disable = m547x_8x_irq_disable,
++};
++#elif defined(CONFIG_M5441X)
++static struct irq_controller m5441x_irq_controller = {
++ .name = "M5441X",
++ .lock = __SPIN_LOCK_UNLOCKED(m5441x_irq_controller.lock),
++ .enable = m5441x_irq_enable,
++ .disable = m5441x_irq_disable,
++};
++#else
++# error No IRQ controller defined
++#endif
++
++/*
++ * void init_IRQ(void)
++ *
++ * This function should be called during kernel startup to initialize
++ * the IRQ handling routines.
++ */
++void __init init_IRQ(void)
++{
++ int i;
++
++#if defined(CONFIG_M5445X)
++ for (i = 0; i < SYS_IRQS; i++)
++ irq_controller[i] = &m5445x_irq_controller;
++#elif defined(CONFIG_M547X_8X)
++ for (i = 0; i < SYS_IRQS; i++)
++ irq_controller[i] = &m547x_8x_irq_controller;
++#elif defined(CONFIG_M5441X)
++ for (i = 0; i < SYS_IRQS; i++)
++ irq_controller[i] = &m5441x_irq_controller;
++#endif
++}
+--- /dev/null
++++ b/arch/m68k/coldfire/common/muldi3.S
+@@ -0,0 +1,73 @@
++/*
++ * Coldfire muldi3 assembly verion
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/linkage.h>
++.globl __muldi3
++
++ENTRY(__muldi3)
++ linkw %fp,#0
++ lea %sp@(-32),%sp
++ moveml %d2-%d7/%a2-%a3,%sp@
++ moveal %fp@(8), %a2
++ moveal %fp@(12), %a3
++ moveal %fp@(16), %a0
++ moveal %fp@(20),%a1
++ movel %a3,%d2
++ andil #65535,%d2
++ movel %a3,%d3
++ clrw %d3
++ swap %d3
++ movel %a1,%d0
++ andil #65535,%d0
++ movel %a1,%d1
++ clrw %d1
++ swap %d1
++ movel %d2,%d7
++ mulsl %d0,%d7
++ movel %d2,%d4
++ mulsl %d1,%d4
++ movel %d3,%d2
++ mulsl %d0,%d2
++ mulsl %d1,%d3
++ movel %d7,%d0
++ clrw %d0
++ swap %d0
++ addl %d0,%d4
++ addl %d2,%d4
++ cmpl %d4,%d2
++ blss 1f
++ addil #65536,%d3
++1:
++ movel %d4,%d0
++ clrw %d0
++ swap %d0
++ movel %d3,%d5
++ addl %d0,%d5
++ movew %d4,%d6
++ swap %d6
++ movew %d7,%d6
++ movel %d5,%d0
++ movel %d6,%d1
++ movel %a3,%d2
++ movel %a0,%d3
++ mulsl %d3,%d2
++ movel %a2,%d3
++ movel %a1,%d4
++ mulsl %d4,%d3
++ addl %d3,%d2
++ movel %d2,%d0
++ addl %d5,%d0
++ moveml %sp@, %d2-%d7/%a2-%a3
++ lea %sp@(32),%sp
++ unlk %fp
++ rts
+--- /dev/null
++++ b/arch/m68k/coldfire/common/signal.c
+@@ -0,0 +1,991 @@
++/*
++ * linux/arch/m68k/kernel/signal.c
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Matt Waddel Matt.Waddel@freescale.com
++ * 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.
++ *
++ * Derived from m68k/kernel/signal.c and the original authors are credited
++ * there.
++ */
++
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/kernel.h>
++#include <linux/signal.h>
++#include <linux/syscalls.h>
++#include <linux/errno.h>
++#include <linux/wait.h>
++#include <linux/ptrace.h>
++#include <linux/unistd.h>
++#include <linux/stddef.h>
++#include <linux/highuid.h>
++#include <linux/personality.h>
++#include <linux/tty.h>
++#include <linux/binfmts.h>
++
++#include <asm/setup.h>
++#include <asm/uaccess.h>
++#include <asm/cf_pgtable.h>
++#include <asm/traps.h>
++#include <asm/ucontext.h>
++#include <asm/cacheflush.h>
++
++#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
++
++asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
++
++const int frame_extra_sizes[16] = {
++ [1] = -1,
++ [2] = -1,
++ [3] = -1,
++ [4] = 0,
++ [5] = 1,
++ [6] = 1,
++ [7] = 2,
++ [8] = 3,
++ [9] = -1,
++ [10] = -1,
++ [11] = -1,
++ [12] = -1,
++ [13] = -1,
++ [14] = -1,
++ [15] = -1,
++};
++
++/*
++ * Atomically swap in the new signal mask, and wait for a signal.
++ */
++asmlinkage int do_sigsuspend(struct pt_regs *regs)
++{
++ old_sigset_t mask = regs->d3;
++ sigset_t saveset;
++
++ mask &= _BLOCKABLE;
++ spin_lock_irq(&current->sighand->siglock);
++ saveset = current->blocked;
++ siginitset(&current->blocked, mask);
++ recalc_sigpending();
++ spin_unlock_irq(&current->sighand->siglock);
++
++ regs->d0 = -EINTR;
++ while (1) {
++ current->state = TASK_INTERRUPTIBLE;
++ schedule();
++ if (do_signal(&saveset, regs))
++ return -EINTR;
++ }
++}
++
++asmlinkage int
++do_rt_sigsuspend(struct pt_regs *regs)
++{
++ sigset_t __user *unewset = (sigset_t __user *)regs->d1;
++ size_t sigsetsize = (size_t)regs->d2;
++ sigset_t saveset, newset;
++
++ /* XXX: Don't preclude handling different sized sigset_t's. */
++ if (sigsetsize != sizeof(sigset_t))
++ return -EINVAL;
++
++ if (copy_from_user(&newset, unewset, sizeof(newset)))
++ return -EFAULT;
++ sigdelsetmask(&newset, ~_BLOCKABLE);
++
++ spin_lock_irq(&current->sighand->siglock);
++ saveset = current->blocked;
++ current->blocked = newset;
++ recalc_sigpending();
++ spin_unlock_irq(&current->sighand->siglock);
++
++ regs->d0 = -EINTR;
++ while (1) {
++ current->state = TASK_INTERRUPTIBLE;
++ schedule();
++ if (do_signal(&saveset, regs))
++ return -EINTR;
++ }
++}
++
++asmlinkage int
++sys_sigaction(int sig, const struct old_sigaction __user *act,
++ struct old_sigaction __user *oact)
++{
++ struct k_sigaction new_ka, old_ka;
++ int ret;
++
++ if (act) {
++ old_sigset_t mask;
++ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
++ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
++ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
++ return -EFAULT;
++ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
++ __get_user(mask, &act->sa_mask);
++ siginitset(&new_ka.sa.sa_mask, mask);
++ }
++
++ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
++
++ if (!ret && oact) {
++ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
++ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
++ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
++ return -EFAULT;
++ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
++ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
++ }
++
++ return ret;
++}
++
++asmlinkage int
++sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
++{
++ return do_sigaltstack(uss, uoss, rdusp());
++}
++
++
++/*
++ * Do a signal return; undo the signal stack.
++ *
++ * Keep the return code on the stack quadword aligned!
++ * That makes the cache flush below easier.
++ */
++
++struct sigframe {
++ char __user *pretcode;
++ int sig;
++ int code;
++ struct sigcontext __user *psc;
++ char retcode[8];
++ unsigned long extramask[_NSIG_WORDS-1];
++ struct sigcontext sc;
++};
++
++struct rt_sigframe {
++ char __user *pretcode;
++ int sig;
++ struct siginfo __user *pinfo;
++ void __user *puc;
++ char retcode[8];
++ struct siginfo info;
++ struct ucontext uc;
++};
++
++#define FPCONTEXT_SIZE 216
++#define uc_fpstate uc_filler[0]
++#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
++#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
++
++#ifdef CONFIG_FPU
++static unsigned char fpu_version; /* version num of fpu, set by setup_frame */
++
++static inline int restore_fpu_state(struct sigcontext *sc)
++{
++ int err = 1;
++
++ if (FPU_IS_EMU) {
++ /* restore registers */
++ memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
++ memcpy(current->thread.fp, sc->sc_fpregs, 24);
++ return 0;
++ }
++
++ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
++ /* Verify the frame format. */
++ if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
++ goto out;
++ if (CPU_IS_020_OR_030) {
++ if (m68k_fputype & FPU_68881 &&
++ !(sc->sc_fpstate[1] == 0x18 ||
++ sc->sc_fpstate[1] == 0xb4))
++ goto out;
++ if (m68k_fputype & FPU_68882 &&
++ !(sc->sc_fpstate[1] == 0x38 ||
++ sc->sc_fpstate[1] == 0xd4))
++ goto out;
++ } else if (CPU_IS_040) {
++ if (!(sc->sc_fpstate[1] == 0x00 ||
++ sc->sc_fpstate[1] == 0x28 ||
++ sc->sc_fpstate[1] == 0x60))
++ goto out;
++ } else if (CPU_IS_060) {
++ if (!(sc->sc_fpstate[3] == 0x00 ||
++ sc->sc_fpstate[3] == 0x60 ||
++ sc->sc_fpstate[3] == 0xe0))
++ goto out;
++ } else if (CPU_IS_CFV4E) {
++ pr_debug("restore v4e fpu state at %s\n", __func__);
++ } else
++ goto out;
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fmovem %0,%/fp0-%/fp1\n\t"
++ QCHIP_RESTORE_DIRECTIVE
++ : /* no outputs */
++ : "m" (sc->sc_fpregs[0][0])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpcr"
++ : : "m" (sc->sc_fpcntl[0])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpsr"
++ : : "m" (sc->sc_fpcntl[1])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpiar"
++ : : "m" (sc->sc_fpcntl[2])
++ : "memory");
++
++#endif
++ }
++
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("frestore %0\n\t"
++ QCHIP_RESTORE_DIRECTIVE : : "m" (*sc->sc_fpstate));
++#endif
++ err = 0;
++
++out:
++ return err;
++}
++
++static inline int rt_restore_fpu_state(struct ucontext __user *uc)
++{
++ unsigned char fpstate[FPCONTEXT_SIZE];
++ int context_size = CPU_IS_060 ? 8 : 0;
++ fpregset_t fpregs;
++ int err = 1;
++
++ if (FPU_IS_EMU) {
++ /* restore fpu control register */
++ if (__copy_from_user(current->thread.fpcntl,
++ uc->uc_mcontext.fpregs.f_fpcntl, 12))
++ goto out;
++ /* restore all other fpu register */
++ if (__copy_from_user(current->thread.fp,
++ uc->uc_mcontext.fpregs.f_fpregs, 96))
++ goto out;
++ return 0;
++ }
++
++ if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
++ goto out;
++ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
++ if (!CPU_IS_060)
++ context_size = fpstate[1];
++ /* Verify the frame format. */
++ if (!CPU_IS_060 && (fpstate[0] != fpu_version))
++ goto out;
++ if (CPU_IS_020_OR_030) {
++ if (m68k_fputype & FPU_68881 &&
++ !(context_size == 0x18 || context_size == 0xb4))
++ goto out;
++ if (m68k_fputype & FPU_68882 &&
++ !(context_size == 0x38 || context_size == 0xd4))
++ goto out;
++ } else if (CPU_IS_040) {
++ if (!(context_size == 0x00 ||
++ context_size == 0x28 ||
++ context_size == 0x60))
++ goto out;
++ } else if (CPU_IS_060) {
++ if (!(fpstate[3] == 0x00 ||
++ fpstate[3] == 0x60 ||
++ fpstate[3] == 0xe0))
++ goto out;
++ } else if (CPU_IS_CFV4E) {
++ pr_debug("restore coldfire rt v4e fpu"
++ " state at %s\n", __func__);
++ } else
++ goto out;
++ if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
++ sizeof(fpregs)))
++ goto out;
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fmovem %0,%/fp0-%/fp7\n\t"
++ QCHIP_RESTORE_DIRECTIVE
++ : /* no outputs */
++ : "m" (fpregs.f_fpregs[0][0])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpcr"
++ : : "m" (fpregs.f_fpcntl[0])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpsr"
++ : : "m" (fpregs.f_fpcntl[1])
++ : "memory");
++ __asm__ volatile ("fmovel %0,%/fpiar"
++ : : "m" (fpregs.f_fpcntl[2])
++ : "memory");
++#endif
++ }
++ if (context_size &&
++ __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
++ context_size))
++ goto out;
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("frestore %0\n\t"
++ QCHIP_RESTORE_DIRECTIVE : : "m" (*fpstate));
++#endif
++ err = 0;
++
++out:
++ return err;
++}
++#endif
++
++static inline int
++restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc,
++ void __user *fp, int *pd0)
++{
++ int fsize, formatvec;
++ struct sigcontext context;
++ int err = 0;
++
++ /* get previous context */
++ if (copy_from_user(&context, usc, sizeof(context)))
++ goto badframe;
++
++ /* restore passed registers */
++ regs->d1 = context.sc_d1;
++ regs->a0 = context.sc_a0;
++ regs->a1 = context.sc_a1;
++ regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
++ regs->pc = context.sc_pc;
++ regs->orig_d0 = -1; /* disable syscall checks */
++ wrusp(context.sc_usp);
++ formatvec = context.sc_formatvec;
++ regs->format = formatvec >> 12;
++ regs->vector = formatvec & 0xfff;
++
++#ifdef CONFIG_FPU
++ err = restore_fpu_state(&context);
++#endif
++
++ fsize = frame_extra_sizes[regs->format];
++ if (fsize < 0) {
++ /*
++ * user process trying to return with weird frame format
++ */
++#ifdef DEBUG
++ printk(KERN_DEBUG "user process returning with weird \
++ frame format\n");
++#endif
++ goto badframe;
++ }
++
++ /* OK. Make room on the supervisor stack for the extra junk,
++ * if necessary.
++ */
++
++ {
++ struct switch_stack *sw = (struct switch_stack *)regs - 1;
++ regs->d0 = context.sc_d0;
++#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
++ __asm__ __volatile__
++ (" movel %0,%/sp\n\t"
++ " bra ret_from_signal\n"
++ "4:\n"
++ ".section __ex_table,\"a\"\n"
++ " .align 4\n"
++ " .long 2b,4b\n"
++ ".previous"
++ : /* no outputs, it doesn't ever return */
++ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
++ "n" (frame_offset), "a" (fp)
++ : "a0");
++#undef frame_offset
++ /*
++ * If we ever get here an exception occurred while
++ * building the above stack-frame.
++ */
++ goto badframe;
++ }
++
++ *pd0 = context.sc_d0;
++ return err;
++
++badframe:
++ return 1;
++}
++
++static inline int
++rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
++ struct ucontext __user *uc, int *pd0)
++{
++ int fsize, temp;
++ greg_t __user *gregs = uc->uc_mcontext.gregs;
++ unsigned long usp;
++ int err;
++
++ err = __get_user(temp, &uc->uc_mcontext.version);
++ if (temp != MCONTEXT_VERSION)
++ goto badframe;
++ /* restore passed registers */
++ err |= __get_user(regs->d0, &gregs[0]);
++ err |= __get_user(regs->d1, &gregs[1]);
++ err |= __get_user(regs->d2, &gregs[2]);
++ err |= __get_user(regs->d3, &gregs[3]);
++ err |= __get_user(regs->d4, &gregs[4]);
++ err |= __get_user(regs->d5, &gregs[5]);
++ err |= __get_user(sw->d6, &gregs[6]);
++ err |= __get_user(sw->d7, &gregs[7]);
++ err |= __get_user(regs->a0, &gregs[8]);
++ err |= __get_user(regs->a1, &gregs[9]);
++ err |= __get_user(regs->a2, &gregs[10]);
++ err |= __get_user(sw->a3, &gregs[11]);
++ err |= __get_user(sw->a4, &gregs[12]);
++ err |= __get_user(sw->a5, &gregs[13]);
++ err |= __get_user(sw->a6, &gregs[14]);
++ err |= __get_user(usp, &gregs[15]);
++ wrusp(usp);
++ err |= __get_user(regs->pc, &gregs[16]);
++ err |= __get_user(temp, &gregs[17]);
++ regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
++ regs->orig_d0 = -1; /* disable syscall checks */
++ err |= __get_user(temp, &uc->uc_formatvec);
++ regs->format = temp >> 12;
++ regs->vector = temp & 0xfff;
++
++#ifdef CONFIG_FPU
++ err |= rt_restore_fpu_state(uc);
++#endif
++
++ if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
++ goto badframe;
++
++ fsize = frame_extra_sizes[regs->format];
++ if (fsize < 0) {
++ /*
++ * user process trying to return with weird frame format
++ */
++#ifdef DEBUG
++ printk(KERN_DEBUG "user process returning with weird \
++ frame format\n");
++#endif
++ goto badframe;
++ }
++
++ /* OK. Make room on the supervisor stack for the extra junk,
++ * if necessary.
++ */
++
++ {
++#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
++ __asm__ __volatile__
++ (" movel %0,%/sp\n\t"
++ " bra ret_from_signal\n"
++ "4:\n"
++ ".section __ex_table,\"a\"\n"
++ " .align 4\n"
++ " .long 2b,4b\n"
++ ".previous"
++ : /* no outputs, it doesn't ever return */
++ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
++ "n" (frame_offset), "a" (&uc->uc_extra)
++ : "a0");
++#undef frame_offset
++ /*
++ * If we ever get here an exception occurred while
++ * building the above stack-frame.
++ */
++ goto badframe;
++ }
++
++ *pd0 = regs->d0;
++ return err;
++
++badframe:
++ return 1;
++}
++
++asmlinkage int do_sigreturn(unsigned long __unused)
++{
++ struct switch_stack *sw = (struct switch_stack *) &__unused;
++ struct pt_regs *regs = (struct pt_regs *) (sw + 1);
++ unsigned long usp = rdusp();
++ struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
++ sigset_t set;
++ int d0;
++
++ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
++ goto badframe;
++ if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
++ (_NSIG_WORDS > 1 &&
++ __copy_from_user(&set.sig[1], &frame->extramask,
++ sizeof(frame->extramask))))
++ goto badframe;
++
++ sigdelsetmask(&set, ~_BLOCKABLE);
++ spin_lock_irq(&current->sighand->siglock);
++ current->blocked = set;
++ recalc_sigpending();
++ spin_unlock_irq(&current->sighand->siglock);
++
++ if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
++ goto badframe;
++ return d0;
++
++badframe:
++ force_sig(SIGSEGV, current);
++ return 0;
++}
++
++asmlinkage int do_rt_sigreturn(unsigned long __unused)
++{
++ struct switch_stack *sw = (struct switch_stack *) &__unused;
++ struct pt_regs *regs = (struct pt_regs *) (sw + 1);
++ unsigned long usp = rdusp();
++ struct rt_sigframe __user *frame =
++ (struct rt_sigframe __user *)(usp - 4);
++ sigset_t set;
++ int d0;
++
++ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
++ goto badframe;
++ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
++ goto badframe;
++
++ sigdelsetmask(&set, ~_BLOCKABLE);
++ spin_lock_irq(&current->sighand->siglock);
++ current->blocked = set;
++ recalc_sigpending();
++ spin_unlock_irq(&current->sighand->siglock);
++
++ if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
++ goto badframe;
++ return d0;
++
++badframe:
++ force_sig(SIGSEGV, current);
++ return 0;
++}
++
++#ifdef CONFIG_FPU
++/*
++ * Set up a signal frame.
++ */
++
++static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
++{
++ if (FPU_IS_EMU) {
++ /* save registers */
++ memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
++ memcpy(sc->sc_fpregs, current->thread.fp, 24);
++ return;
++ }
++
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fsave %0\n\t"
++ QCHIP_RESTORE_DIRECTIVE
++ : : "m" (*sc->sc_fpstate) : "memory");
++#endif
++
++ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
++ fpu_version = sc->sc_fpstate[0];
++ if (CPU_IS_020_OR_030 &&
++ regs->vector >= (VEC_FPBRUC * 4) &&
++ regs->vector <= (VEC_FPNAN * 4)) {
++ /* Clear pending exception in 68882 idle frame */
++ if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
++ sc->sc_fpstate[0x38] |= 1 << 3;
++ }
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fmovemd %/fp0-%/fp1,%0"
++ : : "m" (sc->sc_fpregs[0][0])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpcr,%0"
++ : : "m" (sc->sc_fpcntl[0])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpsr,%0"
++ : : "m" (sc->sc_fpcntl[1])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpiar,%0"
++ : : "m" (sc->sc_fpcntl[2])
++ : "memory");
++
++#endif
++ }
++}
++
++static inline int rt_save_fpu_state(struct ucontext __user *uc,
++ struct pt_regs *regs)
++{
++ unsigned char fpstate[FPCONTEXT_SIZE];
++ int context_size = CPU_IS_060 ? 8 : 0;
++ int err = 0;
++
++ if (FPU_IS_EMU) {
++ /* save fpu control register */
++ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
++ current->thread.fpcntl, 12);
++ /* save all other fpu register */
++ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
++ current->thread.fp, 96);
++ return err;
++ }
++
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fsave %0\n\t"
++ QCHIP_RESTORE_DIRECTIVE
++ : : "m" (*fpstate) : "memory");
++#endif
++ err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
++ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
++ fpregset_t fpregs;
++ if (!CPU_IS_060)
++ context_size = fpstate[1];
++ fpu_version = fpstate[0];
++#ifdef CONFIG_CFV4E
++ __asm__ volatile ("fmovemd %/fp0-%/fp7,%0"
++ : : "m" (fpregs.f_fpregs[0][0])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpcr,%0"
++ : : "m" (fpregs.f_fpcntl[0])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpsr,%0"
++ : : "m" (fpregs.f_fpcntl[1])
++ : "memory");
++ __asm__ volatile ("fmovel %/fpiar,%0"
++ : : "m" (fpregs.f_fpcntl[2])
++ : "memory");
++#endif
++ err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
++ sizeof(fpregs));
++ }
++ if (context_size)
++ err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
++ context_size);
++ return err;
++
++
++ return err;
++}
++#endif
++
++static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
++ unsigned long mask)
++{
++ sc->sc_mask = mask;
++ sc->sc_usp = rdusp();
++ sc->sc_d0 = regs->d0;
++ sc->sc_d1 = regs->d1;
++ sc->sc_a0 = regs->a0;
++ sc->sc_a1 = regs->a1;
++ sc->sc_sr = regs->sr;
++ sc->sc_pc = regs->pc;
++ sc->sc_formatvec = regs->format << 12 | regs->vector;
++#ifdef CONFIG_FPU
++ save_fpu_state(sc, regs);
++#endif
++}
++
++static inline int rt_setup_ucontext(struct ucontext __user *uc,
++ struct pt_regs *regs)
++{
++ struct switch_stack *sw = (struct switch_stack *)regs - 1;
++ greg_t __user *gregs = uc->uc_mcontext.gregs;
++ int err = 0;
++
++ err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
++ err |= __put_user(regs->d0, &gregs[0]);
++ err |= __put_user(regs->d1, &gregs[1]);
++ err |= __put_user(regs->d2, &gregs[2]);
++ err |= __put_user(regs->d3, &gregs[3]);
++ err |= __put_user(regs->d4, &gregs[4]);
++ err |= __put_user(regs->d5, &gregs[5]);
++ err |= __put_user(sw->d6, &gregs[6]);
++ err |= __put_user(sw->d7, &gregs[7]);
++ err |= __put_user(regs->a0, &gregs[8]);
++ err |= __put_user(regs->a1, &gregs[9]);
++ err |= __put_user(regs->a2, &gregs[10]);
++ err |= __put_user(sw->a3, &gregs[11]);
++ err |= __put_user(sw->a4, &gregs[12]);
++ err |= __put_user(sw->a5, &gregs[13]);
++ err |= __put_user(sw->a6, &gregs[14]);
++ err |= __put_user(rdusp(), &gregs[15]);
++ err |= __put_user(regs->pc, &gregs[16]);
++ err |= __put_user(regs->sr, &gregs[17]);
++ err |= __put_user((regs->format << 12) | regs->vector,
++ &uc->uc_formatvec);
++#ifdef CONFIG_FPU
++ err |= rt_save_fpu_state(uc, regs);
++#endif
++ return err;
++}
++
++static inline void push_cache(unsigned long vaddr)
++{
++#if defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
++ pgd_t *pdir;
++ pmd_t *pmdp;
++ pte_t *ptep;
++ unsigned long paddr;
++
++ pdir = pgd_offset(current->mm, vaddr);
++ pmdp = pmd_offset(pdir, vaddr);
++ ptep = pte_offset_map(pmdp, vaddr);
++ paddr = ((pte_val(*ptep) & PAGE_MASK) | (vaddr & ~PAGE_MASK));
++ cf_icache_flush_range(paddr, paddr + 8);
++#elif defined(CONFIG_M547X_8X)
++ flush_icache_range(vaddr, vaddr + 8);
++#endif
++}
++
++static inline void __user *
++get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
++{
++ unsigned long usp;
++
++ /* Default to using normal stack. */
++ usp = rdusp();
++
++ /* This is the X/Open sanctioned signal stack switching. */
++ if (ka->sa.sa_flags & SA_ONSTACK) {
++ if (!sas_ss_flags(usp))
++ usp = current->sas_ss_sp + current->sas_ss_size;
++ }
++ return (void __user *)((usp - frame_size) & -8UL);
++}
++
++static void setup_frame(int sig, struct k_sigaction *ka,
++ sigset_t *set, struct pt_regs *regs)
++{
++ struct sigframe __user *frame;
++ int fsize = frame_extra_sizes[regs->format];
++ struct sigcontext context;
++ int err = 0;
++
++ if (fsize < 0) {
++#ifdef DEBUG
++ printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
++ regs->format);
++#endif
++ goto give_sigsegv;
++ }
++
++ frame = get_sigframe(ka, regs, sizeof(*frame));
++
++ err |= __put_user((current_thread_info()->exec_domain
++ && current_thread_info()->exec_domain->signal_invmap
++ && sig < 32
++ ? current_thread_info()->exec_domain->signal_invmap[sig]
++ : sig),
++ &frame->sig);
++
++ err |= __put_user(regs->vector, &frame->code);
++ err |= __put_user(&frame->sc, &frame->psc);
++
++ if (_NSIG_WORDS > 1)
++ err |= copy_to_user(frame->extramask, &set->sig[1],
++ sizeof(frame->extramask));
++
++ setup_sigcontext(&context, regs, set->sig[0]);
++ err |= copy_to_user(&frame->sc, &context, sizeof(context));
++
++ /* Set up to return from userspace. */
++ err |= __put_user(frame->retcode, &frame->pretcode);
++ /* moveq #,d0; trap #0 */
++ err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
++ (long __user *)(frame->retcode));
++
++ if (err)
++ goto give_sigsegv;
++
++ push_cache((unsigned long) &frame->retcode);
++
++ /* Set up registers for signal handler */
++ wrusp((unsigned long) frame);
++ regs->pc = (unsigned long) ka->sa.sa_handler;
++
++adjust_stack:
++ /* Prepare to skip over the extra stuff in the exception frame. */
++ if (regs->stkadj) {
++ struct pt_regs *tregs =
++ (struct pt_regs *)((ulong)regs + regs->stkadj);
++#ifdef DEBUG
++ printk(KERN_DEBUG "Performing stackadjust=%04x\n",
++ regs->stkadj);
++#endif
++ /* This must be copied with decreasing addresses to
++ handle overlaps. */
++ tregs->vector = 0;
++ tregs->format = 0;
++ tregs->pc = regs->pc;
++ tregs->sr = regs->sr;
++ }
++ return;
++
++give_sigsegv:
++ force_sigsegv(sig, current);
++ goto adjust_stack;
++}
++
++static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
++ sigset_t *set, struct pt_regs *regs)
++{
++ struct rt_sigframe __user *frame;
++ int fsize = frame_extra_sizes[regs->format];
++ int err = 0;
++
++ if (fsize < 0) {
++#ifdef DEBUG
++ printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
++ regs->format);
++#endif
++ goto give_sigsegv;
++ }
++
++ frame = get_sigframe(ka, regs, sizeof(*frame));
++
++ if (fsize) {
++ err |= copy_to_user(&frame->uc.uc_extra, regs + 1, fsize);
++ regs->stkadj = fsize;
++ }
++
++ err |= __put_user((current_thread_info()->exec_domain
++ && current_thread_info()->exec_domain->signal_invmap
++ && sig < 32
++ ? current_thread_info()->exec_domain->signal_invmap[sig]
++ : sig),
++ &frame->sig);
++ err |= __put_user(&frame->info, &frame->pinfo);
++ err |= __put_user(&frame->uc, &frame->puc);
++ err |= copy_siginfo_to_user(&frame->info, info);
++
++ /* Create the ucontext. */
++ err |= __put_user(0, &frame->uc.uc_flags);
++ err |= __put_user(NULL, &frame->uc.uc_link);
++ err |= __put_user((void __user *)current->sas_ss_sp,
++ &frame->uc.uc_stack.ss_sp);
++ err |= __put_user(sas_ss_flags(rdusp()),
++ &frame->uc.uc_stack.ss_flags);
++ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
++ err |= rt_setup_ucontext(&frame->uc, regs);
++ err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
++
++ /* Set up to return from userspace. */
++ err |= __put_user(frame->retcode, &frame->pretcode);
++
++ /* movel #__NR_rt_sigreturn(0xAD),d0; trap #0 */
++ err |= __put_user(0x203c0000, (long *)(frame->retcode + 0));
++ err |= __put_user(0x00ad4e40, (long *)(frame->retcode + 4));
++
++ if (err)
++ goto give_sigsegv;
++
++ push_cache((unsigned long) &frame->retcode);
++
++ /* Set up registers for signal handler */
++ wrusp((unsigned long) frame);
++ regs->pc = (unsigned long) ka->sa.sa_handler;
++
++adjust_stack:
++ /* Prepare to skip over the extra stuff in the exception frame. */
++ if (regs->stkadj) {
++ struct pt_regs *tregs =
++ (struct pt_regs *)((ulong)regs + regs->stkadj);
++#ifdef DEBUG
++ printk(KERN_DEBUG "Performing stackadjust=%04x\n",
++ regs->stkadj);
++#endif
++ /* This must be copied with decreasing addresses to
++ handle overlaps. */
++ tregs->vector = 0;
++ tregs->format = 0;
++ tregs->pc = regs->pc;
++ tregs->sr = regs->sr;
++ }
++ return;
++
++give_sigsegv:
++ force_sigsegv(sig, current);
++ goto adjust_stack;
++}
++
++static inline void
++handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
++{
++ switch (regs->d0) {
++ case -ERESTARTNOHAND:
++ if (!has_handler)
++ goto do_restart;
++ regs->d0 = -EINTR;
++ break;
++
++ case -ERESTARTSYS:
++ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
++ regs->d0 = -EINTR;
++ break;
++ }
++ /* fallthrough */
++ case -ERESTARTNOINTR:
++do_restart:
++ regs->d0 = regs->orig_d0;
++ regs->pc -= 2;
++ break;
++ }
++}
++
++/*
++ * OK, we're invoking a handler
++ */
++static void
++handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
++ sigset_t *oldset, struct pt_regs *regs)
++{
++ /* are we from a system call? */
++ if (regs->orig_d0 >= 0)
++ /* If so, check system call restarting.. */
++ handle_restart(regs, ka, 1);
++
++ /* set up the stack frame */
++ if (ka->sa.sa_flags & SA_SIGINFO)
++ setup_rt_frame(sig, ka, info, oldset, regs);
++ else
++ setup_frame(sig, ka, oldset, regs);
++
++ if (ka->sa.sa_flags & SA_ONESHOT)
++ ka->sa.sa_handler = SIG_DFL;
++
++ spin_lock_irq(&current->sighand->siglock);
++ sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
++ if (!(ka->sa.sa_flags & SA_NODEFER))
++ sigaddset(&current->blocked, sig);
++ recalc_sigpending();
++ spin_unlock_irq(&current->sighand->siglock);
++}
++
++/*
++ * Note that 'init' is a special process: it doesn't get signals it doesn't
++ * want to handle. Thus you cannot kill init even with a SIGKILL even by
++ * mistake.
++ */
++asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
++{
++ siginfo_t info;
++ struct k_sigaction ka;
++ int signr;
++
++ current->thread.esp0 = (unsigned long) regs;
++
++ if (!oldset)
++ oldset = &current->blocked;
++
++ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++ if (signr > 0) {
++ /* Whee! Actually deliver the signal. */
++ handle_signal(signr, &ka, &info, oldset, regs);
++ return 1;
++ }
++
++ /* Did we come from a system call? */
++ if (regs->orig_d0 >= 0)
++ /* Restart the system call - no handlers present */
++ handle_restart(regs, NULL, 0);
++
++ return 0;
++}
+--- /dev/null
++++ b/arch/m68k/coldfire/common/traps.c
+@@ -0,0 +1,457 @@
++/*
++ * linux/arch/m68knommu/kernel/traps.c
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
++ */
++
++/*
++ * Sets up all exception vectors
++ */
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/a.out.h>
++#include <linux/user.h>
++#include <linux/string.h>
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <linux/ptrace.h>
++#include <linux/kallsyms.h>
++
++#include <asm/setup.h>
++#include <asm/fpu.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/traps.h>
++#include <asm/pgtable.h>
++#include <asm/machdep.h>
++#include <asm/siginfo.h>
++
++static char const * const vec_names[] = {
++ "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
++ "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
++ "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
++ "UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
++ "FORMAT ERROR", "UNINITIALIZED INTERRUPT",
++ "UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
++ "UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
++ "UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
++ "UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
++ "SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
++ "LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
++ "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
++ "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
++ "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
++ "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
++ "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
++ "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
++ "FPCP UNSUPPORTED OPERATION",
++ "MMU CONFIGURATION ERROR"
++};
++
++asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
++ unsigned long error_code);
++asmlinkage void trap_c(struct frame *fp);
++extern void __init coldfire_trap_init(void);
++
++void __init trap_init(void)
++{
++ coldfire_trap_init();
++}
++
++/* The following table converts the FS encoding of a ColdFire
++ exception stack frame into the error_code value needed by
++ do_fault. */
++
++static const unsigned char fs_err_code[] = {
++ 0, /* 0000 */
++ 0, /* 0001 */
++ 0, /* 0010 */
++ 0, /* 0011 */
++ 1, /* 0100 */
++ 0, /* 0101 */
++ 0, /* 0110 */
++ 0, /* 0111 */
++ 2, /* 1000 */
++ 3, /* 1001 */
++ 2, /* 1010 */
++ 0, /* 1011 */
++ 1, /* 1100 */
++ 1, /* 1101 */
++ 0, /* 1110 */
++ 0 /* 1111 */
++};
++
++#ifdef DEBUG
++static const char *fs_err_msg[16] = {
++ "Normal",
++ "Reserved",
++ "Interrupt during debug service routine",
++ "Reserved",
++ "X Protection",
++ "TLB X miss (opword)",
++ "TLB X miss (ext. word)",
++ "IFP in emulator mode",
++ "W Protection",
++ "Write error",
++ "TLB W miss",
++ "Reserved",
++ "R Protection",
++ "R/RMW Protection",
++ "TLB R miss",
++ "OEP in emulator mode",
++};
++#endif
++
++static inline void access_errorCF(struct frame *fp)
++{
++ unsigned long int mmusr, complainingAddress;
++ unsigned int err_code, fs;
++ int need_page_fault;
++
++ mmusr = fp->ptregs.mmusr;
++ complainingAddress = fp->ptregs.mmuar;
++#ifdef DEBUG
++ printk(KERN_DEBUG "pc %#lx, mmusr %#lx, complainingAddress %#lx\n", \
++ fp->ptregs.pc, mmusr, complainingAddress);
++#endif
++
++ /*
++ * error_code:
++ * bit 0 == 0 means no page found, 1 means protection fault
++ * bit 1 == 0 means read, 1 means write
++ */
++
++ fs = (fp->ptregs.fs2 << 2) | fp->ptregs.fs1;
++ switch (fs) {
++ case 5: /* 0101 TLB opword X miss */
++ need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0);
++ complainingAddress = fp->ptregs.pc;
++ break;
++ case 6: /* 0110 TLB extension word X miss */
++ need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1);
++ complainingAddress = fp->ptregs.pc + sizeof(long);
++ break;
++ case 10: /* 1010 TLB W miss */
++ need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0);
++ break;
++ case 14: /* 1110 TLB R miss */
++ need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0);
++ break;
++ default:
++ /* 0000 Normal */
++ /* 0001 Reserved */
++ /* 0010 Interrupt during debug service routine */
++ /* 0011 Reserved */
++ /* 0100 X Protection */
++ /* 0111 IFP in emulator mode */
++ /* 1000 W Protection*/
++ /* 1001 Write error*/
++ /* 1011 Reserved*/
++ /* 1100 R Protection*/
++ /* 1101 R Protection*/
++ /* 1111 OEP in emulator mode*/
++ need_page_fault = 1;
++ break;
++ }
++
++ if (need_page_fault) {
++ err_code = fs_err_code[fs];
++ if ((fs == 13) && (mmusr & MMUSR_WF)) /* rd-mod-wr access */
++ err_code |= 2; /* bit1 - write, bit0 - protection */
++ do_page_fault(&fp->ptregs, complainingAddress, err_code);
++ }
++}
++
++void die_if_kernel(char *str, struct pt_regs *fp, int nr)
++{
++ if (!(fp->sr & PS_S))
++ return;
++
++ console_verbose();
++ printk(KERN_EMERG "%s: %08x\n", str, nr);
++ printk(KERN_EMERG "PC: [<%08lx>]", fp->pc);
++ print_symbol(" %s", fp->pc);
++ printk(KERN_EMERG "\nSR: %04x SP: %p a2: %08lx\n",
++ fp->sr, fp, fp->a2);
++ printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
++ fp->d0, fp->d1, fp->d2, fp->d3);
++ printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
++ fp->d4, fp->d5, fp->a0, fp->a1);
++
++ printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
++ current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
++ show_stack(NULL, (unsigned long *)fp);
++ do_exit(SIGSEGV);
++}
++
++asmlinkage void buserr_c(struct frame *fp)
++{
++ unsigned int fs;
++
++ /* Only set esp0 if coming from user mode */
++ if (user_mode(&fp->ptregs))
++ current->thread.esp0 = (unsigned long) fp;
++
++ fs = (fp->ptregs.fs2 << 2) | fp->ptregs.fs1;
++#if defined(DEBUG)
++ printk(KERN_DEBUG "*** Bus Error *** (%x)%s\n", fs,
++ fs_err_msg[fs & 0xf]);
++#endif
++ switch (fs) {
++ case 0x5:
++ case 0x6:
++ case 0x7:
++ case 0x9:
++ case 0xa:
++ case 0xd:
++ case 0xe:
++ case 0xf:
++ access_errorCF(fp);
++ break;
++ default:
++ die_if_kernel("bad frame format", &fp->ptregs, 0);
++#if defined(DEBUG)
++ printk(KERN_DEBUG "Unknown SIGSEGV - 4\n");
++#endif
++ force_sig(SIGSEGV, current);
++ }
++}
++
++void show_trace(unsigned long *stack)
++{
++ unsigned long *endstack;
++ unsigned long addr;
++ int i;
++
++ printk(KERN_INFO "Call Trace:");
++ addr = (unsigned long)stack + THREAD_SIZE - 1;
++ endstack = (unsigned long *)(addr & -THREAD_SIZE);
++ i = 0;
++ while (stack + 1 <= endstack) {
++ addr = *stack++;
++ /*
++ * If the address is either in the text segment of the
++ * kernel, or in the region which contains vmalloc'ed
++ * memory, it *may* be the address of a calling
++ * routine; if so, print it so that someone tracing
++ * down the cause of the crash will be able to figure
++ * out the call path that was taken.
++ */
++ if (__kernel_text_address(addr)) {
++#ifndef CONFIG_KALLSYMS
++ if (i % 5 == 0)
++ printk("\n ");
++#endif
++ printk(" [<%08lx>] %pS\n", addr, (void *)addr);
++ i++;
++ }
++ }
++ printk(KERN_INFO "\n");
++}
++
++int kstack_depth_to_print = 48;
++void show_stack(struct task_struct *task, unsigned long *stack)
++{
++ unsigned long *p;
++ unsigned long *endstack;
++ int i;
++
++ if (!stack) {
++ if (task)
++ stack = (unsigned long *)task->thread.esp0;
++ else
++ stack = (unsigned long *)&stack;
++ }
++ endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1)
++ & -THREAD_SIZE);
++
++ printk(KERN_INFO "Stack from %08lx:", (unsigned long)stack);
++ p = stack;
++ for (i = 0; i < kstack_depth_to_print; i++) {
++ if (p + 1 > endstack)
++ break;
++ if (i % 8 == 0)
++ printk("\n ");
++ printk(" %08lx", *p++);
++ }
++ printk("\n");
++ show_trace(stack);
++}
++
++void bad_super_trap(struct frame *fp)
++{
++ console_verbose();
++ if (fp->ptregs.vector < sizeof(vec_names)/sizeof(vec_names[0]))
++ printk(KERN_WARNING "*** %s *** FORMAT=%X\n",
++ vec_names[fp->ptregs.vector],
++ fp->ptregs.format);
++ else
++ printk(KERN_WARNING "*** Exception %d *** FORMAT=%X\n",
++ fp->ptregs.vector,
++ fp->ptregs.format);
++ printk(KERN_WARNING "Current process id is %d\n", current->pid);
++ die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
++}
++
++asmlinkage void trap_c(struct frame *fp)
++{
++ int sig;
++ siginfo_t info;
++
++ if (fp->ptregs.sr & PS_S) {
++ if (fp->ptregs.vector == VEC_TRACE) {
++ /* traced a trapping instruction */
++ current->ptrace |= PT_DTRACE;
++ } else
++ bad_super_trap(fp);
++ return;
++ }
++
++ /* send the appropriate signal to the user program */
++ switch (fp->ptregs.vector) {
++ case VEC_ADDRERR:
++ info.si_code = BUS_ADRALN;
++ sig = SIGBUS;
++ break;
++ case VEC_ILLEGAL:
++ case VEC_LINE10:
++ case VEC_LINE11:
++ info.si_code = ILL_ILLOPC;
++ sig = SIGILL;
++ break;
++ case VEC_PRIV:
++ info.si_code = ILL_PRVOPC;
++ sig = SIGILL;
++ break;
++ case VEC_COPROC:
++ info.si_code = ILL_COPROC;
++ sig = SIGILL;
++ break;
++ case VEC_TRAP1: /* gdbserver breakpoint */
++ fp->ptregs.pc -= 2;
++ info.si_code = TRAP_TRACE;
++ sig = SIGTRAP;
++ break;
++ case VEC_TRAP2:
++ case VEC_TRAP3:
++ case VEC_TRAP4:
++ case VEC_TRAP5:
++ case VEC_TRAP6:
++ case VEC_TRAP7:
++ case VEC_TRAP8:
++ case VEC_TRAP9:
++ case VEC_TRAP10:
++ case VEC_TRAP11:
++ case VEC_TRAP12:
++ case VEC_TRAP13:
++ case VEC_TRAP14:
++ info.si_code = ILL_ILLTRP;
++ sig = SIGILL;
++ break;
++ case VEC_FPBRUC:
++ case VEC_FPOE:
++ case VEC_FPNAN:
++ info.si_code = FPE_FLTINV;
++ sig = SIGFPE;
++ break;
++ case VEC_FPIR:
++ info.si_code = FPE_FLTRES;
++ sig = SIGFPE;
++ break;
++ case VEC_FPDIVZ:
++ info.si_code = FPE_FLTDIV;
++ sig = SIGFPE;
++ break;
++ case VEC_FPUNDER:
++ info.si_code = FPE_FLTUND;
++ sig = SIGFPE;
++ break;
++ case VEC_FPOVER:
++ info.si_code = FPE_FLTOVF;
++ sig = SIGFPE;
++ break;
++ case VEC_ZERODIV:
++ info.si_code = FPE_INTDIV;
++ sig = SIGFPE;
++ break;
++ case VEC_CHK:
++ case VEC_TRAP:
++ info.si_code = FPE_INTOVF;
++ sig = SIGFPE;
++ break;
++ case VEC_TRACE: /* ptrace single step */
++ info.si_code = TRAP_TRACE;
++ sig = SIGTRAP;
++ break;
++ case VEC_TRAP15: /* breakpoint */
++ info.si_code = TRAP_BRKPT;
++ sig = SIGTRAP;
++ break;
++ default:
++ info.si_code = ILL_ILLOPC;
++ sig = SIGILL;
++ break;
++ }
++ info.si_signo = sig;
++ info.si_errno = 0;
++ switch (fp->ptregs.format) {
++ default:
++ info.si_addr = (void *) fp->ptregs.pc;
++ break;
++ case 2:
++ info.si_addr = (void *) fp->un.fmt2.iaddr;
++ break;
++ case 7:
++ info.si_addr = (void *) fp->un.fmt7.effaddr;
++ break;
++ case 9:
++ info.si_addr = (void *) fp->un.fmt9.iaddr;
++ break;
++ case 10:
++ info.si_addr = (void *) fp->un.fmta.daddr;
++ break;
++ case 11:
++ info.si_addr = (void *) fp->un.fmtb.daddr;
++ break;
++ }
++ force_sig_info(sig, &info, current);
++}
++
++asmlinkage void set_esp0(unsigned long ssp)
++{
++ current->thread.esp0 = ssp;
++}
++
++/*
++ * The architecture-independent backtrace generator
++ */
++void dump_stack(void)
++{
++ unsigned long stack;
++
++ show_stack(current, &stack);
++}
++EXPORT_SYMBOL(dump_stack);
++
++#ifdef CONFIG_M68KFPU_EMU
++asmlinkage void fpemu_signal(int signal, int code, void *addr)
++{
++ siginfo_t info;
++
++ info.si_signo = signal;
++ info.si_errno = 0;
++ info.si_code = code;
++ info.si_addr = addr;
++ force_sig_info(signal, &info, current);
++}
++#endif
+--- a/arch/m68k/include/asm/atomic.h
++++ b/arch/m68k/include/asm/atomic.h
+@@ -1,3 +1,11 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
++
+ #ifndef __ARCH_M68K_ATOMIC__
+ #define __ARCH_M68K_ATOMIC__
+
+@@ -30,12 +38,20 @@
+
+ static inline void atomic_add(int i, atomic_t *v)
+ {
+- __asm__ __volatile__("addl %1,%0" : "+m" (*v) : ASM_DI (i));
++#ifndef CONFIG_COLDFIRE
++ __asm__ __volatile__("addl %1,%0" : "+m" (*v) : ASM_DI(i));
++#else
++ __asm__ __volatile__("addl %1,%0" : "=m" (*v) : ASM_DI(i), "m" (*v));
++#endif
+ }
+
+ static inline void atomic_sub(int i, atomic_t *v)
+ {
+- __asm__ __volatile__("subl %1,%0" : "+m" (*v) : ASM_DI (i));
++#ifndef CONFIG_COLDFIRE
++ __asm__ __volatile__("subl %1,%0" : "+m" (*v) : ASM_DI(i));
++#else
++ __asm__ __volatile__("subl %1,%0" : "=m" (*v) : ASM_DI(i), "m" (*v));
++#endif
+ }
+
+ static inline void atomic_inc(atomic_t *v)
+@@ -55,6 +71,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;
+@@ -167,9 +191,14 @@ 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)
+ : "id" (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
+@@ -1,12 +1,18 @@
+-#ifndef _M68K_BITOPS_H
+-#define _M68K_BITOPS_H
+ /*
+ * Copyright 1992, Linus Torvalds.
+ *
++ * Copyright (C) 2011 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
+ * for more details.
+ */
++#ifndef _M68K_BITOPS_H
++#define _M68K_BITOPS_H
++
++#ifdef CONFIG_COLDFIRE
++#include <asm/cf_bitops.h>
++#else
+
+ #ifndef _LINUX_BITOPS_H
+ #error only <linux/bitops.h> can be included directly
+@@ -463,4 +469,6 @@ static inline unsigned long generic_find
+
+ #endif /* __KERNEL__ */
+
++#endif /* CONFIG_COLDFIRE */
++
+ #endif /* _M68K_BITOPS_H */
+--- a/arch/m68k/include/asm/bootinfo.h
++++ b/arch/m68k/include/asm/bootinfo.h
+@@ -2,6 +2,7 @@
+ ** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+ **
+ ** Copyright 1992 by Greg Harp
++ * Copyright (C) 2007-2011 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
+@@ -24,6 +25,47 @@
+ #ifndef _M68K_BOOTINFO_H
+ #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
+@@ -1,3 +1,11 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
++
+ #ifndef _M68K_CACHEFLUSH_H
+ #define _M68K_CACHEFLUSH_H
+
+@@ -6,6 +14,10 @@
+ /* cache code */
+ #define FLUSH_I_AND_D (0x00000808)
+ #define FLUSH_I (0x00000008)
++#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
++#ifdef CONFIG_COLDFIRE
++#include <asm/cf_cacheflush.h>
++#else /* !CONFIG_COLDFIRE */
+
+ /*
+ * Cache handling functions
+@@ -128,7 +140,6 @@ static inline void __flush_page_to_ram(v
+ }
+ }
+
+-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+ #define flush_dcache_page(page) __flush_page_to_ram(page_address(page))
+ #define flush_dcache_mmap_lock(mapping) do { } while (0)
+ #define flush_dcache_mmap_unlock(mapping) do { } while (0)
+@@ -154,4 +165,5 @@ static inline void copy_from_user_page(s
+ memcpy(dst, src, len);
+ }
+
++#endif /* !CONFIG_COLDFIRE */
+ #endif /* _M68K_CACHEFLUSH_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf-sram.h
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Author: Lanttor.Guo@freescale.com
++ *
++ * Providing on-chip SRAM allocation and free APIs to kernel
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef CF_SRAM_H
++#define CF_SRAM_H
++
++extern int declare_sram_pool(void *start, size_t size);
++
++extern void *sram_alloc(size_t len);
++extern void sram_free(void *addr, size_t len);
++
++#endif
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_bitops.h
+@@ -0,0 +1,443 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++#ifndef __CF_BITOPS__
++#define __CF_BITOPS__
++
++#ifndef _LINUX_BITOPS_H
++#error only <linux/bitops.h> can be included directly
++#endif
++
++#include <linux/compiler.h>
++
++#define test_and_set_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_test_and_set_bit(nr, vaddr) : \
++ __generic_coldfire_test_and_set_bit(nr, vaddr))
++
++static inline int __constant_coldfire_test_and_set_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++ __asm__ __volatile__ ("bset %2,(%4); sne %0"
++ : "=d" (retval), "=m" (*p)
++ : "di" (nr & 7), "m" (*p), "a" (p));
++ return retval;
++}
++
++static inline int __generic_coldfire_test_and_set_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++
++ __asm__ __volatile__ ("bset %2,%1; sne %0"
++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "d" (nr)
++ : "memory");
++ return retval;
++}
++#define __test_and_set_bit(nr, vaddr) test_and_set_bit(nr, vaddr)
++
++#define set_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_set_bit(nr, vaddr) : \
++ __generic_coldfire_set_bit(nr, vaddr))
++
++static inline void __constant_coldfire_set_bit(int nr,
++ volatile void *vaddr)
++{
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++ __asm__ __volatile__ ("bset %1,(%3)"
++ : "=m" (*p) : "di" (nr & 7), "m" (*p), "a" (p));
++}
++
++static inline void __generic_coldfire_set_bit(int nr,
++ volatile void *vaddr)
++{
++ __asm__ __volatile__ ("bset %1,%0"
++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "d" (nr)
++ : "memory");
++}
++#define __set_bit(nr, vaddr) set_bit(nr, vaddr)
++
++#define test_and_clear_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_test_and_clear_bit(nr, vaddr) : \
++ __generic_coldfire_test_and_clear_bit(nr, vaddr))
++
++static inline int __constant_coldfire_test_and_clear_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++
++ __asm__ __volatile__ ("bclr %2,(%4); sne %0"
++ : "=d" (retval), "=m" (*p)
++ : "id" (nr & 7), "m" (*p), "a" (p));
++
++ return retval;
++}
++
++static inline int __generic_coldfire_test_and_clear_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++
++ __asm__ __volatile__ ("bclr %2,%1; sne %0"
++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "d" (nr & 7)
++ : "memory");
++
++ return retval;
++}
++#define __test_and_clear_bit(nr, vaddr) test_and_clear_bit(nr, vaddr)
++
++/*
++ * clear_bit() doesn't provide any barrier for the compiler.
++ */
++#define smp_mb__before_clear_bit() barrier()
++#define smp_mb__after_clear_bit() barrier()
++
++#define clear_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_clear_bit(nr, vaddr) : \
++ __generic_coldfire_clear_bit(nr, vaddr))
++
++static inline void __constant_coldfire_clear_bit(int nr,
++ volatile void *vaddr)
++{
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++ __asm__ __volatile__ ("bclr %1,(%3)"
++ : "=m" (*p) : "id" (nr & 7), "m" (*p), "a" (p));
++}
++
++static inline void __generic_coldfire_clear_bit(int nr,
++ volatile void *vaddr)
++{
++ __asm__ __volatile__ ("bclr %1,%0"
++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "d" (nr)
++ : "memory");
++}
++#define __clear_bit(nr, vaddr) clear_bit(nr, vaddr)
++
++#define test_and_change_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_test_and_change_bit(nr, vaddr) : \
++ __generic_coldfire_test_and_change_bit(nr, vaddr))
++
++static inline int __constant_coldfire_test_and_change_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++
++ __asm__ __volatile__ ("bchg %2,(%4); sne %0"
++ : "=d" (retval), "=m" (*p)
++ : "id" (nr & 7), "m" (*p), "a" (p));
++
++ return retval;
++}
++
++static inline int __generic_coldfire_test_and_change_bit(int nr,
++ volatile void *vaddr)
++{
++ char retval;
++
++ __asm__ __volatile__ ("bchg %2,%1; sne %0"
++ : "=d" (retval), "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "id" (nr)
++ : "memory");
++
++ return retval;
++}
++#define __test_and_change_bit(nr, vaddr) test_and_change_bit(nr, vaddr)
++#define __change_bit(nr, vaddr) change_bit(nr, vaddr)
++
++#define change_bit(nr, vaddr) \
++ (__builtin_constant_p(nr) ? \
++ __constant_coldfire_change_bit(nr, vaddr) : \
++ __generic_coldfire_change_bit(nr, vaddr))
++
++static inline void __constant_coldfire_change_bit(int nr,
++ volatile void *vaddr)
++{
++ volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3];
++ __asm__ __volatile__ ("bchg %1,(%3)"
++ : "=m" (*p) : "id" (nr & 7), "m" (*p), "a" (p));
++}
++
++static inline void __generic_coldfire_change_bit(int nr,
++ volatile void *vaddr)
++{
++ __asm__ __volatile__ ("bchg %1,%0"
++ : "=m" (((volatile char *)vaddr)[(nr^31) >> 3])
++ : "d" (nr)
++ : "memory");
++}
++
++static inline int test_bit(int nr, const unsigned long *vaddr)
++{
++ return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
++}
++
++static inline unsigned long ffz(unsigned long word)
++{
++ unsigned long result = 0;
++
++ while (word & 1) {
++ result++;
++ word >>= 1;
++ }
++ return result;
++}
++
++/* find_next_zero_bit() finds the first zero bit in a bit string of length
++ * 'size' bits, starting the search at bit 'offset'. This is largely based
++ * on Linus's ALPHA routines.
++ */
++static inline unsigned long find_next_zero_bit(void *addr,
++ unsigned long size, unsigned long offset)
++{
++ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
++ unsigned long result = offset & ~31UL;
++ unsigned long tmp;
++
++ if (offset >= size)
++ return size;
++ size -= result;
++ offset &= 31UL;
++ if (offset) {
++ tmp = *(p++);
++ tmp |= ~0UL >> (32-offset);
++ if (size < 32)
++ goto found_first;
++ if (~tmp)
++ goto found_middle;
++ size -= 32;
++ result += 32;
++ }
++ while (size & ~31UL) {
++ tmp = *(p++);
++ if (~tmp)
++ goto found_middle;
++ result += 32;
++ size -= 32;
++ }
++ if (!size)
++ return result;
++ tmp = *p;
++
++found_first:
++ tmp |= ~0UL >> size;
++found_middle:
++ return result + ffz(tmp);
++}
++
++#define find_first_zero_bit(addr, size) find_next_zero_bit(((void *)addr), \
++ (size), 0)
++
++/* Ported from included/linux/bitops.h */
++static inline int ffs(int x)
++{
++ int r = 1;
++
++ if (!x)
++ return 0;
++ if (!(x & 0xffff)) {
++ x >>= 16;
++ r += 16;
++ }
++ if (!(x & 0xff)) {
++ x >>= 8;
++ r += 8;
++ }
++ if (!(x & 0xf)) {
++ x >>= 4;
++ r += 4;
++ }
++ if (!(x & 3)) {
++ x >>= 2;
++ r += 2;
++ }
++ if (!(x & 1)) {
++ x >>= 1;
++ r += 1;
++ }
++ return r;
++}
++#define __ffs(x) (ffs(x) - 1)
++
++/* find_next_bit - find the next set bit in a memory region
++ * (from asm-ppc/bitops.h)
++ */
++static inline unsigned long find_next_bit(const unsigned long *addr,
++ unsigned long size, unsigned long offset)
++{
++ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
++ unsigned int result = offset & ~31UL;
++ unsigned int tmp;
++
++ if (offset >= size)
++ return size;
++ size -= result;
++ offset &= 31UL;
++ if (offset) {
++ tmp = *p++;
++ tmp &= ~0UL << offset;
++ if (size < 32)
++ goto found_first;
++ if (tmp)
++ goto found_middle;
++ size -= 32;
++ result += 32;
++ }
++ while (size >= 32) {
++ tmp = *p++;
++ if (tmp != 0)
++ goto found_middle;
++ result += 32;
++ size -= 32;
++ }
++ if (!size)
++ return result;
++ tmp = *p;
++
++found_first:
++ tmp &= ~0UL >> (32 - size);
++ if (tmp == 0UL) /* Are any bits set? */
++ return result + size; /* Nope. */
++found_middle:
++ return result + __ffs(tmp);
++}
++
++#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
++
++#ifdef __KERNEL__
++
++/* Ported from include/linux/bitops.h */
++static inline int fls(int x)
++{
++ int r = 32;
++
++ if (!x)
++ return 0;
++ if (!(x & 0xffff0000u)) {
++ x <<= 16;
++ r -= 16;
++ }
++ if (!(x & 0xff000000u)) {
++ x <<= 8;
++ r -= 8;
++ }
++ if (!(x & 0xf0000000u)) {
++ x <<= 4;
++ r -= 4;
++ }
++ if (!(x & 0xc0000000u)) {
++ x <<= 2;
++ r -= 2;
++ }
++ if (!(x & 0x80000000u)) {
++ x <<= 1;
++ r -= 1;
++ }
++ return r;
++}
++
++static inline int __fls(int x)
++{
++ return fls(x) - 1;
++}
++
++#include <asm-generic/bitops/fls64.h>
++#include <asm-generic/bitops/sched.h>
++#include <asm-generic/bitops/hweight.h>
++#include <asm-generic/bitops/lock.h>
++
++#define minix_find_first_zero_bit(addr, size) find_next_zero_bit((addr), \
++ (size), 0)
++#define minix_test_and_set_bit(nr, addr) test_and_set_bit((nr), \
++ (unsigned long *)(addr))
++#define minix_set_bit(nr, addr) set_bit((nr), \
++ (unsigned long *)(addr))
++#define minix_test_and_clear_bit(nr, addr) test_and_clear_bit((nr), \
++ (unsigned long *)(addr))
++
++static inline int minix_test_bit(int nr, const volatile unsigned long *vaddr)
++{
++ int *a = (int *)vaddr;
++ int mask;
++
++ a += nr >> 5;
++ mask = 1 << (nr & 0x1f);
++ return ((mask & *a) != 0);
++}
++
++#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 24, \
++ (unsigned long *)(addr))
++#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, \
++ (unsigned long *)(addr))
++#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 24, \
++ (unsigned long *)(addr))
++#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, \
++ (unsigned long *)(addr))
++
++static inline int ext2_test_bit(int nr, const void *vaddr)
++{
++ const unsigned char *p = vaddr;
++ return (p[nr >> 3] & (1U << (nr & 7))) != 0;
++}
++
++static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
++{
++ const unsigned long *p = vaddr, *addr = vaddr;
++ int res;
++
++ if (!size)
++ return 0;
++
++ size = (size >> 5) + ((size & 31) > 0);
++ while (*p++ == ~0UL) {
++ if (--size == 0)
++ return (p - addr) << 5;
++ }
++
++ --p;
++ for (res = 0; res < 32; res++)
++ if (!ext2_test_bit(res, p))
++ break;
++ return (p - addr) * 32 + res;
++}
++
++static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
++ unsigned offset)
++{
++ const unsigned long *addr = vaddr;
++ const unsigned long *p = addr + (offset >> 5);
++ int bit = offset & 31UL, res;
++
++ if (offset >= size)
++ return size;
++
++ if (bit) {
++ /* Look for zero in first longword */
++ for (res = bit; res < 32; res++)
++ if (!ext2_test_bit(res, p))
++ return (p - addr) * 32 + res;
++ p++;
++ }
++ /* No zero yet, search remaining full bytes for a zero */
++ res = ext2_find_first_zero_bit(p, size - 32 * (p - addr));
++ return (p - addr) * 32 + res;
++}
++
++#endif /* KERNEL */
++
++#endif /* __CF_BITOPS__ */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_cacheflush.h
+@@ -0,0 +1,20 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
++
++#ifndef M68K_CF_CACHEFLUSH_H
++#define M68K_CF_CACHEFLUSH_H
++
++#ifdef CONFIG_M5445X
++#include "cf_5445x_cacheflush.h"
++#elif defined(CONFIG_M5441X)
++#include "cf_5441x_cacheflush.h"
++#elif defined(CONFIG_M547X_8X)
++#include "cf_548x_cacheflush.h"
++#endif
++
++#endif /* M68K_CF_CACHEFLUSH_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_entry.h
+@@ -0,0 +1,153 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
++
++#ifndef __CF_M68K_ENTRY_H
++#define __CF_M68K_ENTRY_H
++
++#include <asm/setup.h>
++#include <asm/page.h>
++#include <asm/coldfire.h>
++#include <asm/cfmmu.h>
++
++/*
++ * Stack layout in 'ret_from_exception':
++ *
++ * This allows access to the syscall arguments in registers d1-d5
++ *
++ * 0(sp) - d1
++ * 4(sp) - d2
++ * 8(sp) - d3
++ * C(sp) - d4
++ * 10(sp) - d5
++ * 14(sp) - a0
++ * 18(sp) - a1
++ * 1C(sp) - a2
++ * 20(sp) - d0
++ * 24(sp) - orig_d0
++ * 28(sp) - stack adjustment
++ * 2C(sp) - sr
++ * 2E(sp) - pc
++ * 32(sp) - format & vector
++ * 36(sp) - MMUSR
++ * 3A(sp) - MMUAR
++ */
++
++/*
++ * 97/05/14 Andreas: Register %a2 is now set to the current task throughout
++ * the whole kernel.
++ */
++
++/* the following macro is used when enabling interrupts */
++/* portable version */
++#define ALLOWINT (~0x700)
++#define MAX_NOINT_IPL 0
++
++#ifdef __ASSEMBLY__
++
++#define curptr a2
++
++LFLUSH_I_AND_D = 0x00000808
++LSIGTRAP = 5
++
++/* process bits for task_struct.ptrace */
++PT_TRACESYS_OFF = 3
++PT_TRACESYS_BIT = 1
++PT_PTRACED_OFF = 3
++PT_PTRACED_BIT = 0
++PT_DTRACE_OFF = 3
++PT_DTRACE_BIT = 2
++
++#define SAVE_ALL_INT save_all_int
++#define SAVE_ALL_SYS save_all_sys
++#define RESTORE_ALL restore_all
++/*
++ * This defines the normal kernel pt-regs layout.
++ *
++ * regs a3-a6 and d6-d7 are preserved by C code
++ * the kernel doesn't mess with usp unless it needs to
++ */
++
++/*
++ * a -1 in the orig_d0 field signifies
++ * that the stack frame is NOT for syscall
++ */
++.macro save_all_int
++ movel MMUSR, % sp@ -
++ movel MMUAR, % sp@ -
++ clrl % sp@ - | stk_adj
++ pea - 1 : w | orig d0
++ movel % d0, % sp@ - | d0
++ subal #(8*4), % sp
++ moveml % d1-%d5/%a0-%a1/%curptr, % sp@
++.endm
++
++.macro save_all_sys
++ movel MMUSR, % sp@-
++ movel MMUAR, % sp@-
++ clrl % sp@ - | stk_adj
++ movel % d0, % sp@ - | orig d0
++ movel % d0, % sp@ - | d0
++ subal #(8*4), % sp
++ moveml % d1-%d5/%a0-%a1/%curptr, % sp@
++.endm
++
++.macro restore_all
++ moveml % sp@, % a0-%a1/%curptr/%d1-%d5
++ addal #(8*4), % sp
++ movel % sp@+, % d0 | d0
++ addql #4, % sp | orig d0
++ addl % sp@+, % sp | stk_adj
++ addql #8, % sp | MMUAR & MMUSR
++ rte
++.endm
++
++#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */
++
++#define SAVE_SWITCH_STACK save_switch_stack
++#define RESTORE_SWITCH_STACK restore_switch_stack
++#define GET_CURRENT(tmp) get_current tmp
++
++.macro save_switch_stack
++ subal #(6*4), % sp
++ moveml % a3-%a6/%d6-%d7, % sp@
++.endm
++
++.macro restore_switch_stack
++ moveml % sp@, % a3-%a6/%d6-%d7
++ addal #(6*4), % sp
++.endm
++
++.macro get_current reg = % d0
++ movel % sp, \reg
++ andl #-THREAD_SIZE, \reg
++ movel \reg, % curptr
++ movel % curptr@, % curptr
++.endm
++
++#else /* C source */
++
++#define STR(X) STR1(X)
++#define STR1(X) #X
++
++#define PT_OFF_ORIG_D0 0x24
++#define PT_OFF_FORMATVEC 0x32
++#define PT_OFF_SR 0x2C
++#define SAVE_ALL_INT \
++ "clrl %%sp@-;" /* stk_adj */ \
++ "pea -1:w;" /* orig d0 = -1 */ \
++ "movel %%d0,%%sp@-;" /* d0 */ \
++ "subal #(8*4),%sp" \
++ "moveml %%d1-%%d5/%%a0-%%a2,%%sp@"
++#define GET_CURRENT(tmp) \
++ "movel %%sp,"#tmp"\n\t" \
++ "andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \
++ "movel "#tmp",%%a2\n\t"
++
++#endif
++
++#endif /* __CF_M68K_ENTRY_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_io.h
+@@ -0,0 +1,185 @@
++/*
++ * linux/include/asm-m68k/cf_io.h
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 9/30/08 JKM - Separated Coldfire pieces out from m68k.
++ *
++ * 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.
++ */
++
++#ifndef __CF_IO__
++#define __CF_IO__
++
++#ifdef __KERNEL__
++
++#include <linux/compiler.h>
++#include <asm/raw_io.h>
++#include <asm/virtconvert.h>
++
++#include <asm-generic/iomap.h>
++
++#define readb_relaxed(addr) readb(addr)
++#define readw_relaxed(addr) readw(addr)
++#define readl_relaxed(addr) readl(addr)
++
++#ifdef CONFIG_PCI
++
++/*
++ * IO space in Coldfire
++ */
++#define inb_p inb
++#define inw_p inw
++#define inl_p inl
++#define outb_p outb
++#define outw_p outw
++#define outl_p outl
++
++#ifndef CONFIG_COLDFIRE
++#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)
++#else
++#define inb(port) pci_inb(port)
++#define outb(val, port) pci_outb((val), (port))
++#define inw(port) pci_inw(port)
++#define outw(val, port) pci_outw((val), (port))
++#define insb(a, b, c) \
++ pci_insb((volatile unsigned char *)a, (unsigned char *)b, c)
++#define insw(a, b, c) \
++ pci_insw((volatile unsigned short *)a, (unsigned short *)b, c)
++#define insl(a, b, c) \
++ pci_insl((volatile unsigned long *)a, (unsigned long *)b, c)
++#define outsb(a, b, c) \
++ pci_outsb((volatile unsigned char *)a, (const unsigned char *)b, c)
++#define outsw(a, b, c) \
++ pci_outsw((volatile unsigned short *)a, (const unsigned short *)b, c)
++#define outsl(a, b, c) \
++ pci_outsl((volatile unsigned long *)a, (const unsigned long *)b, c)
++#define inl(port) pci_inl(port)
++#define outl(val, port) pci_outl((val), (port))
++#endif
++
++#else
++/* no pci */
++
++#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)
++
++#endif /* CONFIG_PCI */
++
++#define mmiowb()
++
++static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++static inline void __iomem *ioremap_nocache(unsigned long physaddr,
++ unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++static inline void __iomem *ioremap_writethrough(unsigned long physaddr,
++ unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
++}
++static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
++ unsigned long size)
++{
++ return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
++}
++
++static inline void memset_io(volatile void __iomem *addr,
++ unsigned char val, int count)
++{
++ __builtin_memset((void __force *) addr, val, count);
++}
++static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
++ int count)
++{
++ __builtin_memcpy(dst, (void __force *) src, count);
++}
++static inline void memcpy_toio(volatile void __iomem *dst,
++ const void *src, int count)
++{
++ __builtin_memcpy((void __force *) dst, src, count);
++}
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++#endif /* __KERNEL__ */
++
++#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
++
++/*
++ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
++ * access
++ */
++#define xlate_dev_mem_ptr(p) __va(p)
++
++/*
++ * Convert a virtual cached pointer to an uncached pointer
++ */
++#define xlate_dev_kmem_ptr(p) p
++
++#define __raw_readb(addr) \
++ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
++#define __raw_readw(addr) \
++ ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
++#define __raw_readl(addr) \
++ ({ unsigned long __v = (*(volatile unsigned long *) (addr)); __v; })
++#define __raw_writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
++#define __raw_writew(b, addr) \
++ (void)((*(volatile unsigned short *) (addr)) = (b))
++#define __raw_writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
++
++#define memset_io(a, b, c) memset((void *)(a), (b), (c))
++#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
++#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
++
++#if !defined(readb)
++#define readb(addr) \
++ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
++#define readw(addr) \
++ ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
++#define readl(addr) \
++ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
++#define writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b))
++#define writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b))
++#define writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b))
++#endif /* readb */
++
++#endif /* _IO_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_pgalloc.h
+@@ -0,0 +1,112 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++
++#ifndef M68K_CF_PGALLOC_H
++#define M68K_CF_PGALLOC_H
++#include <linux/highmem.h>
++#include <asm/coldfire.h>
++#include <asm/page.h>
++#include <asm/cf_tlbflush.h>
++#include <asm/cf_cacheflush.h>
++
++extern inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
++{
++ free_page((unsigned long) pte);
++}
++
++extern const char bad_pmd_string[];
++
++extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
++ unsigned long address)
++{
++ unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
++
++ if (!page)
++ return NULL;
++
++ memset((void *)page, 0, PAGE_SIZE);
++ return (pte_t *) (page);
++}
++
++extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
++{
++ return (pmd_t *) pgd;
++}
++
++#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
++#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); })
++
++#define pte_alloc_one_fast(mm, addr) pte_alloc_one(mm, addr)
++
++#define pmd_populate(mm, pmd, page) (pmd_val(*pmd) = \
++ (unsigned long)(page_address(page)))
++
++#define pmd_populate_kernel(mm, pmd, pte) (pmd_val(*pmd) = (unsigned long)(pte))
++
++#define pmd_pgtable(pmd) pmd_page(pmd)
++
++static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *page,
++ unsigned long address)
++{
++ __free_page(page);
++}
++
++#define __pmd_free_tlb(tlb, pmd, address) do { } while (0)
++
++static inline struct page *pte_alloc_one(struct mm_struct *mm,
++ unsigned long address)
++{
++ struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
++ pte_t *pte;
++
++ if (!page)
++ return NULL;
++
++ pte = kmap(page);
++ if (pte) {
++ clear_page(pte);
++ __flush_page_to_ram(pte);
++ flush_tlb_kernel_page(pte);
++ nocache_page(pte);
++ }
++ kunmap(page);
++
++ return page;
++}
++
++extern inline void pte_free(struct mm_struct *mm, struct page *page)
++{
++ __free_page(page);
++}
++
++/*
++ * In our implementation, each pgd entry contains 1 pmd that is never allocated
++ * or freed. pgd_present is always 1, so this should never be called. -NL
++ */
++#define pmd_free(mm, pmd) BUG()
++
++extern inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
++{
++ free_page((unsigned long) pgd);
++}
++
++extern inline pgd_t *pgd_alloc(struct mm_struct *mm)
++{
++ pgd_t *new_pgd;
++
++ new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
++ if (!new_pgd)
++ return NULL;
++ memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
++ memset(new_pgd, 0, PAGE_OFFSET >> PGDIR_SHIFT);
++ return new_pgd;
++}
++
++#define pgd_populate(mm, pmd, pte) BUG()
++
++#endif /* M68K_CF_PGALLOC_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_pgtable.h
+@@ -0,0 +1,364 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++
++#ifndef _CF_PGTABLE_H
++#define _CF_PGTABLE_H
++
++#include <asm/cfmmu.h>
++#include <asm/page.h>
++
++#ifndef __ASSEMBLY__
++#include <asm/virtconvert.h>
++#include <linux/linkage.h>
++
++/* For virtual address to physical address conversion */
++#define VTOP(addr) __pa(addr)
++#define PTOV(addr) __va(addr)
++
++
++#endif /* !__ASSEMBLY__ */
++
++/* Page protection values within PTE. */
++
++/* MMUDR bits, in proper place. */
++#define CF_PAGE_LOCKED (0x00000002)
++#define CF_PAGE_EXEC (0x00000004)
++#define CF_PAGE_WRITABLE (0x00000008)
++#define CF_PAGE_READABLE (0x00000010)
++#define CF_PAGE_SYSTEM (0x00000020)
++#define CF_PAGE_COPYBACK (0x00000040)
++#define CF_PAGE_NOCACHE (0x00000080)
++
++#define CF_CACHEMASK (~0x00000040)
++#define CF_PAGE_MMUDR_MASK (0x000000fe)
++
++#define _PAGE_NOCACHE030 (CF_PAGE_NOCACHE)
++
++/* MMUTR bits, need shifting down. */
++#define CF_PAGE_VALID (0x00000400)
++#define CF_PAGE_SHARED (0x00000800)
++
++#define CF_PAGE_MMUTR_MASK (0x00000c00)
++#define CF_PAGE_MMUTR_SHIFT (10)
++#define CF_ASID_MMU_SHIFT (2)
++
++/* Fake bits, not implemented in CF, will get masked out before
++ hitting hardware, and might go away altogether once this port is
++ complete. */
++#if PAGE_SHIFT < 13
++#error COLDFIRE Error: Pages must be at least 8k in size
++#endif
++#define CF_PAGE_ACCESSED (0x00001000)
++#define CF_PAGE_FILE (0x00000200)
++#define CF_PAGE_DIRTY (0x00000001)
++
++#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */
++#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */
++#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */
++#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */
++#define _DESCTYPE_MASK 0x003
++#define _CACHEMASK040 (~0x060)
++#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */
++
++
++/* Externally used page protection values. */
++#define _PAGE_PRESENT (CF_PAGE_VALID)
++#define _PAGE_ACCESSED (CF_PAGE_ACCESSED)
++#define _PAGE_DIRTY (CF_PAGE_DIRTY)
++#define _PAGE_READWRITE (CF_PAGE_WRITABLE \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_SHARED \
++ | CF_PAGE_SYSTEM)
++
++/* Compound page protection values. */
++#define PAGE_NONE __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED)
++
++#define PAGE_SHARED __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_ACCESSED)
++
++#define PAGE_INIT __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_EXEC \
++ | CF_PAGE_SYSTEM \
++ | CF_PAGE_SHARED)
++
++#define PAGE_KERNEL __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_EXEC \
++ | CF_PAGE_SYSTEM \
++ | CF_PAGE_SHARED \
++ | CF_PAGE_ACCESSED)
++
++#define PAGE_COPY __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE)
++
++/*
++ * Page protections for initialising protection_map. See mm/mmap.c
++ * for use. In general, the bit positions are xwr, and P-items are
++ * private, the S-items are shared.
++ */
++
++#define __P000 PAGE_NONE
++#define __P100 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_EXEC)
++#define __P010 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_ACCESSED)
++#define __P110 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_EXEC)
++#define __P001 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE)
++#define __P101 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_EXEC)
++#define __P011 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_ACCESSED)
++#define __P111 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_EXEC)
++
++#define __S000 PAGE_NONE
++#define __S100 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_EXEC)
++#define __S010 PAGE_SHARED
++#define __S110 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_EXEC)
++#define __S001 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE)
++#define __S101 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_EXEC)
++#define __S011 PAGE_SHARED
++#define __S111 __pgprot(CF_PAGE_VALID \
++ | CF_PAGE_ACCESSED \
++ | CF_PAGE_READABLE \
++ | CF_PAGE_WRITABLE \
++ | CF_PAGE_EXEC)
++
++#define PTE_MASK PAGE_MASK
++#define CF_PAGE_CHG_MASK (PTE_MASK | CF_PAGE_ACCESSED | CF_PAGE_DIRTY)
++
++#ifndef __ASSEMBLY__
++
++/*
++ * Conversion functions: convert a page and protection to a page entry,
++ * and a page entry and page directory to the page they refer to.
++ */
++#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
++
++extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
++{
++ pte_val(pte) = (pte_val(pte) & CF_PAGE_CHG_MASK) | pgprot_val(newprot);
++ return pte;
++}
++
++#define pmd_set(pmdp, ptep) do {} while (0)
++
++static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
++{
++ pgd_val(*pgdp) = virt_to_phys(pmdp);
++}
++
++#define __pte_page(pte) \
++ ((unsigned long) ((pte_val(pte) & CF_PAGE_PGNUM_MASK) + PAGE_OFFSET))
++#define __pmd_page(pmd) ((unsigned long) (pmd_val(pmd)))
++
++extern inline int pte_none(pte_t pte)
++{
++ return !pte_val(pte);
++}
++extern inline int pte_present(pte_t pte)
++{
++ return pte_val(pte) & CF_PAGE_VALID;
++}
++extern inline void pte_clear(struct mm_struct *mm, unsigned long addr,
++ pte_t *ptep)
++{
++ pte_val(*ptep) = 0;
++}
++
++#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
++#define pte_page(pte) virt_to_page(__pte_page(pte))
++
++extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
++#define pmd_none(pmd) pmd_none2(&(pmd))
++extern inline int pmd_bad2(pmd_t *pmd) { return 0; }
++#define pmd_bad(pmd) pmd_bad2(&(pmd))
++#define pmd_present(pmd) (!pmd_none2(&(pmd)))
++extern inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = 0; }
++
++extern inline int pgd_none(pgd_t pgd) { return 0; }
++extern inline int pgd_bad(pgd_t pgd) { return 0; }
++extern inline int pgd_present(pgd_t pgd) { return 1; }
++extern inline void pgd_clear(pgd_t *pgdp) {}
++
++
++#define pte_ERROR(e) \
++ printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \
++ __FILE__, __LINE__, pte_val(e))
++#define pmd_ERROR(e) \
++ printk(KERN_ERR "%s:%d: bad pmd %08lx.\n", \
++ __FILE__, __LINE__, pmd_val(e))
++#define pgd_ERROR(e) \
++ printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \
++ __FILE__, __LINE__, pgd_val(e))
++
++
++/*
++ * The following only work if pte_present() is true.
++ * Undefined behaviour if not...
++ * [we have the full set here even if they don't change from m68k]
++ */
++extern inline int pte_read(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_READABLE; }
++extern inline int pte_write(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_WRITABLE; }
++extern inline int pte_exec(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_EXEC; }
++extern inline int pte_dirty(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_DIRTY; }
++extern inline int pte_young(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_ACCESSED; }
++extern inline int pte_file(pte_t pte) \
++ { return pte_val(pte) & CF_PAGE_FILE; }
++static inline int pte_special(pte_t pte) { return 0; }
++
++
++extern inline pte_t pte_wrprotect(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_WRITABLE; return pte; }
++extern inline pte_t pte_rdprotect(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_READABLE; return pte; }
++extern inline pte_t pte_exprotect(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_EXEC; return pte; }
++extern inline pte_t pte_mkclean(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_DIRTY; return pte; }
++extern inline pte_t pte_mkold(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_ACCESSED; return pte; }
++extern inline pte_t pte_mkwrite(pte_t pte) \
++ { pte_val(pte) |= CF_PAGE_WRITABLE; return pte; }
++extern inline pte_t pte_mkread(pte_t pte) \
++ { pte_val(pte) |= CF_PAGE_READABLE; return pte; }
++extern inline pte_t pte_mkexec(pte_t pte) \
++ { pte_val(pte) |= CF_PAGE_EXEC; return pte; }
++extern inline pte_t pte_mkdirty(pte_t pte) \
++ { pte_val(pte) |= CF_PAGE_DIRTY; return pte; }
++extern inline pte_t pte_mkyoung(pte_t pte) \
++ { pte_val(pte) |= CF_PAGE_ACCESSED; return pte; }
++extern inline pte_t pte_mknocache(pte_t pte) \
++ { pte_val(pte) |= 0x80 | (pte_val(pte) & ~0x40); return pte; }
++extern inline pte_t pte_mkcache(pte_t pte) \
++ { pte_val(pte) &= ~CF_PAGE_NOCACHE; return pte; }
++static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
++
++
++#define swapper_pg_dir kernel_pg_dir
++extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
++
++/* Find an entry in a pagetable directory. */
++#define pgd_index(address) ((address) >> PGDIR_SHIFT)
++
++#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
++
++/* Find an entry in a kernel pagetable directory. */
++#define pgd_offset_k(address) pgd_offset(&init_mm, address)
++
++/* Find an entry in the second-level pagetable. */
++extern inline pmd_t *pmd_offset(pgd_t *pgd, unsigned long address)
++{
++ return (pmd_t *) pgd;
++}
++
++/* Find an entry in the third-level pagetable. */
++#define __pte_offset(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
++#define pte_offset_kernel(dir, address) ((pte_t *) __pmd_page(*(dir)) + \
++ __pte_offset(address))
++
++/* Disable caching for page at given kernel virtual address. */
++static inline void nocache_page(void *vaddr)
++{
++ pgd_t *dir;
++ pmd_t *pmdp;
++ pte_t *ptep;
++ unsigned long addr = (unsigned long)vaddr;
++
++ dir = pgd_offset_k(addr);
++ pmdp = pmd_offset(dir, addr);
++ ptep = pte_offset_kernel(pmdp, addr);
++ *ptep = pte_mknocache(*ptep);
++}
++
++/* Enable caching for page at given kernel virtual address. */
++static inline void cache_page(void *vaddr)
++{
++ pgd_t *dir;
++ pmd_t *pmdp;
++ pte_t *ptep;
++ unsigned long addr = (unsigned long)vaddr;
++
++ dir = pgd_offset_k(addr);
++ pmdp = pmd_offset(dir, addr);
++ ptep = pte_offset_kernel(pmdp, addr);
++ *ptep = pte_mkcache(*ptep);
++}
++
++#define PTE_FILE_MAX_BITS 21
++#define PTE_FILE_SHIFT 11
++
++static inline unsigned long pte_to_pgoff(pte_t pte)
++{
++ return pte_val(pte) >> PTE_FILE_SHIFT;
++}
++
++static inline pte_t pgoff_to_pte(unsigned pgoff)
++{
++ pte_t pte = __pte((pgoff << PTE_FILE_SHIFT) + CF_PAGE_FILE);
++ return pte;
++}
++
++/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
++#define __swp_entry(type, offset) ((swp_entry_t) { (type) | \
++ (offset << PTE_FILE_SHIFT) })
++#define __swp_type(x) ((x).val & 0xFF)
++#define __swp_offset(x) ((x).val >> PTE_FILE_SHIFT)
++#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
++#define __swp_entry_to_pte(x) (__pte((x).val))
++
++#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
++
++#define pte_offset_map(pmdp, address) ((pte_t *)__pmd_page(*pmdp) + \
++ __pte_offset(address))
++#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address)
++#define pte_unmap(pte) do { } while (0)
++#define pte_unmap_nested(pte) kunmap(pte)
++
++#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
++
++
++#endif /* !__ASSEMBLY__ */
++#endif /* !_CF_PGTABLE_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_raw_io.h
+@@ -0,0 +1,188 @@
++/*
++ * linux/include/asm-m68k/cf_raw_io.h
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 09/30/08 JKM: split Coldfire pieces into separate file
++ *
++ * 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.
++ */
++#ifndef __CF_RAW_IO__
++#define __CF_RAW_IO__
++
++#ifdef __KERNEL__
++
++#include <asm/types.h>
++
++/* Values for nocacheflag and cmode */
++#define IOMAP_FULL_CACHING 0
++#define IOMAP_NOCACHE_SER 1
++#define IOMAP_NOCACHE_NONSER 2
++#define IOMAP_WRITETHROUGH 3
++
++extern void iounmap(void __iomem *addr);
++
++extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
++ int cacheflag);
++extern void __iounmap(void *addr, unsigned long size);
++
++
++/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
++ * two accesses to memory, which may be undesirable for some devices.
++ */
++#define in_8(addr) \
++ ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
++#define in_be16(addr) \
++ ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
++#define in_be32(addr) \
++ ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; })
++#define in_le16(addr) \
++ ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; })
++#define in_le32(addr) \
++ ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; })
++
++#define out_8(addr, b) (void)((*(__force volatile u8 *) (addr)) = (b))
++#define out_be16(addr, w) (void)((*(__force volatile u16 *) (addr)) = (w))
++#define out_be32(addr, l) (void)((*(__force volatile u32 *) (addr)) = (l))
++#define out_le16(addr, w) \
++ (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w))
++#define out_le32(addr, l) \
++ (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l))
++
++
++#ifdef CONFIG_PCI
++/* pci */
++unsigned char pci_inb(long addr);
++unsigned short pci_inw(long addr);
++unsigned long pci_inl(long addr);
++
++void pci_outb(unsigned char val, long addr);
++void pci_outw(unsigned short val, long addr);
++void pci_outl(unsigned long val, long addr);
++
++void pci_insb(volatile unsigned char *addr,
++ unsigned char *buf, int len);
++void pci_insw(volatile unsigned short *addr,
++ unsigned short *buf, int len);
++void pci_insl(volatile unsigned long *addr,
++ unsigned long *buf, int len);
++
++void pci_outsb(volatile unsigned char *addr,
++ const unsigned char *buf, int len);
++void pci_outsw(volatile unsigned short *addr,
++ const unsigned short *buf, int len);
++void pci_outsl(volatile unsigned long *addr,
++ const unsigned long *buf, int len);
++
++unsigned short pci_raw_inw(long addr);
++unsigned long pci_raw_inl(long addr);
++void pci_raw_outw(unsigned short val, long addr);
++void pci_raw_outl(unsigned long val, long addr);
++
++#define raw_inb(port) pci_inb((long)((volatile unsigned char *)(port)))
++#define raw_inw(port) pci_raw_inw((long)((volatile unsigned short *)(port)))
++#define raw_inl(port) pci_raw_inl((long)((volatile unsigned long *)(port)))
++
++#define raw_outb(val, port) \
++ pci_outb((val), (long)((volatile unsigned char *)(port)))
++#define raw_outw(val, port) \
++ pci_raw_outw((val), (long)((volatile unsigned short *)(port)))
++#define raw_outl(val, port) \
++ pci_raw_outl((val), (long)((volatile unsigned long *)(port)))
++
++#define swap_inw(port) pci_inw((long)((volatile unsigned short *)(port)))
++#define swap_outw(val, port) \
++ pci_outw((val), (long)((volatile unsigned short *)(port)))
++
++#else
++/* non-pci */
++#define raw_inb in_8
++#define raw_inw in_be16
++#define raw_inl in_be32
++
++#define raw_outb(val, port) out_8((port), (val))
++#define raw_outw(val, port) out_be16((port), (val))
++#define raw_outl(val, port) out_be32((port), (val))
++
++#define swap_inw(port) in_le16((port))
++#define swap_outw(val, port) out_le16((port), (val))
++#endif
++
++static inline void raw_insb(volatile u8 __iomem *port,
++ u8 *buf, unsigned int len)
++{
++ unsigned int i;
++
++ for (i = 0; i < len; i++)
++ *buf++ = in_8(port);
++}
++
++static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
++ unsigned int len)
++{
++ unsigned int i;
++
++ for (i = 0; i < len; i++)
++ out_8(port, *buf++);
++}
++
++static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr)
++{
++ unsigned int i;
++
++ for (i = 0; i < nr; i++)
++ *buf++ = raw_inw(port);
++}
++
++static inline void raw_outsw(volatile u16 *port, const u16 *buf,
++ unsigned int nr)
++{
++ unsigned int i;
++
++ for (i = 0; i < nr; i++, buf++)
++ raw_outw(*buf, port);
++}
++
++static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr)
++{
++ unsigned int i;
++
++ for (i = 0; i < nr; i++)
++ *buf++ = raw_inl(port);
++}
++
++static inline void raw_outsl(volatile u32 *port, const u32 *buf,
++ unsigned int nr)
++{
++ unsigned int i;
++
++ for (i = 0; i < nr; i++, buf++)
++ raw_outl(*buf, port);
++}
++
++static inline void raw_insw_swapw(volatile u16 *port, u16 *buf,
++ unsigned int nr)
++{
++#ifdef UNDEF
++ unsigned int i;
++
++ for (i = 0; i < nr; i++)
++ *buf++ = in_le16(port);
++#endif
++}
++
++static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
++ unsigned int nr)
++{
++#ifdef UNDEF
++ unsigned int i;
++
++ for (i = 0; i < nr; i++, buf++)
++ out_le16(port, *buf);
++#endif
++}
++
++#endif /* __KERNEL__ */
++
++#endif /* __CF_RAW_IO__ */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_tlbflush.h
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++#ifndef M68K_CF_TLBFLUSH_H
++#define M68K_CF_TLBFLUSH_H
++
++#include <asm/coldfire.h>
++
++/* Flush all userspace mappings. */
++static inline void flush_tlb_all(void)
++{
++ preempt_disable();
++ *MMUOR = MMUOR_CNL;
++ preempt_enable();
++}
++
++/* Clear user TLB entries within the context named in mm */
++static inline void flush_tlb_mm(struct mm_struct *mm)
++{
++ preempt_disable();
++ *MMUOR = MMUOR_CNL;
++ preempt_enable();
++}
++
++/* Flush a single TLB page. */
++static inline void flush_tlb_page(struct vm_area_struct *vma,
++ unsigned long addr)
++{
++ preempt_disable();
++ *MMUOR = MMUOR_CNL;
++ preempt_enable();
++}
++/* Flush a range of pages from TLB. */
++
++static inline void flush_tlb_range(struct vm_area_struct *mm,
++ unsigned long start, unsigned long end)
++{
++ preempt_disable();
++ *MMUOR = MMUOR_CNL;
++ preempt_enable();
++}
++
++/* Flush kernel page from TLB. */
++static inline void flush_tlb_kernel_page(void *addr)
++{
++ preempt_disable();
++ *MMUOR = MMUOR_CNL;
++ preempt_enable();
++}
++
++static inline void flush_tlb_kernel_range(unsigned long start,
++ unsigned long end)
++{
++ flush_tlb_all();
++}
++
++extern inline void flush_tlb_pgtables(struct mm_struct *mm,
++ unsigned long start, unsigned long end)
++{
++}
++
++#endif /* M68K_CF_TLBFLUSH_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_uaccess.h
+@@ -0,0 +1,262 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++#ifndef __M68K_CF_UACCESS_H
++#define __M68K_CF_UACCESS_H
++
++/*
++ * User space memory access functions
++ */
++
++/* The "moves" command is not available in the CF instruction set. */
++#include <linux/compiler.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <asm/segment.h>
++
++#define VERIFY_READ 0
++#define VERIFY_WRITE 1
++
++/* We let the MMU do all checking */
++#define access_ok(type, addr, size) 1
++
++/*
++ * The exception table consists of pairs of addresses: the first is the
++ * address of an instruction that is allowed to fault, and the second is
++ * the address at which the program should continue. No registers are
++ * modified, so it is entirely up to the continuation code to figure out
++ * what to do.
++ *
++ * All the routines below use bits of fixup code that are out of line
++ * with the main instruction path. This means when everything is well,
++ * we don't even have to jump over them. Further, they do not intrude
++ * on our cache or tlb entries.
++ */
++
++struct exception_table_entry {
++ unsigned long insn, fixup;
++};
++
++extern int __put_user_bad(void);
++extern int __get_user_bad(void);
++
++#define __put_user_asm(res, x, ptr, bwl, reg, err) \
++asm volatile ("\n" \
++ "1: move."#bwl" %2,%1\n" \
++ "2:\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "10: moveq.l %3,%0\n" \
++ " jra 2b\n" \
++ " .previous\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 1b,10b\n" \
++ " .long 2b,10b\n" \
++ " .previous" \
++ : "+d" (res), "=m" (*(ptr)) \
++ : #reg(x), "i" (err))
++
++/*
++ * These are the main single-value transfer routines. They automatically
++ * use the right size if we just have the right pointer type.
++ */
++
++#define __put_user(x, ptr) \
++({ \
++ typeof(*(ptr)) __pu_val = (x); \
++ int __pu_err = 0; \
++ __chk_user_ptr(ptr); \
++ switch (sizeof(*(ptr))) { \
++ case 1: \
++ __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
++ break; \
++ case 2: \
++ __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT); \
++ break; \
++ case 4: \
++ __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \
++ break; \
++ case 8: \
++ { \
++ const void __user *__pu_ptr = (ptr); \
++ asm volatile ("\n" \
++ "1: move.l %2,(%1)+\n" \
++ "2: move.l %R2,(%1)\n" \
++ "3:\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "10: movel %3,%0\n" \
++ " jra 3b\n" \
++ " .previous\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 1b,10b\n" \
++ " .long 2b,10b\n" \
++ " .long 3b,10b\n" \
++ " .previous" \
++ : "+d" (__pu_err), "+a" (__pu_ptr) \
++ : "r" (__pu_val), "i" (-EFAULT) \
++ : "memory"); \
++ break; \
++ } \
++ default: \
++ __pu_err = __put_user_bad(); \
++ break; \
++ } \
++ __pu_err; \
++})
++#define put_user(x, ptr) __put_user(x, ptr)
++
++
++#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \
++ type __gu_val; \
++ asm volatile ("\n" \
++ "1: move."#bwl" %2,%1\n" \
++ "2:\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "10: move.l %3,%0\n" \
++ " subl %1,%1\n" \
++ " jra 2b\n" \
++ " .previous\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 1b,10b\n" \
++ " .previous" \
++ : "+d" (res), "=&" #reg(__gu_val) \
++ : "m" (*(ptr)), "i" (err)); \
++ (x) = (typeof(*(ptr)))(unsigned long)__gu_val; \
++})
++
++#define __get_user(x, ptr) \
++({ \
++ int __gu_err = 0; \
++ __chk_user_ptr(ptr); \
++ switch (sizeof(*(ptr))) { \
++ case 1: \
++ __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \
++ break; \
++ case 2: \
++ __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT); \
++ break; \
++ case 4: \
++ __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \
++ break; \
++/* case 8: disabled because gcc-4.1 has a broken typeof \
++ { \
++ const void *__gu_ptr = (ptr); \
++ u64 __gu_val; \
++ asm volatile ("\n" \
++ "1: move.l (%2)+,%1\n" \
++ "2: move.l (%2),%R1\n" \
++ "3:\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "10: move.l %3,%0\n" \
++ " subl %1,%1\n" \
++ " subl %R1,%R1\n" \
++ " jra 3b\n" \
++ " .previous\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 1b,10b\n" \
++ " .long 2b,10b\n" \
++ " .previous" \
++ : "+d" (__gu_err), "=&r" (__gu_val), \
++ "+a" (__gu_ptr) \
++ : "i" (-EFAULT) \
++ : "memory"); \
++ (x) = (typeof(*(ptr)))__gu_val; \
++ break; \
++ } */ \
++ default : \
++ __gu_err = __get_user_bad(); \
++ break; \
++ } \
++ __gu_err; \
++})
++#define get_user(x, ptr) __get_user(x, ptr)
++
++unsigned long __generic_copy_from_user(void *to, const void __user *from,
++ unsigned long n);
++unsigned long __generic_copy_to_user(void __user *to, const void *from,
++ unsigned long n);
++
++#define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\
++ asm volatile ("\n" \
++ "1: move."#s1" (%2)+,%3\n" \
++ " move."#s1" %3,(%1)+\n" \
++ "2: move."#s2" (%2)+,%3\n" \
++ " move."#s2" %3,(%1)+\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ "3: move."#s3" (%2)+,%3\n" \
++ " move."#s3" %3,(%1)+\n" \
++ " .endif\n" \
++ "4:\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 1b,10f\n" \
++ " .long 2b,20f\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ " .long 3b,30f\n" \
++ " .endif\n" \
++ " .previous\n" \
++ "\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "10: clr."#s1" (%1)+\n" \
++ "20: clr."#s2" (%1)+\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ "30: clr."#s3" (%1)+\n" \
++ " .endif\n" \
++ " moveq.l #"#n",%0\n" \
++ " jra 4b\n" \
++ " .previous\n" \
++ : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \
++ : : "memory")
++
++#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
++ asm volatile ("\n" \
++ " move."#s1" (%2)+,%3\n" \
++ "11: move."#s1" %3,(%1)+\n" \
++ "12: move."#s2" (%2)+,%3\n" \
++ "21: move."#s2" %3,(%1)+\n" \
++ "22:\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ " move."#s3" (%2)+,%3\n" \
++ "31: move."#s3" %3,(%1)+\n" \
++ "32:\n" \
++ " .endif\n" \
++ "4:\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 11b,5f\n" \
++ " .long 12b,5f\n" \
++ " .long 21b,5f\n" \
++ " .long 22b,5f\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ " .long 31b,5f\n" \
++ " .long 32b,5f\n" \
++ " .endif\n" \
++ " .previous\n" \
++ "\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "5: moveq.l #"#n",%0\n" \
++ " jra 4b\n" \
++ " .previous\n" \
++ : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
++ : : "memory")
++
++#endif /* _M68K_CF_UACCESS_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cf_virtconvert.h
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
++#ifndef __CF_VIRTCONVERT__
++#define __CF_VIRTCONVERT__
++
++/*
++ * Macros used for converting between virtual and physical mappings.
++ *
++ * Coldfire Specific
++ */
++
++#ifdef __KERNEL__
++
++#include <linux/compiler.h>
++#include <linux/mmzone.h>
++#include <asm/setup.h>
++#include <asm/page.h>
++
++/*
++ * Change virtual addresses to physical addresses and vv.
++ */
++static inline unsigned long virt_to_phys(void *address)
++{
++ return __pa(address);
++}
++
++static inline void *phys_to_virt(unsigned long address)
++{
++ return __va(address);
++}
++
++/* Permanent address of a page. */
++#ifdef CONFIG_SINGLE_MEMORY_CHUNK
++#define page_to_phys(page) \
++ __pa(PAGE_OFFSET + \
++ (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT))
++#else
++#define page_to_phys(_page) ({ \
++ struct page *__page = _page; \
++ struct pglist_data *pgdat; \
++ pgdat = pg_data_table[page_to_nid(__page)]; \
++ page_to_pfn(__page) << PAGE_SHIFT; \
++})
++#endif
++
++/*
++ * IO bus memory addresses are 1:1 with the physical address,
++ */
++#ifdef CONFIG_PCI
++#define virt_to_bus(a) (a + PCI_DMA_BASE)
++#define bus_to_virt(a) (a - PCI_DMA_BASE)
++#else
++#define virt_to_bus(a) (a)
++#define bus_to_virt(a) (a)
++#endif
++
++#endif /* __KERNEL__ */
++#endif /* __CF_VIRTCONVERT__ */
+--- /dev/null
++++ b/arch/m68k/include/asm/cfcache.h
+@@ -0,0 +1,146 @@
++/*
++ * include/asm-m68k/cfcache.h - Coldfire Cache Controller
++ *
++ * Kurt Mahan kmahan@freescale.com
++ *
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ *
++ * 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
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++#ifndef CF_CFCACHE_H
++#define CF_CFCACHE_H
++
++/*
++ * CACR Cache Control Register
++ */
++#define CF_CACR_DEC (0x80000000) /* Data Cache Enable */
++#define CF_CACR_DW (0x40000000) /* Data default Write-protect */
++#define CF_CACR_DESB (0x20000000) /* Data Enable Store Buffer */
++#define CF_CACR_DPI (0x10000000) /* Data Disable CPUSHL Invalidate */
++#define CF_CACR_DHLCK (0x08000000) /* 1/2 Data Cache Lock Mode */
++#define CF_CACR_DDCM_00 (0x00000000) /* Cacheable writethrough imprecise */
++#define CF_CACR_DDCM_01 (0x02000000) /* Cacheable copyback */
++#define CF_CACR_DDCM_10 (0x04000000) /* Noncacheable precise */
++#define CF_CACR_DDCM_11 (0x06000000) /* Noncacheable imprecise */
++#define CF_CACR_DCINVA (0x01000000) /* Data Cache Invalidate All */
++#define CF_CACR_DDSP (0x00800000) /* Data default supervisor-protect */
++#define CF_CACR_IVO (0x00100000) /* Invalidate only */
++#define CF_CACR_BEC (0x00080000) /* Branch Cache Enable */
++#define CF_CACR_BCINVA (0x00040000) /* Branch Cache Invalidate All */
++#define CF_CACR_IEC (0x00008000) /* Instruction Cache Enable */
++#define CF_CACR_SPA (0x00004000) /* Search by Physical Address */
++#define CF_CACR_DNFB (0x00002000) /* Default cache-inhibited fill buf */
++#define CF_CACR_IDPI (0x00001000) /* Instr Disable CPUSHL Invalidate */
++#define CF_CACR_IHLCK (0x00000800) /* 1/2 Instruction Cache Lock Mode */
++#define CF_CACR_IDCM (0x00000400) /* Noncacheable Instr default mode */
++#define CF_CACR_ICINVA (0x00000100) /* Instr Cache Invalidate All */
++#define CF_CACR_IDSP (0x00000080) /* Ins default supervisor-protect */
++#define CF_CACR_EUSP (0x00000020) /* Switch stacks in user mode */
++
++#ifdef CONFIG_M5445X
++/*
++ * M5445x Cache Configuration
++ * - cache line size is 16 bytes
++ * - cache is 4-way set associative
++ * - each cache has 256 sets (64k / 16bytes / 4way)
++ * - I-Cache size is 16KB
++ * - D-Cache size is 16KB
++ */
++#define ICACHE_SIZE 0x4000 /* instruction - 16k */
++#define DCACHE_SIZE 0x4000 /* data - 16k */
++
++#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */
++#define CACHE_SETS 0x0100 /* 256 sets */
++#define CACHE_WAYS 0x0004 /* 4 way */
++
++#define CACHE_DISABLE_MODE (CF_CACR_DCINVA+ \
++ CF_CACR_BCINVA+ \
++ CF_CACR_ICINVA)
++
++#ifndef CONFIG_M5445X_DISABLE_CACHE
++#define CACHE_INITIAL_MODE (CF_CACR_DEC+ \
++ CF_CACR_BEC+ \
++ CF_CACR_IEC+ \
++ CF_CACR_DESB+ \
++ CF_CACR_EUSP)
++#else
++/* cache disabled for testing */
++#define CACHE_INITIAL_MODE (CF_CACR_EUSP)
++#endif /* CONFIG_M5445X_DISABLE_CACHE */
++
++#elif defined(CONFIG_M547X_8X)
++/*
++ * * M547x/M548x Cache Configuration
++ * * - cache line size is 16 bytes
++ * * - cache is 4-way set associative
++ * * - each cache has 512 sets (128k / 16bytes / 4way)
++ * * - I-Cache size is 32KB
++ * * - D-Cache size is 32KB
++ * */
++#define ICACHE_SIZE 0x8000 /* instruction - 32k */
++#define DCACHE_SIZE 0x8000 /* data - 32k */
++
++#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */
++#define CACHE_SETS 0x0200 /* 512 sets */
++#define CACHE_WAYS 0x0004 /* 4 way */
++
++/* in for the old cpushl caching code */
++#define _DCACHE_SET_MASK ((DCACHE_SIZE/64-1)<<CACHE_WAYS)
++#define _ICACHE_SET_MASK ((ICACHE_SIZE/64-1)<<CACHE_WAYS)
++#define LAST_DCACHE_ADDR _DCACHE_SET_MASK
++#define LAST_ICACHE_ADDR _ICACHE_SET_MASK
++
++#define CACHE_DISABLE_MODE (CF_CACR_DCINVA+ \
++ CF_CACR_BCINVA+ \
++ CF_CACR_ICINVA)
++
++#define CACHE_INITIAL_MODE (CF_CACR_DEC+ \
++ CF_CACR_BEC+ \
++ CF_CACR_IEC+ \
++ CF_CACR_DESB+ \
++ CF_CACR_EUSP)
++#elif defined(CONFIG_M5441X)
++/*
++ * M5441x Cache Configuration
++ * - cache line size is 16 bytes
++ * - cache is 4-way set associative
++ * - each cache has 128 sets (8k / 16bytes / 4way)
++ * - I-Cache size is 8KB
++ * - D-Cache size is 8KB
++ */
++#define ICACHE_SIZE 0x2000 /* instruction - 8k */
++#define DCACHE_SIZE 0x2000 /* data - 8k */
++
++#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */
++#define CACHE_SETS 0x0080 /* 128 sets */
++#define CACHE_WAYS 0x0004 /* 4 way */
++
++#define CACHE_DISABLE_MODE (CF_CACR_DCINVA+ \
++ CF_CACR_BCINVA+ \
++ CF_CACR_ICINVA)
++
++#ifndef CONFIG_M5441X_DISABLE_CACHE
++#define CACHE_INITIAL_MODE (CF_CACR_DEC+ \
++ CF_CACR_BEC+ \
++ CF_CACR_IEC+ \
++ CF_CACR_DESB+ \
++ CF_CACR_DDCM_01+ \
++ CF_CACR_EUSP)
++#else
++/* cache disabled for testing */
++#define CACHE_INITIAL_MODE (CF_CACR_EUSP)
++#endif /* CONFIG_M5441X_DISABLE_CACHE */
++
++#endif
++
++#ifndef __ASSEMBLY__
++
++extern unsigned long shadow_cacr;
++extern void cacr_set(unsigned long x);
++
++#endif /* !__ASSEMBLY__ */
++
++#endif /* CF_CACHE_H */
+--- /dev/null
++++ b/arch/m68k/include/asm/cfmmu.h
+@@ -0,0 +1,112 @@
++/*
++ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Definitions for Coldfire V4e MMU
++ *
++ * 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 <asm/movs.h>
++
++#ifndef __CF_MMU_H__
++#define __CF_MMU_H__
++
++
++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
++#define MMU_BASE 0xE8000000
++#elif defined(CONFIG_M5441X)
++#define MMU_BASE 0xD8000000
++#endif
++
++#define MMUCR (MMU_BASE+0x00)
++#define MMUCR_ASMN 1
++#define MMUCR_ASM (1<<MMUCR_ASMN)
++#define MMUCR_ENN 0
++#define MMUCR_EN (1<<MMUCR_ENN)
++
++#define MMUOR REG16(MMU_BASE+0x04+0x02)
++#define MMUOR_AAN 16
++#define MMUOR_AA (0xffff<<MMUOR_AAN)
++#define MMUOR_STLBN 8
++#define MMUOR_STLB (1<<MMUOR_STLBN)
++#define MMUOR_CAN 7
++#define MMUOR_CA (1<<MMUOR_CAN)
++#define MMUOR_CNLN 6
++#define MMUOR_CNL (1<<MMUOR_CNLN)
++#define MMUOR_CASN 5
++#define MMUOR_CAS (1<<MMUOR_CASN)
++#define MMUOR_ITLBN 4
++#define MMUOR_ITLB (1<<MMUOR_ITLBN)
++#define MMUOR_ADRN 3
++#define MMUOR_ADR (1<<MMUOR_ADRN)
++#define MMUOR_RWN 2
++#define MMUOR_RW (1<<MMUOR_RWN)
++#define MMUOR_ACCN 1
++#define MMUOR_ACC (1<<MMUOR_ACCN)
++#define MMUOR_UAAN 0
++#define MMUOR_UAA (1<<MMUOR_UAAN)
++
++#define MMUSR REG32(MMU_BASE+0x08)
++#define MMUSR_SPFN 5
++#define MMUSR_SPF (1<<MMUSR_SPFN)
++#define MMUSR_RFN 4
++#define MMUSR_RF (1<<MMUSR_RFN)
++#define MMUSR_WFN 3
++#define MMUSR_WF (1<<MMUSR_WFN)
++#define MMUSR_HITN 1
++#define MMUSR_HIT (1<<MMUSR_HITN)
++
++#define MMUAR REG32(MMU_BASE+0x10)
++#define MMUAR_VPN 1
++#define MMUAR_VP (0xfffffffe)
++#define MMUAR_SN 0
++#define MMUAR_S (1<<MMUAR_SN)
++
++#define MMUTR REG32(MMU_BASE+0x14)
++#define MMUTR_VAN 10
++#define MMUTR_VA (0xfffffc00)
++#define MMUTR_IDN 2
++#define MMUTR_ID (0xff<<MMUTR_IDN)
++#define MMUTR_SGN 1
++#define MMUTR_SG (1<<MMUTR_SGN)
++#define MMUTR_VN 0
++#define MMUTR_V (1<<MMUTR_VN)
++
++#define MMUDR REG32(MMU_BASE+0x18)
++#define MMUDR_PAN 10
++#define MMUDR_PA (0xfffffc00)
++#define MMUDR_SZN 8
++#define MMUDR_SZ_MASK (0x2<<MMUDR_SZN)
++#define MMUDR_SZ1M (0<<MMUDR_SZN)
++#define MMUDR_SZ4K (1<<MMUDR_SZN)
++#define MMUDR_SZ8K (2<<MMUDR_SZN)
++#define MMUDR_SZ16M (3<<MMUDR_SZN)
++#define MMUDR_CMN 6
++#define MMUDR_INC (2<<MMUDR_CMN)
++#define MMUDR_IC (0<<MMUDR_CMN)
++#define MMUDR_DWT (0<<MMUDR_CMN)
++#define MMUDR_DCB (1<<MMUDR_CMN)
++#define MMUDR_DNCP (2<<MMUDR_CMN)
++#define MMUDR_DNCIP (3<<MMUDR_CMN)
++#define MMUDR_SPN 5
++#define MMUDR_SP (1<<MMUDR_SPN)
++#define MMUDR_RN 4
++#define MMUDR_R (1<<MMUDR_RN)
++#define MMUDR_WN 3
++#define MMUDR_W (1<<MMUDR_WN)
++#define MMUDR_XN 2
++#define MMUDR_X (1<<MMUDR_XN)
++#define MMUDR_LKN 1
++#define MMUDR_LK (1<<MMUDR_LKN)
++
++
++#ifndef __ASSEMBLY__
++#define CF_PMEGS_NUM 256
++#define CF_INVALID_CONTEXT 255
++#define CF_PAGE_PGNUM_MASK (PAGE_MASK)
++
++extern int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb,
++ int extension_word);
++#endif /* __ASSEMBLY__*/
++
++#endif /* !__CF_MMU_H__ */
+--- a/arch/m68k/include/asm/coldfire.h
++++ b/arch/m68k/include/asm/coldfire.h
+@@ -5,6 +5,13 @@
+ *
+ * (C) Copyright 1999-2006, Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2000, Lineo (www.lineo.com)
++ *
++ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Right Reserved.
++ * 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.
+ */
+
+ /****************************************************************************/
+@@ -19,27 +26,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) || defined(CONFIG_M5441X)
++#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_M54xx)
+-#define MCF_IPSBAR MCF_MBAR
+-#elif 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
+@@ -1,18 +1,41 @@
+-#ifndef _M68K_DELAY_H
+-#define _M68K_DELAY_H
+-
+-#include <asm/param.h>
+-
+ /*
+ * Copyright (C) 1994 Hamish Macdonald
+ *
++ * Copyright (C) 2011 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
++ * for more details.
++ *
+ * Delay routines, using a pre-computed "loops_per_jiffy" value.
+ */
+
++#ifndef _M68K_DELAY_H
++#define _M68K_DELAY_H
++
++#include <asm/param.h>
++
+ 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 +49,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 +74,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,12 +1,17 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
+ #ifndef _M68K_DIV64_H
+ #define _M68K_DIV64_H
+
+-#ifdef CONFIG_MMU
+-
++#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
+ #include <linux/types.h>
+
+ /* n = n / base; return rem; */
+-
+ #define do_div(n, base) ({ \
+ union { \
+ unsigned long n32[2]; \
+--- a/arch/m68k/include/asm/dma.h
++++ b/arch/m68k/include/asm/dma.h
+@@ -1,7 +1,10 @@
+-#ifndef _M68K_DMA_H
+-#define _M68K_DMA_H 1
+-
+-#ifdef CONFIG_COLDFIRE
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
+ /*
+ * ColdFire DMA Model:
+ * ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+@@ -25,6 +28,11 @@
+ * Arthur Shipkowski (art@videon-central.com)
+ */
+
++#ifndef _M68K_DMA_H
++#define _M68K_DMA_H 1
++
++#ifdef CONFIG_COLDFIRE
++
+ #include <asm/coldfire.h>
+ #include <asm/mcfsim.h>
+ #include <asm/mcfdma.h>
+@@ -479,13 +487,106 @@ static __inline__ int get_dma_residue(un
+
+ /* it's useless on the m68k, but unfortunately needed by the new
+ bootmem allocator (but this should do it for this) */
++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
++#define MAX_DMA_ADDRESS 0xefffffff
++#elif defined(CONFIG_M5441X)
++#define MAX_DMA_ADDRESS 0xdfffffff
++#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
++
++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);
++}
++#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
+@@ -1,10 +1,17 @@
+-#ifndef __ASMm68k_ELF_H
+-#define __ASMm68k_ELF_H
+-
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
+ /*
+ * ELF register definitions..
+ */
+
++#ifndef __ASMm68k_ELF_H
++#define __ASMm68k_ELF_H
++
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+
+@@ -34,6 +41,26 @@
+ #define R_68K_GLOB_DAT 20
+ #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;
+
+@@ -59,7 +86,7 @@ typedef struct user_m68kfp_struct elf_fp
+ is actually used on ASV. */
+ #define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
+
+-#ifndef CONFIG_SUN3
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+ #define ELF_EXEC_PAGESIZE 4096
+ #else
+ #define ELF_EXEC_PAGESIZE 8192
+@@ -70,8 +97,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
+@@ -115,4 +144,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
+@@ -1,23 +1,36 @@
+ /*
+ * linux/include/asm-m68k/io.h
+ *
++ * Copyright (C) 2011 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
++ * for more details.
++ *
+ * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other
+ * IO access
+ * - added Q40 support
+ * - 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>
+@@ -49,6 +62,27 @@
+ #define MULTI_ISA 0
+ #endif /* Q40 */
+
++/* GG-II Zorro to ISA bridge */
++#ifdef CONFIG_GG2
++
++extern unsigned long gg2_isa_base;
++#define GG2_ISA_IO_B(ioaddr) \
++ (gg2_isa_base + 1 + ((unsigned long)(ioaddr) * 4))
++#define GG2_ISA_IO_W(ioaddr) \
++ (gg2_isa_base + ((unsigned long)(ioaddr) * 4))
++#define GG2_ISA_MEM_B(madr) \
++ (gg2_isa_base + 1 + (((unsigned long)(madr) * 4) & 0xfffff))
++#define GG2_ISA_MEM_W(madr) \
++ (gg2_isa_base + (((unsigned long)(madr) * 4) & 0xfffff))
++
++#ifndef MULTI_ISA
++#define MULTI_ISA 0
++#else
++#undef MULTI_ISA
++#define MULTI_ISA 1
++#endif
++#endif /* GG2 */
++
+ #ifdef CONFIG_AMIGA_PCMCIA
+ #include <asm/amigayle.h>
+
+@@ -71,17 +105,22 @@
+ #undef MULTI_ISA
+ #endif
+
+-#define ISA_TYPE_Q40 (1)
+-#define ISA_TYPE_AG (2)
++#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 GG2_ISA
++#define ISA_SEX 0
++#endif
+
+ #ifdef MULTI_ISA
+ extern int isa_type;
+@@ -98,65 +137,72 @@ extern int isa_sex;
+
+ static inline u8 __iomem *isa_itb(unsigned long addr)
+ {
+- switch(ISA_TYPE)
+- {
++ 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 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 */
+- }
++ default: return NULL; /* avoid warnings, just in case */
++ }
+ }
+ static inline u16 __iomem *isa_itw(unsigned long addr)
+ {
+- switch(ISA_TYPE)
+- {
++ 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 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 */
+- }
++ default: return NULL; /* avoid warnings, just in case */
++ }
+ }
+ static inline u32 __iomem *isa_itl(unsigned long addr)
+ {
+- switch(ISA_TYPE)
+- {
++ 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 */
+- }
++ default: return 0; /* avoid warnings, just in case */
++ }
+ }
+ static inline u8 __iomem *isa_mtb(unsigned long addr)
+ {
+- switch(ISA_TYPE)
+- {
++ 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 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 */
+- }
++ default: return NULL; /* avoid warnings, just in case */
++ }
+ }
+ static inline u16 __iomem *isa_mtw(unsigned long addr)
+ {
+- switch(ISA_TYPE)
+- {
++ 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 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 */
+- }
++ default: return NULL; /* avoid warnings, just in case */
++ }
+ }
+
+
+@@ -167,27 +213,30 @@ 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 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;})
+@@ -216,7 +265,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
+@@ -239,9 +291,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.
+ */
+@@ -272,11 +395,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()
+
+@@ -333,4 +456,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.h
++++ b/arch/m68k/include/asm/irq.h
+@@ -1,14 +1,20 @@
+-#ifndef _M68K_IRQ_H_
+-#define _M68K_IRQ_H_
+-
+ /*
++ * Copyright (C) 2011 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
++ * for more details.
++ *
+ * This should be the same as the max(NUM_X_SOURCES) for all the
+ * different m68k hosts compiled into the kernel.
+ * 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.
+ */
++#ifndef _M68K_IRQ_H_
++#define _M68K_IRQ_H_
+ #if defined(CONFIG_COLDFIRE)
+-#define NR_IRQS 256
++#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)
+--- a/arch/m68k/include/asm/machdep.h
++++ b/arch/m68k/include/asm/machdep.h
+@@ -1,6 +1,12 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
+ #ifndef _M68K_MACHDEP_H
+ #define _M68K_MACHDEP_H
+-
+ #include <linux/seq_file.h>
+ #include <linux/interrupt.h>
+
+@@ -42,4 +48,11 @@ extern irqreturn_t arch_timer_interrupt(
+ extern void config_BSP(char *command, int len);
+ extern void do_IRQ(int irq, struct pt_regs *fp);
+
++#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 */
+--- /dev/null
++++ b/arch/m68k/include/asm/mcfdspi.h
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Author: Andrey Butok
++ *
++ * This file is based on mcfqspi.h
++ *
++ * 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
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ ***************************************************************************
++ * Changes:
++ * v0.001 25 March 2008 Andrey Butok
++ * Initial Release - developed on uClinux with 2.6.23 kernel.
++ *
++ */
++
++#ifndef MCFDSPI_H_
++#define MCFDSPI_H_
++
++struct coldfire_dspi_chip {
++ u8 mode;
++ u8 bits_per_word;
++ u16 void_write_data;
++ /* Only used in master mode */
++ u8 dbr; /* Double baud rate */
++ u8 pbr; /* Baud rate prescaler */
++ u8 br; /* Baud rate scaler */
++ u8 pcssck; /* PCS to SCK delay prescaler */
++ u8 pasc; /* After SCK delay prescaler */
++ u8 pdt; /* Delay after transfer prescaler */
++ u8 cssck; /* PCS to SCK delay scaler */
++ u8 asc; /* After SCK delay scaler */
++ u8 dt; /* Delay after transfer scaler */
++};
++
++struct coldfire_spi_master {
++ u16 bus_num;
++ u16 num_chipselect;
++ u8 irq_source;
++ u32 irq_vector;
++ u32 irq_mask;
++ u8 irq_lp;
++ u8 par_val;
++ u16 par_val16;
++ u32 *irq_list;
++ void (*cs_control)(u8 cs, u8 command);
++};
++#endif /*MCFDSPI_H_*/
+--- a/arch/m68k/include/asm/mcfsim.h
++++ b/arch/m68k/include/asm/mcfsim.h
+@@ -5,6 +5,12 @@
+ *
+ * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2000, Lineo Inc. (www.lineo.com)
++ *
++ * Copyright (C) 2010-2011 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
++ * for more details.
+ */
+
+ /****************************************************************************/
+@@ -45,5 +51,120 @@
+ #include <asm/m54xxsim.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>
++#elif defined(CONFIG_M5441X)
++#include <asm/mcf5441x_intc.h>
++#include <asm/mcf5441x_gpio.h>
++#include <asm/mcf5441x_ccm.h>
++#include <asm/mcf5441x_eport.h>
++#include <asm/mcf5441x_fbcs.h>
++#include <asm/mcf5441x_xbs.h>
++#include <asm/mcf5441x_dtim.h>
++#include <asm/mcf5441x_rtc.h>
++#include <asm/mcf5441x_scm.h>
++#include <asm/mcf5441x_pm.h>
++#include <asm/mcf5441x_flexcan.h>
++#include <asm/mcf5441x_clock.h>
++#endif
++
++/*
++ * Define the base address of the SIM within the MBAR address space.
++ */
++#define MCFSIM_BASE 0x0 /* Base address of SIM */
++
++
++/*
++ * Bit definitions for the ICR family of registers.
++ */
++#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */
++#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */
++#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */
++#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */
++#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */
++#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */
++#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */
++#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */
++#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */
++
++#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */
++#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */
++#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */
++#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */
++
++/*
++ * Bit definitions for the Interrupt Mask register (IMR).
++ */
++#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */
++#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */
++#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */
++#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */
++#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */
++#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */
++#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */
++
++#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */
++#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */
++#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */
++#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */
++#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */
++#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */
++
++#if defined(CONFIG_M5206e)
++#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */
++#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */
++#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
++#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */
++#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */
++#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */
++#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */
++#endif
++
++/*
++ * Mask for all of the SIM devices. Some parts have more or less
++ * SIM devices. This is a catchall for the sandard set.
++ */
++#ifndef MCFSIM_IMR_MASKALL
++#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */
++#endif
++
++
++/*
++ * PIT interrupt settings, if not found in mXXXXsim.h file.
++ */
++#ifndef ICR_INTRCONF
++#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */
++#endif
++#ifndef MCFPIT_IMR
++#define MCFPIT_IMR MCFINTC_IMRH
++#endif
++#ifndef MCFPIT_IMR_IBIT
++#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32))
++#endif
++
++
++#ifndef __ASSEMBLY__
++/*
++ * Definition for the interrupt auto-vectoring support.
++ */
++extern void mcf_autovector(unsigned int vec);
++#endif /* __ASSEMBLY__ */
++
+ /****************************************************************************/
+ #endif /* mcfsim_h */
+--- a/arch/m68k/include/asm/mcfuart.h
++++ b/arch/m68k/include/asm/mcfuart.h
+@@ -5,6 +5,11 @@
+ *
+ * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ * (C) Copyright 2000, Lineo Inc. (www.lineo.com)
++ * Copyright (C) 2009-2011 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
++ * for more details.
+ */
+
+ /****************************************************************************/
+@@ -12,6 +17,59 @@
+ #define mcfuart_h
+ /****************************************************************************/
+
++#if defined(CONFIG_M5445X)
++#include <asm/mcf5445x_intc.h>
++#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */
++#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */
++#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */
++#define MCFINT_VECBASE 64
++#define MCFINT_UART0 26
++#define MCFINT_UART1 27
++#elif defined(CONFIG_M547X_8X)
++#define MCFUART_BASE1 0x8600 /* Base address of UART1 */
++#define MCFUART_BASE2 0x8700 /* Base address of UART2 */
++#define MCFUART_BASE3 0x8800 /* Base address of UART3 */
++#define MCFUART_BASE4 0x8900 /* Base address of UART4 */
++#define MCFINT_VECBASE 64
++#define MCFINT_UART0 35
++#define MCFINT_UART1 34
++#define MCFINT_UART2 33
++#define MCFINT_UART3 32
++#elif defined(CONFIG_M5441X)
++#define MCFUART_BASE0 0xfc060000 /* Base address of UART1 */
++#define MCFUART_BASE1 0xfc064000 /* Base address of UART2 */
++#define MCFUART_BASE2 0xfc068000 /* Base address of UART3 */
++#define MCFUART_BASE3 0xfc06C000 /* Base address of UART4 */
++#define MCFUART_BASE4 0xec060000
++#define MCFUART_BASE5 0xec064000
++#define MCFUART_BASE6 0xec068000
++#define MCFUART_BASE7 0xec06C000
++#define MCFUART_BASE8 0xec070000
++#define MCFUART_BASE9 0xec074000
++
++#define MCFINT0_VECBASE 64
++#define MCFINT1_VECBASE (64 + 64)
++#define MCFINT_UART0 26
++#define MCFINT_UART1 27
++#define MCFINT_UART2 28
++#define MCFINT_UART3 29
++#define MCFINT_UART4 48
++#define MCFINT_UART5 49
++#define MCFINT_UART6 50
++#define MCFINT_UART7 51
++#define MCFINT_UART8 52
++#define MCFINT_UART9 53
++#endif
++
++#if defined(CONFIG_M5441X)
++#define MAX_PORT_NUM 10
++#elif defined(CONFIG_M547X_8X)
++#define MAX_PORT_NUM 4
++#else
++#define MAX_PORT_NUM 3
++#endif
++
++#ifndef __ASSEMBLY__
+ #include <linux/serial_core.h>
+ #include <linux/platform_device.h>
+
+@@ -21,6 +79,7 @@ struct mcf_platform_uart {
+ unsigned int irq; /* Interrupt vector */
+ unsigned int uartclk; /* UART clock rate */
+ };
++#endif
+
+ /*
+ * Define the ColdFire UART register set addresses.
+@@ -94,6 +153,11 @@ struct mcf_platform_uart {
+ #define MCFUART_USR_RXFULL 0x02 /* Receiver full */
+ #define MCFUART_USR_RXREADY 0x01 /* Receiver ready */
+
++#if defined(CONFIG_M547X_8X)
++#define MCFUART_USR_TXREADY_BN 0x0a
++#define MCFUART_USR_TXEMPTY_BN 0x0b
++#endif
++
+ #define MCFUART_USR_RXERR (MCFUART_USR_RXBREAK | MCFUART_USR_RXFRAMING | \
+ MCFUART_USR_RXPARITY | MCFUART_USR_RXOVERRUN)
+
+--- a/arch/m68k/include/asm/mmu.h
++++ b/arch/m68k/include/asm/mmu.h
+@@ -1,9 +1,22 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef __MMU_H
+ #define __MMU_H
+-
+ #ifdef CONFIG_MMU
++#ifdef CONFIG_VDSO
++typedef struct {
++ unsigned long id;
++ void *vdso;
++} mm_context_t;
++#else
+ /* Default "unsigned long" context */
+ typedef unsigned long mm_context_t;
++#endif
+ #else
+ typedef struct {
+ unsigned long end_brk;
+--- a/arch/m68k/include/asm/mmu_context.h
++++ b/arch/m68k/include/asm/mmu_context.h
+@@ -1,14 +1,21 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef __M68K_MMU_CONTEXT_H
+ #define __M68K_MMU_CONTEXT_H
+-
+ #include <asm-generic/mm_hooks.h>
++#include <asm-generic/pgtable.h>
+
+ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+ {
+ }
+
+ #ifdef CONFIG_MMU
+-#ifndef CONFIG_SUN3
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+
+ #include <asm/setup.h>
+ #include <asm/page.h>
+@@ -103,7 +110,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 +158,178 @@ 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)
++{
++ unsigned long 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.h
++++ b/arch/m68k/include/asm/page.h
+@@ -1,12 +1,18 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_PAGE_H
+ #define _M68K_PAGE_H
+-
+ #include <linux/const.h>
+ #include <asm/setup.h>
+ #include <asm/page_offset.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)
+--- a/arch/m68k/include/asm/page_mm.h
++++ b/arch/m68k/include/asm/page_mm.h
+@@ -1,5 +1,17 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_PAGE_MM_H
+ #define _M68K_PAGE_MM_H
++#if PAGE_SHIFT < 13
++#define THREAD_SIZE (8192)
++#else
++#define THREAD_SIZE PAGE_SIZE
++#endif
+
+ #ifndef __ASSEMBLY__
+
+@@ -70,6 +82,49 @@ extern unsigned long m68k_memoffset;
+
+ #define WANT_PAGE_VIRTUAL
+
++#if defined(CONFIG_COLDFIRE)
++extern unsigned long cf_dma_base;
++extern unsigned long cf_dma_end;
++
++static inline unsigned long ___pa(void *vaddr)
++{
++#if CONFIG_SDRAM_BASE != PAGE_OFFSET
++ return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_SDRAM_BASE;
++#else
++ if ((unsigned long)vaddr >= CONFIG_DMA_BASE &&
++ (unsigned long)vaddr < (CONFIG_DMA_BASE + CONFIG_DMA_SIZE)) {
++ /* address is in carved out DMA range */
++ return ((unsigned long)vaddr - CONFIG_DMA_BASE)
++ + CONFIG_SDRAM_BASE;
++ } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
++ (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_SDRAM_SIZE)) {
++ /* normal mapping */
++ return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_SDRAM_BASE;
++ }
++
++ 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
++ if (paddr >= cf_dma_base && paddr <= cf_dma_end) {
++ /* mapped address for DMA */
++ return (void *)((paddr - CONFIG_SDRAM_BASE) + CONFIG_DMA_BASE);
++ } else if (paddr >= cf_dma_end &&
++ paddr < (CONFIG_SDRAM_BASE + CONFIG_SDRAM_SIZE)) {
++ /* normal mapping */
++ return (void *)((paddr - CONFIG_SDRAM_BASE) + PAGE_OFFSET);
++ }
++ return (void *)paddr;
++#endif
++}
++
++#else
+ static inline unsigned long ___pa(void *vaddr)
+ {
+ unsigned long paddr;
+@@ -91,6 +146,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 */
+@@ -176,4 +232,9 @@ static inline __attribute_const__ int __
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
++#ifdef CONFIG_VDSO
++/* vDSO support */
++#define __HAVE_ARCH_GATE_AREA
++#endif
++
+ #endif /* _M68K_PAGE_MM_H */
+--- a/arch/m68k/include/asm/page_offset.h
++++ b/arch/m68k/include/asm/page_offset.h
+@@ -1,10 +1,21 @@
+-/* This handles the memory map.. */
+-
++/*
++ * Page and physical memory maps.
++ *
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #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) \
++ || defined(CONFIG_M5441X)
++#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
+@@ -1,14 +1,22 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef M68K_PGALLOC_H
+ #define M68K_PGALLOC_H
+-
+ #include <linux/mm.h>
+ #include <linux/highmem.h>
+ #include <asm/setup.h>
+
+ #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
+@@ -1,6 +1,12 @@
++/*
++ * Copyright (C) 2009-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_PGTABLE_H
+ #define _M68K_PGTABLE_H
+-
+ #include <asm-generic/4level-fixup.h>
+
+ #include <asm/setup.h>
+@@ -40,6 +46,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 +62,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 +78,18 @@
+ #ifdef CONFIG_SUN3
+ #define KMAP_START 0x0DC00000
+ #define KMAP_END 0x0E000000
++#elif defined(CONFIG_COLDFIRE)
++#if defined(CONFIG_M5445X) || defined(CONFIG_M547X_8X)
++#define VMALLOC_START 0xc0000000
++#define VMALLOC_END 0xcfffffff
++#define KMAP_START (VMALLOC_END + 1)
++#define KMAP_END (0xe8000000 - 1)
++#elif defined(CONFIG_M5441X)
++#define VMALLOC_START 0xc0000000
++#define VMALLOC_END 0xcfffffff
++#define KMAP_START (VMALLOC_END + 1)
++#define KMAP_END (0xd8000000 - 1)
++#endif
+ #else
+ #define KMAP_START 0xd0000000
+ #define KMAP_END 0xf0000000
+@@ -79,9 +103,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 m68k_vmalloc_end;
+ #define VMALLOC_START 0x0f800000
+@@ -130,6 +156,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
+@@ -143,6 +171,10 @@ static inline void update_mmu_cache(stru
+ #else
+ # define __SUN3_PAGE_NOCACHE 0
+ #endif
++
++#ifdef CONFIG_COLDFIRE
++# define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | CF_PAGE_NOCACHE))
++#else /* CONFIG_COLDFIRE */
+ #define pgprot_noncached(prot) \
+ (MMU_IS_SUN3 \
+ ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \
+@@ -151,7 +183,7 @@ static inline void update_mmu_cache(stru
+ : (MMU_IS_040 || MMU_IS_060) \
+ ? (__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.h
++++ b/arch/m68k/include/asm/processor.h
+@@ -2,6 +2,11 @@
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
++ * Copyright (C) 2007-2011 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
++ * for more details.
+ */
+
+ #ifndef __ASM_M68K_PROCESSOR_H
+@@ -23,6 +28,10 @@ static inline unsigned long rdusp(void)
+ #ifdef CONFIG_COLDFIRE_SW_A7
+ extern unsigned int sw_usp;
+ return sw_usp;
++#elif defined(CONFIG_COLDFIRE)
++ unsigned long usp;
++ __asm__ __volatile__("movel %/usp,%0" : "=a" (usp));
++ return usp;
+ #else
+ register unsigned long usp __asm__("a0");
+ /* move %usp,%a0 */
+@@ -36,6 +45,8 @@ static inline void wrusp(unsigned long u
+ #ifdef CONFIG_COLDFIRE_SW_A7
+ extern unsigned int sw_usp;
+ sw_usp = usp;
++#elif defined(CONFIG_COLDFIRE)
++ __asm__ __volatile__("movel %0,%/usp" : : "a" (usp));
+ #else
+ register unsigned long a0 __asm__("a0") = usp;
+ /* move %a0,%usp */
+@@ -48,11 +59,17 @@ static inline void wrusp(unsigned long u
+ * so don't change it unless you know what you are doing.
+ */
+ #ifdef CONFIG_MMU
+-#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
+ #else
+ #define TASK_SIZE (0xFFFFFFFFUL)
+ #endif
+@@ -66,8 +83,10 @@ static inline void wrusp(unsigned long u
+ * space during mmap's.
+ */
+ #ifdef CONFIG_MMU
+-#ifndef CONFIG_SUN3
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+ #define TASK_UNMAPPED_BASE 0xC0000000UL
++#elif defined(CONFIG_COLDFIRE)
++#define TASK_UNMAPPED_BASE 0x60000000UL
+ #else
+ #define TASK_UNMAPPED_BASE 0x0A000000UL
+ #endif
+@@ -80,7 +99,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 */
+@@ -102,6 +125,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)
+ {
+@@ -112,7 +136,24 @@ 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
+ #else
+
+ /*
+--- a/arch/m68k/include/asm/ptrace.h
++++ b/arch/m68k/include/asm/ptrace.h
+@@ -1,3 +1,10 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_PTRACE_H
+ #define _M68K_PTRACE_H
+
+@@ -27,27 +34,38 @@
+ stack during a system call. */
+
+ struct pt_regs {
+- long d1;
+- long d2;
+- long d3;
+- long d4;
+- long d5;
+- long a0;
+- long a1;
+- long a2;
+- long d0;
+- long orig_d0;
+- long stkadj;
++ long d1;
++ long d2;
++ long d3;
++ long d4;
++ long d5;
++ long a0;
++ long a1;
++ long a2;
++ long d0;
++ 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;
+- unsigned format : 4; /* frame format specifier */
+- unsigned vector : 12; /* vector offset */
++ unsigned short sr;
++ unsigned long pc;
++ unsigned format:4; /* frame format specifier */
++ unsigned vector:12; /* vector offset */
+ #endif
+ };
+
+--- a/arch/m68k/include/asm/raw_io.h
++++ b/arch/m68k/include/asm/raw_io.h
+@@ -3,11 +3,19 @@
+ *
+ * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
+ *
++ * Copyright (C) 2007-2011 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
++ * for more details.
+ */
+-
+ #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 +68,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 +355,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
+@@ -1,3 +1,10 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_SEGMENT_H
+ #define _M68K_SEGMENT_H
+
+@@ -29,6 +36,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 +64,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 (C) 2007-2011 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/signal.h
++++ b/arch/m68k/include/asm/signal.h
+@@ -1,6 +1,12 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_SIGNAL_H
+ #define _M68K_SIGNAL_H
+-
+ #include <linux/types.h>
+
+ /* Avoid too many header ordering problems. */
+@@ -150,7 +156,7 @@ typedef struct sigaltstack {
+ #ifdef __KERNEL__
+ #include <asm/sigcontext.h>
+
+-#ifndef __uClinux__
++#ifndef CONFIG_COLDFIRE /*FIXME Jason*/
+ #define __HAVE_ARCH_SIG_BITOPS
+
+ static inline void sigaddset(sigset_t *set, int _sig)
+--- a/arch/m68k/include/asm/string.h
++++ b/arch/m68k/include/asm/string.h
+@@ -1,6 +1,12 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_STRING_H_
+ #define _M68K_STRING_H_
+-
+ #include <linux/types.h>
+ #include <linux/compiler.h>
+
+@@ -81,6 +87,18 @@ static inline char *strncpy(char *dest,
+ strcpy(__d + strlen(__d), (s)); \
+ })
+
++#define __HAVE_ARCH_STRCHR
++static inline char *strchr(const char *s, int c)
++{
++ char sc, ch = c;
++
++ for (; (sc = *s++) != ch; ) {
++ if (!sc)
++ return NULL;
++ }
++ return (char *)s - 1;
++}
++
+ #ifndef CONFIG_COLDFIRE
+ #define __HAVE_ARCH_STRCMP
+ static inline int strcmp(const char *cs, const char *ct)
+--- a/arch/m68k/include/asm/swab.h
++++ b/arch/m68k/include/asm/swab.h
+@@ -1,11 +1,18 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_SWAB_H
+ #define _M68K_SWAB_H
+-
+ #include <linux/types.h>
+ #include <linux/compiler.h>
+
+ #define __SWAB_64_THRU_32__
+
++#if defined(__GNUC__)
+ #if defined (__mcfisaaplus__) || defined (__mcfisac__)
+ static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+ {
+@@ -23,5 +30,11 @@ static inline __attribute_const__ __u32
+ }
+ #define __arch_swab32 __arch_swab32
+ #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
+@@ -1,14 +1,35 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_SYSTEM_H
+ #define _M68K_SYSTEM_H
+-
+ #include <linux/linkage.h>
+ #include <linux/kernel.h>
+ #include <linux/irqflags.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
+--- a/arch/m68k/include/asm/tlbflush.h
++++ b/arch/m68k/include/asm/tlbflush.h
+@@ -1,8 +1,14 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _M68K_TLBFLUSH_H
+ #define _M68K_TLBFLUSH_H
+-
+ #ifdef CONFIG_MMU
+-#ifndef CONFIG_SUN3
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+
+ #include <asm/current.h>
+
+@@ -92,7 +98,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 +225,13 @@ static inline void flush_tlb_kernel_page
+ sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+ }
+
++static inline void flush_tlb_pgtables(struct mm_struct *mm,
++ unsigned long start, unsigned long end)
++{
++}
++
++#else /* CONFIG_COLDFIRE */
++#include <asm/cf_tlbflush.h>
+ #endif
+
+ #else /* !CONFIG_MMU */
+--- a/arch/m68k/include/asm/uaccess_mm.h
++++ b/arch/m68k/include/asm/uaccess_mm.h
+@@ -1,6 +1,15 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef __M68K_UACCESS_H
+ #define __M68K_UACCESS_H
+-
++#ifdef CONFIG_COLDFIRE
++#include <asm/cf_uaccess.h>
++#else
+ /*
+ * User space memory access functions
+ */
+@@ -219,6 +228,41 @@ unsigned long __generic_copy_to_user(voi
+ : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \
+ : : "memory")
+
++#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
++ asm volatile ("\n" \
++ " move."#s1" (%2)+,%3\n" \
++ "11: moves."#s1" %3,(%1)+\n" \
++ "12: move."#s2" (%2)+,%3\n" \
++ "21: moves."#s2" %3,(%1)+\n" \
++ "22:\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ " move."#s3" (%2)+,%3\n" \
++ "31: moves."#s3" %3,(%1)+\n" \
++ "32:\n" \
++ " .endif\n" \
++ "4:\n" \
++ "\n" \
++ " .section __ex_table,\"a\"\n" \
++ " .align 4\n" \
++ " .long 11b,5f\n" \
++ " .long 12b,5f\n" \
++ " .long 21b,5f\n" \
++ " .long 22b,5f\n" \
++ " .ifnc \""#s3"\",\"\"\n" \
++ " .long 31b,5f\n" \
++ " .long 32b,5f\n" \
++ " .endif\n" \
++ " .previous\n" \
++ "\n" \
++ " .section .fixup,\"ax\"\n" \
++ " .even\n" \
++ "5: moveq.l #"#n",%0\n" \
++ " jra 4b\n" \
++ " .previous\n" \
++ : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
++ : : "memory")
++
++#endif /* CONFIG_COLDFIRE */
+ static __always_inline unsigned long
+ __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+@@ -266,40 +310,6 @@ __constant_copy_from_user(void *to, cons
+ return res;
+ }
+
+-#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
+- asm volatile ("\n" \
+- " move."#s1" (%2)+,%3\n" \
+- "11: moves."#s1" %3,(%1)+\n" \
+- "12: move."#s2" (%2)+,%3\n" \
+- "21: moves."#s2" %3,(%1)+\n" \
+- "22:\n" \
+- " .ifnc \""#s3"\",\"\"\n" \
+- " move."#s3" (%2)+,%3\n" \
+- "31: moves."#s3" %3,(%1)+\n" \
+- "32:\n" \
+- " .endif\n" \
+- "4:\n" \
+- "\n" \
+- " .section __ex_table,\"a\"\n" \
+- " .align 4\n" \
+- " .long 11b,5f\n" \
+- " .long 12b,5f\n" \
+- " .long 21b,5f\n" \
+- " .long 22b,5f\n" \
+- " .ifnc \""#s3"\",\"\"\n" \
+- " .long 31b,5f\n" \
+- " .long 32b,5f\n" \
+- " .endif\n" \
+- " .previous\n" \
+- "\n" \
+- " .section .fixup,\"ax\"\n" \
+- " .even\n" \
+- "5: moveq.l #"#n",%0\n" \
+- " jra 4b\n" \
+- " .previous\n" \
+- : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
+- : : "memory")
+-
+ static __always_inline unsigned long
+ __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+--- a/arch/m68k/include/asm/unistd.h
++++ b/arch/m68k/include/asm/unistd.h
+@@ -1,6 +1,12 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef _ASM_M68K_UNISTD_H_
+ #define _ASM_M68K_UNISTD_H_
+-
+ /*
+ * This file contains the system call numbers.
+ */
+@@ -343,10 +349,11 @@
+ #define __NR_fanotify_init 337
+ #define __NR_fanotify_mark 338
+ #define __NR_prlimit64 339
++#define __NR_recvmmsg 340
+
+ #ifdef __KERNEL__
+
+-#define NR_syscalls 340
++#define NR_syscalls 341
+
+ #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,5 +1,15 @@
++/*
++ * Copyright (C) 2007-2011 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
++ * for more details.
++ */
+ #ifndef __VIRT_CONVERT__
+ #define __VIRT_CONVERT__
++#ifdef CONFIG_COLDFIRE
++#include <asm/cf_virtconvert.h>
++#else
+
+ /*
+ * Macros used for converting between virtual and physical mappings.
+@@ -45,3 +55,4 @@ static inline void *phys_to_virt(unsigne
+
+ #endif
+ #endif
++#endif
+--- a/arch/m68k/kernel/Makefile
++++ b/arch/m68k/kernel/Makefile
+@@ -2,16 +2,27 @@
+ # 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
++ obj-y := time.o
++ 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/asm-offsets.c
++++ b/arch/m68k/kernel/asm-offsets.c
+@@ -2,6 +2,15 @@
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ * Add Codlfire support
++ *
++ * 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.
++ *
+ * 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
+@@ -22,6 +31,9 @@
+ int main(void)
+ {
+ /* offsets into the task struct */
++ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
++ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
++ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+ DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+@@ -43,6 +55,7 @@ int main(void)
+ /* offsets into the thread_info struct */
+ DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
++ DEFINE(TINFO_TP_VALUE, offsetof(struct thread_info, tp_value));
+
+ /* offsets into the pt_regs */
+ DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
+@@ -57,8 +70,23 @@ int main(void)
+ DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
+ DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_OFF_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_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
++#endif
++
++ /* offsets into the irq_handler struct */
++ DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
++ DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
++ DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
++
++ /* offsets into the kernel_stat struct */
++ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+ /* offsets into the irq_cpustat_t struct */
+ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+--- a/arch/m68k/kernel/dma.c
++++ b/arch/m68k/kernel/dma.c
+@@ -1,4 +1,7 @@
+ /*
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+@@ -12,12 +15,25 @@
+ #include <linux/scatterlist.h>
+ #include <linux/slab.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) || \
++ defined(CONFIG_M5441X)
++ /*
++ * 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;
+@@ -56,6 +72,7 @@ void *dma_alloc_coherent(struct device *
+ kfree(map);
+
+ return addr;
++#endif
+ }
+ EXPORT_SYMBOL(dma_alloc_coherent);
+
+@@ -63,7 +80,12 @@ 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) || \
++ defined(CONFIG_M5441X)
++ kfree((void *)handle);
++#else
+ vfree(addr);
++#endif
+ }
+ EXPORT_SYMBOL(dma_free_coherent);
+
+@@ -77,6 +99,9 @@ void dma_sync_single_for_device(struct d
+ case DMA_FROM_DEVICE:
+ cache_clear(handle, size);
+ break;
++ case PCI_DMA_BIDIRECTIONAL:
++ flush_dcache();
++ break;
+ default:
+ if (printk_ratelimit())
+ printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
+@@ -89,16 +114,23 @@ 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);
+
+ dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
+ enum dma_data_direction dir)
+ {
+- dma_addr_t handle = virt_to_bus(addr);
++ dma_addr_t handle = (dma_addr_t)virt_to_bus(addr);
+
+ dma_sync_single_for_device(dev, handle, size, dir);
+ return handle;
+@@ -120,10 +152,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/process.c
++++ b/arch/m68k/kernel/process.c
+@@ -4,6 +4,15 @@
+ * Copyright (C) 1995 Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Kurt.Mahan@freescale.com
++ * 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.
+ */
+
+ /*
+@@ -185,12 +194,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
+ }
+
+ /*
+@@ -258,6 +276,7 @@ int copy_thread(unsigned long clone_flag
+ * 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) {
+@@ -269,9 +288,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;
+ }
+@@ -280,7 +324,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;
+@@ -297,6 +343,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;
+@@ -307,6 +354,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/setup.c
++++ b/arch/m68k/kernel/setup.c
+@@ -2,7 +2,14 @@
+ * linux/arch/m68k/kernel/setup.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+- */
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
++*/
+
+ /*
+ * This file handles the architecture-dependent parts of system setup
+@@ -74,14 +81,26 @@ struct mem_info m68k_memory[NUM_MEMINFO]
+ EXPORT_SYMBOL(m68k_memory);
+
+ struct mem_info m68k_ramdisk;
++EXPORT_SYMBOL(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 +156,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) && !(CONFIG_COLDFIRE)) {
+ int unknown = 0;
+ const unsigned long *data = record->data;
+
+@@ -203,6 +226,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,7 +242,9 @@ static void __init m68k_parse_bootinfo(c
+
+ void __init setup_arch(char **cmdline_p)
+ {
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+ int i;
++#endif
+
+ /* The bootinfo is located right after the kernel bss */
+ m68k_parse_bootinfo((const struct bi_record *)_end);
+@@ -230,9 +259,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,16 +350,17 @@ 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
+- for (i = 1; i < m68k_num_memory; i++)
+- free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
+- m68k_memory[i].size);
+ #ifdef CONFIG_BLK_DEV_INITRD
+ if (m68k_ramdisk.size) {
+ reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
+@@ -341,6 +372,10 @@ void __init setup_arch(char **cmdline_p)
+ }
+ #endif
+
++#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
++ for (i = 1; i < m68k_num_memory; i++)
++ free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
++ m68k_memory[i].size);
+ #ifdef CONFIG_ATARI
+ if (MACH_IS_ATARI)
+ atari_stram_reserve_pages((void *)availmem);
+@@ -353,12 +388,22 @@ 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) {
+ isa_type = ISA_TYPE_Q40;
+ isa_sex = 0;
+ }
++#ifdef CONFIG_GG2
++ if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)) {
++ isa_type = ISA_TYPE_GG2;
++ isa_sex = 0;
++ }
++#endif
+ #ifdef CONFIG_AMIGA_PCMCIA
+ if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
+ isa_type = ISA_TYPE_AG;
+@@ -377,6 +422,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";
+@@ -390,6 +436,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;
+@@ -408,6 +457,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
+@@ -424,6 +475,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";
+
+@@ -506,7 +559,8 @@ module_init(proc_hardware_init);
+
+ void check_bugs(void)
+ {
+-#ifndef CONFIG_M68KFPU_EMU
++#if !defined(CONFIG_M68KFPU_EMU) && !defined(CONFIG_M5445X) && \
++ !defined(CONFIG_M5441X)
+ 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,12 @@
+ /*
+ * linux/arch/m68k/kernel/sys_m68k.c
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+@@ -29,6 +36,9 @@
+ #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);
+@@ -45,6 +55,59 @@ asmlinkage long sys_mmap2(unsigned long
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+ }
+
++/*
++ * Perform the select(nd, in, out, ex, tv) and mmap() system
++ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
++ * handle more than 4 system call parameters, so these system calls
++ * used a memory block for parameter passing..
++ */
++
++struct mmap_arg_struct {
++ unsigned long addr;
++ unsigned long len;
++ unsigned long prot;
++ unsigned long flags;
++ unsigned long fd;
++ unsigned long offset;
++};
++
++asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
++{
++ struct mmap_arg_struct a;
++ int error = -EFAULT;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ goto out;
++
++ error = -EINVAL;
++ if (a.offset & ~PAGE_MASK)
++ goto out;
++
++ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++
++ error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags,
++ a.fd, a.offset >> PAGE_SHIFT);
++out:
++ return error;
++}
++
++struct sel_arg_struct {
++ unsigned long n;
++ fd_set __user *inp, *outp, *exp;
++ struct timeval __user *tvp;
++};
++
++asmlinkage int old_select(struct sel_arg_struct __user *arg)
++{
++ struct sel_arg_struct a;
++
++ if (copy_from_user(&a, arg, sizeof(a)))
++ return -EFAULT;
++ /* sys_select() does the appropriate kernel locking */
++ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
++}
++
++#ifndef CONFIG_COLDFIRE
+ /* Convert virtual (user) address VADDR to physical address PADDR */
+ #define virt_to_phys_040(vaddr) \
+ ({ \
+@@ -368,6 +431,7 @@ cache_flush_060 (unsigned long addr, int
+ }
+ return 0;
+ }
++#endif /* CONFIG_COLDFIRE */
+
+ /* sys_cacheflush -- flush (part of) the processor cache. */
+ asmlinkage int
+@@ -399,6 +463,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;
+@@ -443,6 +508,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:
+ return ret;
+ }
+@@ -474,9 +549,14 @@ asmlinkage unsigned long sys_get_thread_
+ return current_thread_info()->tp_value;
+ }
+
++extern void *_vdso_tp;
++
+ asmlinkage int sys_set_thread_area(unsigned long tp)
+ {
+ current_thread_info()->tp_value = tp;
++#ifdef CONFIG_VDSO
++ *(unsigned long *)_vdso_tp = tp;
++#endif
+ return 0;
+ }
+
+--- a/arch/m68k/kernel/time.c
++++ b/arch/m68k/kernel/time.c
+@@ -2,6 +2,14 @@
+ * linux/arch/m68k/kernel/time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ * Alison Wang b18965@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.
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+@@ -9,9 +17,12 @@
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+-
++#include <linux/clk.h>
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
++#include <linux/sysdev.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/param.h>
+@@ -27,6 +38,7 @@
+ #include <linux/time.h>
+ #include <linux/timex.h>
+ #include <linux/profile.h>
++#include <asm/mcfsim.h>
+
+ static inline int set_rtc_mmss(unsigned long nowtime)
+ {
+@@ -35,12 +47,18 @@ static inline int set_rtc_mmss(unsigned
+ return -1;
+ }
+
++#ifndef CONFIG_GENERIC_CLOCKEVENTS
+ /*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+ 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);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
+@@ -91,11 +109,133 @@ void __init time_init(void)
+ {
+ mach_sched_init(timer_interrupt);
+ }
++#endif
+
++#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+ u32 arch_gettimeoffset(void)
+ {
+ return mach_gettimeoffset() * 1000;
+ }
++#endif
++
++#ifdef CONFIG_GENERIC_CLOCKEVENTS
++
++extern unsigned long long sys_dtim2_read(void);
++extern void sys_dtim2_init(void);
++static int cfv4_set_next_event(unsigned long evt,
++ struct clock_event_device *dev);
++static void cfv4_set_mode(enum clock_event_mode mode,
++ struct clock_event_device *dev);
++
++#if defined(CONFIG_M5445X) || defined(CONFIG_M5441X)
++#define FREQ (MCF_BUSCLK / 16)
++#else
++#define FREQ (MCF_BUSCLK)
++#endif
++
++/*
++ * Clock Evnt setup
++ */
++static struct clock_event_device clockevent_cfv4 = {
++ .name = "CFV4 timer2even",
++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++ .rating = 200,
++ .shift = 20,
++ .set_mode = cfv4_set_mode,
++ .set_next_event = cfv4_set_next_event,
++};
++
++static int cfv4_set_next_event(unsigned long evt,
++ struct clock_event_device *dev)
++{
++ return 0;
++}
++
++static void cfv4_set_mode(enum clock_event_mode mode,
++ struct clock_event_device *dev)
++{
++ if (mode != CLOCK_EVT_MODE_ONESHOT)
++ cfv4_set_next_event((FREQ / HZ), dev);
++}
++
++static int __init cfv4_clockevent_init(void)
++{
++ clockevent_cfv4.mult =
++ div_sc(FREQ, NSEC_PER_SEC,
++ clockevent_cfv4.shift);
++ clockevent_cfv4.max_delta_ns =
++ clockevent_delta2ns((FREQ / HZ),
++ &clockevent_cfv4);
++ clockevent_cfv4.min_delta_ns =
++ clockevent_delta2ns(1, &clockevent_cfv4);
++
++ clockevent_cfv4.cpumask = &cpumask_of_cpu(0);
++
++ printk(KERN_INFO "timer: register clockevent\n");
++ clockevents_register_device(&clockevent_cfv4);
++
++ return 0;
++}
++
++/*
++ * clocksource setup
++ */
++
++struct clocksource clocksource_cfv4 = {
++ .name = "ColdfireV4",
++ .rating = 250,
++ .mask = CLOCKSOURCE_MASK(32),
++ .read = sys_dtim2_read,
++ .shift = 20,
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
++};
++
++/*
++ * Initialize time subsystem. Called from linux/init/main.c
++ */
++void __init time_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "Initializing time\n");
++
++ cfv4_clockevent_init();
++ /* initialize the system timer */
++ sys_dtim2_init();
++
++ /* JKM */
++ clocksource_cfv4.mult = clocksource_hz2mult(FREQ,
++ clocksource_cfv4.shift);
++
++ /* register our clocksource */
++ ret = clocksource_register(&clocksource_cfv4);
++ if (ret)
++ printk(KERN_ERR "timer: unable to "
++ "register clocksource - %d\n", ret);
++}
++
++/*
++ * sysfs pieces
++ */
++
++static struct sysdev_class timer_class = {
++ .name = "timer",
++};
++
++static struct sys_device timer_device = {
++ .id = 0,
++ .cls = &timer_class,
++};
++
++static int __init timer_init_sysfs(void)
++{
++ int err = sysdev_class_register(&timer_class);
++ if (!err)
++ err = sysdev_register(&timer_device);
++ return err;
++}
++device_initcall(timer_init_sysfs);
++#endif /* CONFIG_GENERIC_CLOCKEVENTS */
+
+ static int __init rtc_init(void)
+ {
+--- /dev/null
++++ b/arch/m68k/kernel/vmlinux-cf.lds
+@@ -0,0 +1,142 @@
++/* ld script to make m68k Coldfire Linux kernel
++ *
++ * Derived from arch/m68k/kernel/vmlinux-std.lds
++ *
++ * Updated 11/26/2007 for new CodeSourcery toolset
++ * by Kurt Mahan <kmahan@freescale.com>
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
++ */
++
++#define LOAD_OFFSET 0x00000000
++
++#include <asm-generic/vmlinux.lds.h>
++#include <asm/page_offset.h>
++
++#define START_OFFSET 0x00020000
++#define IMAGE_START PAGE_OFFSET_RAW + START_OFFSET
++
++OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
++OUTPUT_ARCH(m68k)
++ENTRY(_stext)
++jiffies = jiffies_64 + 4;
++
++SECTIONS
++{
++ . = IMAGE_START;
++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
++ _text = .; /* Text and read-only data */
++ *(.text.head)
++ } :text = 0x4e75
++
++ .text : AT(ADDR(.text) - LOAD_OFFSET) {
++ TEXT_TEXT
++ SCHED_TEXT
++ LOCK_TEXT
++ *(.fixup)
++ *(.gnu.warning)
++ } :text = 0x4e75
++ _etext = .; /* End of text section */
++
++ . = ALIGN(16);
++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
++ __start___ex_table = .;
++ *(__ex_table)
++ __stop___ex_table = .;
++ }
++
++ RODATA
++
++ . = ALIGN(8192);
++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
++ DATA_DATA
++ CONSTRUCTORS
++ } :data
++
++
++ . = ALIGN(16);
++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET ) {
++ *(.data.cacheline_aligned)
++ } :data
++
++ _edata = .; /* End of data section */
++
++ NOTES /* support ld --build-id */
++
++ . = ALIGN(8192); /* Initrd */
++ .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
++ __init_begin = .;
++ _sinittext = .;
++ *(.init.text)
++ _einittext = .;
++ }
++
++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
++ *(.init.data)
++ }
++
++ . = ALIGN(16);
++ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
++ __setup_start = .;
++ *(.init.setup)
++ __setup_end = .;
++ }
++
++ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
++ __initcall_start = .;
++ INITCALLS
++ __initcall_end = .;
++ }
++
++ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
++ __con_initcall_start = .;
++ *(.con_initcall.init)
++ __con_initcall_end = .;
++ }
++
++ SECURITY_INIT
++
++#ifdef CONFIG_BLK_DEV_INITRD
++ . = ALIGN(8192);
++ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
++ __initramfs_start = .;
++ *(.init.ramfs)
++ __initramfs_end = .;
++ }
++#endif
++
++ . = ALIGN(8192);
++ __init_end = .;
++
++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
++ *(.data.init_task) /* The initial task and kernel stack */
++ }
++
++ _sbss = .;
++ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { /* BSS */
++ *(.bss)
++ }
++ _ebss = .;
++
++ _end = . ;
++
++ __ctors_start = . ;
++
++ __ctors_end = . ;
++
++ /* Sections to be discarded */
++ /DISCARD/ : {
++ *(.exit.text)
++ *(.exit.data)
++ *(.exitcall.exit)
++ }
++
++ /* Stabs debugging sections. */
++ STABS_DEBUG
++}
+--- a/arch/m68k/kernel/vmlinux.lds.S
++++ b/arch/m68k/kernel/vmlinux.lds.S
+@@ -1,10 +1,20 @@
++/*
++ * Copyright (C) 2011 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
++ * for more details.
++ */
+ 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 (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
+ */
+
+ #include <linux/module.h>
+@@ -39,8 +43,132 @@
+ * 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 +551,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 (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ 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 (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * * 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 (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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,245 @@ 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/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/cache.c
++++ b/arch/m68k/mm/cache.c
+@@ -4,13 +4,24 @@
+ * Instruction cache handling
+ *
+ * Copyright (C) 1995 Hamish Macdonald
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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>
+ #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 +80,16 @@ 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
++ flush_icache();
++#else /* !CONFIG_COLDFIRE */
+
+ if (CPU_IS_040_OR_060) {
+ address &= PAGE_MASK;
+@@ -94,9 +110,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 +133,5 @@ void flush_icache_user_range(struct vm_a
+ : "di" (FLUSH_I));
+ }
+ }
++#endif /* CONFIG_COLDFIRE */
+
+--- /dev/null
++++ b/arch/m68k/mm/cf-mmu.c
+@@ -0,0 +1,311 @@
++/*
++ * linux/arch/m68k/mm/cf-mmu.c
++ *
++ * Based upon linux/arch/m68k/mm/sun3mmu.c
++ * Based upon linux/arch/ppc/mm/mmu_context.c
++ *
++ * Implementations of mm routines specific to the Coldfire MMU.
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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/signal.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#ifdef CONFIG_BLK_DEV_RAM
++#include <linux/blkdev.h>
++#endif
++#include <linux/bootmem.h>
++
++#include <asm/setup.h>
++#include <asm/uaccess.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/machdep.h>
++#include <asm/io.h>
++#include <asm/mmu_context.h>
++#include <asm/cf_pgalloc.h>
++
++#include <asm/coldfire.h>
++#include <asm/tlbflush.h>
++
++#define KMAPAREA(x) ((x >= VMALLOC_START) && (x < KMAP_END))
++
++#undef DEBUG
++
++#ifdef CONFIG_VDSO
++unsigned long next_mmu_context;
++#else
++mm_context_t next_mmu_context;
++#endif
++
++unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
++
++atomic_t nr_free_contexts;
++struct mm_struct *context_mm[LAST_CONTEXT+1];
++const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
++
++extern unsigned long num_pages;
++EXPORT_SYMBOL(num_pages);
++/*
++ * Free memory used for system initialization.
++ */
++void free_initmem(void)
++{
++#if 0
++ unsigned long addr;
++ unsigned long start = (unsigned long)&__init_begin;
++ unsigned long end = (unsigned long)&__init_end;
++
++ printk(KERN_INFO "free_initmem: __init_begin = 0x%lx"
++ " __init_end = 0x%lx\n", start, end);
++
++ addr = (unsigned long)&__init_begin;
++ for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
++ /* not currently used */
++ virt_to_page(addr)->flags &= ~(1 << PG_reserved);
++ init_page_count(virt_to_page(addr));
++ free_page(addr);
++ totalram_pages++;
++ }
++#endif
++}
++
++/*
++ * Initialize the paging system.
++ */
++void __init paging_init(void)
++{
++ pgd_t *pg_dir;
++ pte_t *pg_table;
++ int i;
++ unsigned long address;
++ unsigned long next_pgtable;
++ unsigned long zones_size[MAX_NR_ZONES];
++ unsigned long size;
++ enum zone_type zone;
++
++ /* allocate zero page */
++ empty_zero_page = (void *)alloc_bootmem_pages(PAGE_SIZE);
++ memset((void *)empty_zero_page, 0, PAGE_SIZE);
++
++ /* zero kernel page directory */
++ pg_dir = swapper_pg_dir;
++ memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
++ /*
++ * setup page tables for PHYSRAM
++ */
++
++ /* starting loc in page directory */
++ pg_dir += PAGE_OFFSET >> PGDIR_SHIFT;
++
++ /* allocate page tables */
++ size = num_pages * sizeof(pte_t);
++ size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
++ next_pgtable = (unsigned long)alloc_bootmem_pages(size);
++ address = PAGE_OFFSET;
++ while (address < (unsigned long)high_memory) {
++ /* setup page table in page directory */
++ pg_table = (pte_t *)next_pgtable;
++ next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
++ pgd_val(*pg_dir) = (unsigned long)pg_table;
++ pg_dir++;
++
++ /* create PTEs in page table */
++ for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
++ pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
++ if (address >= (unsigned long)high_memory)
++ pte_val(pte) = 0;
++
++ set_pte(pg_table, pte);
++ address += PAGE_SIZE;
++ }
++ }
++
++ /*
++ * setup page tables for DMA area
++ */
++
++ /* starting loc in page directory */
++ pg_dir = swapper_pg_dir;
++ pg_dir += CONFIG_DMA_BASE >> PGDIR_SHIFT;
++
++ /* allocate page tables */
++ size = (CONFIG_DMA_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
++ size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
++ next_pgtable = (unsigned long)alloc_bootmem_pages(size);
++ address = CONFIG_DMA_BASE;
++ while (address < (CONFIG_DMA_BASE + CONFIG_DMA_SIZE)) {
++ /* setup page table in page directory */
++ pg_table = (pte_t *)next_pgtable;
++ next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
++ pgd_val(*pg_dir) = (unsigned long)pg_table;
++ pg_dir++;
++
++ /* create PTEs in page table */
++ for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
++ pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
++ if (address >= (CONFIG_DMA_BASE + CONFIG_DMA_SIZE))
++ pte_val(pte) = 0;
++
++ set_pte(pg_table, pte);
++ address += PAGE_SIZE;
++ }
++ }
++
++ /*
++ * setup zones
++ */
++
++ current->mm = NULL;
++
++ /* clear zones */
++ for (zone = 0; zone < MAX_NR_ZONES; zone++)
++ zones_size[zone] = 0x0;
++
++ zones_size[ZONE_DMA] = CONFIG_DMA_SIZE >> PAGE_SHIFT;
++ zones_size[ZONE_NORMAL] = (((unsigned long)high_memory -
++ PAGE_OFFSET) >> PAGE_SHIFT) -
++ zones_size[ZONE_DMA];
++
++ free_area_init(zones_size);
++}
++/*
++ * Handle a missed TLB
++ */
++int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
++{
++ struct mm_struct *mm;
++ pgd_t *pgd;
++ pmd_t *pmd;
++ pte_t *pte;
++ unsigned long mmuar;
++ int asid;
++ unsigned long flags;
++
++ local_save_flags(flags);
++ local_irq_disable();
++
++ mmuar = (dtlb) ? regs->mmuar
++ : regs->pc + (extension_word * sizeof(long));
++
++ mm = (!user_mode(regs) && KMAPAREA(mmuar)) ? &init_mm : current->mm;
++
++ if (!mm) {
++ local_irq_restore(flags);
++ return -1;
++ }
++
++ pgd = pgd_offset(mm, mmuar);
++ if (pgd_none(*pgd)) {
++ local_irq_restore(flags);
++ return -1;
++ }
++
++ pmd = pmd_offset(pgd, mmuar);
++ if (pmd_none(*pmd)) {
++ local_irq_restore(flags);
++ return -1;
++ }
++
++ pte = (KMAPAREA(mmuar)) ? pte_offset_kernel(pmd, mmuar)
++ : pte_offset_map(pmd, mmuar);
++ if (pte_none(*pte) || !pte_present(*pte)) {
++ local_irq_restore(flags);
++ return -1;
++ }
++
++ if (write) {
++ if (!pte_write(*pte)) {
++ local_irq_restore(flags);
++ return -1;
++ }
++ set_pte(pte, pte_mkdirty(*pte));
++ }
++
++ set_pte(pte, pte_mkyoung(*pte));
++ asid = cpu_context(mm) & 0xff;
++ if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
++ 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;
++
++ if (dtlb)
++ *MMUOR = MMUOR_ACC | MMUOR_UAA;
++ else
++ *MMUOR = MMUOR_ITLB | MMUOR_ACC | MMUOR_UAA;
++
++ asm("nop");
++
++#ifdef DEBUG
++ printk(KERN_INFO "cf_tlb_miss: va=%lx, pa=%lx\n", (mmuar & PAGE_MASK),
++ (pte_val(*pte) & PAGE_MASK));
++#endif
++ local_irq_restore(flags);
++ return 0;
++}
++
++
++/*
++ * Context Management
++ *
++ * Based on arch/ppc/mmu_context.c
++ */
++
++/*
++ * Initialize the context management system.
++ */
++void __init mmu_context_init(void)
++{
++ /*
++ * Some processors have too few contexts to reserve one for
++ * init_mm, and require using context 0 for a normal task.
++ * Other processors reserve the use of context zero for the kernel.
++ * This code assumes FIRST_CONTEXT < 32.
++ */
++ context_map[0] = (1 << FIRST_CONTEXT) - 1;
++ next_mmu_context = FIRST_CONTEXT;
++ atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
++}
++
++/*
++ * Steal a context from a task that has one at the moment.
++ * This is only used on 8xx and 4xx and we presently assume that
++ * they don't do SMP. If they do then thicfpgalloc.hs will have to check
++ * whether the MM we steal is in use.
++ * We also assume that this is only used on systems that don't
++ * use an MMU hash table - this is true for 8xx and 4xx.
++ * This isn't an LRU system, it just frees up each context in
++ * turn (sort-of pseudo-random replacement :). This would be the
++ * place to implement an LRU scheme if anyone was motivated to do it.
++ * -- paulus
++ */
++void steal_context(void)
++{
++ struct mm_struct *mm;
++ /* free up context `next_mmu_context' */
++ /* if we shouldn't free context 0, don't... */
++ if (next_mmu_context < FIRST_CONTEXT)
++ next_mmu_context = FIRST_CONTEXT;
++ mm = context_mm[next_mmu_context];
++ flush_tlb_mm(mm);
++ destroy_context(mm);
++}
+--- /dev/null
++++ b/arch/m68k/mm/cf-sram.c
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Author: Lanttor.Guo@freescale.com
++ *
++ * Providing on-chip SRAM allocation and free APIs to kernel
++ * The implemention uses gen_pool_alloc/gen_pool_free interface
++ *
++ * 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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/genalloc.h>
++
++/* sram memory min allocation size per once */
++static long blk_size = CONFIG_SRAM_ALLOC_GRANULARITY;
++static struct gen_pool *sram_pool;
++
++/*
++ * Set up memory pools to manage on-chip sram.
++ * @ start the start address of SRAM
++ * @ size the size of SRAM
++ * return return 0 express success
++ */
++int declare_sram_pool(void *start, size_t size)
++{
++ int status = 0;
++
++ pr_debug("%s %p %d\n", __func__, start, size);
++
++ sram_pool = gen_pool_create(ilog2(blk_size), -1);
++ if (!sram_pool) {
++ printk(KERN_ERR "gen_pool_creat faile at %s()\n", __func__);
++ status = -ENOMEM;
++ }
++
++ status = gen_pool_add(sram_pool, (unsigned long)start, size, -1);
++ if (status < 0)
++ printk(KERN_ERR "gen_pool_add failed at %s()\n", __func__);
++
++ return status;
++
++}
++
++/*
++ * Allocate memory from sram pool
++ * @ len the size of allocated memory
++ * return return the start addr of allocated memory
++ */
++void *sram_alloc(size_t len)
++{
++ unsigned long vaddr;
++
++ if (!len) {
++ printk(KERN_ERR "the len parameter of sram_alloc() is zero\n");
++ return NULL;
++ }
++
++ vaddr = gen_pool_alloc(sram_pool, len);
++ if (!vaddr)
++ return NULL;
++
++ return (void *)vaddr;
++}
++EXPORT_SYMBOL(sram_alloc);
++
++/*
++ * Free memory to sram pool
++ * @ addr the addr of allocated memory
++ * @ len the size of allocated memory
++ */
++void sram_free(void *addr, size_t len)
++{
++ gen_pool_free(sram_pool, (unsigned long)addr, len);
++}
++EXPORT_SYMBOL(sram_free);
+--- a/arch/m68k/mm/hwtest.c
++++ b/arch/m68k/mm/hwtest.c
+@@ -12,6 +12,14 @@
+ * them here complete with the comments from the original atari
+ * config.c...
+ * -- PMM <pmaydell@chiark.greenend.org.uk>, 05/1998
++ *
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+ */
+
+ /* This function tests for the presence of an address, specially a
+@@ -25,6 +33,7 @@
+
+ #include <linux/module.h>
+
++#ifndef CONFIG_COLDFIRE
+ int hwreg_present( volatile void *regp )
+ {
+ int ret = 0;
+@@ -82,4 +91,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,13 @@
+ * linux/arch/m68k/mm/init.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+ *
+ * Contains common initialization routines, specific init code moved
+ * to motorola.c and sun3mmu.c
+@@ -32,6 +39,7 @@
+ #include <asm/sections.h>
+ #include <asm/tlb.h>
+
++
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+ pg_data_t pg_data_map[MAX_NUMNODES];
+@@ -113,7 +121,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++) {
+@@ -132,6 +140,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,13 @@
+ * linux/arch/m68k/mm/kmap.c
+ *
+ * Copyright (C) 1997 Roman Hodek
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+ *
+ * 10/01/99 cleaned up the code and changing to the same interface
+ * used by other architectures /Roman Zippel
+@@ -24,7 +31,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 +61,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;
+
+@@ -126,8 +141,58 @@ 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 CONFIG_M5441X
++ if (physaddr >= 0xe0000000) {
++ /*
++ * On the M5441x processors an ACR is setup to map
++ * the 0xe0000000 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 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
+@@ -146,7 +211,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
+
+ /*
+@@ -171,7 +237,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:
+@@ -251,6 +322,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/memory.c
++++ b/arch/m68k/mm/memory.c
+@@ -2,6 +2,13 @@
+ * linux/arch/m68k/mm/memory.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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>
+@@ -127,6 +134,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 +181,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 +212,9 @@ static inline void pushcl040(unsigned lo
+
+ void cache_clear (unsigned long paddr, int len)
+ {
++#ifdef CONFIG_COLDFIRE
++ flush_bcache();
++#else
+ if (CPU_IS_040_OR_060) {
+ int tmp;
+
+@@ -237,6 +249,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 +263,9 @@ EXPORT_SYMBOL(cache_clear);
+
+ void cache_push (unsigned long paddr, int len)
+ {
++#ifdef CONFIG_COLDFIRE
++ flush_bcache();
++#else
+ if (CPU_IS_040_OR_060) {
+ int tmp = PAGE_SIZE;
+
+@@ -290,6 +306,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.
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * 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.
+@@ -2161,7 +2165,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 (C) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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,7 +18,7 @@
+ #define _FSL_DEVICE_H_
+
+ #include <linux/types.h>
+-
++#include <linux/interrupt.h>
+ /*
+ * Some conventions on how we handle peripherals on Freescale chips
+ *
+@@ -119,4 +119,14 @@ int fsl_deep_sleep(void);
+ static inline int fsl_deep_sleep(void) { return 0; }
+ #endif
+
++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);
++};
+ #endif /* _FSL_DEVICE_H_ */