]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branches 'at91', 'ep93xx', 'errata', 'footbridge', 'fncpy', 'gemini', 'irqdata...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 16 Mar 2011 23:35:17 +0000 (23:35 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 16 Mar 2011 23:35:17 +0000 (23:35 +0000)
125 files changed:
Documentation/arm/SH-Mobile/Makefile [new file with mode: 0644]
Documentation/arm/SH-Mobile/vrl4.c [new file with mode: 0644]
Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt [new file with mode: 0644]
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-shmobile.S
arch/arm/boot/compressed/head-vt8500.S [new file with mode: 0644]
arch/arm/boot/compressed/mmcif-sh7372.c [new file with mode: 0644]
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/cpu-multi32.h [deleted file]
arch/arm/include/asm/cpu-single.h [deleted file]
arch/arm/include/asm/fncpy.h [new file with mode: 0644]
arch/arm/include/asm/glue-cache.h [new file with mode: 0644]
arch/arm/include/asm/glue-df.h [new file with mode: 0644]
arch/arm/include/asm/glue-pf.h [new file with mode: 0644]
arch/arm/include/asm/glue-proc.h [new file with mode: 0644]
arch/arm/include/asm/glue.h
arch/arm/include/asm/proc-fns.h
arch/arm/include/asm/processor.h
arch/arm/include/asm/smp_scu.h
arch/arm/kernel/Makefile
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/sleep.S [new file with mode: 0644]
arch/arm/kernel/smp_scu.c
arch/arm/mach-at91/board-snapper9260.c
arch/arm/mach-at91/include/mach/gpio.h
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-ep93xx/include/mach/gpio.h
arch/arm/mach-footbridge/dc21285-timer.c
arch/arm/mach-footbridge/isa-timer.c
arch/arm/mach-gemini/board-nas4220b.c
arch/arm/mach-gemini/board-rut1xx.c
arch/arm/mach-gemini/board-wbd111.c
arch/arm/mach-gemini/board-wbd222.c
arch/arm/mach-gemini/common.h
arch/arm/mach-gemini/devices.c
arch/arm/mach-mxs/gpio.c
arch/arm/mach-mxs/icoll.c
arch/arm/mach-omap1/pm.h
arch/arm/mach-omap1/sleep.S
arch/arm/mach-omap1/sram.S
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/sleep24xx.S
arch/arm/mach-omap2/sleep34xx.S
arch/arm/mach-omap2/sram242x.S
arch/arm/mach-omap2/sram243x.S
arch/arm/mach-omap2/sram34xx.S
arch/arm/mach-pxa/include/mach/pm.h
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/sleep.S
arch/arm/mach-pxa/zeus.c
arch/arm/mach-s3c64xx/sleep.S
arch/arm/mach-s5pv210/sleep.S
arch/arm/mach-sa1100/pm.c
arch/arm/mach-sa1100/sleep.S
arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/mmcif.h [new file with mode: 0644]
arch/arm/mach-ux500/Kconfig
arch/arm/mach-vt8500/Kconfig [new file with mode: 0644]
arch/arm/mach-vt8500/Makefile [new file with mode: 0644]
arch/arm/mach-vt8500/Makefile.boot [new file with mode: 0644]
arch/arm/mach-vt8500/bv07.c [new file with mode: 0644]
arch/arm/mach-vt8500/devices-vt8500.c [new file with mode: 0644]
arch/arm/mach-vt8500/devices-wm8505.c [new file with mode: 0644]
arch/arm/mach-vt8500/devices.c [new file with mode: 0644]
arch/arm/mach-vt8500/devices.h [new file with mode: 0644]
arch/arm/mach-vt8500/gpio.c [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/i8042.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/vt8500_irqs.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/vt8500_regs.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/vt8500fb.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/wm8505_irqs.h [new file with mode: 0644]
arch/arm/mach-vt8500/include/mach/wm8505_regs.h [new file with mode: 0644]
arch/arm/mach-vt8500/irq.c [new file with mode: 0644]
arch/arm/mach-vt8500/pwm.c [new file with mode: 0644]
arch/arm/mach-vt8500/timer.c [new file with mode: 0644]
arch/arm/mach-vt8500/wm8505_7in.c [new file with mode: 0644]
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm6_7.S
arch/arm/mm/proc-arm720.S
arch/arm/mm/proc-arm740.S
arch/arm/mm/proc-arm7tdmi.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-arm940.S
arch/arm/mm/proc-arm946.S
arch/arm/mm/proc-arm9tdmi.S
arch/arm/mm/proc-fa526.S
arch/arm/mm/proc-feroceon.S
arch/arm/mm/proc-mohawk.S
arch/arm/mm/proc-sa110.S
arch/arm/mm/proc-sa1100.S
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/plat-omap/include/plat/sram.h
arch/arm/plat-omap/sram.c
arch/arm/plat-s3c24xx/sleep.S
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/plat-samsung/pm.c

diff --git a/Documentation/arm/SH-Mobile/Makefile b/Documentation/arm/SH-Mobile/Makefile
new file mode 100644 (file)
index 0000000..8771d83
--- /dev/null
@@ -0,0 +1,8 @@
+BIN := vrl4
+
+.PHONY: all
+all: $(BIN)
+
+.PHONY: clean
+clean:
+       rm -f *.o $(BIN)
diff --git a/Documentation/arm/SH-Mobile/vrl4.c b/Documentation/arm/SH-Mobile/vrl4.c
new file mode 100644 (file)
index 0000000..e8a1913
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * vrl4 format generator
+ *
+ * Copyright (C) 2010 Simon Horman
+ *
+ * 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.
+ */
+
+/*
+ * usage: vrl4 < zImage > out
+ *       dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 1
+ *
+ * Reads a zImage from stdin and writes a vrl4 image to stdout.
+ * In practice this means writing a padded vrl4 header to stdout followed
+ * by the zImage.
+ *
+ * The padding places the zImage at ALIGN bytes into the output.
+ * The vrl4 uses ALIGN + START_BASE as the start_address.
+ * This is where the mask ROM will jump to after verifying the header.
+ *
+ * The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN.
+ * That is, the mask ROM will load the padded header (ALIGN bytes)
+ * And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image,
+ * whichever is smaller.
+ *
+ * The zImage is not modified in any way.
+ */
+
+#define _BSD_SOURCE
+#include <endian.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+struct hdr {
+       uint32_t magic1;
+       uint32_t reserved1;
+       uint32_t magic2;
+       uint32_t reserved2;
+       uint16_t copy_size;
+       uint16_t boot_options;
+       uint32_t reserved3;
+       uint32_t start_address;
+       uint32_t reserved4;
+       uint32_t reserved5;
+       char     reserved6[308];
+};
+
+#define DECLARE_HDR(h)                                 \
+       struct hdr (h) = {                              \
+               .magic1 =       htole32(0xea000000),    \
+               .reserved1 =    htole32(0x56),          \
+               .magic2 =       htole32(0xe59ff008),    \
+               .reserved3 =    htole16(0x1) }
+
+/* Align to 512 bytes, the MMCIF sector size */
+#define ALIGN_BITS     9
+#define ALIGN          (1 << ALIGN_BITS)
+
+#define START_BASE     0xe55b0000
+
+/*
+ * With an alignment of 512 the header uses the first sector.
+ * There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM.
+ * So there are 127 sectors left for the boot programme. But in practice
+ * Only a small portion of a zImage is needed, 16 sectors should be more
+ * than enough.
+ *
+ * Note that this sets how much of the zImage is copied by the mask ROM.
+ * The entire zImage is present after the header and is loaded
+ * by the code in the boot program (which is the first portion of the zImage).
+ */
+#define        MAX_BOOT_PROG_LEN (16 * 512)
+
+#define ROUND_UP(x)    ((x + ALIGN - 1) & ~(ALIGN - 1))
+
+ssize_t do_read(int fd, void *buf, size_t count)
+{
+       size_t offset = 0;
+       ssize_t l;
+
+       while (offset < count) {
+               l = read(fd, buf + offset, count - offset);
+               if (!l)
+                       break;
+               if (l < 0) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK)
+                               continue;
+                       perror("read");
+                       return -1;
+               }
+               offset += l;
+       }
+
+       return offset;
+}
+
+ssize_t do_write(int fd, const void *buf, size_t count)
+{
+       size_t offset = 0;
+       ssize_t l;
+
+       while (offset < count) {
+               l = write(fd, buf + offset, count - offset);
+               if (l < 0) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK)
+                               continue;
+                       perror("write");
+                       return -1;
+               }
+               offset += l;
+       }
+
+       return offset;
+}
+
+ssize_t write_zero(int fd, size_t len)
+{
+       size_t i = len;
+
+       while (i--) {
+               const char x = 0;
+               if (do_write(fd, &x, 1) < 0)
+                       return -1;
+       }
+
+       return len;
+}
+
+int main(void)
+{
+       DECLARE_HDR(hdr);
+       char boot_program[MAX_BOOT_PROG_LEN];
+       size_t aligned_hdr_len, alligned_prog_len;
+       ssize_t prog_len;
+
+       prog_len = do_read(0, boot_program, sizeof(boot_program));
+       if (prog_len <= 0)
+               return -1;
+
+       aligned_hdr_len = ROUND_UP(sizeof(hdr));
+       hdr.start_address = htole32(START_BASE + aligned_hdr_len);
+       alligned_prog_len = ROUND_UP(prog_len);
+       hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len);
+
+       if (do_write(1, &hdr, sizeof(hdr)) < 0)
+               return -1;
+       if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0)
+               return -1;
+
+       if (do_write(1, boot_program, prog_len) < 0)
+               return 1;
+
+       /* Write out the rest of the kernel */
+       while (1) {
+               prog_len = do_read(0, boot_program, sizeof(boot_program));
+               if (prog_len < 0)
+                       return 1;
+               if (prog_len == 0)
+                       break;
+               if (do_write(1, boot_program, prog_len) < 0)
+                       return 1;
+       }
+
+       return 0;
+}
diff --git a/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt b/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
new file mode 100644 (file)
index 0000000..efff8ae
--- /dev/null
@@ -0,0 +1,29 @@
+ROM-able zImage boot from MMC
+-----------------------------
+
+An ROM-able zImage compiled with ZBOOT_ROM_MMCIF may be written to MMC and
+SuperH Mobile ARM will to boot directly from the MMCIF hardware block.
+
+This is achieved by the mask ROM loading the first portion of the image into
+MERAM and then jumping to it. This portion contains loader code which
+copies the entire image to SDRAM and jumps to it. From there the zImage
+boot code proceeds as normal, uncompressing the image into its final
+location and then jumping to it.
+
+This code has been tested on an AP4EB board using the developer 1A eMMC
+boot mode which is configured using the following jumper settings.
+The board used for testing required a patched mask ROM in order for
+this mode to function.
+
+   8 7 6 5 4 3 2 1
+   x|x|x|x|x| |x|
+S4 -+-+-+-+-+-+-+-
+    | | | | |x| |x on
+
+The zImage must be written to the MMC card at sector 1 (512 bytes) in
+vrl4 format. A utility vrl4 is supplied to accomplish this.
+
+e.g.
+       vrl4 < zImage | dd of=/dev/sdX bs=512 seek=1
+
+A dual-voltage MMC 4.0 card was used for testing.
index 166efa2a19cd96eb05ad5b4b599708c9a68c1d70..38bf684448e72b41295c662ef617fb02e9acea97 100644 (file)
@@ -346,7 +346,7 @@ config ARCH_FOOTBRIDGE
        bool "FootBridge"
        select CPU_SA110
        select FOOTBRIDGE
-       select ARCH_USES_GETTIMEOFFSET
+       select GENERIC_CLOCKEVENTS
        help
          Support for systems based on the DC21285 companion chip
          ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
@@ -875,6 +875,16 @@ config PLAT_SPEAR
        help
          Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
 
+config ARCH_VT8500
+       bool "VIA/WonderMedia 85xx"
+       select CPU_ARM926T
+       select GENERIC_GPIO
+       select ARCH_HAS_CPUFREQ
+       select GENERIC_CLOCKEVENTS
+       select ARCH_REQUIRE_GPIOLIB
+       select HAVE_PWM
+       help
+         Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
 endchoice
 
 #
@@ -1007,6 +1017,8 @@ source "arch/arm/mach-versatile/Kconfig"
 
 source "arch/arm/mach-vexpress/Kconfig"
 
+source "arch/arm/mach-vt8500/Kconfig"
+
 source "arch/arm/mach-w90x900/Kconfig"
 
 # Definitions to make life easier
@@ -1202,6 +1214,28 @@ config ARM_ERRATA_753970
          This has the same effect as the cache sync operation: store buffer
          drain and waiting for all buffers empty.
 
+config ARM_ERRATA_754322
+       bool "ARM errata: possible faulty MMU translations following an ASID switch"
+       depends on CPU_V7
+       help
+         This option enables the workaround for the 754322 Cortex-A9 (r2p*,
+         r3p*) erratum. A speculative memory access may cause a page table walk
+         which starts prior to an ASID switch but completes afterwards. This
+         can populate the micro-TLB with a stale entry which may be hit with
+         the new ASID. This workaround places two dsb instructions in the mm
+         switching code so that no page table walks can cross the ASID switch.
+
+config ARM_ERRATA_754327
+       bool "ARM errata: no automatic Store Buffer drain"
+       depends on CPU_V7 && SMP
+       help
+         This option enables the workaround for the 754327 Cortex-A9 (prior to
+         r2p0) erratum. The Store Buffer does not have any automatic draining
+         mechanism and therefore a livelock may occur if an external agent
+         continuously polls a memory location waiting to observe an update.
+         This workaround defines cpu_relax() as smp_mb(), preventing correctly
+         written polling loops from denying visibility of updates to memory.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1644,6 +1678,18 @@ config ZBOOT_ROM
          Say Y here if you intend to execute your compressed kernel image
          (zImage) directly from ROM or flash.  If unsure, say N.
 
+config ZBOOT_ROM_MMCIF
+       bool "Include MMCIF loader in zImage (EXPERIMENTAL)"
+       depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL
+       help
+         Say Y here to include experimental MMCIF loading code in the
+         ROM-able zImage. With this enabled it is possible to write the
+         the ROM-able zImage kernel image to an MMC card and boot the
+         kernel straight from the reset vector. At reset the processor
+         Mask ROM will load the first part of the the ROM-able zImage
+         which in turn loads the rest the kernel image to RAM using the
+         MMCIF hardware block.
+
 config CMDLINE
        string "Default kernel command string"
        default ""
index 6f7b29294c80fdc23370406db824056e918b8ee9..cd56c9129a1a9a095afaff357381963002b190a5 100644 (file)
@@ -190,6 +190,7 @@ machine-$(CONFIG_ARCH_U300)         := u300
 machine-$(CONFIG_ARCH_U8500)           := ux500
 machine-$(CONFIG_ARCH_VERSATILE)       := versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                := vexpress
+machine-$(CONFIG_ARCH_VT8500)          := vt8500
 machine-$(CONFIG_ARCH_W90X900)         := w90x900
 machine-$(CONFIG_ARCH_NUC93X)          := nuc93x
 machine-$(CONFIG_FOOTBRIDGE)           := footbridge
index 0a8f748e506adfc415b857bc94dec36e25498999..5f3a1614dc63945490d9a1918949f1c275cf349d 100644 (file)
@@ -4,9 +4,20 @@
 # create a compressed vmlinuz image from the original vmlinux
 #
 
+OBJS           =
+
+# Ensure that mmcif loader code appears early in the image
+# to minimise that number of bocks that have to be read in
+# order to load it.
+ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
+ifeq ($(CONFIG_ARCH_SH7372),y)
+OBJS           += mmcif-sh7372.o
+endif
+endif
+
 AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
 HEAD   = head.o
-OBJS   = misc.o decompress.o
+OBJS   += misc.o decompress.o
 FONTC  = $(srctree)/drivers/video/console/font_acorn_8x8.c
 
 #
@@ -29,6 +40,10 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
 OBJS           += head-sa1100.o
 endif
 
+ifeq ($(CONFIG_ARCH_VT8500),y)
+OBJS           += head-vt8500.o
+endif
+
 ifeq ($(CONFIG_CPU_XSCALE),y)
 OBJS           += head-xscale.o
 endif
index 30973b76e6ae367bd293d2d14a0aaaca1e2fe1db..c943d2e7da9dddbad978d7ea60c45339ac76360f 100644 (file)
        /* load board-specific initialization code */
 #include <mach/zboot.h>
 
+#ifdef CONFIG_ZBOOT_ROM_MMCIF
+       /* Load image from MMC */
+       adr     sp, __tmp_stack + 128
+       ldr     r0, __image_start
+       ldr     r1, __image_end
+       subs    r1, r1, r0
+       ldr     r0, __load_base
+       bl      mmcif_loader
+
+       /* Jump to loaded code */
+       ldr     r0, __loaded
+       ldr     r1, __image_start
+       sub     r0, r0, r1
+       ldr     r1, __load_base
+       add     pc, r0, r1
+
+__image_start:
+       .long   _start
+__image_end:
+       .long   _got_end
+__load_base:
+       .long   CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
+__loaded:
+       .long   __continue
+       .align
+__tmp_stack:
+       .space  128
+__continue:
+#endif /* CONFIG_ZBOOT_ROM_MMCIF */
+
        b       1f
 __atags:@ tag #1
        .long   12                      @ tag->hdr.size = tag_size(tag_core);
diff --git a/arch/arm/boot/compressed/head-vt8500.S b/arch/arm/boot/compressed/head-vt8500.S
new file mode 100644 (file)
index 0000000..1dc1e21
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/boot/compressed/head-vt8500.S
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * VIA VT8500 specific tweaks. This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+               .section        ".start", "ax"
+
+__VT8500_start:
+       @ Compare the SCC ID register against a list of known values
+       ldr     r1, .SCCID
+       ldr     r3, [r1]
+
+       @ VT8500 override
+       ldr     r4, .VT8500SCC
+       cmp     r3, r4
+       ldreq   r7, .ID_BV07
+       beq     .Lendvt8500
+
+       @ WM8505 override
+       ldr     r4, .WM8505SCC
+       cmp     r3, r4
+       ldreq   r7, .ID_8505
+       beq     .Lendvt8500
+
+       @ Otherwise, leave the bootloader's machine id untouched
+
+.SCCID:
+       .word   0xd8120000
+.VT8500SCC:
+       .word   0x34000102
+.WM8505SCC:
+       .word   0x34260103
+
+.ID_BV07:
+       .word   MACH_TYPE_BV07
+.ID_8505:
+       .word   MACH_TYPE_WM8505_7IN_NETBOOK
+
+.Lendvt8500:
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644 (file)
index 0000000..e6180af
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * sh7372 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Simon Horman
+ *
+ * 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/mmc/sh_mmcif.h>
+#include <mach/mmcif.h>
+
+#define MMCIF_BASE      (void __iomem *)0xe6bd0000
+
+#define PORT84CR       (void __iomem *)0xe6050054
+#define PORT85CR       (void __iomem *)0xe6050055
+#define PORT86CR       (void __iomem *)0xe6050056
+#define PORT87CR       (void __iomem *)0xe6050057
+#define PORT88CR       (void __iomem *)0xe6050058
+#define PORT89CR       (void __iomem *)0xe6050059
+#define PORT90CR       (void __iomem *)0xe605005a
+#define PORT91CR       (void __iomem *)0xe605005b
+#define PORT92CR       (void __iomem *)0xe605005c
+#define PORT99CR       (void __iomem *)0xe6050063
+
+#define SMSTPCR3       (void __iomem *)0xe615013c
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the zImage from an MMC card starting from block 1.
+ *
+ * The image must be start with a vrl4 header and
+ * the zImage must start at offset 512 of the image. That is,
+ * at block 2 (=byte 1024) on the media
+ *
+ * Use the following line to write the vrl4 formated zImage
+ * to an MMC card
+ * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
+{
+       mmcif_init_progress();
+       mmcif_update_progress(MMCIF_PROGRESS_ENTER);
+
+       /* Initialise MMC
+        * registers: PORT84CR-PORT92CR
+        *            (MMCD0_0-MMCD0_7,MMCCMD0 Control)
+        * value: 0x04 - select function 4
+        */
+        __raw_writeb(0x04, PORT84CR);
+        __raw_writeb(0x04, PORT85CR);
+        __raw_writeb(0x04, PORT86CR);
+        __raw_writeb(0x04, PORT87CR);
+        __raw_writeb(0x04, PORT88CR);
+        __raw_writeb(0x04, PORT89CR);
+        __raw_writeb(0x04, PORT90CR);
+        __raw_writeb(0x04, PORT91CR);
+        __raw_writeb(0x04, PORT92CR);
+
+       /* Initialise MMC
+        * registers: PORT99CR (MMCCLK0 Control)
+        * value: 0x10 | 0x04 - enable output | select function 4
+        */
+       __raw_writeb(0x14, PORT99CR);
+
+       /* Enable clock to MMC hardware block */
+       __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
+
+       mmcif_update_progress(MMCIF_PROGRESS_INIT);
+
+       /* setup MMCIF hardware */
+       sh_mmcif_boot_init(MMCIF_BASE);
+
+       mmcif_update_progress(MMCIF_PROGRESS_LOAD);
+
+       /* load kernel via MMCIF interface */
+       sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
+                             (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
+
+
+       /* Disable clock to MMC hardware block */
+       __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+       mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}
index 3acd8fa25e347dc1bcd276ba036e9107ff5d06d9..18a56640d97d7a8124fffde066cdf3037b36c7b5 100644 (file)
 
 #include <linux/mm.h>
 
-#include <asm/glue.h>
+#include <asm/glue-cache.h>
 #include <asm/shmparam.h>
 #include <asm/cachetype.h>
 #include <asm/outercache.h>
 
 #define CACHE_COLOUR(vaddr)    ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
-/*
- *     Cache Model
- *     ===========
- */
-#undef _CACHE
-#undef MULTI_CACHE
-
-#if defined(CONFIG_CPU_CACHE_V3)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE v3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_CACHE_V4)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE v4
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
-    defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
-    defined(CONFIG_CPU_ARM1026)
-# define MULTI_CACHE 1
-#endif
-
-#if defined(CONFIG_CPU_FA526)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE fa
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM926T)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE arm926
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM940T)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE arm940
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM946E)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE arm946
-# endif
-#endif
-
-#if defined(CONFIG_CPU_CACHE_V4WB)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE v4wb
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSCALE)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE xscale
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSC3)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE xsc3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_MOHAWK)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE mohawk
-# endif
-#endif
-
-#if defined(CONFIG_CPU_FEROCEON)
-# define MULTI_CACHE 1
-#endif
-
-#if defined(CONFIG_CPU_V6)
-//# ifdef _CACHE
-#  define MULTI_CACHE 1
-//# else
-//#  define _CACHE v6
-//# endif
-#endif
-
-#if defined(CONFIG_CPU_V7)
-//# ifdef _CACHE
-#  define MULTI_CACHE 1
-//# else
-//#  define _CACHE v7
-//# endif
-#endif
-
-#if !defined(_CACHE) && !defined(MULTI_CACHE)
-#error Unknown cache maintainence model
-#endif
-
 /*
  * This flag is used to indicate that the page pointed to by a pte is clean
  * and does not require cleaning before returning it to the user.
@@ -249,19 +132,11 @@ extern struct cpu_cache_fns cpu_cache;
  * visible to the CPU.
  */
 #define dmac_map_area                  cpu_cache.dma_map_area
-#define dmac_unmap_area                cpu_cache.dma_unmap_area
+#define dmac_unmap_area                        cpu_cache.dma_unmap_area
 #define dmac_flush_range               cpu_cache.dma_flush_range
 
 #else
 
-#define __cpuc_flush_icache_all                __glue(_CACHE,_flush_icache_all)
-#define __cpuc_flush_kern_all          __glue(_CACHE,_flush_kern_cache_all)
-#define __cpuc_flush_user_all          __glue(_CACHE,_flush_user_cache_all)
-#define __cpuc_flush_user_range                __glue(_CACHE,_flush_user_cache_range)
-#define __cpuc_coherent_kern_range     __glue(_CACHE,_coherent_kern_range)
-#define __cpuc_coherent_user_range     __glue(_CACHE,_coherent_user_range)
-#define __cpuc_flush_dcache_area       __glue(_CACHE,_flush_kern_dcache_area)
-
 extern void __cpuc_flush_icache_all(void);
 extern void __cpuc_flush_kern_all(void);
 extern void __cpuc_flush_user_all(void);
@@ -276,10 +151,6 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_map_area                  __glue(_CACHE,_dma_map_area)
-#define dmac_unmap_area                __glue(_CACHE,_dma_unmap_area)
-#define dmac_flush_range               __glue(_CACHE,_dma_flush_range)
-
 extern void dmac_map_area(const void *, size_t, int);
 extern void dmac_unmap_area(const void *, size_t, int);
 extern void dmac_flush_range(const void *, const void *);
diff --git a/arch/arm/include/asm/cpu-multi32.h b/arch/arm/include/asm/cpu-multi32.h
deleted file mode 100644 (file)
index e2b5b0b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  arch/arm/include/asm/cpu-multi32.h
- *
- *  Copyright (C) 2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <asm/page.h>
-
-struct mm_struct;
-
-/*
- * Don't change this structure - ASM code
- * relies on it.
- */
-extern struct processor {
-       /* MISC
-        * get data abort address/flags
-        */
-       void (*_data_abort)(unsigned long pc);
-       /*
-        * Retrieve prefetch fault address
-        */
-       unsigned long (*_prefetch_abort)(unsigned long lr);
-       /*
-        * Set up any processor specifics
-        */
-       void (*_proc_init)(void);
-       /*
-        * Disable any processor specifics
-        */
-       void (*_proc_fin)(void);
-       /*
-        * Special stuff for a reset
-        */
-       void (*reset)(unsigned long addr) __attribute__((noreturn));
-       /*
-        * Idle the processor
-        */
-       int (*_do_idle)(void);
-       /*
-        * Processor architecture specific
-        */
-       /*
-        * clean a virtual address range from the
-        * D-cache without flushing the cache.
-        */
-       void (*dcache_clean_area)(void *addr, int size);
-
-       /*
-        * Set the page table
-        */
-       void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
-       /*
-        * Set a possibly extended PTE.  Non-extended PTEs should
-        * ignore 'ext'.
-        */
-       void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
-} processor;
-
-#define cpu_proc_init()                        processor._proc_init()
-#define cpu_proc_fin()                 processor._proc_fin()
-#define cpu_reset(addr)                        processor.reset(addr)
-#define cpu_do_idle()                  processor._do_idle()
-#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
-#define cpu_set_pte_ext(ptep,pte,ext)  processor.set_pte_ext(ptep,pte,ext)
-#define cpu_do_switch_mm(pgd,mm)       processor.switch_mm(pgd,mm)
diff --git a/arch/arm/include/asm/cpu-single.h b/arch/arm/include/asm/cpu-single.h
deleted file mode 100644 (file)
index f073a6d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  arch/arm/include/asm/cpu-single.h
- *
- *  Copyright (C) 2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-/*
- * Single CPU
- */
-#ifdef __STDC__
-#define __catify_fn(name,x)    name##x
-#else
-#define __catify_fn(name,x)    name/**/x
-#endif
-#define __cpu_fn(name,x)       __catify_fn(name,x)
-
-/*
- * If we are supporting multiple CPUs, then we must use a table of
- * function pointers for this lot.  Otherwise, we can optimise the
- * table away.
- */
-#define cpu_proc_init                  __cpu_fn(CPU_NAME,_proc_init)
-#define cpu_proc_fin                   __cpu_fn(CPU_NAME,_proc_fin)
-#define cpu_reset                      __cpu_fn(CPU_NAME,_reset)
-#define cpu_do_idle                    __cpu_fn(CPU_NAME,_do_idle)
-#define cpu_dcache_clean_area          __cpu_fn(CPU_NAME,_dcache_clean_area)
-#define cpu_do_switch_mm               __cpu_fn(CPU_NAME,_switch_mm)
-#define cpu_set_pte_ext                        __cpu_fn(CPU_NAME,_set_pte_ext)
-
-#include <asm/page.h>
-
-struct mm_struct;
-
-/* declare all the functions as extern */
-extern void cpu_proc_init(void);
-extern void cpu_proc_fin(void);
-extern int cpu_do_idle(void);
-extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
-extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
-extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644 (file)
index 0000000..de53547
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ * NOTE: in order for embedded literals and data to get referenced correctly,
+ * the alignment of functions must be preserved when copying.  To ensure this,
+ * the source and destination addresses for fncpy() must be aligned to a
+ * multiple of 8 bytes: you will be get a BUG() if this condition is not met.
+ * You will typically need a ".align 3" directive in the assembler where the
+ * function to be copied is defined, and ensure that your allocator for the
+ * destination buffer returns 8-byte-aligned pointers.
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Minimum alignment requirement for the source and destination addresses
+ * for function copying.
+ */
+#define FNCPY_ALIGN 8
+
+#define fncpy(dest_buf, funcp, size) ({                                        \
+       uintptr_t __funcp_address;                                      \
+       typeof(funcp) __result;                                         \
+                                                                       \
+       asm("" : "=r" (__funcp_address) : "0" (funcp));                 \
+                                                                       \
+       /*                                                              \
+        * Ensure alignment of source and destination addresses,        \
+        * disregarding the function's Thumb bit:                       \
+        */                                                             \
+       BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) ||             \
+               (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+                                                                       \
+       memcpy(dest_buf, (void const *)(__funcp_address & ~1), size);   \
+       flush_icache_range((unsigned long)(dest_buf),                   \
+               (unsigned long)(dest_buf) + (size));                    \
+                                                                       \
+       asm("" : "=r" (__result)                                        \
+               : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
+                                                                       \
+       __result;                                                       \
+})
+
+#endif /* !__ASM_FNCPY_H */
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
new file mode 100644 (file)
index 0000000..0591d35
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ *  arch/arm/include/asm/glue-cache.h
+ *
+ *  Copyright (C) 1999-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASM_GLUE_CACHE_H
+#define ASM_GLUE_CACHE_H
+
+#include <asm/glue.h>
+
+/*
+ *     Cache Model
+ *     ===========
+ */
+#undef _CACHE
+#undef MULTI_CACHE
+
+#if defined(CONFIG_CPU_CACHE_V3)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE v3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE v4
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+    defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
+    defined(CONFIG_CPU_ARM1026)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_FA526)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE fa
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM926T)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE arm926
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM940T)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE arm940
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM946E)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE arm946
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4WB)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE v4wb
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSCALE)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE xscale
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSC3)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE xsc3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_MOHAWK)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE mohawk
+# endif
+#endif
+
+#if defined(CONFIG_CPU_FEROCEON)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_V6)
+//# ifdef _CACHE
+#  define MULTI_CACHE 1
+//# else
+//#  define _CACHE v6
+//# endif
+#endif
+
+#if defined(CONFIG_CPU_V7)
+//# ifdef _CACHE
+#  define MULTI_CACHE 1
+//# else
+//#  define _CACHE v7
+//# endif
+#endif
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintainence model
+#endif
+
+#ifndef MULTI_CACHE
+#define __cpuc_flush_icache_all                __glue(_CACHE,_flush_icache_all)
+#define __cpuc_flush_kern_all          __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_user_all          __glue(_CACHE,_flush_user_cache_all)
+#define __cpuc_flush_user_range                __glue(_CACHE,_flush_user_cache_range)
+#define __cpuc_coherent_kern_range     __glue(_CACHE,_coherent_kern_range)
+#define __cpuc_coherent_user_range     __glue(_CACHE,_coherent_user_range)
+#define __cpuc_flush_dcache_area       __glue(_CACHE,_flush_kern_dcache_area)
+
+#define dmac_map_area                  __glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area                        __glue(_CACHE,_dma_unmap_area)
+#define dmac_flush_range               __glue(_CACHE,_dma_flush_range)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h
new file mode 100644 (file)
index 0000000..354d571
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  arch/arm/include/asm/glue-df.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *  Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASM_GLUE_DF_H
+#define ASM_GLUE_DF_H
+
+#include <asm/glue.h>
+
+/*
+ *     Data Abort Model
+ *     ================
+ *
+ *     We have the following to choose from:
+ *       arm6          - ARM6 style
+ *       arm7          - ARM7 style
+ *       v4_early      - ARMv4 without Thumb early abort handler
+ *       v4t_late      - ARMv4 with Thumb late abort handler
+ *       v4t_early     - ARMv4 with Thumb early abort handler
+ *       v5tej_early   - ARMv5 with Thumb and Java early abort handler
+ *       xscale        - ARMv5 with Thumb with Xscale extensions
+ *       v6_early      - ARMv6 generic early abort handler
+ *       v7_early      - ARMv7 generic early abort handler
+ */
+#undef CPU_DABORT_HANDLER
+#undef MULTI_DABORT
+
+#if defined(CONFIG_CPU_ARM610)
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER cpu_arm6_data_abort
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM710)
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER cpu_arm7_data_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_LV4T
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v4t_late_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v4_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4T
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v4t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5TJ
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v5tj_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5T
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v5t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV6
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v6_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV7
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER v7_early_abort
+# endif
+#endif
+
+#ifndef CPU_DABORT_HANDLER
+#error Unknown data abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-pf.h b/arch/arm/include/asm/glue-pf.h
new file mode 100644 (file)
index 0000000..d385f37
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  arch/arm/include/asm/glue-pf.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *  Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASM_GLUE_PF_H
+#define ASM_GLUE_PF_H
+
+#include <asm/glue.h>
+
+/*
+ *     Prefetch Abort Model
+ *     ================
+ *
+ *     We have the following to choose from:
+ *       legacy        - no IFSR, no IFAR
+ *       v6            - ARMv6: IFSR, no IFAR
+ *       v7            - ARMv7: IFSR and IFAR
+ */
+
+#undef CPU_PABORT_HANDLER
+#undef MULTI_PABORT
+
+#ifdef CONFIG_CPU_PABRT_LEGACY
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER legacy_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V6
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER v6_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V7
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER v7_pabort
+# endif
+#endif
+
+#ifndef CPU_PABORT_HANDLER
+#error Unknown prefetch abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
new file mode 100644 (file)
index 0000000..6469521
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  arch/arm/include/asm/glue-proc.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASM_GLUE_PROC_H
+#define ASM_GLUE_PROC_H
+
+#include <asm/glue.h>
+
+/*
+ * Work out if we need multiple CPU support
+ */
+#undef MULTI_CPU
+#undef CPU_NAME
+
+/*
+ * CPU_NAME - the prefix for CPU related functions
+ */
+
+#ifdef CONFIG_CPU_ARM610
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM7TDMI
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm7tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM710
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm7
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM720T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm720
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM740T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm740
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM9TDMI
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm9tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM920T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm920
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM922T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm922
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FA526
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_fa526
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm925
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm926
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM940T
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm940
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm946
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA110
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_sa110
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_sa1100
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1020
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1020e
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1022
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_arm1026
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_xscale
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_xsc3
+# endif
+#endif
+
+#ifdef CONFIG_CPU_MOHAWK
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_mohawk
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FEROCEON
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_feroceon
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V6
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V7
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v7
+# endif
+#endif
+
+#ifndef MULTI_CPU
+#define cpu_proc_init                  __glue(CPU_NAME,_proc_init)
+#define cpu_proc_fin                   __glue(CPU_NAME,_proc_fin)
+#define cpu_reset                      __glue(CPU_NAME,_reset)
+#define cpu_do_idle                    __glue(CPU_NAME,_do_idle)
+#define cpu_dcache_clean_area          __glue(CPU_NAME,_dcache_clean_area)
+#define cpu_do_switch_mm               __glue(CPU_NAME,_switch_mm)
+#define cpu_set_pte_ext                        __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size               __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend                 __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume                  __glue(CPU_NAME,_do_resume)
+#endif
+
+#endif
index 234a3fc1c78ee43357dba69b4c850aa73c819541..0ec35d1698aacb7d96203f64563ba746dfa3018b 100644 (file)
@@ -15,7 +15,6 @@
  */
 #ifdef __KERNEL__
 
-
 #ifdef __STDC__
 #define ____glue(name,fn)      name##fn
 #else
 #endif
 #define __glue(name,fn)                ____glue(name,fn)
 
-
-
-/*
- *     Data Abort Model
- *     ================
- *
- *     We have the following to choose from:
- *       arm6          - ARM6 style
- *       arm7          - ARM7 style
- *       v4_early      - ARMv4 without Thumb early abort handler
- *       v4t_late      - ARMv4 with Thumb late abort handler
- *       v4t_early     - ARMv4 with Thumb early abort handler
- *       v5tej_early   - ARMv5 with Thumb and Java early abort handler
- *       xscale        - ARMv5 with Thumb with Xscale extensions
- *       v6_early      - ARMv6 generic early abort handler
- *       v7_early      - ARMv7 generic early abort handler
- */
-#undef CPU_DABORT_HANDLER
-#undef MULTI_DABORT
-
-#if defined(CONFIG_CPU_ARM610)
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER cpu_arm6_data_abort
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM710)
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER cpu_arm7_data_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_LV4T
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v4t_late_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV4
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v4_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV4T
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v4t_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV5TJ
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v5tj_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV5T
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v5t_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV6
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v6_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV7
-# ifdef CPU_DABORT_HANDLER
-#  define MULTI_DABORT 1
-# else
-#  define CPU_DABORT_HANDLER v7_early_abort
-# endif
-#endif
-
-#ifndef CPU_DABORT_HANDLER
-#error Unknown data abort handler type
-#endif
-
-/*
- *     Prefetch Abort Model
- *     ================
- *
- *     We have the following to choose from:
- *       legacy        - no IFSR, no IFAR
- *       v6            - ARMv6: IFSR, no IFAR
- *       v7            - ARMv7: IFSR and IFAR
- */
-
-#undef CPU_PABORT_HANDLER
-#undef MULTI_PABORT
-
-#ifdef CONFIG_CPU_PABRT_LEGACY
-# ifdef CPU_PABORT_HANDLER
-#  define MULTI_PABORT 1
-# else
-#  define CPU_PABORT_HANDLER legacy_pabort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_PABRT_V6
-# ifdef CPU_PABORT_HANDLER
-#  define MULTI_PABORT 1
-# else
-#  define CPU_PABORT_HANDLER v6_pabort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_PABRT_V7
-# ifdef CPU_PABORT_HANDLER
-#  define MULTI_PABORT 1
-# else
-#  define CPU_PABORT_HANDLER v7_pabort
-# endif
-#endif
-
-#ifndef CPU_PABORT_HANDLER
-#error Unknown prefetch abort handler type
-#endif
-
 #endif
index 8fdae9bc9abba945dcfb4406fae70b07ae4cf957..8ec535e11fd73c81ebdc12500c1ad24d7a9add35 100644 (file)
 
 #ifdef __KERNEL__
 
+#include <asm/glue-proc.h>
+#include <asm/page.h>
 
-/*
- * Work out if we need multiple CPU support
- */
-#undef MULTI_CPU
-#undef CPU_NAME
+#ifndef __ASSEMBLY__
+
+struct mm_struct;
 
 /*
- * CPU_NAME - the prefix for CPU related functions
+ * Don't change this structure - ASM code relies on it.
  */
-
-#ifdef CONFIG_CPU_ARM610
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm6
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM7TDMI
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm7tdmi
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM710
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm7
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM720T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm720
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM740T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm740
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM9TDMI
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm9tdmi
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM920T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm920
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM922T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm922
-# endif
-#endif
-
-#ifdef CONFIG_CPU_FA526
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_fa526
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM925T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm925
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM926T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm926
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM940T
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm940
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM946E
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm946
-# endif
-#endif
-
-#ifdef CONFIG_CPU_SA110
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_sa110
-# endif
-#endif
-
-#ifdef CONFIG_CPU_SA1100
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_sa1100
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1020
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm1020
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1020E
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm1020e
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1022
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm1022
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1026
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_arm1026
-# endif
-#endif
-
-#ifdef CONFIG_CPU_XSCALE
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_xscale
-# endif
-#endif
-
-#ifdef CONFIG_CPU_XSC3
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_xsc3
-# endif
-#endif
-
-#ifdef CONFIG_CPU_MOHAWK
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_mohawk
-# endif
-#endif
-
-#ifdef CONFIG_CPU_FEROCEON
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_feroceon
-# endif
-#endif
-
-#ifdef CONFIG_CPU_V6
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_v6
-# endif
-#endif
-
-#ifdef CONFIG_CPU_V7
-# ifdef CPU_NAME
-#  undef  MULTI_CPU
-#  define MULTI_CPU
-# else
-#  define CPU_NAME cpu_v7
-# endif
-#endif
-
-#ifndef __ASSEMBLY__
+extern struct processor {
+       /* MISC
+        * get data abort address/flags
+        */
+       void (*_data_abort)(unsigned long pc);
+       /*
+        * Retrieve prefetch fault address
+        */
+       unsigned long (*_prefetch_abort)(unsigned long lr);
+       /*
+        * Set up any processor specifics
+        */
+       void (*_proc_init)(void);
+       /*
+        * Disable any processor specifics
+        */
+       void (*_proc_fin)(void);
+       /*
+        * Special stuff for a reset
+        */
+       void (*reset)(unsigned long addr) __attribute__((noreturn));
+       /*
+        * Idle the processor
+        */
+       int (*_do_idle)(void);
+       /*
+        * Processor architecture specific
+        */
+       /*
+        * clean a virtual address range from the
+        * D-cache without flushing the cache.
+        */
+       void (*dcache_clean_area)(void *addr, int size);
+
+       /*
+        * Set the page table
+        */
+       void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+       /*
+        * Set a possibly extended PTE.  Non-extended PTEs should
+        * ignore 'ext'.
+        */
+       void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+       /* Suspend/resume */
+       unsigned int suspend_size;
+       void (*do_suspend)(void *);
+       void (*do_resume)(void *);
+} processor;
 
 #ifndef MULTI_CPU
-#include <asm/cpu-single.h>
+extern void cpu_proc_init(void);
+extern void cpu_proc_fin(void);
+extern int cpu_do_idle(void);
+extern void cpu_dcache_clean_area(void *, int);
+extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
 #else
-#include <asm/cpu-multi32.h>
+#define cpu_proc_init()                        processor._proc_init()
+#define cpu_proc_fin()                 processor._proc_fin()
+#define cpu_reset(addr)                        processor.reset(addr)
+#define cpu_do_idle()                  processor._do_idle()
+#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
+#define cpu_set_pte_ext(ptep,pte,ext)  processor.set_pte_ext(ptep,pte,ext)
+#define cpu_do_switch_mm(pgd,mm)       processor.switch_mm(pgd,mm)
 #endif
 
+extern void cpu_resume(void);
+
 #include <asm/memory.h>
 
 #ifdef CONFIG_MMU
index 67357baaeeebd93417932c70ca0d370d17818f51..7a1f03c10f1b1069d39f503f5c485e3a86b066ea 100644 (file)
@@ -95,7 +95,7 @@ extern void release_thread(struct task_struct *);
 
 unsigned long get_wchan(struct task_struct *p);
 
-#if __LINUX_ARM_ARCH__ == 6
+#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
 #define cpu_relax()                    smp_mb()
 #else
 #define cpu_relax()                    barrier()
index 2376835015d62ce991abe4aef1f5946ac19707f5..4eb6d005ffaa4b625c9f86fc8532b046d0cf1f6a 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef __ASMARM_ARCH_SCU_H
 #define __ASMARM_ARCH_SCU_H
 
+#define SCU_PM_NORMAL  0
+#define SCU_PM_DORMANT 2
+#define SCU_PM_POWEROFF        3
+
+#ifndef __ASSEMBLER__
 unsigned int scu_get_core_count(void __iomem *);
 void scu_enable(void __iomem *);
+int scu_power_mode(void __iomem *, unsigned int);
+#endif
 
 #endif
index 185ee822c9353ee203d1a8adf6d6aefce26762fa..74554f1742d72efd2c01a639e5fd0e3460221f94 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES)         += armksyms.o module.o
 obj-$(CONFIG_ARTHUR)           += arthur.o
 obj-$(CONFIG_ISA_DMA)          += dma-isa.o
 obj-$(CONFIG_PCI)              += bios32.o isa.o
+obj-$(CONFIG_PM)               += sleep.o
 obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
 obj-$(CONFIG_SMP)              += smp.o smp_tlb.o
 obj-$(CONFIG_HAVE_ARM_SCU)     += smp_scu.o
index 82da661721327c12744b58f3a7686e76f182cff3..927522cfc12e3b547783175a40c19f98ef4d7b4a 100644 (file)
@@ -13,6 +13,9 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
 #include <asm/mach/arch.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
@@ -113,6 +116,14 @@ int main(void)
 #endif
 #ifdef MULTI_PABORT
   DEFINE(PROCESSOR_PABT_FUNC,  offsetof(struct processor, _prefetch_abort));
+#endif
+#ifdef MULTI_CPU
+  DEFINE(CPU_SLEEP_SIZE,       offsetof(struct processor, suspend_size));
+  DEFINE(CPU_DO_SUSPEND,       offsetof(struct processor, do_suspend));
+  DEFINE(CPU_DO_RESUME,                offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+  DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
 #endif
   BLANK();
   DEFINE(DMA_BIDIRECTIONAL,    DMA_BIDIRECTIONAL);
index 2b46fea36c9fa30ab41c3747686d40eb2f64e67f..e8d88567680718167cf2fe389dbe4af3e0155887 100644 (file)
@@ -16,7 +16,8 @@
  */
 
 #include <asm/memory.h>
-#include <asm/glue.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
 #include <asm/vfpmacros.h>
 #include <mach/entry-macro.S>
 #include <asm/thread_notify.h>
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644 (file)
index 0000000..bfad698
--- /dev/null
@@ -0,0 +1,134 @@
+#include <linux/linkage.h>
+#include <linux/threads.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+#include <asm/system.h>
+       .text
+
+/*
+ * Save CPU state for a suspend
+ *  r1 = v:p offset
+ *  r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+       mov     r9, lr
+#ifdef MULTI_CPU
+       ldr     r10, =processor
+       mov     r2, sp                  @ current virtual SP
+       ldr     r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+       ldr     ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+       sub     sp, sp, r0              @ allocate CPU state on stack
+       mov     r0, sp                  @ save pointer
+       add     ip, ip, r1              @ convert resume fn to phys
+       stmfd   sp!, {r1, r2, r3, ip}   @ save v:p, virt SP, retfn, phys resume fn
+       ldr     r3, =sleep_save_sp
+       add     r2, sp, r1              @ convert SP to phys
+#ifdef CONFIG_SMP
+       ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+       ALT_UP(mov lr, #0)
+       and     lr, lr, #15
+       str     r2, [r3, lr, lsl #2]    @ save phys SP
+#else
+       str     r2, [r3]                @ save phys SP
+#endif
+       mov     lr, pc
+       ldr     pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+       mov     r2, sp                  @ current virtual SP
+       ldr     r0, =cpu_suspend_size
+       sub     sp, sp, r0              @ allocate CPU state on stack
+       mov     r0, sp                  @ save pointer
+       stmfd   sp!, {r1, r2, r3}       @ save v:p, virt SP, return fn
+       ldr     r3, =sleep_save_sp
+       add     r2, sp, r1              @ convert SP to phys
+#ifdef CONFIG_SMP
+       ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+       ALT_UP(mov lr, #0)
+       and     lr, lr, #15
+       str     r2, [r3, lr, lsl #2]    @ save phys SP
+#else
+       str     r2, [r3]                @ save phys SP
+#endif
+       bl      cpu_do_suspend
+#endif
+
+       @ flush data cache
+#ifdef MULTI_CACHE
+       ldr     r10, =cpu_cache
+       mov     lr, r9
+       ldr     pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+       mov     lr, r9
+       b       __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+       .ltorg
+
+/*
+ * r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
+ */
+ENTRY(cpu_resume_mmu)
+       adr     r4, cpu_resume_turn_mmu_on
+       mov     r4, r4, lsr #20
+       orr     r3, r3, r4, lsl #20
+       ldr     r5, [r2, r4, lsl #2]    @ save old mapping
+       str     r3, [r2, r4, lsl #2]    @ setup 1:1 mapping for mmu code
+       sub     r2, r2, r1
+       ldr     r3, =cpu_resume_after_mmu
+       bic     r1, r0, #CR_C           @ ensure D-cache is disabled
+       b       cpu_resume_turn_mmu_on
+ENDPROC(cpu_resume_mmu)
+       .ltorg
+       .align  5
+cpu_resume_turn_mmu_on:
+       mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
+       mrc     p15, 0, r1, c0, c0, 0   @ read id reg
+       mov     r1, r1
+       mov     r1, r1
+       mov     pc, r3                  @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
+cpu_resume_after_mmu:
+       str     r5, [r2, r4, lsl #2]    @ restore old mapping
+       mcr     p15, 0, r0, c1, c0, 0   @ turn on D-cache
+       mov     pc, lr
+ENDPROC(cpu_resume_after_mmu)
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on it to be truly read-only.
+ */
+       .data
+       .align
+ENTRY(cpu_resume)
+#ifdef CONFIG_SMP
+       adr     r0, sleep_save_sp
+       ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
+       ALT_UP(mov r1, #0)
+       and     r1, r1, #15
+       ldr     r0, [r0, r1, lsl #2]    @ stack phys addr
+#else
+       ldr     r0, sleep_save_sp       @ stack phys addr
+#endif
+       msr     cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+#ifdef MULTI_CPU
+       ldmia   r0!, {r1, sp, lr, pc}   @ load v:p, stack, return fn, resume fn
+#else
+       ldmia   r0!, {r1, sp, lr}       @ load v:p, stack, return fn
+       b       cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+       .rept   CONFIG_NR_CPUS
+       .long   0                               @ preserve stack phys ptr here
+       .endr
index 9ab4149bd9830883f88d2b1d20739c981a344551..a1e757c3439bcb8155f5f93f940788854fd364d0 100644 (file)
@@ -50,3 +50,26 @@ void __init scu_enable(void __iomem *scu_base)
         */
        flush_cache_all();
 }
+
+/*
+ * Set the executing CPUs power mode as defined.  This will be in
+ * preparation for it executing a WFI instruction.
+ *
+ * This function must be called with preemption disabled, and as it
+ * has the side effect of disabling coherency, caches must have been
+ * flushed.  Interrupts must also have been disabled.
+ */
+int scu_power_mode(void __iomem *scu_base, unsigned int mode)
+{
+       unsigned int val;
+       int cpu = smp_processor_id();
+
+       if (mode > 3 || mode == 1 || cpu > 3)
+               return -EINVAL;
+
+       val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
+       val |= mode;
+       __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
+
+       return 0;
+}
index 0a99b3cedd7a433b44bb0b0177aa4b5742017307..17f7d9b32142d73984f60cc554c874865a385e17 100644 (file)
@@ -153,6 +153,7 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
        {
                /* RTC */
                I2C_BOARD_INFO("isl1208", 0x6f),
+               .irq = gpio_to_irq(AT91_PIN_PA31),
        },
 };
 
index bfdd8ab26dc8a2399a379058df2e9a04f41c2888..ddeb6453675692d8dc3831920d5e96f8b7961e9c 100644 (file)
@@ -220,15 +220,8 @@ extern void at91_gpio_resume(void);
 #define gpio_set_value __gpio_set_value
 #define gpio_cansleep  __gpio_cansleep
 
-static inline int gpio_to_irq(unsigned gpio)
-{
-       return gpio;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-       return irq;
-}
+#define gpio_to_irq(gpio) (gpio)
+#define irq_to_gpio(irq)  (irq)
 
 #endif /* __ASSEMBLY__ */
 
index 4b04316521318fb025c0821c9b4c63f52ae60f72..9969bb115f602d915330b0ebdca3c683862d7269 100644 (file)
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+
+#include <sound/cs4271.h>
 
 #include <mach/hardware.h>
+#include <mach/fb.h>
+#include <mach/ep93xx_spi.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -92,6 +97,83 @@ static void __init edb93xx_register_i2c(void)
 }
 
 
+/*************************************************************************
+ * EDB93xx SPI peripheral handling
+ *************************************************************************/
+static struct cs4271_platform_data edb93xx_cs4271_data = {
+       .gpio_nreset    = -EINVAL,      /* filled in later */
+};
+
+static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
+{
+       return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
+                               GPIOF_OUT_INIT_HIGH, spi->modalias);
+}
+
+static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
+{
+       gpio_free(EP93XX_GPIO_LINE_EGPIO6);
+}
+
+static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
+{
+       gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
+}
+
+static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
+       .setup          = edb93xx_cs4271_hw_setup,
+       .cleanup        = edb93xx_cs4271_hw_cleanup,
+       .cs_control     = edb93xx_cs4271_hw_cs_control,
+};
+
+static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
+       {
+               .modalias               = "cs4271",
+               .platform_data          = &edb93xx_cs4271_data,
+               .controller_data        = &edb93xx_cs4271_hw,
+               .max_speed_hz           = 6000000,
+               .bus_num                = 0,
+               .chip_select            = 0,
+               .mode                   = SPI_MODE_3,
+       },
+};
+
+static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
+       .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info),
+};
+
+static void __init edb93xx_register_spi(void)
+{
+       if (machine_is_edb9301() || machine_is_edb9302())
+               edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
+       else if (machine_is_edb9302a() || machine_is_edb9307a())
+               edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
+       else if (machine_is_edb9315a())
+               edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
+
+       ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
+                           ARRAY_SIZE(edb93xx_spi_board_info));
+}
+
+
+/*************************************************************************
+ * EDB93xx I2S
+ *************************************************************************/
+static int __init edb93xx_has_audio(void)
+{
+       return (machine_is_edb9301() || machine_is_edb9302() ||
+               machine_is_edb9302a() || machine_is_edb9307a() ||
+               machine_is_edb9315a());
+}
+
+static void __init edb93xx_register_i2s(void)
+{
+       if (edb93xx_has_audio()) {
+               ep93xx_register_i2s();
+       }
+}
+
+
 /*************************************************************************
  * EDB93xx pwm
  *************************************************************************/
@@ -111,13 +193,47 @@ static void __init edb93xx_register_pwm(void)
 }
 
 
+/*************************************************************************
+ * EDB93xx framebuffer
+ *************************************************************************/
+static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
+       .num_modes      = EP93XXFB_USE_MODEDB,
+       .bpp            = 16,
+       .flags          = 0,
+};
+
+static int __init edb93xx_has_fb(void)
+{
+       /* These platforms have an ep93xx with video capability */
+       return machine_is_edb9307() || machine_is_edb9307a() ||
+              machine_is_edb9312() || machine_is_edb9315() ||
+              machine_is_edb9315a();
+}
+
+static void __init edb93xx_register_fb(void)
+{
+       if (!edb93xx_has_fb())
+               return;
+
+       if (machine_is_edb9307a() || machine_is_edb9315a())
+               edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
+       else
+               edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
+
+       ep93xx_register_fb(&edb93xxfb_info);
+}
+
+
 static void __init edb93xx_init_machine(void)
 {
        ep93xx_init_devices();
        edb93xx_register_flash();
        ep93xx_register_eth(&edb93xx_eth_data, 1);
        edb93xx_register_i2c();
+       edb93xx_register_spi();
+       edb93xx_register_i2s();
        edb93xx_register_pwm();
+       edb93xx_register_fb();
 }
 
 
index bec34b83495870057d686573df9bbfd69865be76..a889fa7c3ba19952b80f189727779c1aa35a4acf 100644 (file)
@@ -61,7 +61,7 @@ static inline void ep93xx_gpio_int_mask(unsigned line)
        gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 }
 
-void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
+static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
 {
        int line = irq_to_gpio(irq);
        int port = line >> 3;
@@ -75,7 +75,6 @@ void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
        __raw_writeb(gpio_int_debounce[port],
                EP93XX_GPIO_REG(int_debounce_register_offset[port]));
 }
-EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
 
 static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
@@ -335,6 +334,20 @@ static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
        local_irq_restore(flags);
 }
 
+static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
+                                   unsigned offset, unsigned debounce)
+{
+       int gpio = chip->base + offset;
+       int irq = gpio_to_irq(gpio);
+
+       if (irq < 0)
+               return -EINVAL;
+
+       ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+
+       return 0;
+}
+
 static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
        struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
@@ -434,6 +447,18 @@ void __init ep93xx_gpio_init(void)
                                 EP93XX_SYSCON_DEVCFG_GONIDE |
                                 EP93XX_SYSCON_DEVCFG_HONIDE);
 
-       for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++)
-               gpiochip_add(&ep93xx_gpio_banks[i].chip);
+       for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
+               struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
+
+               /*
+                * Ports A, B, and F support input debouncing when
+                * used as interrupts.
+                */
+               if (!strcmp(chip->label, "A") ||
+                   !strcmp(chip->label, "B") ||
+                   !strcmp(chip->label, "F"))
+                       chip->set_debounce = ep93xx_gpio_set_debounce;
+
+               gpiochip_add(chip);
+       }
 }
index c991b149bdf2bfe804337fccc1fca357213ff713..c57152c231f16a474442c0d65cefc2e9de8342cb 100644 (file)
@@ -99,8 +99,6 @@
 /* maximum value for irq capable line identifiers */
 #define EP93XX_GPIO_LINE_MAX_IRQ       EP93XX_GPIO_LINE_F(7)
 
-extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
-
 /* new generic GPIO API - see Documentation/gpio.txt */
 
 #include <asm-generic/gpio.h>
index bc5e83fb5819edacfc17c1315a16028b3dd4cc8c..a921fe92b858c730d5c5669602b8aa58f435f588 100644 (file)
@@ -4,10 +4,11 @@
  *  Copyright (C) 1998 Russell King.
  *  Copyright (C) 1998 Phil Blundell
  */
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/spinlock.h>
 
 #include <asm/irq.h>
 
 
 #include "common.h"
 
-/*
- * Footbridge timer 1 support.
- */
-static unsigned long timer1_latch;
+static cycle_t cksrc_dc21285_read(struct clocksource *cs)
+{
+       return cs->mask - *CSR_TIMER2_VALUE;
+}
 
-static unsigned long timer1_gettimeoffset (void)
+static int cksrc_dc21285_enable(struct clocksource *cs)
 {
-       unsigned long value = timer1_latch - *CSR_TIMER1_VALUE;
+       *CSR_TIMER2_LOAD = cs->mask;
+       *CSR_TIMER2_CLR = 0;
+       *CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
+       return 0;
+}
 
-       return ((tick_nsec / 1000) * value) / timer1_latch;
+static int cksrc_dc21285_disable(struct clocksource *cs)
+{
+       *CSR_TIMER2_CNTL = 0;
 }
 
-static irqreturn_t
-timer1_interrupt(int irq, void *dev_id)
+static struct clocksource cksrc_dc21285 = {
+       .name           = "dc21285_timer2",
+       .rating         = 200,
+       .read           = cksrc_dc21285_read,
+       .enable         = cksrc_dc21285_enable,
+       .disable        = cksrc_dc21285_disable,
+       .mask           = CLOCKSOURCE_MASK(24),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
+       struct clock_event_device *c)
 {
+       switch (mode) {
+       case CLOCK_EVT_MODE_RESUME:
+       case CLOCK_EVT_MODE_PERIODIC:
+               *CSR_TIMER1_CLR = 0;
+               *CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
+               *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
+                                  TIMER_CNTL_DIV16;
+               break;
+
+       default:
+               *CSR_TIMER1_CNTL = 0;
+               break;
+       }
+}
+
+static struct clock_event_device ckevt_dc21285 = {
+       .name           = "dc21285_timer1",
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .rating         = 200,
+       .irq            = IRQ_TIMER1,
+       .set_mode       = ckevt_dc21285_set_mode,
+};
+
+static irqreturn_t timer1_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *ce = dev_id;
+
        *CSR_TIMER1_CLR = 0;
 
-       timer_tick();
+       ce->event_handler(ce);
 
        return IRQ_HANDLED;
 }
 
 static struct irqaction footbridge_timer_irq = {
-       .name           = "Timer1 timer tick",
+       .name           = "dc21285_timer1",
        .handler        = timer1_interrupt,
        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .dev_id         = &ckevt_dc21285,
 };
 
 /*
@@ -49,16 +94,19 @@ static struct irqaction footbridge_timer_irq = {
  */
 static void __init footbridge_timer_init(void)
 {
-       timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
+       struct clock_event_device *ce = &ckevt_dc21285;
+
+       clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16);
+
+       setup_irq(ce->irq, &footbridge_timer_irq);
 
-       *CSR_TIMER1_CLR  = 0;
-       *CSR_TIMER1_LOAD = timer1_latch;
-       *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+       clockevents_calc_mult_shift(ce, mem_fclk_21285, 5);
+       ce->max_delta_ns = clockevent_delta2ns(0xffffff, ce);
+       ce->min_delta_ns = clockevent_delta2ns(0x000004, ce);
 
-       setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
+       clockevents_register_device(ce);
 }
 
 struct sys_timer footbridge_timer = {
        .init           = footbridge_timer_init,
-       .offset         = timer1_gettimeoffset,
 };
index f488fa2082d76c07e51c890bb81856cb69b1618f..441c6ce0d555afe96ff8eaf1ddd7815846b71b33 100644 (file)
@@ -4,10 +4,13 @@
  *  Copyright (C) 1998 Russell King.
  *  Copyright (C) 1998 Phil Blundell
  */
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/timex.h>
 
 #include <asm/irq.h>
 
 
 #include "common.h"
 
-/*
- * ISA timer tick support
- */
-#define mSEC_10_from_14 ((14318180 + 100) / 200)
+#define PIT_MODE       0x43
+#define PIT_CH0                0x40
+
+#define PIT_LATCH      ((PIT_TICK_RATE + HZ / 2) / HZ)
 
-static unsigned long isa_gettimeoffset(void)
+static cycle_t pit_read(struct clocksource *cs)
 {
+       unsigned long flags;
+       static int old_count;
+       static u32 old_jifs;
        int count;
+       u32 jifs;
 
-       static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
-       static unsigned long jiffies_p = 0;
+       raw_local_irq_save(flags);
 
-       /*
-        * cache volatile jiffies temporarily; we have IRQs turned off. 
-        */
-       unsigned long jiffies_t;
+       jifs = jiffies;
+       outb_p(0x00, PIT_MODE);         /* latch the count */
+       count = inb_p(PIT_CH0);         /* read the latched count */
+       count |= inb_p(PIT_CH0) << 8;
 
-       /* timer count may underflow right here */
-       outb_p(0x00, 0x43);     /* latch the count ASAP */
+       if (count > old_count && jifs == old_jifs)
+               count = old_count;
 
-       count = inb_p(0x40);    /* read the latched count */
+       old_count = count;
+       old_jifs = jifs;
 
-       /*
-        * We do this guaranteed double memory access instead of a _p 
-        * postfix in the previous port access. Wheee, hackady hack
-        */
-       jiffies_t = jiffies;
+       raw_local_irq_restore(flags);
 
-       count |= inb_p(0x40) << 8;
+       count = (PIT_LATCH - 1) - count;
 
-       /* Detect timer underflows.  If we haven't had a timer tick since 
-          the last time we were called, and time is apparently going
-          backwards, the counter must have wrapped during this routine. */
-       if ((jiffies_t == jiffies_p) && (count > count_p))
-               count -= (mSEC_10_from_14/6);
-       else
-               jiffies_p = jiffies_t;
+       return (cycle_t)(jifs * PIT_LATCH) + count;
+}
 
-       count_p = count;
+static struct clocksource pit_cs = {
+       .name           = "pit",
+       .rating         = 110,
+       .read           = pit_read,
+       .mask           = CLOCKSOURCE_MASK(32),
+};
 
-       count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000);
-       count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
+static void pit_set_mode(enum clock_event_mode mode,
+       struct clock_event_device *evt)
+{
+       unsigned long flags;
+
+       raw_local_irq_save(flags);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               outb_p(0x34, PIT_MODE);
+               outb_p(PIT_LATCH & 0xff, PIT_CH0);
+               outb_p(PIT_LATCH >> 8, PIT_CH0);
+               break;
+
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+               outb_p(0x30, PIT_MODE);
+               outb_p(0, PIT_CH0);
+               outb_p(0, PIT_CH0);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+       local_irq_restore(flags);
+}
 
-       return count;
+static int pit_set_next_event(unsigned long delta,
+       struct clock_event_device *evt)
+{
+       return 0;
 }
 
-static irqreturn_t
-isa_timer_interrupt(int irq, void *dev_id)
+static struct clock_event_device pit_ce = {
+       .name           = "pit",
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .set_mode       = pit_set_mode,
+       .set_next_event = pit_set_next_event,
+       .shift          = 32,
+};
+
+static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
 {
-       timer_tick();
+       struct clock_event_device *ce = dev_id;
+       ce->event_handler(ce);
        return IRQ_HANDLED;
 }
 
-static struct irqaction isa_timer_irq = {
-       .name           = "ISA timer tick",
-       .handler        = isa_timer_interrupt,
+static struct irqaction pit_timer_irq = {
+       .name           = "pit",
+       .handler        = pit_timer_interrupt,
        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .dev_id         = &pit_ce,
 };
 
 static void __init isa_timer_init(void)
 {
-       /* enable PIT timer */
-       /* set for periodic (4) and LSB/MSB write (0x30) */
-       outb(0x34, 0x43);
-       outb((mSEC_10_from_14/6) & 0xFF, 0x40);
-       outb((mSEC_10_from_14/6) >> 8, 0x40);
+       pit_ce.cpumask = cpumask_of(smp_processor_id());
+       pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
+       pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
+       pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
+
+       clocksource_register_hz(&pit_cs, PIT_TICK_RATE);
 
-       setup_irq(IRQ_ISA_TIMER, &isa_timer_irq);
+       setup_irq(pit_ce.irq, &pit_timer_irq);
+       clockevents_register_device(&pit_ce);
 }
 
 struct sys_timer isa_timer = {
        .init           = isa_timer_init,
-       .offset         = isa_gettimeoffset,
 };
index 2ba096de00348e2be706127107eb2b845d2e83a1..0cf7a07c3f3f88f7309498b340a7603d0f8bd5f7 100644 (file)
@@ -98,6 +98,7 @@ static void __init ib4220b_init(void)
        platform_register_pflash(SZ_16M, NULL, 0);
        platform_device_register(&ib4220b_led_device);
        platform_device_register(&ib4220b_key_device);
+       platform_register_rtc();
 }
 
 MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B")
index a9a0d8b0194296ab86072eb150fac5db5782af0e..4fa09af99495be2b48ad3dd1c73268849ef5e550 100644 (file)
@@ -82,6 +82,7 @@ static void __init rut1xx_init(void)
        platform_register_pflash(SZ_8M, NULL, 0);
        platform_device_register(&rut1xx_leds);
        platform_device_register(&rut1xx_keys_device);
+       platform_register_rtc();
 }
 
 MACHINE_START(RUT100, "Teltonika RUT100")
index 8b88d50d4337db51378737a70bfd4bc2959b7b3b..af7b68a6b2589385ae2996afb7f5da7645278608 100644 (file)
@@ -130,6 +130,7 @@ static void __init wbd111_init(void)
                                 wbd111_num_partitions);
        platform_device_register(&wbd111_leds_device);
        platform_device_register(&wbd111_keys_device);
+       platform_register_rtc();
 }
 
 MACHINE_START(WBD111, "Wiliboard WBD-111")
index 1eebcecd1c3312109213aba372cd915a2525961b..99e5bbecf923afd6a1c173308cfd6f6a6741e09a 100644 (file)
@@ -130,6 +130,7 @@ static void __init wbd222_init(void)
                wbd222_num_partitions);
        platform_device_register(&wbd222_leds_device);
        platform_device_register(&wbd222_keys_device);
+       platform_register_rtc();
 }
 
 MACHINE_START(WBD222, "Wiliboard WBD-222")
index 9392834a214f8b58e62f4e2bb83401129273f964..7670c39acb2f9f3463ccd678c675de4b84c27dba 100644 (file)
@@ -18,6 +18,7 @@ extern void gemini_map_io(void);
 extern void gemini_init_irq(void);
 extern void gemini_timer_init(void);
 extern void gemini_gpio_init(void);
+extern void platform_register_rtc(void);
 
 /* Common platform devices registration functions */
 extern int platform_register_uart(void);
index 6b525253d027293b7c5eca3a19cc205ce7faed67..5cff29818b7359d1e8dfaff33bfb8ed96bc28cfb 100644 (file)
@@ -90,3 +90,29 @@ int platform_register_pflash(unsigned int size, struct mtd_partition *parts,
 
        return platform_device_register(&pflash_device);
 }
+
+static struct resource gemini_rtc_resources[] = {
+       [0] = {
+               .start  = GEMINI_RTC_BASE,
+               .end    = GEMINI_RTC_BASE + 0x24,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_RTC,
+               .end    = IRQ_RTC,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device gemini_rtc_device = {
+       .name           = "rtc-gemini",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(gemini_rtc_resources),
+       .resource       = gemini_rtc_resources,
+};
+
+int __init platform_register_rtc(void)
+{
+       return platform_device_register(&gemini_rtc_device);
+}
+
index cb0c0e83a527a8d5367e0f2b0ca376d5f86a674f..61991e4dde44226810aa848d4228db0a0dc173ee 100644 (file)
@@ -68,29 +68,29 @@ static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
        }
 }
 
-static void mxs_gpio_ack_irq(u32 irq)
+static void mxs_gpio_ack_irq(struct irq_data *d)
 {
-       u32 gpio = irq_to_gpio(irq);
+       u32 gpio = irq_to_gpio(d->irq);
        clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
 }
 
-static void mxs_gpio_mask_irq(u32 irq)
+static void mxs_gpio_mask_irq(struct irq_data *d)
 {
-       u32 gpio = irq_to_gpio(irq);
+       u32 gpio = irq_to_gpio(d->irq);
        set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
 }
 
-static void mxs_gpio_unmask_irq(u32 irq)
+static void mxs_gpio_unmask_irq(struct irq_data *d)
 {
-       u32 gpio = irq_to_gpio(irq);
+       u32 gpio = irq_to_gpio(d->irq);
        set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
 }
 
 static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
 
-static int mxs_gpio_set_irq_type(u32 irq, u32 type)
+static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
 {
-       u32 gpio = irq_to_gpio(irq);
+       u32 gpio = irq_to_gpio(d->irq);
        u32 pin_mask = 1 << (gpio & 31);
        struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
        void __iomem *pin_addr;
@@ -160,9 +160,9 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
  * @param  enable       enable as wake-up if equal to non-zero
  * @return       This function returns 0 on success.
  */
-static int mxs_gpio_set_wake_irq(u32 irq, u32 enable)
+static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
 {
-       u32 gpio = irq_to_gpio(irq);
+       u32 gpio = irq_to_gpio(d->irq);
        u32 gpio_idx = gpio & 0x1f;
        struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
 
@@ -182,11 +182,11 @@ static int mxs_gpio_set_wake_irq(u32 irq, u32 enable)
 }
 
 static struct irq_chip gpio_irq_chip = {
-       .ack = mxs_gpio_ack_irq,
-       .mask = mxs_gpio_mask_irq,
-       .unmask = mxs_gpio_unmask_irq,
-       .set_type = mxs_gpio_set_irq_type,
-       .set_wake = mxs_gpio_set_wake_irq,
+       .irq_ack = mxs_gpio_ack_irq,
+       .irq_mask = mxs_gpio_mask_irq,
+       .irq_unmask = mxs_gpio_unmask_irq,
+       .irq_set_type = mxs_gpio_set_irq_type,
+       .irq_set_wake = mxs_gpio_set_wake_irq,
 };
 
 static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
index 5dd43ba70058647a18ee7141c1e2791a4ce53421..0f4c120fc169f0098710ac8ce433046f32563258 100644 (file)
@@ -34,7 +34,7 @@
 
 static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
 
-static void icoll_ack_irq(unsigned int irq)
+static void icoll_ack_irq(struct irq_data *d)
 {
        /*
         * The Interrupt Collector is able to prioritize irqs.
@@ -45,22 +45,22 @@ static void icoll_ack_irq(unsigned int irq)
                        icoll_base + HW_ICOLL_LEVELACK);
 }
 
-static void icoll_mask_irq(unsigned int irq)
+static void icoll_mask_irq(struct irq_data *d)
 {
        __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-                       icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+                       icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->irq));
 }
 
-static void icoll_unmask_irq(unsigned int irq)
+static void icoll_unmask_irq(struct irq_data *d)
 {
        __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-                       icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+                       icoll_base + HW_ICOLL_INTERRUPTn_SET(d->irq));
 }
 
 static struct irq_chip mxs_icoll_chip = {
-       .ack = icoll_ack_irq,
-       .mask = icoll_mask_irq,
-       .unmask = icoll_unmask_irq,
+       .irq_ack = icoll_ack_irq,
+       .irq_mask = icoll_mask_irq,
+       .irq_unmask = icoll_unmask_irq,
 };
 
 void __init icoll_init_irq(void)
index 56a647986ae95c53b7288f7a1bbe2623c3c7bdb1..cd926dcb5e7fbd93f823639f5c2869073ea92bea 100644 (file)
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 extern void omap1_pm_idle(void);
 extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 extern void omap7xx_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
index ef771ce8b030bf03b6b077c3b0f56dca24cc5a36..c875bdc902c556d1414fbfe8e33c8d932e203d1a 100644 (file)
@@ -58,6 +58,7 @@
  */
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+       .align  3
 ENTRY(omap7xx_cpu_suspend)
 
        @ save registers on stack
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #ifdef CONFIG_ARCH_OMAP15XX
+       .align  3
 ENTRY(omap1510_cpu_suspend)
 
        @ save registers on stack
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP15XX */
 
 #if defined(CONFIG_ARCH_OMAP16XX)
+       .align  3
 ENTRY(omap1610_cpu_suspend)
 
        @ save registers on stack
index 7724e520d07c5c648b982418177d18a8a54e3c65..692587d07ea5c8e2b2795872bc4f4c30166cb6b7 100644 (file)
@@ -18,6 +18,7 @@
 /*
  * Reprograms ULPD and CKCTL.
  */
+       .align  3
 ENTRY(omap1_sram_reprogram_clock)
        stmfd   sp!, {r0 - r12, lr}             @ save registers on stack
 
index 1c1b0ab5b97877695b00a71506d97850a679a410..39580e6060e884469b33d9743c92d987511ddd31 100644 (file)
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
                                        void __iomem *sdrc_power);
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
index c7780cc8d919f3ef685abafca350b16f80e75d10..b5071a47ec395d2619f432eef9226b44a17a8bf7 100644 (file)
@@ -47,6 +47,7 @@
  * Note: This code get's copied to internal SRAM at boot. When the OMAP
  *      wakes up it continues execution at the point it went to sleep.
  */
+       .align  3
 ENTRY(omap24xx_idle_loop_suspend)
        stmfd   sp!, {r0, lr}           @ save registers on stack
        mov     r0, #0                  @ clear for mcr setup
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
  * The DLL load value is not kept in RETENTION or OFF. It needs to be restored
  * at wake
  */
+       .align  3
 ENTRY(omap24xx_cpu_suspend)
        stmfd   sp!, {r0 - r12, lr}     @ save registers on stack
        mov     r3, #0x0                @ clear for mcr call
index 98d8232808b8bf8becddc6a7d047d581c59fadf8..951a0be66cf7928062ee76ef58c53fc86419c239 100644 (file)
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 
        .text
 /* Function to call rom code to save secure ram context */
+       .align  3
 ENTRY(save_secure_ram_context)
        stmfd   sp!, {r1-r12, lr}       @ save registers on stack
        adr     r3, api_params          @ r3 points to parameters
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
  *   depending on the low power mode (non-OFF vs OFF modes),
  *   cf. 'Resume path for xxx mode' comments.
  */
+       .align  3
 ENTRY(omap34xx_cpu_suspend)
        stmfd   sp!, {r0-r12, lr}       @ save registers on stack
 
index 055310cc77decbbd2c454ec08d40dbc0323e643c..ff9b9dbcb30efa9e2a10707b7247646261b40524 100644 (file)
@@ -39,6 +39,7 @@
 
        .text
 
+       .align  3
 ENTRY(omap242x_sram_ddr_init)
        stmfd   sp!, {r0 - r12, lr}     @ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+       .align  3
 ENTRY(omap242x_sram_reprogram_sdrc)
        stmfd   sp!, {r0 - r10, lr}     @ save registers on stack
        mov     r3, #0x0                @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+       .align  3
 ENTRY(omap242x_sram_set_prcm)
        stmfd   sp!, {r0-r12, lr}       @ regs to stack
        adr     r4, pbegin              @ addr of preload start
index f9007580aea344c2f264ae55fde119b187f68b0f..76730209fa0e4ed29820d9608eea2bdab643c04c 100644 (file)
@@ -39,6 +39,7 @@
 
        .text
 
+       .align  3
 ENTRY(omap243x_sram_ddr_init)
        stmfd   sp!, {r0 - r12, lr}     @ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+       .align  3
 ENTRY(omap243x_sram_reprogram_sdrc)
        stmfd   sp!, {r0 - r10, lr}     @ save registers on stack
        mov     r3, #0x0                @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+       .align  3
 ENTRY(omap243x_sram_set_prcm)
        stmfd   sp!, {r0-r12, lr}       @ regs to stack
        adr     r4, pbegin              @ addr of preload start
index 7f893a29d5005052d60c0493c5a37960b71b0ce2..25011ca2145d6abba4d98e4cc441f061c2f9d91c 100644 (file)
  * since it will cause the ARM MMU to attempt to walk the page tables.
  * These crashes may be intermittent.
  */
+       .align  3
 ENTRY(omap3_sram_configure_core_dpll)
        stmfd   sp!, {r1-r12, lr}       @ store regs to stack
 
index fd8360c6839d5a69d9faa44fa3bb77c3edb0dc06..f15afe012995d386f8d9046a1dbfd48ce1267b9e 100644 (file)
@@ -22,9 +22,8 @@ struct pxa_cpu_pm_fns {
 extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
 
 /* sleep.S */
-extern void pxa25x_cpu_suspend(unsigned int);
-extern void pxa27x_cpu_suspend(unsigned int);
-extern void pxa_cpu_resume(void);
+extern void pxa25x_cpu_suspend(unsigned int, long);
+extern void pxa27x_cpu_suspend(unsigned int, long);
 
 extern int pxa_pm_enter(suspend_state_t state);
 extern int pxa_pm_prepare(void);
index 7bf4017326e3d8851615b0a51051c8d74b3c6c73..3010193b081e2f14478119be08a8dac42f809f27 100644 (file)
@@ -212,7 +212,7 @@ static unsigned long store_ptr;
 static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
 {
        /* setup the resume_info struct for the original bootloader */
-       palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume;
+       palmz72_resume_info.resume_addr = (u32) cpu_resume;
 
        /* Storing memory touched by ROM */
        store_ptr = *PALMZ72_SAVE_DWORD;
index 1807c9abdde0e2dc201abb8dc4c3caa9b0246b6b..51e1583265b26e6c834dbd02c914ed2fdb2d24a9 100644 (file)
@@ -67,11 +67,6 @@ int pxa_pm_enter(suspend_state_t state)
 
 EXPORT_SYMBOL_GPL(pxa_pm_enter);
 
-unsigned long sleep_phys_sp(void *sp)
-{
-       return virt_to_phys(sp);
-}
-
 static int pxa_pm_valid(suspend_state_t state)
 {
        if (pxa_cpu_pm_fns)
index b166b1d845d76cbc6b8039336bc955344f362f48..6bde5956358d88ceef7c23641bb92c77e3a44154 100644 (file)
@@ -244,7 +244,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
 
        switch (state) {
        case PM_SUSPEND_MEM:
-               pxa25x_cpu_suspend(PWRMODE_SLEEP);
+               pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
                break;
        }
 }
@@ -252,7 +252,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
 static int pxa25x_cpu_pm_prepare(void)
 {
        /* set resume return address */
-       PSPR = virt_to_phys(pxa_cpu_resume);
+       PSPR = virt_to_phys(cpu_resume);
        return 0;
 }
 
index 987301ff4c33af17ac18c21fa9e24b77917976e4..28b11be00b3f84b8e5efbe16878f8c3827c80bd7 100644 (file)
@@ -300,7 +300,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
                pxa_cpu_standby();
                break;
        case PM_SUSPEND_MEM:
-               pxa27x_cpu_suspend(pwrmode);
+               pxa27x_cpu_suspend(pwrmode, PLAT_PHYS_OFFSET - PAGE_OFFSET);
                break;
        }
 }
@@ -313,7 +313,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
 static int pxa27x_cpu_pm_prepare(void)
 {
        /* set resume return address */
-       PSPR = virt_to_phys(pxa_cpu_resume);
+       PSPR = virt_to_phys(cpu_resume);
        return 0;
 }
 
index a7a19e1cd640f5987b0eafdeb1e8dc0921f8bebd..1230343d9c70d828f69ef004a17c93dbe2af7a90 100644 (file)
@@ -142,8 +142,7 @@ static void pxa3xx_cpu_pm_suspend(void)
        volatile unsigned long *p = (volatile void *)0xc0000000;
        unsigned long saved_data = *p;
 
-       extern void pxa3xx_cpu_suspend(void);
-       extern void pxa3xx_cpu_resume(void);
+       extern void pxa3xx_cpu_suspend(long);
 
        /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */
        CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM);
@@ -161,9 +160,9 @@ static void pxa3xx_cpu_pm_suspend(void)
        PSPR = 0x5c014000;
 
        /* overwrite with the resume address */
-       *p = virt_to_phys(pxa3xx_cpu_resume);
+       *p = virt_to_phys(cpu_resume);
 
-       pxa3xx_cpu_suspend();
+       pxa3xx_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
 
        *p = saved_data;
 
index c551da86baf60b1b10bddb6f021a53de3ae82b24..6f5368899d84f595d052b4bf9068ad1cf9662889 100644 (file)
 
                .text
 
-pxa_cpu_save_cp:
-       @ get coprocessor registers
-       mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
-       mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
-       mrc     p15, 0, r5, c13, c0, 0          @ PID
-       mrc     p15, 0, r6, c3, c0, 0           @ domain ID
-       mrc     p15, 0, r7, c2, c0, 0           @ translation table base addr
-       mrc     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
-       mrc     p15, 0, r9, c1, c0, 0           @ control reg
-
-       bic     r3, r3, #2                      @ clear frequency change bit
-
-       @ store them plus current virtual stack ptr on stack
-       mov     r10, sp
-       stmfd   sp!, {r3 - r10}
-
-       mov     pc, lr
-
-pxa_cpu_save_sp:
-       @ preserve phys address of stack
-       mov     r0, sp
-       str     lr, [sp, #-4]!
-       bl      sleep_phys_sp
-       ldr     r1, =sleep_save_sp
-       str     r0, [r1]
-       ldr     pc, [sp], #4
-
 #ifdef CONFIG_PXA3xx
 /*
  * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
  *
- * NOTE:  unfortunately, pxa_cpu_save_cp can not be reused here since
- * the auxiliary control register address is different between pxa3xx
- * and pxa{25x,27x}
+ * r0 = v:p offset
  */
-
 ENTRY(pxa3xx_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
        mra     r2, r3, acc0
 #endif
        stmfd   sp!, {r2 - r12, lr}     @ save registers on stack
-
-       mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
-       mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
-       mrc     p15, 0, r5, c13, c0, 0          @ PID
-       mrc     p15, 0, r6, c3, c0, 0           @ domain ID
-       mrc     p15, 0, r7, c2, c0, 0           @ translation table base addr
-       mrc     p15, 0, r8, c1, c0, 1           @ auxiliary control reg
-       mrc     p15, 0, r9, c1, c0, 0           @ control reg
-
-       bic     r3, r3, #2                      @ clear frequency change bit
-
-       @ store them plus current virtual stack ptr on stack
-       mov     r10, sp
-       stmfd   sp!, {r3 - r10}
-
-       @ store physical address of stack pointer
-       mov     r0, sp
-       bl      sleep_phys_sp
-       ldr     r1, =sleep_save_sp
-       str     r0, [r1]
-
-       @ clean data cache
-       bl      xsc3_flush_kern_cache_all
+       mov     r1, r0
+       ldr     r3, =pxa_cpu_resume     @ resume function
+       bl      cpu_suspend
 
        mov     r0, #0x06               @ S2D3C4 mode
        mcr     p14, 0, r0, c7, c0, 0   @ enter sleep
 
 20:    b       20b                     @ waiting for sleep
-
-       .data
-       .align 5
-/*
- * pxa3xx_cpu_resume
- */
-
-ENTRY(pxa3xx_cpu_resume)
-
-       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE   @ set SVC, irqs off
-       msr     cpsr_c, r0
-
-       ldr     r0, sleep_save_sp               @ stack phys addr
-       ldmfd   r0, {r3 - r9, sp}               @ CP regs + virt stack ptr
-
-       mov     r1, #0
-       mcr     p15, 0, r1, c7, c7, 0           @ invalidate I & D caches, BTB
-       mcr     p15, 0, r1, c7, c10, 4          @ drain write (&fill) buffer
-       mcr     p15, 0, r1, c7, c5, 4           @ flush prefetch buffer
-       mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
-
-       mcr     p14, 0, r3, c6, c0, 0           @ clock configuration, turbo mode.
-       mcr     p15, 0, r4, c15, c1, 0          @ CP access reg
-       mcr     p15, 0, r5, c13, c0, 0          @ PID
-       mcr     p15, 0, r6, c3, c0, 0           @ domain ID
-       mcr     p15, 0, r7, c2, c0, 0           @ translation table base addr
-       mcr     p15, 0, r8, c1, c0, 1           @ auxiliary control reg
-
-       @ temporarily map resume_turn_on_mmu into the page table,
-       @ otherwise prefetch abort occurs after MMU is turned on
-       mov     r1, r7
-       bic     r1, r1, #0x00ff
-       bic     r1, r1, #0x3f00
-       ldr     r2, =0x542e
-
-       adr     r3, resume_turn_on_mmu
-       mov     r3, r3, lsr #20
-       orr     r4, r2, r3, lsl #20
-       ldr     r5, [r1, r3, lsl #2]
-       str     r4, [r1, r3, lsl #2]
-
-       @ Mapping page table address in the page table
-       mov     r6, r1, lsr #20
-       orr     r7, r2, r6, lsl #20
-       ldr     r8, [r1, r6, lsl #2]
-       str     r7, [r1, r6, lsl #2]
-
-       ldr     r2, =pxa3xx_resume_after_mmu    @ absolute virtual address
-       b       resume_turn_on_mmu              @ cache align execution
-
-       .text
-pxa3xx_resume_after_mmu:
-       /* restore the temporary mapping */
-       str     r5, [r1, r3, lsl #2]
-       str     r8, [r1, r6, lsl #2]
-       b       resume_after_mmu
-
 #endif /* CONFIG_PXA3xx */
 
 #ifdef CONFIG_PXA27x
@@ -158,28 +51,23 @@ pxa3xx_resume_after_mmu:
  * Forces CPU into sleep state.
  *
  * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
  */
-
 ENTRY(pxa27x_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
        mra     r2, r3, acc0
 #endif
        stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
-
-       bl      pxa_cpu_save_cp
-
-       mov     r5, r0                          @ save sleep mode
-       bl      pxa_cpu_save_sp
-
-       @ clean data cache
-       bl      xscale_flush_kern_cache_all
+       mov     r4, r0                          @ save sleep mode
+       ldr     r3, =pxa_cpu_resume             @ resume function
+       bl      cpu_suspend
 
        @ Put the processor to sleep
        @ (also workaround for sighting 28071)
 
        @ prepare value for sleep mode
-       mov     r1, r5                          @ sleep mode
+       mov     r1, r4                          @ sleep mode
 
        @ prepare pointer to physical address 0 (virtual mapping in generic.c)
        mov     r2, #UNCACHED_PHYS_0
@@ -216,21 +104,16 @@ ENTRY(pxa27x_cpu_suspend)
  * Forces CPU into sleep state.
  *
  * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
  */
 
 ENTRY(pxa25x_cpu_suspend)
        stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
-
-       bl      pxa_cpu_save_cp
-
-       mov     r5, r0                          @ save sleep mode
-       bl      pxa_cpu_save_sp
-
-       @ clean data cache
-       bl      xscale_flush_kern_cache_all
-
+       mov     r4, r0                          @ save sleep mode
+       ldr     r3, =pxa_cpu_resume             @ resume function
+       bl      cpu_suspend
        @ prepare value for sleep mode
-       mov     r1, r5                          @ sleep mode
+       mov     r1, r4                          @ sleep mode
 
        @ prepare pointer to physical address 0 (virtual mapping in generic.c)
        mov     r2, #UNCACHED_PHYS_0
@@ -317,53 +200,9 @@ pxa_cpu_do_suspend:
  * pxa_cpu_resume()
  *
  * entry point from bootloader into kernel during resume
- *
- * Note: Yes, part of the following code is located into the .data section.
- *       This is to allow sleep_save_sp to be accessed with a relative load
- *       while we can't rely on any MMU translation.  We could have put
- *       sleep_save_sp in the .text section as well, but some setups might
- *       insist on it to be truly read-only.
  */
-
-       .data
-       .align 5
-ENTRY(pxa_cpu_resume)
-       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE   @ set SVC, irqs off
-       msr     cpsr_c, r0
-
-       ldr     r0, sleep_save_sp               @ stack phys addr
-       ldr     r2, =resume_after_mmu           @ its absolute virtual address
-       ldmfd   r0, {r3 - r9, sp}               @ CP regs + virt stack ptr
-
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
-       mcr     p15, 0, r1, c7, c7, 0           @ invalidate I & D caches, BTB
-
-       mcr     p14, 0, r3, c6, c0, 0           @ clock configuration, turbo mode.
-       mcr     p15, 0, r4, c15, c1, 0          @ CP access reg
-       mcr     p15, 0, r5, c13, c0, 0          @ PID
-       mcr     p15, 0, r6, c3, c0, 0           @ domain ID
-       mcr     p15, 0, r7, c2, c0, 0           @ translation table base addr
-       mcr     p15, 0, r8, c1, c1, 0           @ auxiliary control reg
-       b       resume_turn_on_mmu              @ cache align execution
-
        .align 5
-resume_turn_on_mmu:
-       mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, caches, etc.
-
-       @ Let us ensure we jump to resume_after_mmu only when the mcr above
-       @ actually took effect.  They call it the "cpwait" operation.
-       mrc     p15, 0, r0, c2, c0, 0           @ queue a dependency on CP15
-       sub     pc, r2, r0, lsr #32             @ jump to virtual addr
-       nop
-       nop
-       nop
-
-sleep_save_sp:
-       .word   0                               @ preserve stack phys ptr here
-
-       .text
-resume_after_mmu:
+pxa_cpu_resume:
        ldmfd   sp!, {r2, r3}
 #ifndef CONFIG_IWMMXT
        mar     acc0, r2, r3
index f4b053b35815495aec494f7396888f4cf8db7758..b92aa3b8c4f795894b73fe4ea8e846959ffe25d3 100644 (file)
@@ -676,7 +676,7 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = {
 static void zeus_power_off(void)
 {
        local_irq_disable();
-       pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
+       pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
 }
 #else
 #define zeus_power_off   NULL
index b2ef44317368a6f20d0baf5e005e2983c7b243a1..afe5a762f46e7cc48e4d5b704bf07c8cc04ca514 100644 (file)
         * code after resume.
         *
         * entry:
-        *      r0 = pointer to the save block
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
        stmfd   sp!, { r4 - r12, lr }
-
-       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mrc     p15, 0, r9, c1, c0, 0   @ Control register
-       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-
-       stmia   r0, { r4 - r13 }        @ Save CP registers and SP
-
-       @@ save our state to ram
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        @@ call final suspend code
        ldr     r0, =pm_cpu_sleep
@@ -61,18 +49,6 @@ ENTRY(s3c_cpu_save)
 resume_with_mmu:
        ldmfd   sp!, { r4 - r12, pc }   @ return, from sp from s3c_cpu_save
 
-       .data
-
-       /* the next bit is code, but it requires easy access to the
-        * s3c_sleep_save_phys data before the MMU is switched on, so
-        * we store the code that needs this variable in the .data where
-        * the value can be written to (the .text segment is RO).
-       */
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
        /* Sleep magic, the word before the resume entry point so that the
         * bootloader can check for a resumeable image. */
 
@@ -110,35 +86,4 @@ ENTRY(s3c_cpu_resume)
        orr     r0, r0, #1 << 15                        @ GPN15
        str     r0, [ r3, #S3C64XX_GPNDAT ]
 #endif
-
-       /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
-        * are thoroughly cleaned just in case the bootloader didn't do it
-        * for us. */
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
-       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
-       mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
-       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
-       @@mcr   p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
-       @@mcr   p15, 0, r0, c7, c7, 0           @ Invalidate I + D caches
-
-       ldr     r0, s3c_sleep_save_phys
-       ldmia   r0, { r4 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mcr     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mcr     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mcr     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-
-       mov     r0, #0                  @ restore copro access controls
-       mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-       mcr     p15, 0, r0, c7, c5, 4
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r9, c1, c0, 0           /* turn mmu back on */
-       nop
-       mov     pc, r2                          /* jump back */
-
-       .end
+       b       cpu_resume
index d4d222b716b434e046ccd274e7b9a8dd01f4484d..a3d649466fb1b8b89086f55939011612e3e8b64e 100644 (file)
        /* s3c_cpu_save
         *
         * entry:
-        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
 
        stmfd   sp!, { r3 - r12, lr }
-
-       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mrc     p15, 0, r9, c1, c0, 0   @ Control register
-       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-       mrc     p15, 0, r12, c10, c2, 0 @ Read PRRR
-       mrc     p15, 0, r3, c10, c2, 1  @ READ NMRR
-
-       stmia   r0, { r3 - r13 }
-
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        ldr     r0, =pm_cpu_sleep
        ldr     r0, [ r0 ]
        mov     pc, r0
 
 resume_with_mmu:
-       /*
-        * After MMU is turned on, restore the previous MMU table.
-        */
-       ldr     r9 , =(PAGE_OFFSET - PHYS_OFFSET)
-       add     r4, r4, r9
-       str     r12, [r4]
-
        ldmfd   sp!, { r3 - r12, pc }
 
        .ltorg
 
-       .data
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
        /* sleep magic, to allow the bootloader to check for an valid
         * image to resume to. Must be the first word before the
         * s3c_cpu_resume entry.
@@ -96,75 +70,4 @@ s3c_sleep_save_phys:
        */
 
 ENTRY(s3c_cpu_resume)
-       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
-       msr     cpsr_c, r0
-
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @ invalidate TLBs
-       mcr     p15, 0, r1, c7, c5, 0           @ invalidate I Cache
-
-       ldr     r0, s3c_sleep_save_phys         @ address of restore block
-       ldmia   r0, { r3 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0          @ FCSE/PID
-       mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
-
-       mcr     p15, 0, r8, c2, c0, 2           @ Translation Table Control
-       mcr     p15, 0, r7, c2, c0, 1           @ Translation Table BASE1
-       mcr     p15, 0, r6, c2, c0, 0           @ Translation Table BASE0
-
-       mcr     p15, 0, r10, c1, c0, 1          @ Auxiliary control register
-
-       mov     r0, #0
-       mcr     p15, 0, r0, c8, c7, 0           @ Invalidate I & D TLB
-
-       mov     r0, #0                          @ restore copro access
-       mcr     p15, 0, r11, c1, c0, 2          @ Co-processor access
-       mcr     p15, 0, r0, c7, c5, 4
-
-       mcr     p15, 0, r12, c10, c2, 0         @ write PRRR
-       mcr     p15, 0, r3, c10, c2, 1          @ write NMRR
-
-       /*
-        * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
-        * And there are no valid entries in the MMU table at this point.
-        * So before turning on the MMU, the MMU entry for the DRAM address
-        * range is added. After the MMU is turned on, the other entries
-        * in the MMU table will be restored.
-       */
-
-       /* r6 = Translation Table BASE0 */
-       mov     r4, r6
-       mov     r4, r4, LSR #14
-       mov     r4, r4, LSL #14
-
-       /* Load address for adding to MMU table list */
-       ldr     r11, =0xE010F000                @ INFORM0 reg.
-       ldr     r10, [r11, #0]
-       mov     r10, r10, LSR #18
-       bic     r10, r10, #0x3
-       orr     r4, r4, r10
-
-       /* Calculate MMU table entry */
-       mov     r10, r10, LSL #18
-       ldr     r5, =0x40E
-       orr     r10, r10, r5
-
-       /* Back up originally data */
-       ldr     r12, [r4]
-
-       /* Add calculated MMU table entry into MMU table list */
-       str     r10, [r4]
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, etc
-
-       nop
-       nop
-       nop
-       nop
-       nop                                     @ second-to-last before mmu
-
-       mov     pc, r2                          @ go back to virtual address
-
-       .ltorg
+       b       cpu_resume
index ab9fc4470d361bcd69041a3e35edb35bf7709e2d..c4661aab22fb5475200b22f584c80755d425b0ca 100644 (file)
@@ -32,8 +32,7 @@
 #include <asm/system.h>
 #include <asm/mach/time.h>
 
-extern void sa1100_cpu_suspend(void);
-extern void sa1100_cpu_resume(void);
+extern void sa1100_cpu_suspend(long);
 
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
@@ -73,10 +72,10 @@ static int sa11x0_pm_enter(suspend_state_t state)
        RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
 
        /* set resume return address */
-       PSPR = virt_to_phys(sa1100_cpu_resume);
+       PSPR = virt_to_phys(cpu_resume);
 
        /* go zzz */
-       sa1100_cpu_suspend();
+       sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
 
        cpu_init();
 
@@ -115,11 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
        return 0;
 }
 
-unsigned long sleep_phys_sp(void *sp)
-{
-       return virt_to_phys(sp);
-}
-
 static const struct platform_suspend_ops sa11x0_pm_ops = {
        .enter          = sa11x0_pm_enter,
        .valid          = suspend_valid_only_mem,
index 80f31bad707cae69ac80246c44a887eb248b5f4f..04f2a618d4ef11b20976ecc3eb141e10835f4aa9 100644 (file)
 #include <asm/assembler.h>
 #include <mach/hardware.h>
 
-
-
                .text
-
-
-
 /*
  * sa1100_cpu_suspend()
  *
  */
 
 ENTRY(sa1100_cpu_suspend)
-
        stmfd   sp!, {r4 - r12, lr}             @ save registers on stack
-
-       @ get coprocessor registers
-       mrc     p15, 0, r4, c3, c0, 0           @ domain ID
-       mrc     p15, 0, r5, c2, c0, 0           @ translation table base addr
-       mrc     p15, 0, r6, c13, c0, 0          @ PID
-       mrc     p15, 0, r7, c1, c0, 0           @ control reg
-
-       @ store them plus current virtual stack ptr on stack
-       mov     r8, sp
-       stmfd   sp!, {r4 - r8}
-
-       @ preserve phys address of stack
-       mov     r0, sp
-       bl      sleep_phys_sp
-       ldr     r1, =sleep_save_sp
-       str     r0, [r1]
-
-       @ clean data cache and invalidate WB
-       bl      v4wb_flush_kern_cache_all
+       mov     r1, r0
+       ldr     r3, =sa1100_cpu_resume          @ return function
+       bl      cpu_suspend
 
        @ disable clock switching
        mcr     p15, 0, r1, c15, c2, 2
@@ -166,50 +144,8 @@ sa1110_sdram_controller_fix:
  * cpu_sa1100_resume()
  *
  * entry point from bootloader into kernel during resume
- *
- * Note: Yes, part of the following code is located into the .data section.
- *       This is to allow sleep_save_sp to be accessed with a relative load
- *       while we can't rely on any MMU translation.  We could have put
- *       sleep_save_sp in the .text section as well, but some setups might
- *       insist on it to be truly read-only.
  */
-
-       .data
-       .align 5
-ENTRY(sa1100_cpu_resume)
-       mov     r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
-       msr     cpsr_c, r0                      @ set SVC, irqs off
-
-       ldr     r0, sleep_save_sp               @ stack phys addr
-       ldr     r2, =resume_after_mmu           @ its absolute virtual address
-       ldmfd   r0, {r4 - r7, sp}               @ CP regs + virt stack ptr
-
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @ flush I+D TLBs
-       mcr     p15, 0, r1, c7, c7, 0           @ flush I&D cache
-       mcr     p15, 0, r1, c9, c0, 0           @ invalidate RB
-       mcr     p15, 0, r1, c9, c0, 5           @ allow user space to use RB
-
-       mcr     p15, 0, r4, c3, c0, 0           @ domain ID
-       mcr     p15, 0, r5, c2, c0, 0           @ translation table base addr
-       mcr     p15, 0, r6, c13, c0, 0          @ PID
-       b       resume_turn_on_mmu              @ cache align execution
-
        .align 5
-resume_turn_on_mmu:
-       mcr     p15, 0, r7, c1, c0, 0           @ turn on MMU, caches, etc.
-       nop
-       mov     pc, r2                          @ jump to virtual addr
-       nop
-       nop
-       nop
-
-sleep_save_sp:
-       .word   0                               @ preserve stack phys ptr here
-
-       .text
-resume_after_mmu:
+sa1100_cpu_resume:
        mcr     p15, 0, r1, c15, c1, 2          @ enable clock switching
        ldmfd   sp!, {r4 - r12, pc}             @ return to caller
-
-
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
new file mode 100644 (file)
index 0000000..a8d02be
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MMCIF_AP4EB_H
+#define MMCIF_AP4EB_H
+
+#define PORT185CR      (void __iomem *)0xe60520b9
+#define PORT186CR      (void __iomem *)0xe60520ba
+#define PORT187CR      (void __iomem *)0xe60520bb
+#define PORT188CR      (void __iomem *)0xe60520bc
+
+#define PORTR191_160DR (void __iomem *)0xe6056014
+
+static inline void mmcif_init_progress(void)
+{
+       /* Initialise LEDS1-4
+        * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
+        * value:     0x10 - enable output
+        */
+       __raw_writeb(0x10, PORT185CR);
+       __raw_writeb(0x10, PORT186CR);
+       __raw_writeb(0x10, PORT187CR);
+       __raw_writeb(0x10, PORT188CR);
+}
+
+static inline void mmcif_update_progress(int n)
+{
+       __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
+                    (1 << (25 + n)), PORTR191_160DR);
+}
+
+#endif /* MMCIF_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h b/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
new file mode 100644 (file)
index 0000000..4b4f694
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef MMCIF_MACKEREL_H
+#define MMCIF_MACKEREL_H
+
+#define PORT0CR      (void __iomem *)0xe6051000
+#define PORT1CR      (void __iomem *)0xe6051001
+#define PORT2CR      (void __iomem *)0xe6051002
+#define PORT159CR    (void __iomem *)0xe605009f
+
+#define PORTR031_000DR (void __iomem *)0xe6055000
+#define PORTL159_128DR (void __iomem *)0xe6054010
+
+static inline void mmcif_init_progress(void)
+{
+       /* Initialise LEDS0-3
+        * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control)
+        * value:     0x10 - enable output
+        */
+       __raw_writeb(0x10, PORT0CR);
+       __raw_writeb(0x10, PORT1CR);
+       __raw_writeb(0x10, PORT2CR);
+       __raw_writeb(0x10, PORT159CR);
+}
+
+static inline void mmcif_update_progress(int n)
+{
+       unsigned a = 0, b = 0;
+
+       if (n < 3)
+               a = 1 << n;
+       else
+               b = 1 << 31;
+
+       __raw_writel((__raw_readl(PORTR031_000DR) & ~0x7) | a,
+                    PORTR031_000DR);
+       __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b,
+                    PORTL159_128DR);
+}
+
+#endif /* MMCIF_MACKEREL_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif.h b/arch/arm/mach-shmobile/include/mach/mmcif.h
new file mode 100644 (file)
index 0000000..f4dc327
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef MMCIF_H
+#define MMCIF_H
+
+/**************************************************
+ *
+ *             board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#include "mach/mmcif-ap4eb.h"
+#elif CONFIG_MACH_MACKEREL
+#include "mach/mmcif-mackerel.h"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* MMCIF_H */
index 247caa3400d081b88013131190fc8c191f39d9b7..203b986280f54d8987f74f7b9a92d9bf5a10bc02 100644 (file)
@@ -6,6 +6,7 @@ config UX500_SOC_COMMON
        select ARM_GIC
        select HAS_MTU
        select NOMADIK_GPIO
+       select ARM_ERRATA_753970
 
 menu "Ux500 SoC"
 
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644 (file)
index 0000000..2c20a34
--- /dev/null
@@ -0,0 +1,73 @@
+if ARCH_VT8500
+
+config VTWM_VERSION_VT8500
+       bool
+
+config VTWM_VERSION_WM8505
+       bool
+
+config MACH_BV07
+       bool "Benign BV07-8500 Mini Netbook"
+       depends on ARCH_VT8500
+       select VTWM_VERSION_VT8500
+       help
+         Add support for the inexpensive 7-inch netbooks sold by many
+         Chinese distributors under various names. Note that there are
+         many hardware implementations in identical exterior, make sure
+         that yours is indeed based on a VIA VT8500 chip.
+
+config MACH_WM8505_7IN_NETBOOK
+       bool "WM8505 7-inch generic netbook"
+       depends on ARCH_VT8500
+       select VTWM_VERSION_WM8505
+       help
+         Add support for the inexpensive 7-inch netbooks sold by many
+         Chinese distributors under various names. Note that there are
+         many hardware implementations in identical exterior, make sure
+         that yours is indeed based on a WonderMedia WM8505 chip.
+
+comment "LCD panel size"
+
+config WMT_PANEL_800X480
+       bool "7-inch with 800x480 resolution"
+       depends on (FB_VT8500 || FB_WM8505)
+       default y
+       help
+         These are found in most of the netbooks in generic cases, as
+         well as in Eken M001 tablets and possibly elsewhere.
+
+         To select this panel at runtime, say y here and append
+         'panel=800x480' to your kernel command line. Otherwise, the
+         largest one available will be used.
+
+config WMT_PANEL_800X600
+       bool "8-inch with 800x600 resolution"
+       depends on (FB_VT8500 || FB_WM8505)
+       help
+         These are found in Eken M003 tablets and possibly elsewhere.
+
+         To select this panel at runtime, say y here and append
+         'panel=800x600' to your kernel command line. Otherwise, the
+         largest one available will be used.
+
+config WMT_PANEL_1024X576
+       bool "10-inch with 1024x576 resolution"
+       depends on (FB_VT8500 || FB_WM8505)
+       help
+         These are found in CherryPal netbooks and possibly elsewhere.
+
+         To select this panel at runtime, say y here and append
+         'panel=1024x576' to your kernel command line. Otherwise, the
+         largest one available will be used.
+
+config WMT_PANEL_1024X600
+       bool "10-inch with 1024x600 resolution"
+       depends on (FB_VT8500 || FB_WM8505)
+       help
+         These are found in Eken M006 tablets and possibly elsewhere.
+
+         To select this panel at runtime, say y here and append
+         'panel=1024x600' to your kernel command line. Otherwise, the
+         largest one available will be used.
+
+endif
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
new file mode 100644 (file)
index 0000000..81aedb7
--- /dev/null
@@ -0,0 +1,9 @@
+obj-y += devices.o gpio.o irq.o timer.o
+
+obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o
+obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
+
+obj-$(CONFIG_MACH_BV07) += bv07.o
+obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-vt8500/Makefile.boot b/arch/arm/mach-vt8500/Makefile.boot
new file mode 100644 (file)
index 0000000..a8acc4e
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x01000000
diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c
new file mode 100644 (file)
index 0000000..94a261d
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  arch/arm/mach-vt8500/bv07.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+#include <linux/io.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "devices.h"
+
+static void __iomem *pmc_hiber;
+
+static struct platform_device *devices[] __initdata = {
+       &vt8500_device_uart0,
+       &vt8500_device_lcdc,
+       &vt8500_device_ehci,
+       &vt8500_device_ge_rops,
+       &vt8500_device_pwm,
+       &vt8500_device_pwmbl,
+       &vt8500_device_rtc,
+};
+
+static void vt8500_power_off(void)
+{
+       local_irq_disable();
+       writew(5, pmc_hiber);
+       asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+void __init bv07_init(void)
+{
+#ifdef CONFIG_FB_VT8500
+       void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
+       if (gpio_mux_reg) {
+               writel(readl(gpio_mux_reg) | 1, gpio_mux_reg);
+               iounmap(gpio_mux_reg);
+       } else {
+               printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
+       }
+#endif
+       pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
+       if (pmc_hiber)
+               pm_power_off = &vt8500_power_off;
+       else
+               printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
+
+       vt8500_set_resources();
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+       vt8500_gpio_init();
+}
+
+MACHINE_START(BV07, "Benign BV07 Mini Netbook")
+       .boot_params    = 0x00000100,
+       .reserve        = vt8500_reserve_mem,
+       .map_io         = vt8500_map_io,
+       .init_irq       = vt8500_init_irq,
+       .timer          = &vt8500_timer,
+       .init_machine   = bv07_init,
+MACHINE_END
diff --git a/arch/arm/mach-vt8500/devices-vt8500.c b/arch/arm/mach-vt8500/devices-vt8500.c
new file mode 100644 (file)
index 0000000..19519ae
--- /dev/null
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-vt8500/devices-vt8500.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <mach/vt8500_regs.h>
+#include <mach/vt8500_irqs.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+void __init vt8500_set_resources(void)
+{
+       struct resource tmp[3];
+
+       tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K);
+       tmp[1] = wmt_irq_res(IRQ_LCDC);
+       wmt_res_add(&vt8500_device_lcdc, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART0);
+       wmt_res_add(&vt8500_device_uart0, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART1);
+       wmt_res_add(&vt8500_device_uart1, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART2);
+       wmt_res_add(&vt8500_device_uart2, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART3);
+       wmt_res_add(&vt8500_device_uart3, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512);
+       tmp[1] = wmt_irq_res(IRQ_EHCI);
+       wmt_res_add(&vt8500_device_ehci, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256);
+       wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
+
+       tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44);
+       wmt_res_add(&vt8500_device_pwm, tmp, 1);
+
+       tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c);
+       tmp[1] = wmt_irq_res(IRQ_RTC);
+       tmp[2] = wmt_irq_res(IRQ_RTCSM);
+       wmt_res_add(&vt8500_device_rtc, tmp, 3);
+}
+
+static void __init vt8500_set_externs(void)
+{
+       /* Non-resource-aware stuff */
+       wmt_ic_base = VT8500_IC_BASE;
+       wmt_gpio_base = VT8500_GPIO_BASE;
+       wmt_pmc_base = VT8500_PMC_BASE;
+       wmt_i8042_base = VT8500_PS2_BASE;
+
+       wmt_nr_irqs = VT8500_NR_IRQS;
+       wmt_timer_irq = IRQ_PMCOS0;
+       wmt_gpio_ext_irq[0] = IRQ_EXT0;
+       wmt_gpio_ext_irq[1] = IRQ_EXT1;
+       wmt_gpio_ext_irq[2] = IRQ_EXT2;
+       wmt_gpio_ext_irq[3] = IRQ_EXT3;
+       wmt_gpio_ext_irq[4] = IRQ_EXT4;
+       wmt_gpio_ext_irq[5] = IRQ_EXT5;
+       wmt_gpio_ext_irq[6] = IRQ_EXT6;
+       wmt_gpio_ext_irq[7] = IRQ_EXT7;
+       wmt_i8042_kbd_irq = IRQ_PS2KBD;
+       wmt_i8042_aux_irq = IRQ_PS2MOUSE;
+}
+
+void __init vt8500_map_io(void)
+{
+       iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
+
+       /* Should be done before interrupts and timers are initialized */
+       vt8500_set_externs();
+}
diff --git a/arch/arm/mach-vt8500/devices-wm8505.c b/arch/arm/mach-vt8500/devices-wm8505.c
new file mode 100644 (file)
index 0000000..db4594e
--- /dev/null
@@ -0,0 +1,99 @@
+/* linux/arch/arm/mach-vt8500/devices-wm8505.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <mach/wm8505_regs.h>
+#include <mach/wm8505_irqs.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+void __init wm8505_set_resources(void)
+{
+       struct resource tmp[3];
+
+       tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512);
+       wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART0);
+       wmt_res_add(&vt8500_device_uart0, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART1);
+       wmt_res_add(&vt8500_device_uart1, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART2);
+       wmt_res_add(&vt8500_device_uart2, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART3);
+       wmt_res_add(&vt8500_device_uart3, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART4);
+       wmt_res_add(&vt8500_device_uart4, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040);
+       tmp[1] = wmt_irq_res(IRQ_UART5);
+       wmt_res_add(&vt8500_device_uart5, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512);
+       tmp[1] = wmt_irq_res(IRQ_EHCI);
+       wmt_res_add(&vt8500_device_ehci, tmp, 2);
+
+       tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256);
+       wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
+
+       tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44);
+       wmt_res_add(&vt8500_device_pwm, tmp, 1);
+
+       tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c);
+       tmp[1] = wmt_irq_res(IRQ_RTC);
+       tmp[2] = wmt_irq_res(IRQ_RTCSM);
+       wmt_res_add(&vt8500_device_rtc, tmp, 3);
+}
+
+static void __init wm8505_set_externs(void)
+{
+       /* Non-resource-aware stuff */
+       wmt_ic_base = WM8505_IC_BASE;
+       wmt_sic_base = WM8505_SIC_BASE;
+       wmt_gpio_base = WM8505_GPIO_BASE;
+       wmt_pmc_base = WM8505_PMC_BASE;
+       wmt_i8042_base = WM8505_PS2_BASE;
+
+       wmt_nr_irqs = WM8505_NR_IRQS;
+       wmt_timer_irq = IRQ_PMCOS0;
+       wmt_gpio_ext_irq[0] = IRQ_EXT0;
+       wmt_gpio_ext_irq[1] = IRQ_EXT1;
+       wmt_gpio_ext_irq[2] = IRQ_EXT2;
+       wmt_gpio_ext_irq[3] = IRQ_EXT3;
+       wmt_gpio_ext_irq[4] = IRQ_EXT4;
+       wmt_gpio_ext_irq[5] = IRQ_EXT5;
+       wmt_gpio_ext_irq[6] = IRQ_EXT6;
+       wmt_gpio_ext_irq[7] = IRQ_EXT7;
+       wmt_i8042_kbd_irq = IRQ_PS2KBD;
+       wmt_i8042_aux_irq = IRQ_PS2MOUSE;
+}
+
+void __init wm8505_map_io(void)
+{
+       iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
+
+       /* Should be done before interrupts and timers are initialized */
+       wm8505_set_externs();
+}
diff --git a/arch/arm/mach-vt8500/devices.c b/arch/arm/mach-vt8500/devices.c
new file mode 100644 (file)
index 0000000..1fcdc36
--- /dev/null
@@ -0,0 +1,270 @@
+/* linux/arch/arm/mach-vt8500/devices.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/memblock.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/vt8500fb.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+/* These can't use resources currently */
+unsigned long wmt_ic_base __initdata;
+unsigned long wmt_sic_base __initdata;
+unsigned long wmt_gpio_base __initdata;
+unsigned long wmt_pmc_base __initdata;
+unsigned long wmt_i8042_base __initdata;
+
+int wmt_nr_irqs __initdata;
+int wmt_timer_irq __initdata;
+int wmt_gpio_ext_irq[8] __initdata;
+
+/* Should remain accessible after init.
+ * i8042 driver desperately calls for attention...
+ */
+int wmt_i8042_kbd_irq;
+int wmt_i8042_aux_irq;
+
+static u64 fb_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device vt8500_device_lcdc = {
+       .name           = "vt8500-lcd",
+       .id             = 0,
+       .dev            = {
+               .dma_mask       = &fb_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device vt8500_device_wm8505_fb = {
+       .name           = "wm8505-fb",
+       .id             = 0,
+};
+
+/* Smallest to largest */
+static struct vt8500fb_platform_data panels[] = {
+#ifdef CONFIG_WMT_PANEL_800X480
+{
+       .xres_virtual   = 800,
+       .yres_virtual   = 480 * 2,
+       .mode           = {
+               .name           = "800x480",
+               .xres           = 800,
+               .yres           = 480,
+               .left_margin    = 88,
+               .right_margin   = 40,
+               .upper_margin   = 32,
+               .lower_margin   = 11,
+               .hsync_len      = 0,
+               .vsync_len      = 1,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_800X600
+{
+       .xres_virtual   = 800,
+       .yres_virtual   = 600 * 2,
+       .mode           = {
+               .name           = "800x600",
+               .xres           = 800,
+               .yres           = 600,
+               .left_margin    = 88,
+               .right_margin   = 40,
+               .upper_margin   = 32,
+               .lower_margin   = 11,
+               .hsync_len      = 0,
+               .vsync_len      = 1,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_1024X576
+{
+       .xres_virtual   = 1024,
+       .yres_virtual   = 576 * 2,
+       .mode           = {
+               .name           = "1024x576",
+               .xres           = 1024,
+               .yres           = 576,
+               .left_margin    = 40,
+               .right_margin   = 24,
+               .upper_margin   = 32,
+               .lower_margin   = 11,
+               .hsync_len      = 96,
+               .vsync_len      = 2,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_1024X600
+{
+       .xres_virtual   = 1024,
+       .yres_virtual   = 600 * 2,
+       .mode           = {
+               .name           = "1024x600",
+               .xres           = 1024,
+               .yres           = 600,
+               .left_margin    = 66,
+               .right_margin   = 2,
+               .upper_margin   = 19,
+               .lower_margin   = 1,
+               .hsync_len      = 23,
+               .vsync_len      = 8,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+},
+#endif
+};
+
+static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
+
+static int __init panel_setup(char *str)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(panels); i++) {
+               if (strcmp(panels[i].mode.name, str) == 0) {
+                       current_panel_idx = i;
+                       break;
+               }
+       }
+       return 0;
+}
+
+early_param("panel", panel_setup);
+
+static inline void preallocate_fb(struct vt8500fb_platform_data *p,
+                                 unsigned long align) {
+       p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
+                       (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
+                                       (8 / p->bpp) + 1));
+       p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
+                                                         align);
+       p->video_mem_virt = phys_to_virt(p->video_mem_phys);
+}
+
+struct platform_device vt8500_device_uart0 = {
+       .name           = "vt8500_serial",
+       .id             = 0,
+};
+
+struct platform_device vt8500_device_uart1 = {
+       .name           = "vt8500_serial",
+       .id             = 1,
+};
+
+struct platform_device vt8500_device_uart2 = {
+       .name           = "vt8500_serial",
+       .id             = 2,
+};
+
+struct platform_device vt8500_device_uart3 = {
+       .name           = "vt8500_serial",
+       .id             = 3,
+};
+
+struct platform_device vt8500_device_uart4 = {
+       .name           = "vt8500_serial",
+       .id             = 4,
+};
+
+struct platform_device vt8500_device_uart5 = {
+       .name           = "vt8500_serial",
+       .id             = 5,
+};
+
+static u64 ehci_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device vt8500_device_ehci = {
+       .name           = "vt8500-ehci",
+       .id             = 0,
+       .dev            = {
+               .dma_mask       = &ehci_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device vt8500_device_ge_rops = {
+       .name           = "wmt_ge_rops",
+       .id             = -1,
+};
+
+struct platform_device vt8500_device_pwm = {
+       .name           = "vt8500-pwm",
+       .id             = 0,
+};
+
+static struct platform_pwm_backlight_data vt8500_pwmbl_data = {
+       .pwm_id         = 0,
+       .max_brightness = 128,
+       .dft_brightness = 70,
+       .pwm_period_ns  = 250000, /* revisit when clocks are implemented */
+};
+
+struct platform_device vt8500_device_pwmbl = {
+       .name           = "pwm-backlight",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &vt8500_pwmbl_data,
+       },
+};
+
+struct platform_device vt8500_device_rtc = {
+       .name           = "vt8500-rtc",
+       .id             = 0,
+};
+
+struct map_desc wmt_io_desc[] __initdata = {
+       /* SoC MMIO registers */
+       [0] = {
+               .virtual        = 0xf8000000,
+               .pfn            = __phys_to_pfn(0xd8000000),
+               .length         = 0x00390000, /* max of all chip variants */
+               .type           = MT_DEVICE
+       },
+       /* PCI I/O space, numbers tied to those in <mach/io.h> */
+       [1] = {
+               .virtual        = 0xf0000000,
+               .pfn            = __phys_to_pfn(0xc0000000),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE
+       },
+};
+
+void __init vt8500_reserve_mem(void)
+{
+#ifdef CONFIG_FB_VT8500
+       panels[current_panel_idx].bpp = 16; /* Always use RGB565 */
+       preallocate_fb(&panels[current_panel_idx], SZ_4M);
+       vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx];
+#endif
+}
+
+void __init wm8505_reserve_mem(void)
+{
+#if defined CONFIG_FB_WM8505
+       panels[current_panel_idx].bpp = 32; /* Always use RGB888 */
+       preallocate_fb(&panels[current_panel_idx], 32);
+       vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx];
+#endif
+}
diff --git a/arch/arm/mach-vt8500/devices.h b/arch/arm/mach-vt8500/devices.h
new file mode 100644 (file)
index 0000000..188d4e1
--- /dev/null
@@ -0,0 +1,88 @@
+/* linux/arch/arm/mach-vt8500/devices.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_VT8500_DEVICES_H
+#define __ARCH_ARM_MACH_VT8500_DEVICES_H
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+
+void __init vt8500_init_irq(void);
+void __init wm8505_init_irq(void);
+void __init vt8500_map_io(void);
+void __init wm8505_map_io(void);
+void __init vt8500_reserve_mem(void);
+void __init wm8505_reserve_mem(void);
+void __init vt8500_gpio_init(void);
+void __init vt8500_set_resources(void);
+void __init wm8505_set_resources(void);
+
+extern unsigned long wmt_ic_base __initdata;
+extern unsigned long wmt_sic_base __initdata;
+extern unsigned long wmt_gpio_base __initdata;
+extern unsigned long wmt_pmc_base __initdata;
+
+extern int wmt_nr_irqs __initdata;
+extern int wmt_timer_irq __initdata;
+extern int wmt_gpio_ext_irq[8] __initdata;
+
+extern struct map_desc wmt_io_desc[2] __initdata;
+
+static inline struct resource wmt_mmio_res(u32 start, u32 size)
+{
+       struct resource tmp = {
+               .flags = IORESOURCE_MEM,
+               .start = start,
+               .end = start + size - 1,
+       };
+
+       return tmp;
+}
+
+static inline struct resource wmt_irq_res(int irq)
+{
+       struct resource tmp = {
+               .flags = IORESOURCE_IRQ,
+               .start = irq,
+               .end = irq,
+       };
+
+       return tmp;
+}
+
+static inline void wmt_res_add(struct platform_device *pdev,
+                              const struct resource *res, unsigned int num)
+{
+       if (unlikely(platform_device_add_resources(pdev, res, num)))
+               pr_err("Failed to assign resources\n");
+}
+
+extern struct sys_timer vt8500_timer;
+
+extern struct platform_device vt8500_device_uart0;
+extern struct platform_device vt8500_device_uart1;
+extern struct platform_device vt8500_device_uart2;
+extern struct platform_device vt8500_device_uart3;
+extern struct platform_device vt8500_device_uart4;
+extern struct platform_device vt8500_device_uart5;
+
+extern struct platform_device vt8500_device_lcdc;
+extern struct platform_device vt8500_device_wm8505_fb;
+extern struct platform_device vt8500_device_ehci;
+extern struct platform_device vt8500_device_ge_rops;
+extern struct platform_device vt8500_device_pwm;
+extern struct platform_device vt8500_device_pwmbl;
+extern struct platform_device vt8500_device_rtc;
+#endif
diff --git a/arch/arm/mach-vt8500/gpio.c b/arch/arm/mach-vt8500/gpio.c
new file mode 100644 (file)
index 0000000..2bcc0ec
--- /dev/null
@@ -0,0 +1,240 @@
+/* linux/arch/arm/mach-vt8500/gpio.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include "devices.h"
+
+#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
+
+#define ENABLE_REGS    0x0
+#define DIRECTION_REGS 0x20
+#define OUTVALUE_REGS  0x40
+#define INVALUE_REGS   0x60
+
+#define EXT_REGOFF     0x1c
+
+static void __iomem *regbase;
+
+struct vt8500_gpio_chip {
+       struct gpio_chip        chip;
+       unsigned int            shift;
+       unsigned int            regoff;
+};
+
+static int gpio_to_irq_map[8];
+
+static int vt8500_muxed_gpio_request(struct gpio_chip *chip,
+                                    unsigned offset)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+       unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+       val |= (1 << vt8500_chip->shift << offset);
+       writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+       return 0;
+}
+
+static void vt8500_muxed_gpio_free(struct gpio_chip *chip,
+                                  unsigned offset)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+       unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+       val &= ~(1 << vt8500_chip->shift << offset);
+       writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
+}
+
+static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip,
+                                      unsigned offset)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+       unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+       val &= ~(1 << vt8500_chip->shift << offset);
+       writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+       return 0;
+}
+
+static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+       unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+       val |= (1 << vt8500_chip->shift << offset);
+       writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+       if (value) {
+               val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff);
+               val |= (1 << vt8500_chip->shift << offset);
+               writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff);
+       }
+       return 0;
+}
+
+static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip,
+                                      unsigned offset)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+       return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff)
+               >> vt8500_chip->shift >> offset) & 1;
+}
+
+static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+       unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff);
+
+       if (value)
+               val |= (1 << vt8500_chip->shift << offset);
+       else
+               val &= ~(1 << vt8500_chip->shift << offset);
+
+       writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff);
+}
+
+#define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num)                \
+{                                                                      \
+       .chip = {                                                       \
+               .label                  = __name,                       \
+               .request                = vt8500_muxed_gpio_request,    \
+               .free                   = vt8500_muxed_gpio_free,       \
+               .direction_input  = vt8500_muxed_gpio_direction_input,  \
+               .direction_output = vt8500_muxed_gpio_direction_output, \
+               .get                    = vt8500_muxed_gpio_get_value,  \
+               .set                    = vt8500_muxed_gpio_set_value,  \
+               .can_sleep              = 0,                            \
+               .base                   = __base,                       \
+               .ngpio                  = __num,                        \
+       },                                                              \
+       .shift          = __shift,                                      \
+       .regoff         = __off,                                        \
+}
+
+static struct vt8500_gpio_chip vt8500_muxed_gpios[] = {
+       VT8500_GPIO_BANK("uart0",       0,      0x0,    8,      4),
+       VT8500_GPIO_BANK("uart1",       4,      0x0,    12,     4),
+       VT8500_GPIO_BANK("spi0",        8,      0x0,    16,     4),
+       VT8500_GPIO_BANK("spi1",        12,     0x0,    20,     4),
+       VT8500_GPIO_BANK("spi2",        16,     0x0,    24,     4),
+       VT8500_GPIO_BANK("pwmout",      24,     0x0,    28,     2),
+
+       VT8500_GPIO_BANK("sdmmc",       0,      0x4,    30,     11),
+       VT8500_GPIO_BANK("ms",          16,     0x4,    41,     7),
+       VT8500_GPIO_BANK("i2c0",        24,     0x4,    48,     2),
+       VT8500_GPIO_BANK("i2c1",        26,     0x4,    50,     2),
+
+       VT8500_GPIO_BANK("mii",         0,      0x8,    52,     20),
+       VT8500_GPIO_BANK("see",         20,     0x8,    72,     4),
+       VT8500_GPIO_BANK("ide",         24,     0x8,    76,     7),
+
+       VT8500_GPIO_BANK("ccir",        0,      0xc,    83,     19),
+
+       VT8500_GPIO_BANK("ts",          8,      0x10,   102,    11),
+
+       VT8500_GPIO_BANK("lcd",         0,      0x14,   113,    23),
+};
+
+static int vt8500_gpio_direction_input(struct gpio_chip *chip,
+                                      unsigned offset)
+{
+       unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
+
+       val &= ~(1 << offset);
+       writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
+       return 0;
+}
+
+static int vt8500_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
+
+       val |= (1 << offset);
+       writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
+
+       if (value) {
+               val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
+               val |= (1 << offset);
+               writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
+       }
+       return 0;
+}
+
+static int vt8500_gpio_get_value(struct gpio_chip *chip,
+                                      unsigned offset)
+{
+       return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1;
+}
+
+static void vt8500_gpio_set_value(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
+
+       if (value)
+               val |= (1 << offset);
+       else
+               val &= ~(1 << offset);
+
+       writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
+}
+
+static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       if (offset > 7)
+               return -EINVAL;
+
+       return gpio_to_irq_map[offset];
+}
+
+static struct gpio_chip vt8500_external_gpios = {
+       .label                  = "extgpio",
+       .direction_input        = vt8500_gpio_direction_input,
+       .direction_output       = vt8500_gpio_direction_output,
+       .get                    = vt8500_gpio_get_value,
+       .set                    = vt8500_gpio_set_value,
+       .to_irq                 = vt8500_gpio_to_irq,
+       .can_sleep              = 0,
+       .base                   = 0,
+       .ngpio                  = 8,
+};
+
+void __init vt8500_gpio_init(void)
+{
+       int i;
+
+       for (i = 0; i < 8; i++)
+               gpio_to_irq_map[i] = wmt_gpio_ext_irq[i];
+
+       regbase = ioremap(wmt_gpio_base, SZ_64K);
+       if (!regbase) {
+               printk(KERN_ERR "Failed to map MMIO registers for GPIO\n");
+               return;
+       }
+
+       gpiochip_add(&vt8500_external_gpios);
+
+       for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++)
+               gpiochip_add(&vt8500_muxed_gpios[i].chip);
+}
diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S b/arch/arm/mach-vt8500/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..f119162
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/debug-macro.S
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * Debugging macro include header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+       .macro  addruart, rp, rv
+       mov     \rp,      #0x00200000
+       orr     \rv, \rp, #0xf8000000
+       orr     \rp, \rp, #0xd8000000
+       .endm
+
+       .macro  senduart,rd,rx
+       strb    \rd, [\rx, #0]
+       .endm
+
+       .macro  busyuart,rd,rx
+1001:  ldr     \rd, [\rx, #0x1c]
+       ands    \rd, \rd, #0x2
+       bne     1001b
+       .endm
+
+       .macro  waituart,rd,rx
+       .endm
diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S b/arch/arm/mach-vt8500/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..92684c7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for VIA VT8500
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       @ physical 0xd8140000 is virtual 0xf8140000
+       mov     \base, #0xf8000000
+       orr     \base, \base, #0x00140000
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       ldr     \irqnr, [\base]
+       cmp     \irqnr, #63 @ may be false positive, check interrupt status
+       bne     1001f
+       ldr     \irqstat, [\base, #0x84]
+       ands    \irqstat, #0x80000000
+       moveq   \irqnr, #0
+1001:
+       .endm
+
diff --git a/arch/arm/mach-vt8500/include/mach/gpio.h b/arch/arm/mach-vt8500/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..94ff276
--- /dev/null
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep  __gpio_cansleep
+#define gpio_to_irq    __gpio_to_irq
diff --git a/arch/arm/mach-vt8500/include/mach/hardware.h b/arch/arm/mach-vt8500/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..db4163f
--- /dev/null
@@ -0,0 +1,12 @@
+/* arch/arm/mach-vt8500/include/mach/hardware.h
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
diff --git a/arch/arm/mach-vt8500/include/mach/i8042.h b/arch/arm/mach-vt8500/include/mach/i8042.h
new file mode 100644 (file)
index 0000000..cd7143c
--- /dev/null
@@ -0,0 +1,18 @@
+/* arch/arm/mach-vt8500/include/mach/i8042.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+extern unsigned long wmt_i8042_base __initdata;
+extern int wmt_i8042_kbd_irq;
+extern int wmt_i8042_aux_irq;
diff --git a/arch/arm/mach-vt8500/include/mach/io.h b/arch/arm/mach-vt8500/include/mach/io.h
new file mode 100644 (file)
index 0000000..9077239
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/io.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+#define __io(a)                __typesafe_io((a) + 0xf0000000)
+#define __mem_pci(a)   (a)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/irqs.h b/arch/arm/mach-vt8500/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..a129fd1
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/irqs.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+/* This value is just to make the core happy, never used otherwise */
+#define NR_IRQS 128
diff --git a/arch/arm/mach-vt8500/include/mach/memory.h b/arch/arm/mach-vt8500/include/mach/memory.h
new file mode 100644 (file)
index 0000000..175f914
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/memory.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET    UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h
new file mode 100644 (file)
index 0000000..d6c757e
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/system.h
+ *
+ */
+#include <asm/io.h>
+
+/* PM Software Reset request register */
+#define VT8500_PMSR_VIRT       0xf8130060
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       writel(1, VT8500_PMSR_VIRT);
+}
diff --git a/arch/arm/mach-vt8500/include/mach/timex.h b/arch/arm/mach-vt8500/include/mach/timex.h
new file mode 100644 (file)
index 0000000..8487e4c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/timex.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+#ifndef MACH_TIMEX_H
+#define MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE                (3000000)
+
+#endif /* MACH_TIMEX_H */
diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h b/arch/arm/mach-vt8500/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..bb9e2d2
--- /dev/null
@@ -0,0 +1,37 @@
+/* arch/arm/mach-vt8500/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * Based on arch/arm/mach-dove/include/mach/uncompress.h
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#define UART0_PHYS 0xd8200000
+#include <asm/io.h>
+
+static void putc(const char c)
+{
+       while (readb(UART0_PHYS + 0x1c) & 0x2)
+               /* Tx busy, wait and poll */;
+
+       writeb(c, UART0_PHYS);
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vt8500/include/mach/vmalloc.h b/arch/arm/mach-vt8500/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..4642290
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END    0xd0000000UL
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
new file mode 100644 (file)
index 0000000..ecfee91
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+/* VT8500 Interrupt Sources */
+
+#define IRQ_JPEGENC    0       /* JPEG Encoder */
+#define IRQ_JPEGDEC    1       /* JPEG Decoder */
+                               /* Reserved */
+#define IRQ_PATA       3       /* PATA Controller */
+                               /* Reserved */
+#define IRQ_DMA                5       /* DMA Controller */
+#define IRQ_EXT0       6       /* External Interrupt 0 */
+#define IRQ_EXT1       7       /* External Interrupt 1 */
+#define IRQ_GE         8       /* Graphic Engine */
+#define IRQ_GOV                9       /* Graphic Overlay Engine */
+#define IRQ_ETHER      10      /* Ethernet MAC */
+#define IRQ_MPEGTS     11      /* Transport Stream Interface */
+#define IRQ_LCDC       12      /* LCD Controller */
+#define IRQ_EXT2       13      /* External Interrupt 2 */
+#define IRQ_EXT3       14      /* External Interrupt 3 */
+#define IRQ_EXT4       15      /* External Interrupt 4 */
+#define IRQ_CIPHER     16      /* Cipher */
+#define IRQ_VPP                17      /* Video Post-Processor */
+#define IRQ_I2C1       18      /* I2C 1 */
+#define IRQ_I2C0       19      /* I2C 0 */
+#define IRQ_SDMMC      20      /* SD/MMC Controller */
+#define IRQ_SDMMC_DMA  21      /* SD/MMC Controller DMA */
+#define IRQ_PMC_WU     22      /* Power Management Controller Wakeup */
+                               /* Reserved */
+#define IRQ_SPI0       24      /* SPI 0 */
+#define IRQ_SPI1       25      /* SPI 1 */
+#define IRQ_SPI2       26      /* SPI 2 */
+#define IRQ_LCDDF      27      /* LCD Data Formatter */
+#define IRQ_NAND       28      /* NAND Flash Controller */
+#define IRQ_NAND_DMA   29      /* NAND Flash Controller DMA */
+#define IRQ_MS         30      /* MemoryStick Controller */
+#define IRQ_MS_DMA     31      /* MemoryStick Controller DMA */
+#define IRQ_UART0      32      /* UART 0 */
+#define IRQ_UART1      33      /* UART 1 */
+#define IRQ_I2S                34      /* I2S */
+#define IRQ_PCM                35      /* PCM */
+#define IRQ_PMCOS0     36      /* PMC OS Timer 0 */
+#define IRQ_PMCOS1     37      /* PMC OS Timer 1 */
+#define IRQ_PMCOS2     38      /* PMC OS Timer 2 */
+#define IRQ_PMCOS3     39      /* PMC OS Timer 3 */
+#define IRQ_VPU                40      /* Video Processing Unit */
+#define IRQ_VID                41      /* Video Digital Input Interface */
+#define IRQ_AC97       42      /* AC97 Interface */
+#define IRQ_EHCI       43      /* USB */
+#define IRQ_NOR                44      /* NOR Flash Controller */
+#define IRQ_PS2MOUSE   45      /* PS/2 Mouse */
+#define IRQ_PS2KBD     46      /* PS/2 Keyboard */
+#define IRQ_UART2      47      /* UART 2 */
+#define IRQ_RTC                48      /* RTC Interrupt */
+#define IRQ_RTCSM      49      /* RTC Second/Minute Update Interrupt */
+#define IRQ_UART3      50      /* UART 3 */
+#define IRQ_ADC                51      /* ADC */
+#define IRQ_EXT5       52      /* External Interrupt 5 */
+#define IRQ_EXT6       53      /* External Interrupt 6 */
+#define IRQ_EXT7       54      /* External Interrupt 7 */
+#define IRQ_CIR                55      /* CIR */
+#define IRQ_DMA0       56      /* DMA Channel 0 */
+#define IRQ_DMA1       57      /* DMA Channel 1 */
+#define IRQ_DMA2       58      /* DMA Channel 2 */
+#define IRQ_DMA3       59      /* DMA Channel 3 */
+#define IRQ_DMA4       60      /* DMA Channel 4 */
+#define IRQ_DMA5       61      /* DMA Channel 5 */
+#define IRQ_DMA6       62      /* DMA Channel 6 */
+#define IRQ_DMA7       63      /* DMA Channel 7 */
+
+#define VT8500_NR_IRQS         64
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_regs.h b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
new file mode 100644 (file)
index 0000000..29c63ec
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/vt8500_regs.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_VT8500_REGS_H
+#define __ASM_ARM_ARCH_VT8500_REGS_H
+
+/* VT8500 Registers Map */
+
+#define VT8500_REGS_START_PHYS 0xd8000000      /* Start of MMIO registers */
+#define VT8500_REGS_START_VIRT 0xf8000000      /* Virtual mapping start */
+
+#define VT8500_DDR_BASE                0xd8000000      /* 1k   DDR/DDR2 Memory
+                                                       Controller */
+#define VT8500_DMA_BASE                0xd8001000      /* 1k   DMA Controller */
+#define VT8500_SFLASH_BASE     0xd8002000      /* 1k   Serial Flash Memory
+                                                       Controller */
+#define VT8500_ETHER_BASE      0xd8004000      /* 1k   Ethernet MAC 0 */
+#define VT8500_CIPHER_BASE     0xd8006000      /* 4k   Cipher */
+#define VT8500_USB_BASE                0xd8007800      /* 2k   USB OTG */
+# define VT8500_EHCI_BASE      0xd8007900      /*      EHCI */
+# define VT8500_UHCI_BASE      0xd8007b01      /*      UHCI */
+#define VT8500_PATA_BASE       0xd8008000      /* 512  PATA */
+#define VT8500_PS2_BASE                0xd8008800      /* 1k   PS/2 */
+#define VT8500_NAND_BASE       0xd8009000      /* 1k   NAND Controller */
+#define VT8500_NOR_BASE                0xd8009400      /* 1k   NOR Controller */
+#define VT8500_SDMMC_BASE      0xd800a000      /* 1k   SD/MMC Controller */
+#define VT8500_MS_BASE         0xd800b000      /* 1k   MS/MSPRO Controller */
+#define VT8500_LCDC_BASE       0xd800e400      /* 1k   LCD Controller */
+#define VT8500_VPU_BASE                0xd8050000      /* 256  VPU */
+#define VT8500_GOV_BASE                0xd8050300      /* 256  GOV */
+#define VT8500_GEGEA_BASE      0xd8050400      /* 768  GE/GE Alpha Mixing */
+#define VT8500_LCDF_BASE       0xd8050900      /* 256  LCD Formatter */
+#define VT8500_VID_BASE                0xd8050a00      /* 256  VID */
+#define VT8500_VPP_BASE                0xd8050b00      /* 256  VPP */
+#define VT8500_TSBK_BASE       0xd80f4000      /* 4k   TSBK */
+#define VT8500_JPEGDEC_BASE    0xd80fe000      /* 4k   JPEG Decoder */
+#define VT8500_JPEGENC_BASE    0xd80ff000      /* 4k   JPEG Encoder */
+#define VT8500_RTC_BASE                0xd8100000      /* 64k  RTC */
+#define VT8500_GPIO_BASE       0xd8110000      /* 64k  GPIO Configuration */
+#define VT8500_SCC_BASE                0xd8120000      /* 64k  System Configuration*/
+#define VT8500_PMC_BASE                0xd8130000      /* 64k  PMC Configuration */
+#define VT8500_IC_BASE         0xd8140000      /* 64k  Interrupt Controller*/
+#define VT8500_UART0_BASE      0xd8200000      /* 64k  UART 0 */
+#define VT8500_UART2_BASE      0xd8210000      /* 64k  UART 2 */
+#define VT8500_PWM_BASE                0xd8220000      /* 64k  PWM Configuration */
+#define VT8500_SPI0_BASE       0xd8240000      /* 64k  SPI 0 */
+#define VT8500_SPI1_BASE       0xd8250000      /* 64k  SPI 1 */
+#define VT8500_CIR_BASE                0xd8270000      /* 64k  CIR */
+#define VT8500_I2C0_BASE       0xd8280000      /* 64k  I2C 0 */
+#define VT8500_AC97_BASE       0xd8290000      /* 64k  AC97 */
+#define VT8500_SPI2_BASE       0xd82a0000      /* 64k  SPI 2 */
+#define VT8500_UART1_BASE      0xd82b0000      /* 64k  UART 1 */
+#define VT8500_UART3_BASE      0xd82c0000      /* 64k  UART 3 */
+#define VT8500_PCM_BASE                0xd82d0000      /* 64k  PCM */
+#define VT8500_I2C1_BASE       0xd8320000      /* 64k  I2C 1 */
+#define VT8500_I2S_BASE                0xd8330000      /* 64k  I2S */
+#define VT8500_ADC_BASE                0xd8340000      /* 64k  ADC */
+
+#define VT8500_REGS_END_PHYS   0xd834ffff      /* End of MMIO registers */
+#define VT8500_REGS_LENGTH     (VT8500_REGS_END_PHYS \
+                               - VT8500_REGS_START_PHYS + 1)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500fb.h b/arch/arm/mach-vt8500/include/mach/vt8500fb.h
new file mode 100644 (file)
index 0000000..7f399c3
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  VT8500/WM8505 Frame Buffer platform data definitions
+ *
+ *  Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#ifndef _VT8500FB_H
+#define _VT8500FB_H
+
+#include <linux/fb.h>
+
+struct vt8500fb_platform_data {
+       struct fb_videomode     mode;
+       u32                     xres_virtual;
+       u32                     yres_virtual;
+       u32                     bpp;
+       unsigned long           video_mem_phys;
+       void                    *video_mem_virt;
+       unsigned long           video_mem_len;
+};
+
+#endif /* _VT8500FB_H */
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
new file mode 100644 (file)
index 0000000..6128627
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+/* WM8505 Interrupt Sources */
+
+#define IRQ_UHCI       0       /* UHC FS (UHCI?) */
+#define IRQ_EHCI       1       /* UHC HS */
+#define IRQ_UDCDMA     2       /* UDC DMA */
+                               /* Reserved */
+#define IRQ_PS2MOUSE   4       /* PS/2 Mouse */
+#define IRQ_UDC                5       /* UDC */
+#define IRQ_EXT0       6       /* External Interrupt 0 */
+#define IRQ_EXT1       7       /* External Interrupt 1 */
+#define IRQ_KEYPAD     8       /* Keypad */
+#define IRQ_DMA                9       /* DMA Controller */
+#define IRQ_ETHER      10      /* Ethernet MAC */
+                               /* Reserved */
+                               /* Reserved */
+#define IRQ_EXT2       13      /* External Interrupt 2 */
+#define IRQ_EXT3       14      /* External Interrupt 3 */
+#define IRQ_EXT4       15      /* External Interrupt 4 */
+#define IRQ_APB                16      /* APB Bridge */
+#define IRQ_DMA0       17      /* DMA Channel 0 */
+#define IRQ_I2C1       18      /* I2C 1 */
+#define IRQ_I2C0       19      /* I2C 0 */
+#define IRQ_SDMMC      20      /* SD/MMC Controller */
+#define IRQ_SDMMC_DMA  21      /* SD/MMC Controller DMA */
+#define IRQ_PMC_WU     22      /* Power Management Controller Wakeup */
+#define IRQ_PS2KBD     23      /* PS/2 Keyboard */
+#define IRQ_SPI0       24      /* SPI 0 */
+#define IRQ_SPI1       25      /* SPI 1 */
+#define IRQ_SPI2       26      /* SPI 2 */
+#define IRQ_DMA1       27      /* DMA Channel 1 */
+#define IRQ_NAND       28      /* NAND Flash Controller */
+#define IRQ_NAND_DMA   29      /* NAND Flash Controller DMA */
+#define IRQ_UART5      30      /* UART 5 */
+#define IRQ_UART4      31      /* UART 4 */
+#define IRQ_UART0      32      /* UART 0 */
+#define IRQ_UART1      33      /* UART 1 */
+#define IRQ_DMA2       34      /* DMA Channel 2 */
+#define IRQ_I2S                35      /* I2S */
+#define IRQ_PMCOS0     36      /* PMC OS Timer 0 */
+#define IRQ_PMCOS1     37      /* PMC OS Timer 1 */
+#define IRQ_PMCOS2     38      /* PMC OS Timer 2 */
+#define IRQ_PMCOS3     39      /* PMC OS Timer 3 */
+#define IRQ_DMA3       40      /* DMA Channel 3 */
+#define IRQ_DMA4       41      /* DMA Channel 4 */
+#define IRQ_AC97       42      /* AC97 Interface */
+                               /* Reserved */
+#define IRQ_NOR                44      /* NOR Flash Controller */
+#define IRQ_DMA5       45      /* DMA Channel 5 */
+#define IRQ_DMA6       46      /* DMA Channel 6 */
+#define IRQ_UART2      47      /* UART 2 */
+#define IRQ_RTC                48      /* RTC Interrupt */
+#define IRQ_RTCSM      49      /* RTC Second/Minute Update Interrupt */
+#define IRQ_UART3      50      /* UART 3 */
+#define IRQ_DMA7       51      /* DMA Channel 7 */
+#define IRQ_EXT5       52      /* External Interrupt 5 */
+#define IRQ_EXT6       53      /* External Interrupt 6 */
+#define IRQ_EXT7       54      /* External Interrupt 7 */
+#define IRQ_CIR                55      /* CIR */
+#define IRQ_SIC0       56      /* SIC IRQ0 */
+#define IRQ_SIC1       57      /* SIC IRQ1 */
+#define IRQ_SIC2       58      /* SIC IRQ2 */
+#define IRQ_SIC3       59      /* SIC IRQ3 */
+#define IRQ_SIC4       60      /* SIC IRQ4 */
+#define IRQ_SIC5       61      /* SIC IRQ5 */
+#define IRQ_SIC6       62      /* SIC IRQ6 */
+#define IRQ_SIC7       63      /* SIC IRQ7 */
+                               /* Reserved */
+#define IRQ_JPEGDEC    65      /* JPEG Decoder */
+#define IRQ_SAE                66      /* SAE (?) */
+                               /* Reserved */
+#define IRQ_VPU                79      /* Video Processing Unit */
+#define IRQ_VPP                80      /* Video Post-Processor */
+#define IRQ_VID                81      /* Video Digital Input Interface */
+#define IRQ_SPU                82      /* SPU (?) */
+#define IRQ_PIP                83      /* PIP Error */
+#define IRQ_GE         84      /* Graphic Engine */
+#define IRQ_GOV                85      /* Graphic Overlay Engine */
+#define IRQ_DVO                86      /* Digital Video Output */
+                               /* Reserved */
+#define IRQ_DMA8       92      /* DMA Channel 8 */
+#define IRQ_DMA9       93      /* DMA Channel 9 */
+#define IRQ_DMA10      94      /* DMA Channel 10 */
+#define IRQ_DMA11      95      /* DMA Channel 11 */
+#define IRQ_DMA12      96      /* DMA Channel 12 */
+#define IRQ_DMA13      97      /* DMA Channel 13 */
+#define IRQ_DMA14      98      /* DMA Channel 14 */
+#define IRQ_DMA15      99      /* DMA Channel 15 */
+                               /* Reserved */
+#define IRQ_GOVW       111     /* GOVW (?) */
+#define IRQ_GOVRSDSCD  112     /* GOVR SDSCD (?) */
+#define IRQ_GOVRSDMIF  113     /* GOVR SDMIF (?) */
+#define IRQ_GOVRHDSCD  114     /* GOVR HDSCD (?) */
+#define IRQ_GOVRHDMIF  115     /* GOVR HDMIF (?) */
+
+#define WM8505_NR_IRQS         116
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_regs.h b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
new file mode 100644 (file)
index 0000000..df15509
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  arch/arm/mach-vt8500/include/mach/wm8505_regs.h
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+#ifndef __ASM_ARM_ARCH_WM8505_REGS_H
+#define __ASM_ARM_ARCH_WM8505_REGS_H
+
+/* WM8505 Registers Map */
+
+#define WM8505_REGS_START_PHYS 0xd8000000      /* Start of MMIO registers */
+#define WM8505_REGS_START_VIRT 0xf8000000      /* Virtual mapping start */
+
+#define WM8505_DDR_BASE                0xd8000400      /* 1k   DDR/DDR2 Memory
+                                                       Controller */
+#define WM8505_DMA_BASE                0xd8001800      /* 1k   DMA Controller */
+#define WM8505_VDMA_BASE       0xd8001c00      /* 1k   VDMA */
+#define WM8505_SFLASH_BASE     0xd8002000      /* 1k   Serial Flash Memory
+                                                       Controller */
+#define WM8505_ETHER_BASE      0xd8004000      /* 1k   Ethernet MAC 0 */
+#define WM8505_CIPHER_BASE     0xd8006000      /* 4k   Cipher */
+#define WM8505_USB_BASE                0xd8007000      /* 2k   USB 2.0 Host */
+# define WM8505_EHCI_BASE      0xd8007100      /*      EHCI */
+# define WM8505_UHCI_BASE      0xd8007301      /*      UHCI */
+#define WM8505_PS2_BASE                0xd8008800      /* 1k   PS/2 */
+#define WM8505_NAND_BASE       0xd8009000      /* 1k   NAND Controller */
+#define WM8505_NOR_BASE                0xd8009400      /* 1k   NOR Controller */
+#define WM8505_SDMMC_BASE      0xd800a000      /* 1k   SD/MMC Controller */
+#define WM8505_VPU_BASE                0xd8050000      /* 256  VPU */
+#define WM8505_GOV_BASE                0xd8050300      /* 256  GOV */
+#define WM8505_GEGEA_BASE      0xd8050400      /* 768  GE/GE Alpha Mixing */
+#define WM8505_GOVR_BASE       0xd8050800      /* 512  GOVR (frambuffer) */
+#define WM8505_VID_BASE                0xd8050a00      /* 256  VID */
+#define WM8505_SCL_BASE                0xd8050d00      /* 256  SCL */
+#define WM8505_VPP_BASE                0xd8050f00      /* 256  VPP */
+#define WM8505_JPEGDEC_BASE    0xd80fe000      /* 4k   JPEG Decoder */
+#define WM8505_RTC_BASE                0xd8100000      /* 64k  RTC */
+#define WM8505_GPIO_BASE       0xd8110000      /* 64k  GPIO Configuration */
+#define WM8505_SCC_BASE                0xd8120000      /* 64k  System Configuration*/
+#define WM8505_PMC_BASE                0xd8130000      /* 64k  PMC Configuration */
+#define WM8505_IC_BASE         0xd8140000      /* 64k  Interrupt Controller*/
+#define WM8505_SIC_BASE                0xd8150000      /* 64k  Secondary IC */
+#define WM8505_UART0_BASE      0xd8200000      /* 64k  UART 0 */
+#define WM8505_UART2_BASE      0xd8210000      /* 64k  UART 2 */
+#define WM8505_PWM_BASE                0xd8220000      /* 64k  PWM Configuration */
+#define WM8505_SPI0_BASE       0xd8240000      /* 64k  SPI 0 */
+#define WM8505_SPI1_BASE       0xd8250000      /* 64k  SPI 1 */
+#define WM8505_KEYPAD_BASE     0xd8260000      /* 64k  Keypad control */
+#define WM8505_CIR_BASE                0xd8270000      /* 64k  CIR */
+#define WM8505_I2C0_BASE       0xd8280000      /* 64k  I2C 0 */
+#define WM8505_AC97_BASE       0xd8290000      /* 64k  AC97 */
+#define WM8505_SPI2_BASE       0xd82a0000      /* 64k  SPI 2 */
+#define WM8505_UART1_BASE      0xd82b0000      /* 64k  UART 1 */
+#define WM8505_UART3_BASE      0xd82c0000      /* 64k  UART 3 */
+#define WM8505_I2C1_BASE       0xd8320000      /* 64k  I2C 1 */
+#define WM8505_I2S_BASE                0xd8330000      /* 64k  I2S */
+#define WM8505_UART4_BASE      0xd8370000      /* 64k  UART 4 */
+#define WM8505_UART5_BASE      0xd8380000      /* 64k  UART 5 */
+
+#define WM8505_REGS_END_PHYS   0xd838ffff      /* End of MMIO registers */
+#define WM8505_REGS_LENGTH     (WM8505_REGS_END_PHYS \
+                               - WM8505_REGS_START_PHYS + 1)
+
+#endif
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
new file mode 100644 (file)
index 0000000..5f4ddde
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  arch/arm/mach-vt8500/irq.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+
+#include "devices.h"
+
+#define VT8500_IC_DCTR         0x40            /* Destination control
+                                               register, 64*u8 */
+#define VT8500_INT_ENABLE      (1 << 3)
+#define VT8500_TRIGGER_HIGH    (0 << 4)
+#define VT8500_TRIGGER_RISING  (1 << 4)
+#define VT8500_TRIGGER_FALLING (2 << 4)
+#define VT8500_EDGE            ( VT8500_TRIGGER_RISING \
+                               | VT8500_TRIGGER_FALLING)
+#define VT8500_IC_STATUS       0x80            /* Interrupt status, 2*u32 */
+
+static void __iomem *ic_regbase;
+static void __iomem *sic_regbase;
+
+static void vt8500_irq_mask(unsigned int irq)
+{
+       void __iomem *base = ic_regbase;
+       u8 edge;
+
+       if (irq >= 64) {
+               base = sic_regbase;
+               irq -= 64;
+       }
+       edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE;
+       if (edge) {
+               void __iomem *stat_reg = base + VT8500_IC_STATUS
+                                               + (irq < 32 ? 0 : 4);
+               unsigned status = readl(stat_reg);
+
+               status |= (1 << (irq & 0x1f));
+               writel(status, stat_reg);
+       } else {
+               u8 dctr = readb(base + VT8500_IC_DCTR + irq);
+
+               dctr &= ~VT8500_INT_ENABLE;
+               writeb(dctr, base + VT8500_IC_DCTR + irq);
+       }
+}
+
+static void vt8500_irq_unmask(unsigned int irq)
+{
+       void __iomem *base = ic_regbase;
+       u8 dctr;
+
+       if (irq >= 64) {
+               base = sic_regbase;
+               irq -= 64;
+       }
+       dctr = readb(base + VT8500_IC_DCTR + irq);
+       dctr |= VT8500_INT_ENABLE;
+       writeb(dctr, base + VT8500_IC_DCTR + irq);
+}
+
+static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+       void __iomem *base = ic_regbase;
+       unsigned int orig_irq = irq;
+       u8 dctr;
+
+       if (irq >= 64) {
+               base = sic_regbase;
+               irq -= 64;
+       }
+
+       dctr = readb(base + VT8500_IC_DCTR + irq);
+       dctr &= ~VT8500_EDGE;
+
+       switch (flow_type) {
+       case IRQF_TRIGGER_LOW:
+               return -EINVAL;
+       case IRQF_TRIGGER_HIGH:
+               dctr |= VT8500_TRIGGER_HIGH;
+               irq_desc[orig_irq].handle_irq = handle_level_irq;
+               break;
+       case IRQF_TRIGGER_FALLING:
+               dctr |= VT8500_TRIGGER_FALLING;
+               irq_desc[orig_irq].handle_irq = handle_edge_irq;
+               break;
+       case IRQF_TRIGGER_RISING:
+               dctr |= VT8500_TRIGGER_RISING;
+               irq_desc[orig_irq].handle_irq = handle_edge_irq;
+               break;
+       }
+       writeb(dctr, base + VT8500_IC_DCTR + irq);
+
+       return 0;
+}
+
+static struct irq_chip vt8500_irq_chip = {
+       .name      = "vt8500",
+       .ack       = vt8500_irq_mask,
+       .mask      = vt8500_irq_mask,
+       .unmask    = vt8500_irq_unmask,
+       .set_type  = vt8500_irq_set_type,
+};
+
+void __init vt8500_init_irq(void)
+{
+       unsigned int i;
+
+       ic_regbase = ioremap(wmt_ic_base, SZ_64K);
+
+       if (ic_regbase) {
+               /* Enable rotating priority for IRQ */
+               writel((1 << 6), ic_regbase + 0x20);
+               writel(0, ic_regbase + 0x24);
+
+               for (i = 0; i < wmt_nr_irqs; i++) {
+                       /* Disable all interrupts and route them to IRQ */
+                       writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
+
+                       set_irq_chip(i, &vt8500_irq_chip);
+                       set_irq_handler(i, handle_level_irq);
+                       set_irq_flags(i, IRQF_VALID);
+               }
+       } else {
+               printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+       }
+}
+
+void __init wm8505_init_irq(void)
+{
+       unsigned int i;
+
+       ic_regbase = ioremap(wmt_ic_base, SZ_64K);
+       sic_regbase = ioremap(wmt_sic_base, SZ_64K);
+
+       if (ic_regbase && sic_regbase) {
+               /* Enable rotating priority for IRQ */
+               writel((1 << 6), ic_regbase + 0x20);
+               writel(0, ic_regbase + 0x24);
+               writel((1 << 6), sic_regbase + 0x20);
+               writel(0, sic_regbase + 0x24);
+
+               for (i = 0; i < wmt_nr_irqs; i++) {
+                       /* Disable all interrupts and route them to IRQ */
+                       if (i < 64)
+                               writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
+                       else
+                               writeb(0x00, sic_regbase + VT8500_IC_DCTR
+                                                               + i - 64);
+
+                       set_irq_chip(i, &vt8500_irq_chip);
+                       set_irq_handler(i, handle_level_irq);
+                       set_irq_flags(i, IRQF_VALID);
+               }
+       } else {
+               printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+       }
+}
diff --git a/arch/arm/mach-vt8500/pwm.c b/arch/arm/mach-vt8500/pwm.c
new file mode 100644 (file)
index 0000000..8ad825e
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * arch/arm/mach-vt8500/pwm.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+#include <linux/delay.h>
+
+#include <asm/div64.h>
+
+#define VT8500_NR_PWMS 4
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device {
+       struct list_head        node;
+       struct platform_device  *pdev;
+
+       const char      *label;
+
+       void __iomem    *regbase;
+
+       unsigned int    use_count;
+       unsigned int    pwm_id;
+};
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask)
+{
+       int loops = msecs_to_loops(10);
+       while ((readb(reg) & bitmask) && --loops)
+               cpu_relax();
+
+       if (unlikely(!loops))
+               pr_warning("Waiting for status bits 0x%x to clear timed out\n",
+                          bitmask);
+}
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+       unsigned long long c;
+       unsigned long period_cycles, prescale, pv, dc;
+
+       if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+               return -EINVAL;
+
+       c = 25000000/2; /* wild guess --- need to implement clocks */
+       c = c * period_ns;
+       do_div(c, 1000000000);
+       period_cycles = c;
+
+       if (period_cycles < 1)
+               period_cycles = 1;
+       prescale = (period_cycles - 1) / 4096;
+       pv = period_cycles / (prescale + 1) - 1;
+       if (pv > 4095)
+               pv = 4095;
+
+       if (prescale > 1023)
+               return -EINVAL;
+
+       c = (unsigned long long)pv * duty_ns;
+       do_div(c, period_ns);
+       dc = c;
+
+       pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1));
+       writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4));
+
+       pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2));
+       writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4));
+
+       pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3));
+       writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4));
+
+       return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+       pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
+       writel(5, pwm->regbase + (pwm->pwm_id << 4));
+       return 0;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+       pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
+       writel(0, pwm->regbase + (pwm->pwm_id << 4));
+}
+EXPORT_SYMBOL(pwm_disable);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+       struct pwm_device *pwm;
+       int found = 0;
+
+       mutex_lock(&pwm_lock);
+
+       list_for_each_entry(pwm, &pwm_list, node) {
+               if (pwm->pwm_id == pwm_id) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found) {
+               if (pwm->use_count == 0) {
+                       pwm->use_count++;
+                       pwm->label = label;
+               } else {
+                       pwm = ERR_PTR(-EBUSY);
+               }
+       } else {
+               pwm = ERR_PTR(-ENOENT);
+       }
+
+       mutex_unlock(&pwm_lock);
+       return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+       mutex_lock(&pwm_lock);
+
+       if (pwm->use_count) {
+               pwm->use_count--;
+               pwm->label = NULL;
+       } else {
+               pr_warning("PWM device already freed\n");
+       }
+
+       mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static inline void __add_pwm(struct pwm_device *pwm)
+{
+       mutex_lock(&pwm_lock);
+       list_add_tail(&pwm->node, &pwm_list);
+       mutex_unlock(&pwm_lock);
+}
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+       struct pwm_device *pwms;
+       struct resource *r;
+       int ret = 0;
+       int i;
+
+       pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL);
+       if (pwms == NULL) {
+               dev_err(&pdev->dev, "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < VT8500_NR_PWMS; i++) {
+               pwms[i].use_count = 0;
+               pwms[i].pwm_id = i;
+               pwms[i].pdev = pdev;
+       }
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (r == NULL) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               ret = -ENODEV;
+               goto err_free;
+       }
+
+       r = request_mem_region(r->start, resource_size(r), pdev->name);
+       if (r == NULL) {
+               dev_err(&pdev->dev, "failed to request memory resource\n");
+               ret = -EBUSY;
+               goto err_free;
+       }
+
+       pwms[0].regbase = ioremap(r->start, resource_size(r));
+       if (pwms[0].regbase == NULL) {
+               dev_err(&pdev->dev, "failed to ioremap() registers\n");
+               ret = -ENODEV;
+               goto err_free_mem;
+       }
+
+       for (i = 1; i < VT8500_NR_PWMS; i++)
+               pwms[i].regbase = pwms[0].regbase;
+
+       for (i = 0; i < VT8500_NR_PWMS; i++)
+               __add_pwm(&pwms[i]);
+
+       platform_set_drvdata(pdev, pwms);
+       return 0;
+
+err_free_mem:
+       release_mem_region(r->start, resource_size(r));
+err_free:
+       kfree(pwms);
+       return ret;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+       struct pwm_device *pwms;
+       struct resource *r;
+       int i;
+
+       pwms = platform_get_drvdata(pdev);
+       if (pwms == NULL)
+               return -ENODEV;
+
+       mutex_lock(&pwm_lock);
+
+       for (i = 0; i < VT8500_NR_PWMS; i++)
+               list_del(&pwms[i].node);
+       mutex_unlock(&pwm_lock);
+
+       iounmap(pwms[0].regbase);
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(r->start, resource_size(r));
+
+       kfree(pwms);
+       return 0;
+}
+
+static struct platform_driver pwm_driver = {
+       .driver         = {
+               .name   = "vt8500-pwm",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = pwm_probe,
+       .remove         = __devexit_p(pwm_remove),
+};
+
+static int __init pwm_init(void)
+{
+       return platform_driver_register(&pwm_driver);
+}
+arch_initcall(pwm_init);
+
+static void __exit pwm_exit(void)
+{
+       platform_driver_unregister(&pwm_driver);
+}
+module_exit(pwm_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
new file mode 100644 (file)
index 0000000..d5376c5
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *  arch/arm/mach-vt8500/timer.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+
+#include <asm/mach/time.h>
+
+#include "devices.h"
+
+#define VT8500_TIMER_OFFSET    0x0100
+#define TIMER_MATCH_VAL                0x0000
+#define TIMER_COUNT_VAL                0x0010
+#define TIMER_STATUS_VAL       0x0014
+#define TIMER_IER_VAL          0x001c          /* interrupt enable */
+#define TIMER_CTRL_VAL         0x0020
+#define TIMER_AS_VAL           0x0024          /* access status */
+#define TIMER_COUNT_R_ACTIVE   (1 << 5)        /* not ready for read */
+#define TIMER_COUNT_W_ACTIVE   (1 << 4)        /* not ready for write */
+#define TIMER_MATCH_W_ACTIVE   (1 << 0)        /* not ready for write */
+#define VT8500_TIMER_HZ                3000000
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+static void __iomem *regbase;
+
+static cycle_t vt8500_timer_read(struct clocksource *cs)
+{
+       int loops = msecs_to_loops(10);
+       writel(3, regbase + TIMER_CTRL_VAL);
+       while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE)
+                                               && --loops)
+               cpu_relax();
+       return readl(regbase + TIMER_COUNT_VAL);
+}
+
+struct clocksource clocksource = {
+       .name           = "vt8500_timer",
+       .rating         = 200,
+       .read           = vt8500_timer_read,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int vt8500_timer_set_next_event(unsigned long cycles,
+                                   struct clock_event_device *evt)
+{
+       int loops = msecs_to_loops(10);
+       cycle_t alarm = clocksource.read(&clocksource) + cycles;
+       while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE)
+                                               && --loops)
+               cpu_relax();
+       writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
+
+       if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
+               return -ETIME;
+
+       writel(1, regbase + TIMER_IER_VAL);
+
+       return 0;
+}
+
+static void vt8500_timer_set_mode(enum clock_event_mode mode,
+                             struct clock_event_device *evt)
+{
+       switch (mode) {
+       case CLOCK_EVT_MODE_RESUME:
+       case CLOCK_EVT_MODE_PERIODIC:
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               writel(readl(regbase + TIMER_CTRL_VAL) | 1,
+                       regbase + TIMER_CTRL_VAL);
+               writel(0, regbase + TIMER_IER_VAL);
+               break;
+       }
+}
+
+struct clock_event_device clockevent = {
+       .name           = "vt8500_timer",
+       .features       = CLOCK_EVT_FEAT_ONESHOT,
+       .rating         = 200,
+       .set_next_event = vt8500_timer_set_next_event,
+       .set_mode       = vt8500_timer_set_mode,
+};
+
+static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+       writel(0xf, regbase + TIMER_STATUS_VAL);
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+struct irqaction irq = {
+       .name    = "vt8500_timer",
+       .flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler = vt8500_timer_interrupt,
+       .dev_id  = &clockevent,
+};
+
+static void __init vt8500_timer_init(void)
+{
+       regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28);
+       if (!regbase)
+               printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n");
+
+       writel(1, regbase + TIMER_CTRL_VAL);
+       writel(0xf, regbase + TIMER_STATUS_VAL);
+       writel(~0, regbase + TIMER_MATCH_VAL);
+
+       if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
+               printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n",
+                                       clocksource.name);
+
+       clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4);
+
+       /* copy-pasted from mach-msm; no idea */
+       clockevent.max_delta_ns =
+               clockevent_delta2ns(0xf0000000, &clockevent);
+       clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent);
+       clockevent.cpumask = cpumask_of(0);
+
+       if (setup_irq(wmt_timer_irq, &irq))
+               printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n",
+                                       clockevent.name);
+       clockevents_register_device(&clockevent);
+}
+
+struct sys_timer vt8500_timer = {
+       .init = vt8500_timer_init
+};
diff --git a/arch/arm/mach-vt8500/wm8505_7in.c b/arch/arm/mach-vt8500/wm8505_7in.c
new file mode 100644 (file)
index 0000000..e73aadb
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  arch/arm/mach-vt8500/wm8505_7in.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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.
+ *
+ * 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
+ */
+
+#include <linux/io.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "devices.h"
+
+static void __iomem *pmc_hiber;
+
+static struct platform_device *devices[] __initdata = {
+       &vt8500_device_uart0,
+       &vt8500_device_ehci,
+       &vt8500_device_wm8505_fb,
+       &vt8500_device_ge_rops,
+       &vt8500_device_pwm,
+       &vt8500_device_pwmbl,
+       &vt8500_device_rtc,
+};
+
+static void vt8500_power_off(void)
+{
+       local_irq_disable();
+       writew(5, pmc_hiber);
+       asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+void __init wm8505_7in_init(void)
+{
+#ifdef CONFIG_FB_WM8505
+       void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
+       if (gpio_mux_reg) {
+               writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg);
+               iounmap(gpio_mux_reg);
+       } else {
+               printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
+       }
+#endif
+       pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
+       if (pmc_hiber)
+               pm_power_off = &vt8500_power_off;
+       else
+               printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
+
+       wm8505_set_resources();
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+       vt8500_gpio_init();
+}
+
+MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook")
+       .boot_params    = 0x00000100,
+       .reserve        = wm8505_reserve_mem,
+       .map_io         = wm8505_map_io,
+       .init_irq       = wm8505_init_irq,
+       .timer          = &vt8500_timer,
+       .init_machine   = wm8505_7in_init,
+MACHINE_END
index bcf748d9f4e253bc34ec9a885f5d0fe4f58b16c7..226e3d8351c2538a11ad231d4fdb0430ebdd8cc6 100644 (file)
@@ -493,6 +493,9 @@ arm1020_processor_functions:
        .word   cpu_arm1020_dcache_clean_area
        .word   cpu_arm1020_switch_mm
        .word   cpu_arm1020_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm1020_processor_functions, . - arm1020_processor_functions
 
        .section ".rodata"
index ab7ec26657eaf024a7f69bf8c2603f47d88c1304..86d9c2cf0bce374e9fa437fb9f4e8b64ef55b378 100644 (file)
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
        .word   cpu_arm1020e_dcache_clean_area
        .word   cpu_arm1020e_switch_mm
        .word   cpu_arm1020e_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm1020e_processor_functions, . - arm1020e_processor_functions
 
        .section ".rodata"
index 831c5e54e22f0e7fe795bedc4d619dae26ed9c39..83d3dd34f84629f4bc7a05a61b4a567ce5db4edb 100644 (file)
@@ -457,6 +457,9 @@ arm1022_processor_functions:
        .word   cpu_arm1022_dcache_clean_area
        .word   cpu_arm1022_switch_mm
        .word   cpu_arm1022_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm1022_processor_functions, . - arm1022_processor_functions
 
        .section ".rodata"
index e3f7e9a166bfc6668574dc2a7518f56cee9476a6..686043ee7281782065b4ed668f7e1b8dc4406e5c 100644 (file)
@@ -452,6 +452,9 @@ arm1026_processor_functions:
        .word   cpu_arm1026_dcache_clean_area
        .word   cpu_arm1026_switch_mm
        .word   cpu_arm1026_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm1026_processor_functions, . - arm1026_processor_functions
 
        .section .rodata
index 6a7be1863eddaf317640fc41b25ecfdfc1b089f1..5f79dc4ce3fbc98d76d32423b7b0dcb619ffe778 100644 (file)
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
                .word   cpu_arm6_dcache_clean_area
                .word   cpu_arm6_switch_mm
                .word   cpu_arm6_set_pte_ext
+               .word   0
+               .word   0
+               .word   0
                .size   arm6_processor_functions, . - arm6_processor_functions
 
 /*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
                .word   cpu_arm7_dcache_clean_area
                .word   cpu_arm7_switch_mm
                .word   cpu_arm7_set_pte_ext
+               .word   0
+               .word   0
+               .word   0
                .size   arm7_processor_functions, . - arm7_processor_functions
 
                .section ".rodata"
index c285395f44b24e5f5dfb7bc92be1e7f4bd3935be..665266da143cfe7dc283fb437002eb354bae1337 100644 (file)
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
                .word   cpu_arm720_dcache_clean_area
                .word   cpu_arm720_switch_mm
                .word   cpu_arm720_set_pte_ext
+               .word   0
+               .word   0
+               .word   0
                .size   arm720_processor_functions, . - arm720_processor_functions
 
                .section ".rodata"
index 38b27dcba7275bd1038c62990bd49a9d35908f70..6f9d12effee18ccd1bceefa1490093702090c602 100644 (file)
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
        .word   cpu_arm740_dcache_clean_area
        .word   cpu_arm740_switch_mm
        .word   0                       @ cpu_*_set_pte
+       .word   0
+       .word   0
+       .word   0
        .size   arm740_processor_functions, . - arm740_processor_functions
 
        .section ".rodata"
index 0c9786de20af3575100f21b3e3de6d1e006e4f71..e4c165ca669680eb6d74ce8e3d5822de50bbe44f 100644 (file)
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
                .word   cpu_arm7tdmi_dcache_clean_area
                .word   cpu_arm7tdmi_switch_mm
                .word   0               @ cpu_*_set_pte
+               .word   0
+               .word   0
+               .word   0
                .size   arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
 
                .section ".rodata"
index 6109f278a9045f4429bcd31ca9a4f8a092d3c66f..219980ec8b6e6b8065d4a58ff2d743334c31b8e8 100644 (file)
@@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
 #endif
        mov     pc, lr
 
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl cpu_arm920_suspend_size
+.equ   cpu_arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(cpu_arm920_do_suspend)
+       stmfd   sp!, {r4 - r7, lr}
+       mrc     p15, 0, r4, c13, c0, 0  @ PID
+       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r6, c2, c0, 0   @ TTB address
+       mrc     p15, 0, r7, c1, c0, 0   @ Control register
+       stmia   r0, {r4 - r7}
+       ldmfd   sp!, {r4 - r7, pc}
+ENDPROC(cpu_arm920_do_suspend)
+
+ENTRY(cpu_arm920_do_resume)
+       mov     ip, #0
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate I+D TLBs
+       mcr     p15, 0, ip, c7, c7, 0   @ invalidate I+D caches
+       ldmia   r0, {r4 - r7}
+       mcr     p15, 0, r4, c13, c0, 0  @ PID
+       mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mcr     p15, 0, r6, c2, c0, 0   @ TTB address
+       mov     r0, r7                  @ control register
+       mov     r2, r6, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+                    PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+       b       cpu_resume_mmu
+ENDPROC(cpu_arm920_do_resume)
+#else
+#define cpu_arm920_do_suspend  0
+#define cpu_arm920_do_resume   0
+#endif
+
        __CPUINIT
 
        .type   __arm920_setup, #function
@@ -432,6 +466,9 @@ arm920_processor_functions:
        .word   cpu_arm920_dcache_clean_area
        .word   cpu_arm920_switch_mm
        .word   cpu_arm920_set_pte_ext
+       .word   cpu_arm920_suspend_size
+       .word   cpu_arm920_do_suspend
+       .word   cpu_arm920_do_resume
        .size   arm920_processor_functions, . - arm920_processor_functions
 
        .section ".rodata"
index bb2f0f46a5e6cb28f8789da35ecb7d2f0852a4b1..36154b1e792a53dcb800006c94da61b088b5d972 100644 (file)
@@ -436,6 +436,9 @@ arm922_processor_functions:
        .word   cpu_arm922_dcache_clean_area
        .word   cpu_arm922_switch_mm
        .word   cpu_arm922_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm922_processor_functions, . - arm922_processor_functions
 
        .section ".rodata"
index c13e01accfe2e4d38dc5e7e22d6aba32bfd0ce0a..89c5e0009c4cc4117b3a583395adffa1887e5ab6 100644 (file)
@@ -503,6 +503,9 @@ arm925_processor_functions:
        .word   cpu_arm925_dcache_clean_area
        .word   cpu_arm925_switch_mm
        .word   cpu_arm925_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   arm925_processor_functions, . - arm925_processor_functions
 
        .section ".rodata"
index 42eb4315740b1488e26192b5ff0cb07747312df5..6a4bdb2c94a7ba0f856bf06c00f95049ab638dc1 100644 (file)
@@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
 #endif
        mov     pc, lr
 
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl cpu_arm926_suspend_size
+.equ   cpu_arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(cpu_arm926_do_suspend)
+       stmfd   sp!, {r4 - r7, lr}
+       mrc     p15, 0, r4, c13, c0, 0  @ PID
+       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r6, c2, c0, 0   @ TTB address
+       mrc     p15, 0, r7, c1, c0, 0   @ Control register
+       stmia   r0, {r4 - r7}
+       ldmfd   sp!, {r4 - r7, pc}
+ENDPROC(cpu_arm926_do_suspend)
+
+ENTRY(cpu_arm926_do_resume)
+       mov     ip, #0
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate I+D TLBs
+       mcr     p15, 0, ip, c7, c7, 0   @ invalidate I+D caches
+       ldmia   r0, {r4 - r7}
+       mcr     p15, 0, r4, c13, c0, 0  @ PID
+       mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mcr     p15, 0, r6, c2, c0, 0   @ TTB address
+       mov     r0, r7                  @ control register
+       mov     r2, r6, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+                    PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+       b       cpu_resume_mmu
+ENDPROC(cpu_arm926_do_resume)
+#else
+#define cpu_arm926_do_suspend  0
+#define cpu_arm926_do_resume   0
+#endif
+
        __CPUINIT
 
        .type   __arm926_setup, #function
@@ -456,6 +490,9 @@ arm926_processor_functions:
        .word   cpu_arm926_dcache_clean_area
        .word   cpu_arm926_switch_mm
        .word   cpu_arm926_set_pte_ext
+       .word   cpu_arm926_suspend_size
+       .word   cpu_arm926_do_suspend
+       .word   cpu_arm926_do_resume
        .size   arm926_processor_functions, . - arm926_processor_functions
 
        .section ".rodata"
index 7b11cdb9935ff4e8d635ee95a6ea09d225cdc10e..26aea3f71c26feaeb62a5721824fe62e6714e414 100644 (file)
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
        .word   cpu_arm940_dcache_clean_area
        .word   cpu_arm940_switch_mm
        .word   0               @ cpu_*_set_pte
+       .word   0
+       .word   0
+       .word   0
        .size   arm940_processor_functions, . - arm940_processor_functions
 
        .section ".rodata"
index 1a5bbf0803427b159096bfc093a5db07dc510731..8063345406fe58b3282b7f2b5afbdcc30d90917c 100644 (file)
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
        .word   cpu_arm946_dcache_clean_area
        .word   cpu_arm946_switch_mm
        .word   0               @ cpu_*_set_pte
+       .word   0
+       .word   0
+       .word   0
        .size   arm946_processor_functions, . - arm946_processor_functions
 
        .section ".rodata"
index db67e3134d7a50447268e815908e443206d0a7a4..7b7ebd4d096d9cb3939bed7a059be8514486d463 100644 (file)
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
                .word   cpu_arm9tdmi_dcache_clean_area
                .word   cpu_arm9tdmi_switch_mm
                .word   0               @ cpu_*_set_pte
+               .word   0
+               .word   0
+               .word   0
                .size   arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
 
                .section ".rodata"
index 7c9ad621f0e65ab031be819b303528341f7d2356..fc2a4ae15cf4689b69f9cbff2ac2013d3159f619 100644 (file)
@@ -195,6 +195,9 @@ fa526_processor_functions:
        .word   cpu_fa526_dcache_clean_area
        .word   cpu_fa526_switch_mm
        .word   cpu_fa526_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   fa526_processor_functions, . - fa526_processor_functions
 
        .section ".rodata"
index b4597edbff97fe794da687178c5f23cf27e37e47..d3883eed7a4a222420e7b3df4ab32fc1e6c51589 100644 (file)
@@ -554,6 +554,9 @@ feroceon_processor_functions:
        .word   cpu_feroceon_dcache_clean_area
        .word   cpu_feroceon_switch_mm
        .word   cpu_feroceon_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   feroceon_processor_functions, . - feroceon_processor_functions
 
        .section ".rodata"
index 4458ee6aa7133343764792b79c9f87f0f7b67ff2..9d4f2ae63370ab2fb0897944c36a391ebf968103 100644 (file)
@@ -388,6 +388,9 @@ mohawk_processor_functions:
        .word   cpu_mohawk_dcache_clean_area
        .word   cpu_mohawk_switch_mm
        .word   cpu_mohawk_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   mohawk_processor_functions, . - mohawk_processor_functions
 
        .section ".rodata"
index 5aa8d59c2e8546675d132fc48306c89b2d9380da..46f09ed16b98842df396a44b8005fbedadfaba7b 100644 (file)
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
        .word   cpu_sa110_dcache_clean_area
        .word   cpu_sa110_switch_mm
        .word   cpu_sa110_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   sa110_processor_functions, . - sa110_processor_functions
 
        .section ".rodata"
index 2ac4e6f1071378d3f27482483a0e041d540ec648..74483d1977fe788ac2b4b8d42e32952da9e7ed0e 100644 (file)
@@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
 #endif
        mov     pc, lr
 
+.globl cpu_sa1100_suspend_size
+.equ   cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM
+ENTRY(cpu_sa1100_do_suspend)
+       stmfd   sp!, {r4 - r7, lr}
+       mrc     p15, 0, r4, c3, c0, 0           @ domain ID
+       mrc     p15, 0, r5, c2, c0, 0           @ translation table base addr
+       mrc     p15, 0, r6, c13, c0, 0          @ PID
+       mrc     p15, 0, r7, c1, c0, 0           @ control reg
+       stmia   r0, {r4 - r7}                   @ store cp regs
+       ldmfd   sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+       ldmia   r0, {r4 - r7}                   @ load cp regs
+       mov     r1, #0
+       mcr     p15, 0, r1, c8, c7, 0           @ flush I+D TLBs
+       mcr     p15, 0, r1, c7, c7, 0           @ flush I&D cache
+       mcr     p15, 0, r1, c9, c0, 0           @ invalidate RB
+       mcr     p15, 0, r1, c9, c0, 5           @ allow user space to use RB
+
+       mcr     p15, 0, r4, c3, c0, 0           @ domain ID
+       mcr     p15, 0, r5, c2, c0, 0           @ translation table base addr
+       mcr     p15, 0, r6, c13, c0, 0          @ PID
+       mov     r0, r7                          @ control register
+       mov     r2, r5, lsr #14                 @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+                    PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+       b       cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#else
+#define cpu_sa1100_do_suspend  0
+#define cpu_sa1100_do_resume   0
+#endif
+
        __CPUINIT
 
        .type   __sa1100_setup, #function
@@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
        .word   cpu_sa1100_dcache_clean_area
        .word   cpu_sa1100_switch_mm
        .word   cpu_sa1100_set_pte_ext
+       .word   cpu_sa1100_suspend_size
+       .word   cpu_sa1100_do_suspend
+       .word   cpu_sa1100_do_resume
        .size   sa1100_processor_functions, . - sa1100_processor_functions
 
        .section ".rodata"
index 59a7e1ffe7bc02c3fc180c464506ce273f5e9590..832b6bdc192c6bb3cb6da2d5482e7afa4d563cc7 100644 (file)
@@ -121,6 +121,53 @@ ENTRY(cpu_v6_set_pte_ext)
 #endif
        mov     pc, lr
 
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ   cpu_v6_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_v6_do_suspend)
+       stmfd   sp!, {r4 - r11, lr}
+       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mrc     p15, 0, r5, c13, c0, 1  @ Context ID
+       mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r7, c2, c0, 0   @ Translation table base 0
+       mrc     p15, 0, r8, c2, c0, 1   @ Translation table base 1
+       mrc     p15, 0, r9, c1, c0, 1   @ auxillary control register
+       mrc     p15, 0, r10, c1, c0, 2  @ co-processor access control
+       mrc     p15, 0, r11, c1, c0, 0  @ control register
+       stmia   r0, {r4 - r11}
+       ldmfd   sp!, {r4- r11, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c14, 0  @ clean+invalidate D cache
+       mcr     p15, 0, ip, c7, c5, 0   @ invalidate I cache
+       mcr     p15, 0, ip, c7, c15, 0  @ clean+invalidate cache
+       mcr     p15, 0, ip, c7, c10, 4  @ drain write buffer
+       ldmia   r0, {r4 - r11}
+       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mcr     p15, 0, r5, c13, c0, 1  @ Context ID
+       mcr     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mcr     p15, 0, r7, c2, c0, 0   @ Translation table base 0
+       mcr     p15, 0, r8, c2, c0, 1   @ Translation table base 1
+       mcr     p15, 0, r9, c1, c0, 1   @ auxillary control register
+       mcr     p15, 0, r10, c1, c0, 2  @ co-processor access control
+       mcr     p15, 0, ip, c2, c0, 2   @ TTB control register
+       mcr     p15, 0, ip, c7, c5, 4   @ ISB
+       mov     r0, r11                 @ control register
+       mov     r2, r7, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, cpu_resume_l1_flags
+       b       cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+       ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+       ALT_UP(.long  PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v6_do_suspend 0
+#define cpu_v6_do_resume 0
+#endif
 
 
        .type   cpu_v6_name, #object
@@ -206,6 +253,9 @@ ENTRY(v6_processor_functions)
        .word   cpu_v6_dcache_clean_area
        .word   cpu_v6_switch_mm
        .word   cpu_v6_set_pte_ext
+       .word   cpu_v6_suspend_size
+       .word   cpu_v6_do_suspend
+       .word   cpu_v6_do_resume
        .size   v6_processor_functions, . - v6_processor_functions
 
        .section ".rodata"
index 8e3356239136a2423095b24b466858100b00c31d..262fa88a7439b4f0adb4ed76d8bd3b15f57cce17 100644 (file)
@@ -107,11 +107,17 @@ ENTRY(cpu_v7_switch_mm)
        ALT_UP(orr      r0, r0, #TTB_FLAGS_UP)
 #ifdef CONFIG_ARM_ERRATA_430973
        mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
+#endif
+#ifdef CONFIG_ARM_ERRATA_754322
+       dsb
 #endif
        mcr     p15, 0, r2, c13, c0, 1          @ set reserved context ID
        isb
 1:     mcr     p15, 0, r0, c2, c0, 0           @ set TTB 0
        isb
+#ifdef CONFIG_ARM_ERRATA_754322
+       dsb
+#endif
        mcr     p15, 0, r1, c13, c0, 1          @ set context ID
        isb
 #endif
@@ -171,6 +177,87 @@ cpu_v7_name:
        .ascii  "ARMv7 Processor"
        .align
 
+       /*
+        * Memory region attributes with SCTLR.TRE=1
+        *
+        *   n = TEX[0],C,B
+        *   TR = PRRR[2n+1:2n]         - memory type
+        *   IR = NMRR[2n+1:2n]         - inner cacheable property
+        *   OR = NMRR[2n+17:2n+16]     - outer cacheable property
+        *
+        *                      n       TR      IR      OR
+        *   UNCACHED           000     00
+        *   BUFFERABLE         001     10      00      00
+        *   WRITETHROUGH       010     10      10      10
+        *   WRITEBACK          011     10      11      11
+        *   reserved           110
+        *   WRITEALLOC         111     10      01      01
+        *   DEV_SHARED         100     01
+        *   DEV_NONSHARED      100     01
+        *   DEV_WC             001     10
+        *   DEV_CACHED         011     10
+        *
+        * Other attributes:
+        *
+        *   DS0 = PRRR[16] = 0         - device shareable property
+        *   DS1 = PRRR[17] = 1         - device shareable property
+        *   NS0 = PRRR[18] = 0         - normal shareable property
+        *   NS1 = PRRR[19] = 1         - normal shareable property
+        *   NOS = PRRR[24+n] = 1       - not outer shareable
+        */
+.equ   PRRR,   0xff0a81a8
+.equ   NMRR,   0x40e040e0
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ   cpu_v7_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_v7_do_suspend)
+       stmfd   sp!, {r4 - r11, lr}
+       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mrc     p15, 0, r5, c13, c0, 1  @ Context ID
+       mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r7, c2, c0, 0   @ TTB 0
+       mrc     p15, 0, r8, c2, c0, 1   @ TTB 1
+       mrc     p15, 0, r9, c1, c0, 0   @ Control register
+       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access control
+       stmia   r0, {r4 - r11}
+       ldmfd   sp!, {r4 - r11, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+       mov     ip, #0
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate TLBs
+       mcr     p15, 0, ip, c7, c5, 0   @ invalidate I cache
+       ldmia   r0, {r4 - r11}
+       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mcr     p15, 0, r5, c13, c0, 1  @ Context ID
+       mcr     p15, 0, r6, c3, c0, 0   @ Domain ID
+       mcr     p15, 0, r7, c2, c0, 0   @ TTB 0
+       mcr     p15, 0, r8, c2, c0, 1   @ TTB 1
+       mcr     p15, 0, ip, c2, c0, 2   @ TTB control register
+       mcr     p15, 0, r10, c1, c0, 1  @ Auxillary control register
+       mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access control
+       ldr     r4, =PRRR               @ PRRR
+       ldr     r5, =NMRR               @ NMRR
+       mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
+       mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
+       isb
+       mov     r0, r9                  @ control register
+       mov     r2, r7, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, cpu_resume_l1_flags
+       b       cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+       ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+       ALT_UP(.long  PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend      0
+#define cpu_v7_do_resume       0
+#endif
+
        __CPUINIT
 
 /*
@@ -282,36 +369,8 @@ __v7_setup:
        ALT_SMP(orr     r4, r4, #TTB_FLAGS_SMP)
        ALT_UP(orr      r4, r4, #TTB_FLAGS_UP)
        mcr     p15, 0, r4, c2, c0, 1           @ load TTB1
-       /*
-        * Memory region attributes with SCTLR.TRE=1
-        *
-        *   n = TEX[0],C,B
-        *   TR = PRRR[2n+1:2n]         - memory type
-        *   IR = NMRR[2n+1:2n]         - inner cacheable property
-        *   OR = NMRR[2n+17:2n+16]     - outer cacheable property
-        *
-        *                      n       TR      IR      OR
-        *   UNCACHED           000     00
-        *   BUFFERABLE         001     10      00      00
-        *   WRITETHROUGH       010     10      10      10
-        *   WRITEBACK          011     10      11      11
-        *   reserved           110
-        *   WRITEALLOC         111     10      01      01
-        *   DEV_SHARED         100     01
-        *   DEV_NONSHARED      100     01
-        *   DEV_WC             001     10
-        *   DEV_CACHED         011     10
-        *
-        * Other attributes:
-        *
-        *   DS0 = PRRR[16] = 0         - device shareable property
-        *   DS1 = PRRR[17] = 1         - device shareable property
-        *   NS0 = PRRR[18] = 0         - normal shareable property
-        *   NS1 = PRRR[19] = 1         - normal shareable property
-        *   NOS = PRRR[24+n] = 1       - not outer shareable
-        */
-       ldr     r5, =0xff0a81a8                 @ PRRR
-       ldr     r6, =0x40e040e0                 @ NMRR
+       ldr     r5, =PRRR                       @ PRRR
+       ldr     r6, =NMRR                       @ NMRR
        mcr     p15, 0, r5, c10, c2, 0          @ write PRRR
        mcr     p15, 0, r6, c10, c2, 1          @ write NMRR
 #endif
@@ -357,6 +416,9 @@ ENTRY(v7_processor_functions)
        .word   cpu_v7_dcache_clean_area
        .word   cpu_v7_switch_mm
        .word   cpu_v7_set_pte_ext
+       .word   0
+       .word   0
+       .word   0
        .size   v7_processor_functions, . - v7_processor_functions
 
        .section ".rodata"
index ec26355cb7c25b8d0e574e74740569213818cd6a..63d8b2044e84114c4401c7851e14b659a39821f2 100644 (file)
@@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
        mov     pc, lr
 
        .ltorg
-
        .align
 
+.globl cpu_xsc3_suspend_size
+.equ   cpu_xsc3_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_xsc3_do_suspend)
+       stmfd   sp!, {r4 - r10, lr}
+       mrc     p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
+       mrc     p15, 0, r5, c15, c1, 0  @ CP access reg
+       mrc     p15, 0, r6, c13, c0, 0  @ PID
+       mrc     p15, 0, r7, c3, c0, 0   @ domain ID
+       mrc     p15, 0, r8, c2, c0, 0   @ translation table base addr
+       mrc     p15, 0, r9, c1, c0, 1   @ auxiliary control reg
+       mrc     p15, 0, r10, c1, c0, 0  @ control reg
+       bic     r4, r4, #2              @ clear frequency change bit
+       stmia   r0, {r1, r4 - r10}      @ store v:p offset + cp regs
+       ldmia   sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+       ldmia   r0, {r1, r4 - r10}      @ load v:p offset + cp regs
+       mov     ip, #0
+       mcr     p15, 0, ip, c7, c7, 0   @ invalidate I & D caches, BTB
+       mcr     p15, 0, ip, c7, c10, 4  @ drain write (&fill) buffer
+       mcr     p15, 0, ip, c7, c5, 4   @ flush prefetch buffer
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate I & D TLBs
+       mcr     p14, 0, r4, c6, c0, 0   @ clock configuration, turbo mode.
+       mcr     p15, 0, r5, c15, c1, 0  @ CP access reg
+       mcr     p15, 0, r6, c13, c0, 0  @ PID
+       mcr     p15, 0, r7, c3, c0, 0   @ domain ID
+       mcr     p15, 0, r8, c2, c0, 0   @ translation table base addr
+       mcr     p15, 0, r9, c1, c0, 1   @ auxiliary control reg
+
+       @ temporarily map resume_turn_on_mmu into the page table,
+       @ otherwise prefetch abort occurs after MMU is turned on
+       mov     r0, r10                 @ control register
+       mov     r2, r8, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, =0x542e             @ section flags
+       b       cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#else
+#define cpu_xsc3_do_suspend    0
+#define cpu_xsc3_do_resume     0
+#endif
+
        __CPUINIT
 
        .type   __xsc3_setup, #function
@@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
        .word   cpu_xsc3_dcache_clean_area
        .word   cpu_xsc3_switch_mm
        .word   cpu_xsc3_set_pte_ext
+       .word   cpu_xsc3_suspend_size
+       .word   cpu_xsc3_do_suspend
+       .word   cpu_xsc3_do_resume
        .size   xsc3_processor_functions, . - xsc3_processor_functions
 
        .section ".rodata"
index 5a37c5e45c411a8d377dec497207777338ed68db..086038cd86abc1e32ffb0c6552d8fdc85c5a3bd2 100644 (file)
@@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
        xscale_set_pte_ext_epilogue
        mov     pc, lr
 
-
        .ltorg
-
        .align
 
+.globl cpu_xscale_suspend_size
+.equ   cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xscale_do_suspend)
+       stmfd   sp!, {r4 - r10, lr}
+       mrc     p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
+       mrc     p15, 0, r5, c15, c1, 0  @ CP access reg
+       mrc     p15, 0, r6, c13, c0, 0  @ PID
+       mrc     p15, 0, r7, c3, c0, 0   @ domain ID
+       mrc     p15, 0, r8, c2, c0, 0   @ translation table base addr
+       mrc     p15, 0, r9, c1, c1, 0   @ auxiliary control reg
+       mrc     p15, 0, r10, c1, c0, 0  @ control reg
+       bic     r4, r4, #2              @ clear frequency change bit
+       stmia   r0, {r4 - r10}          @ store cp regs
+       ldmfd   sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+       ldmia   r0, {r4 - r10}          @ load cp regs
+       mov     ip, #0
+       mcr     p15, 0, ip, c8, c7, 0   @ invalidate I & D TLBs
+       mcr     p15, 0, ip, c7, c7, 0   @ invalidate I & D caches, BTB
+       mcr     p14, 0, r4, c6, c0, 0   @ clock configuration, turbo mode.
+       mcr     p15, 0, r5, c15, c1, 0  @ CP access reg
+       mcr     p15, 0, r6, c13, c0, 0  @ PID
+       mcr     p15, 0, r7, c3, c0, 0   @ domain ID
+       mcr     p15, 0, r8, c2, c0, 0   @ translation table base addr
+       mcr     p15, 0, r9, c1, c1, 0   @ auxiliary control reg
+       mov     r0, r10                 @ control register
+       mov     r2, r8, lsr #14         @ get TTB0 base
+       mov     r2, r2, lsl #14
+       ldr     r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+                    PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+       b       cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#else
+#define cpu_xscale_do_suspend  0
+#define cpu_xscale_do_resume   0
+#endif
+
        __CPUINIT
 
        .type   __xscale_setup, #function
@@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
        .word   cpu_xscale_dcache_clean_area
        .word   cpu_xscale_switch_mm
        .word   cpu_xscale_set_pte_ext
+       .word   cpu_xscale_suspend_size
+       .word   cpu_xscale_do_suspend
+       .word   cpu_xscale_do_resume
        .size   xscale_processor_functions, . - xscale_processor_functions
 
        .section ".rodata"
index 9967d5e855c76c810e3190fd93f81742993230d3..f500fc34d06595254fb8688cb7c633a7807c113d 100644 (file)
 #define __ARCH_ARM_OMAP_SRAM_H
 
 #ifndef __ASSEMBLY__
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({                         \
+       typeof(&(funcp)) _res = NULL;                           \
+       void *_sram_address = omap_sram_push_address(size);     \
+       if (_sram_address)                                      \
+               _res = fncpy(_sram_address, &(funcp), size);    \
+       _res;                                                   \
+})
+
 extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
 
 extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
index e26e50487d6010fc3ecace2585edb03429b3e990..68fcc7dc56e7a4b4acf849f392e3320211822ba9 100644 (file)
@@ -242,7 +242,14 @@ static void __init omap_map_sram(void)
               omap_sram_size - SRAM_BOOTLOADER_SZ);
 }
 
-void * omap_sram_push(void * start, unsigned long size)
+/*
+ * Memory allocator for SRAM: calculates the new ceiling address
+ * for pushing a function using the fncpy API.
+ *
+ * Note that fncpy requires the returned address to be aligned
+ * to an 8-byte boundary.
+ */
+void *omap_sram_push_address(unsigned long size)
 {
        if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
                printk(KERN_ERR "Not enough space in SRAM\n");
@@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size)
        }
 
        omap_sram_ceil -= size;
-       omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
-       memcpy((void *)omap_sram_ceil, start, size);
-       flush_icache_range((unsigned long)omap_sram_ceil,
-               (unsigned long)(omap_sram_ceil + size));
+       omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
 
        return (void *)omap_sram_ceil;
 }
index e73e3b6e88d2dfbb0a97ca074b0d7863f0eec282..fd7032f84ae7623198f97a28fc40854941be61b3 100644 (file)
        /* s3c_cpu_save
         *
         * entry:
-        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
        stmfd   sp!, { r4 - r12, lr }
-
-       @@ store co-processor registers
-
-       mrc     p15, 0, r4, c13, c0, 0  @ PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ translation table base address
-       mrc     p15, 0, r7, c1, c0, 0   @ control register
-
-       stmia   r0, { r4 - r13 }
-
-       @@ write our state back to RAM
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        @@ jump to final code to send system to sleep
        ldr     r0, =pm_cpu_sleep
@@ -76,20 +66,6 @@ resume_with_mmu:
 
        .ltorg
 
-       @@ the next bits sit in the .data segment, even though they
-       @@ happen to be code... the s3c_sleep_save_phys needs to be
-       @@ accessed by the resume code before it can restore the MMU.
-       @@ This means that the variable has to be close enough for the
-       @@ code to read it... since the .text segment needs to be RO,
-       @@ the data segment can be the only place to put this code.
-
-       .data
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
-
        /* sleep magic, to allow the bootloader to check for an valid
         * image to resume to. Must be the first word before the
         * s3c_cpu_resume entry.
@@ -100,10 +76,6 @@ s3c_sleep_save_phys:
        /* s3c_cpu_resume
         *
         * resume code entry for bootloader to call
-        *
-        * we must put this code here in the data segment as we have no
-        * other way of restoring the stack pointer after sleep, and we
-        * must not write to the code segment (code is read-only)
        */
 
 ENTRY(s3c_cpu_resume)
@@ -134,25 +106,4 @@ ENTRY(s3c_cpu_resume)
        beq     1001b
 #endif /* CONFIG_DEBUG_RESUME */
 
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @@ invalidate I & D TLBs
-       mcr     p15, 0, r1, c7, c7, 0           @@ invalidate I & D caches
-
-       ldr     r0, s3c_sleep_save_phys         @ address of restore block
-       ldmia   r0, { r4 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0          @ PID
-       mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
-       mcr     p15, 0, r6, c2, c0, 0           @ translation table base
-
-#ifdef CONFIG_DEBUG_RESUME
-       mov     r3, #'R'
-       strb    r3, [ r2, #S3C2410_UTXH ]
-#endif
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r7, c1, c0, 0           @ turn on MMU, etc
-       nop                                     @ second-to-last before mmu
-       mov     pc, r2                          @ go back to virtual address
-
-       .ltorg
+       b       cpu_resume
index 30518cc9a67cf0c6dc130979036637b54da0c513..937cc2ace517572283e5b097d97b359c62e3fb60 100644 (file)
@@ -52,13 +52,11 @@ extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
 
 /* from sleep.S */
 
-extern int  s3c_cpu_save(unsigned long *saveblk);
+extern int  s3c_cpu_save(unsigned long *saveblk, long);
 extern void s3c_cpu_resume(void);
 
 extern void s3c2410_cpu_suspend(void);
 
-extern unsigned long s3c_sleep_save_phys;
-
 /* sleep save info */
 
 /**
@@ -181,13 +179,5 @@ extern void s3c_pm_restore_gpios(void);
  */
 extern void s3c_pm_save_gpios(void);
 
-/**
- * s3c_pm_cb_flushcache - callback for assembly code
- *
- * Callback to issue flush_cache_all() as this call is
- * not a directly callable object.
- */
-extern void s3c_pm_cb_flushcache(void);
-
 extern void s3c_pm_save_core(void);
 extern void s3c_pm_restore_core(void);
index 02d531fb3f8160f3abbd925d016a71551cbd14dc..d5b58d31903c740d2a0328a67e3d536adcc832d8 100644 (file)
@@ -241,8 +241,6 @@ void (*pm_cpu_sleep)(void);
 
 static int s3c_pm_enter(suspend_state_t state)
 {
-       static unsigned long regs_save[16];
-
        /* ensure the debug is initialised (if enabled) */
 
        s3c_pm_debug_init();
@@ -266,12 +264,6 @@ static int s3c_pm_enter(suspend_state_t state)
                return -EINVAL;
        }
 
-       /* store the physical address of the register recovery block */
-
-       s3c_sleep_save_phys = virt_to_phys(regs_save);
-
-       S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
-
        /* save all necessary core registers not covered by the drivers */
 
        s3c_pm_save_gpios();
@@ -305,7 +297,7 @@ static int s3c_pm_enter(suspend_state_t state)
         * we resume as it saves its own register state and restores it
         * during the resume.  */
 
-       s3c_cpu_save(regs_save);
+       s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
 
        /* restore the cpu state using the kernel's cpu init code. */
 
@@ -336,12 +328,6 @@ static int s3c_pm_enter(suspend_state_t state)
        return 0;
 }
 
-/* callback from assembly code */
-void s3c_pm_cb_flushcache(void)
-{
-       flush_cache_all();
-}
-
 static int s3c_pm_prepare(void)
 {
        /* prepare check area if configured */