]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge AT91, EP93xx, General devel, PXA, S3C, V6+ and Xscale trees
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Sat, 17 Feb 2007 20:09:53 +0000 (20:09 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 17 Feb 2007 20:09:53 +0000 (20:09 +0000)
203 files changed:
Documentation/arm/Samsung-S3C24XX/DMA.txt [new file with mode: 0644]
Documentation/arm/Samsung-S3C24XX/Overview.txt
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/.gitignore [new file with mode: 0644]
arch/arm/boot/compressed/.gitignore [new file with mode: 0644]
arch/arm/common/dmabounce.c
arch/arm/common/gic.c
arch/arm/configs/s3c2410_defconfig
arch/arm/kernel/Makefile
arch/arm/kernel/calls.S
arch/arm/kernel/crunch.c
arch/arm/kernel/ecard.c
arch/arm/kernel/machine_kexec.c [new file with mode: 0644]
arch/arm/kernel/relocate_kernel.S [new file with mode: 0644]
arch/arm/kernel/setup.c
arch/arm/kernel/time.c
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-realview/Kconfig
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-s3c2400/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2400/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2400/gpio.c [new file with mode: 0644]
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/bast-irq.c
arch/arm/mach-s3c2410/bast.h
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/clock.h [deleted file]
arch/arm/mach-s3c2410/common-smdk.c [deleted file]
arch/arm/mach-s3c2410/common-smdk.h [deleted file]
arch/arm/mach-s3c2410/cpu.c [deleted file]
arch/arm/mach-s3c2410/cpu.h [deleted file]
arch/arm/mach-s3c2410/devs.c [deleted file]
arch/arm/mach-s3c2410/devs.h [deleted file]
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/dma.h [deleted file]
arch/arm/mach-s3c2410/gpio.c
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/irq.h [deleted file]
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/mach-anubis.c [deleted file]
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-nexcoder.c [deleted file]
arch/arm/mach-s3c2410/mach-osiris.c [deleted file]
arch/arm/mach-s3c2410/mach-otom.c
arch/arm/mach-s3c2410/mach-qt2410.c [new file with mode: 0644]
arch/arm/mach-s3c2410/mach-rx3715.c [deleted file]
arch/arm/mach-s3c2410/mach-smdk2410.c
arch/arm/mach-s3c2410/mach-smdk2413.c [deleted file]
arch/arm/mach-s3c2410/mach-smdk2440.c [deleted file]
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-s3c2410/mach-vstms.c [deleted file]
arch/arm/mach-s3c2410/pm-simtec.c [deleted file]
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2410/pm.h [deleted file]
arch/arm/mach-s3c2410/s3c2400-gpio.c [deleted file]
arch/arm/mach-s3c2410/s3c2400.h [deleted file]
arch/arm/mach-s3c2410/s3c2410-clock.c [deleted file]
arch/arm/mach-s3c2410/s3c2410-dma.c [deleted file]
arch/arm/mach-s3c2410/s3c2410-gpio.c [deleted file]
arch/arm/mach-s3c2410/s3c2410-irq.c [deleted file]
arch/arm/mach-s3c2410/s3c2410-pm.c [deleted file]
arch/arm/mach-s3c2410/s3c2410-sleep.S [deleted file]
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2410/s3c2410.h [deleted file]
arch/arm/mach-s3c2410/s3c2412-clock.c [deleted file]
arch/arm/mach-s3c2410/s3c2412-dma.c [deleted file]
arch/arm/mach-s3c2410/s3c2412-irq.c [deleted file]
arch/arm/mach-s3c2410/s3c2412-pm.c [deleted file]
arch/arm/mach-s3c2410/s3c2412.c [deleted file]
arch/arm/mach-s3c2410/s3c2412.h [deleted file]
arch/arm/mach-s3c2410/s3c2440-clock.c [deleted file]
arch/arm/mach-s3c2410/s3c2440-dma.c [deleted file]
arch/arm/mach-s3c2410/s3c2440-dsc.c [deleted file]
arch/arm/mach-s3c2410/s3c2440-irq.c [deleted file]
arch/arm/mach-s3c2410/s3c2440.c [deleted file]
arch/arm/mach-s3c2410/s3c2440.h [deleted file]
arch/arm/mach-s3c2410/s3c2442-clock.c [deleted file]
arch/arm/mach-s3c2410/s3c2442.c [deleted file]
arch/arm/mach-s3c2410/s3c2442.h [deleted file]
arch/arm/mach-s3c2410/s3c244x-irq.c [deleted file]
arch/arm/mach-s3c2410/s3c244x.c [deleted file]
arch/arm/mach-s3c2410/s3c244x.h [deleted file]
arch/arm/mach-s3c2410/sleep.S
arch/arm/mach-s3c2410/time.c [deleted file]
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/mach-s3c2412/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2412/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2412/clock.c [new file with mode: 0644]
arch/arm/mach-s3c2412/dma.c [new file with mode: 0644]
arch/arm/mach-s3c2412/irq.c [new file with mode: 0644]
arch/arm/mach-s3c2412/mach-smdk2413.c [new file with mode: 0644]
arch/arm/mach-s3c2412/mach-vstms.c [new file with mode: 0644]
arch/arm/mach-s3c2412/pm.c [new file with mode: 0644]
arch/arm/mach-s3c2412/s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c2440/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2440/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2440/clock.c [new file with mode: 0644]
arch/arm/mach-s3c2440/dma.c [new file with mode: 0644]
arch/arm/mach-s3c2440/dsc.c [new file with mode: 0644]
arch/arm/mach-s3c2440/irq.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-anubis.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-nexcoder.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-osiris.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-rx3715.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-smdk2440.c [new file with mode: 0644]
arch/arm/mach-s3c2440/s3c2440.c [new file with mode: 0644]
arch/arm/mach-s3c2442/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2442/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2442/clock.c [new file with mode: 0644]
arch/arm/mach-s3c2442/s3c2442.c [new file with mode: 0644]
arch/arm/mach-s3c2443/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2443/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2443/clock.c [new file with mode: 0644]
arch/arm/mach-s3c2443/dma.c [new file with mode: 0644]
arch/arm/mach-s3c2443/irq.c [new file with mode: 0644]
arch/arm/mach-s3c2443/mach-smdk2443.c [new file with mode: 0644]
arch/arm/mach-s3c2443/s3c2443.c [new file with mode: 0644]
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/cache-l2x0.c [new file with mode: 0644]
arch/arm/mm/consistent.c
arch/arm/mm/context.c
arch/arm/mm/fault-armv.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/tlb-v6.S
arch/arm/plat-s3c24xx/Kconfig [new file with mode: 0644]
arch/arm/plat-s3c24xx/Makefile [new file with mode: 0644]
arch/arm/plat-s3c24xx/clock.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/common-smdk.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/cpu.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/devs.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/dma.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/gpio.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/irq.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/pm-simtec.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/pm.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/s3c244x-irq.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/s3c244x.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/s3c244x.h [new file with mode: 0644]
arch/arm/plat-s3c24xx/sleep.S [new file with mode: 0644]
arch/arm/plat-s3c24xx/time.c [new file with mode: 0644]
drivers/i2c/busses/i2c-pxa.c
drivers/serial/Kconfig
drivers/serial/imx.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/gadget/pxa2xx_udc.h
include/asm-arm/.gitignore [new file with mode: 0644]
include/asm-arm/arch-ep93xx/ep93xx-regs.h
include/asm-arm/arch-ep93xx/irqs.h
include/asm-arm/arch-ep93xx/platform.h
include/asm-arm/arch-imx/entry-macro.S
include/asm-arm/arch-ixp4xx/udc.h
include/asm-arm/arch-pxa/pxa-regs.h
include/asm-arm/arch-pxa/udc.h
include/asm-arm/arch-realview/hardware.h
include/asm-arm/arch-realview/irqs.h
include/asm-arm/arch-realview/platform.h
include/asm-arm/arch-realview/scu.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/dma.h
include/asm-arm/arch-s3c2410/irqs.h
include/asm-arm/arch-s3c2410/regs-adc.h
include/asm-arm/arch-s3c2410/regs-gpio.h
include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/regs-serial.h
include/asm-arm/arch-s3c2410/reset.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/system.h
include/asm-arm/arch-s3c2410/udc.h [new file with mode: 0644]
include/asm-arm/cacheflush.h
include/asm-arm/device.h
include/asm-arm/dma-mapping.h
include/asm-arm/domain.h
include/asm-arm/hardware/arm_scu.h
include/asm-arm/hardware/cache-l2x0.h [new file with mode: 0644]
include/asm-arm/hardware/gic.h
include/asm-arm/hardware/sa1111.h
include/asm-arm/kexec.h [new file with mode: 0644]
include/asm-arm/pgtable.h
include/asm-arm/plat-s3c24xx/clock.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/common-smdk.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/cpu.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/devs.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/dma.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/irq.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/pm.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2400.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2410.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2412.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2440.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2442.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/s3c2443.h [new file with mode: 0644]
include/asm-arm/system.h
include/asm-arm/tlbflush.h
include/asm-arm/unistd.h
include/linux/kexec.h

diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
new file mode 100644 (file)
index 0000000..37f4edc
--- /dev/null
@@ -0,0 +1,46 @@
+                       S3C2410 DMA
+                       ===========
+
+Introduction
+------------
+
+   The kernel provides an interface to manage DMA transfers
+   using the DMA channels in the cpu, so that the central
+   duty of managing channel mappings, and programming the
+   channel generators is in one place.
+
+
+DMA Channel Ordering
+--------------------
+
+   Many of the range do not have connections for the DMA
+   channels to all sources, which means that some devices
+   have a restricted number of channels that can be used.
+
+   To allow flexibilty for each cpu type and board, the
+   dma code can be given an dma ordering structure which
+   allows the order of channel search to be specified, as
+   well as allowing the prohibition of certain claims.
+
+   struct s3c24xx_dma_order has a list of channels, and
+   each channel within has a slot for a list of dma
+   channel numbers. The slots are searched in order, for
+   the presence of a dma channel number with DMA_CH_VALID
+   orred in.
+
+   If the order has the flag DMA_CH_NEVER set, then after
+   checking the channel list, the system will return no
+   found channel, thus denying the request.
+
+   A board support file can call s3c24xx_dma_order_set()
+   to register an complete ordering set. The routine will
+   copy the data, so the original can be discared with
+   __initdata.
+
+
+Authour
+-------
+
+Ben Dooks,
+Copyright (c) 2007 Ben Dooks, Simtec Electronics
+Licensed under the GPL v2
index 28d014714ab8930fbfb9c3c65fb0f85644b807b4..c31b76fa66c462601a92054221baea08643057da 100644 (file)
@@ -8,13 +8,10 @@ Introduction
 
   The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported
   by the 's3c2410' architecture of ARM Linux. Currently the S3C2410,
-  S3C2440 and S3C2442 devices are supported.
+  S3C2412, S3C2413, S3C2440 and S3C2442 devices are supported.
 
   Support for the S3C2400 series is in progress.
 
-  Support for the S3C2412 and S3C2413 CPUs is being merged.
-
-
 Configuration
 -------------
 
@@ -26,6 +23,22 @@ Configuration
   please check the machine specific documentation.
 
 
+Layout
+------
+
+  The core support files are located in the platform code contained in
+  arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx.
+  This directory should be kept to items shared between the platform
+  code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
+
+  Each cpu has a directory with the support files for it, and the
+  machines that carry the device. For example S3C2410 is contained
+  in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
+
+  Register, kernel and platform data definitions are held in the
+  include/asm-arm/arch-s3c2410 directory.
+
+
 Machines
 --------
 
index 9c7565c8f3766fd85e2032c82510094e749e7f32..195650935c78d47c43ea08f4f6f453139e19ed0f 100644 (file)
@@ -280,6 +280,7 @@ config ARCH_PXA
        bool "PXA2xx-based"
        depends on MMU
        select ARCH_MTD_XIP
+       select GENERIC_TIME
        help
          Support for Intel's PXA2XX processor line.
 
@@ -303,7 +304,7 @@ config ARCH_SA1100
          Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
-       bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442"
+       bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -363,7 +364,16 @@ source "arch/arm/mach-omap1/Kconfig"
 
 source "arch/arm/mach-omap2/Kconfig"
 
+source "arch/arm/plat-s3c24xx/Kconfig"
+
+if ARCH_S3C2410
+source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
+source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2440/Kconfig"
+source "arch/arm/mach-s3c2442/Kconfig"
+source "arch/arm/mach-s3c2443/Kconfig"
+endif
 
 source "arch/arm/mach-lh7a40x/Kconfig"
 
@@ -738,6 +748,20 @@ config XIP_PHYS_ADDR
          be linked for and stored to.  This address is dependent on your
          own flash usage.
 
+config KEXEC
+       bool "Kexec system call (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is indepedent of the system firmware.   And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         It is an ongoing process to be certain the hardware in a machine
+         is properly shutdown, so do not be surprised if this code does not
+         initially work for you.  It may help to enable device hotplugging
+         support.
+
 endmenu
 
 if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
index 0205547fa45cdf8b31e8657c196b88c9c3048b52..2cd871c82c96545832a740c494ab2fdd0f49fbfa 100644 (file)
@@ -149,7 +149,7 @@ MACHINE  := arch/arm/mach-$(machine-y)/
 else
 MACHINE  :=
 endif
-  
+
 export TEXT_OFFSET GZFLAGS MMUEXT
 
 # Do we have FASTFPE?
@@ -161,6 +161,11 @@ endif
 # If we have a machine-specific directory, then include it in the build.
 core-y                         += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
 core-y                         += $(MACHINE)
+core-$(CONFIG_ARCH_S3C2410)    += arch/arm/mach-s3c2400/
+core-$(CONFIG_ARCH_S3C2410)    += arch/arm/mach-s3c2412/
+core-$(CONFIG_ARCH_S3C2410)    += arch/arm/mach-s3c2440/
+core-$(CONFIG_ARCH_S3C2410)    += arch/arm/mach-s3c2442/
+core-$(CONFIG_ARCH_S3C2410)    += arch/arm/mach-s3c2443/
 core-$(CONFIG_FPE_NWFPE)       += arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)     += $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)             += arch/arm/vfp/
@@ -168,6 +173,7 @@ core-$(CONFIG_VFP)          += arch/arm/vfp/
 # If we have a common platform directory, then include it in the build.
 core-$(CONFIG_PLAT_IOP)                += arch/arm/plat-iop/
 core-$(CONFIG_ARCH_OMAP)       += arch/arm/plat-omap/
+core-$(CONFIG_PLAT_S3C24XX)            += arch/arm/plat-s3c24xx/
 
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 drivers-$(CONFIG_ARCH_CLPS7500)        += drivers/acorn/char/
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
new file mode 100644 (file)
index 0000000..171a085
--- /dev/null
@@ -0,0 +1,2 @@
+Image
+zImage
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
new file mode 100644 (file)
index 0000000..aefee20
--- /dev/null
@@ -0,0 +1 @@
+piggy.gz
index 2e635b814c14b06dd7cf84cbba4ccc2afd72cf58..6fbe7722aa44086403599f64f26c04aebece4568 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <asm/cacheflush.h>
 
-#undef DEBUG
 #undef STATS
 
 #ifdef STATS
@@ -66,14 +65,13 @@ struct dmabounce_pool {
 };
 
 struct dmabounce_device_info {
-       struct list_head node;
-
        struct device *dev;
        struct list_head safe_buffers;
 #ifdef STATS
        unsigned long total_allocs;
        unsigned long map_op_count;
        unsigned long bounce_count;
+       int attr_res;
 #endif
        struct dmabounce_pool   small;
        struct dmabounce_pool   large;
@@ -81,33 +79,23 @@ struct dmabounce_device_info {
        rwlock_t lock;
 };
 
-static LIST_HEAD(dmabounce_devs);
-
 #ifdef STATS
-static void print_alloc_stats(struct dmabounce_device_info *device_info)
+static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
+                             char *buf)
 {
-       printk(KERN_INFO
-               "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
-               device_info->dev->bus_id,
-               device_info->small.allocs, device_info->large.allocs,
+       struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+       return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
+               device_info->small.allocs,
+               device_info->large.allocs,
                device_info->total_allocs - device_info->small.allocs -
                        device_info->large.allocs,
-               device_info->total_allocs);
+               device_info->total_allocs,
+               device_info->map_op_count,
+               device_info->bounce_count);
 }
-#endif
-
-/* find the given device in the dmabounce device list */
-static inline struct dmabounce_device_info *
-find_dmabounce_dev(struct device *dev)
-{
-       struct dmabounce_device_info *d;
 
-       list_for_each_entry(d, &dmabounce_devs, node)
-               if (d->dev == dev)
-                       return d;
-
-       return NULL;
-}
+static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
+#endif
 
 
 /* allocate a 'safe' buffer and keep track of it */
@@ -162,8 +150,6 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
        if (pool)
                pool->allocs++;
        device_info->total_allocs++;
-       if (device_info->total_allocs % 1000 == 0)
-               print_alloc_stats(device_info);
 #endif
 
        write_lock_irqsave(&device_info->lock, flags);
@@ -218,20 +204,11 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
 
 /* ************************************************** */
 
-#ifdef STATS
-static void print_map_stats(struct dmabounce_device_info *device_info)
-{
-       dev_info(device_info->dev,
-               "dmabounce: map_op_count=%lu, bounce_count=%lu\n",
-               device_info->map_op_count, device_info->bounce_count);
-}
-#endif
-
 static inline dma_addr_t
 map_single(struct device *dev, void *ptr, size_t size,
                enum dma_data_direction dir)
 {
-       struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+       struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
        dma_addr_t dma_addr;
        int needs_bounce = 0;
 
@@ -281,10 +258,14 @@ map_single(struct device *dev, void *ptr, size_t size,
                ptr = buf->safe;
 
                dma_addr = buf->safe_dma_addr;
+       } else {
+               /*
+                * We don't need to sync the DMA buffer since
+                * it was allocated via the coherent allocators.
+                */
+               consistent_sync(ptr, size, dir);
        }
 
-       consistent_sync(ptr, size, dir);
-
        return dma_addr;
 }
 
@@ -292,7 +273,7 @@ static inline void
 unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                enum dma_data_direction dir)
 {
-       struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+       struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
        struct safe_buffer *buf = NULL;
 
        /*
@@ -317,12 +298,12 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                DO_STATS ( device_info->bounce_count++ );
 
                if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
-                       unsigned long ptr;
+                       void *ptr = buf->ptr;
 
                        dev_dbg(dev,
                                "%s: copy back safe %p to unsafe %p size %d\n",
-                               __func__, buf->safe, buf->ptr, size);
-                       memcpy(buf->ptr, buf->safe, size);
+                               __func__, buf->safe, ptr, size);
+                       memcpy(ptr, buf->safe, size);
 
                        /*
                         * DMA buffers must have the same cache properties
@@ -332,8 +313,8 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                         * bidirectional case because we know the cache
                         * lines will be coherent with the data written.
                         */
-                       ptr = (unsigned long)buf->ptr;
                        dmac_clean_range(ptr, ptr + size);
+                       outer_clean_range(__pa(ptr), __pa(ptr) + size);
                }
                free_safe_buffer(device_info, buf);
        }
@@ -343,7 +324,7 @@ static inline void
 sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                enum dma_data_direction dir)
 {
-       struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+       struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
        struct safe_buffer *buf = NULL;
 
        if (device_info)
@@ -397,7 +378,10 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
                default:
                        BUG();
                }
-               consistent_sync(buf->safe, size, dir);
+               /*
+                * No need to sync the safe buffer - it was allocated
+                * via the coherent allocators.
+                */
        } else {
                consistent_sync(dma_to_virt(dev, dma_addr), size, dir);
        }
@@ -604,9 +588,10 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
        device_info->total_allocs = 0;
        device_info->map_op_count = 0;
        device_info->bounce_count = 0;
+       device_info->attr_res = device_create_file(dev, &dev_attr_dmabounce_stats);
 #endif
 
-       list_add(&device_info->node, &dmabounce_devs);
+       dev->archdata.dmabounce = device_info;
 
        printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
                dev->bus_id, dev->bus->name);
@@ -623,7 +608,9 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 void
 dmabounce_unregister_dev(struct device *dev)
 {
-       struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
+       struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+
+       dev->archdata.dmabounce = NULL;
 
        if (!device_info) {
                printk(KERN_WARNING
@@ -645,12 +632,10 @@ dmabounce_unregister_dev(struct device *dev)
                dma_pool_destroy(device_info->large.pool);
 
 #ifdef STATS
-       print_alloc_stats(device_info);
-       print_map_stats(device_info);
+       if (device_info->attr_res == 0)
+               device_remove_file(dev, &dev_attr_dmabounce_stats);
 #endif
 
-       list_del(&device_info->node);
-
        kfree(device_info);
 
        printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
index 09b9d1b6844c05315dc50af6e0ea0ffacdfad725..4deece5fbdf467ac1161a24dff612f0b973d3fbb 100644 (file)
@@ -14,7 +14,9 @@
  *
  * o There is one CPU Interface per CPU, which sends interrupts sent
  *   by the Distributor, and interrupts generated locally, to the
- *   associated CPU.
+ *   associated CPU. The base address of the CPU interface is usually
+ *   aliased so that the same address points to different chips depending
+ *   on the CPU it is accessed from.
  *
  * Note that IRQs 0-31 are special - they are local to each CPU.
  * As such, the enable set/clear, pending set/clear and active bit
 #include <asm/mach/irq.h>
 #include <asm/hardware/gic.h>
 
-static void __iomem *gic_dist_base;
-static void __iomem *gic_cpu_base;
 static DEFINE_SPINLOCK(irq_controller_lock);
 
+struct gic_chip_data {
+       unsigned int irq_offset;
+       void __iomem *dist_base;
+       void __iomem *cpu_base;
+};
+
+#ifndef MAX_GIC_NR
+#define MAX_GIC_NR     1
+#endif
+
+static struct gic_chip_data gic_data[MAX_GIC_NR];
+
+static inline void __iomem *gic_dist_base(unsigned int irq)
+{
+       struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+       return gic_data->dist_base;
+}
+
+static inline void __iomem *gic_cpu_base(unsigned int irq)
+{
+       struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+       return gic_data->cpu_base;
+}
+
+static inline unsigned int gic_irq(unsigned int irq)
+{
+       struct gic_chip_data *gic_data = get_irq_chip_data(irq);
+       return irq - gic_data->irq_offset;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  *
@@ -55,8 +85,8 @@ static void gic_ack_irq(unsigned int irq)
        u32 mask = 1 << (irq % 32);
 
        spin_lock(&irq_controller_lock);
-       writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
-       writel(irq, gic_cpu_base + GIC_CPU_EOI);
+       writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
+       writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
        spin_unlock(&irq_controller_lock);
 }
 
@@ -65,7 +95,7 @@ static void gic_mask_irq(unsigned int irq)
        u32 mask = 1 << (irq % 32);
 
        spin_lock(&irq_controller_lock);
-       writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4);
+       writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
        spin_unlock(&irq_controller_lock);
 }
 
@@ -74,14 +104,14 @@ static void gic_unmask_irq(unsigned int irq)
        u32 mask = 1 << (irq % 32);
 
        spin_lock(&irq_controller_lock);
-       writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4);
+       writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4);
        spin_unlock(&irq_controller_lock);
 }
 
 #ifdef CONFIG_SMP
 static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
 {
-       void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3);
+       void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
        unsigned int shift = (irq % 4) * 8;
        unsigned int cpu = first_cpu(mask_val);
        u32 val;
@@ -95,6 +125,37 @@ static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
 }
 #endif
 
+static void fastcall gic_handle_cascade_irq(unsigned int irq,
+                                           struct irq_desc *desc)
+{
+       struct gic_chip_data *chip_data = get_irq_data(irq);
+       struct irq_chip *chip = get_irq_chip(irq);
+       unsigned int cascade_irq;
+       unsigned long status;
+
+       /* primary controller ack'ing */
+       chip->ack(irq);
+
+       spin_lock(&irq_controller_lock);
+       status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
+       spin_unlock(&irq_controller_lock);
+
+       cascade_irq = (status & 0x3ff);
+       if (cascade_irq > 1020)
+               goto out;
+       if (cascade_irq < 32 || cascade_irq >= NR_IRQS) {
+               do_bad_IRQ(cascade_irq, desc);
+               goto out;
+       }
+
+       cascade_irq += chip_data->irq_offset;
+       generic_handle_irq(cascade_irq);
+
+ out:
+       /* primary controller unmasking */
+       chip->unmask(irq);
+}
+
 static struct irq_chip gic_chip = {
        .name           = "GIC",
        .ack            = gic_ack_irq,
@@ -105,15 +166,29 @@ static struct irq_chip gic_chip = {
 #endif
 };
 
-void __init gic_dist_init(void __iomem *base)
+void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+{
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+       if (set_irq_data(irq, &gic_data[gic_nr]) != 0)
+               BUG();
+       set_irq_chained_handler(irq, gic_handle_cascade_irq);
+}
+
+void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
+                         unsigned int irq_start)
 {
        unsigned int max_irq, i;
        u32 cpumask = 1 << smp_processor_id();
 
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
        cpumask |= cpumask << 8;
        cpumask |= cpumask << 16;
 
-       gic_dist_base = base;
+       gic_data[gic_nr].dist_base = base;
+       gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
 
        writel(0, base + GIC_DIST_CTRL);
 
@@ -158,8 +233,9 @@ void __init gic_dist_init(void __iomem *base)
        /*
         * Setup the Linux IRQ subsystem.
         */
-       for (i = 29; i < max_irq; i++) {
+       for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
                set_irq_chip(i, &gic_chip);
+               set_irq_chip_data(i, &gic_data[gic_nr]);
                set_irq_handler(i, handle_level_irq);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
        }
@@ -167,9 +243,13 @@ void __init gic_dist_init(void __iomem *base)
        writel(1, base + GIC_DIST_CTRL);
 }
 
-void __cpuinit gic_cpu_init(void __iomem *base)
+void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
 {
-       gic_cpu_base = base;
+       if (gic_nr >= MAX_GIC_NR)
+               BUG();
+
+       gic_data[gic_nr].cpu_base = base;
+
        writel(0xf0, base + GIC_CPU_PRIMASK);
        writel(1, base + GIC_CPU_CTRL);
 }
@@ -179,6 +259,7 @@ void gic_raise_softirq(cpumask_t cpumask, unsigned int irq)
 {
        unsigned long map = *cpus_addr(cpumask);
 
-       writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT);
+       /* this always happens on GIC0 */
+       writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
 }
 #endif
index 3b31a33d0080eab75165a7f1166a02ab2da00bd1..df19e3632038d8bc0d3252afa41a5fbd44cc7df0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc4
-# Fri Nov  3 17:41:31 2006
+# Linux kernel version: 2.6.20
+# Thu Feb 15 11:26:24 2007
 #
 CONFIG_ARM=y
 # CONFIG_GENERIC_TIME is not set
@@ -11,6 +11,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -37,13 +39,14 @@ CONFIG_SYSVIPC=y
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -76,7 +79,9 @@ CONFIG_KMOD=y
 # Block layer
 #
 CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -110,6 +115,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP23XX is not set
@@ -122,54 +128,73 @@ CONFIG_ARCH_S3C2410=y
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
+CONFIG_PLAT_S3C24XX=y
+CONFIG_CPU_S3C244X=y
+CONFIG_PM_SIMTEC=y
+# CONFIG_S3C2410_BOOT_WATCHDOG is not set
+# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
+# CONFIG_S3C2410_PM_DEBUG is not set
+# CONFIG_S3C2410_PM_CHECK is not set
+CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+CONFIG_S3C2410_DMA=y
+# CONFIG_S3C2410_DMA_DEBUG is not set
+CONFIG_MACH_SMDK=y
 
 #
-# S3C24XX Implementations
+# S3C2400 Machines
 #
-# CONFIG_MACH_AML_M5900 is not set
-CONFIG_MACH_ANUBIS=y
-CONFIG_MACH_OSIRIS=y
-CONFIG_ARCH_BAST=y
-CONFIG_BAST_PC104_IRQ=y
+CONFIG_CPU_S3C2410=y
+CONFIG_CPU_S3C2410_DMA=y
+CONFIG_S3C2410_PM=y
+CONFIG_S3C2410_GPIO=y
+CONFIG_S3C2410_CLOCK=y
+
+#
+# S3C2410 Machines
+#
+CONFIG_ARCH_SMDK2410=y
 CONFIG_ARCH_H1940=y
+CONFIG_PM_H1940=y
 CONFIG_MACH_N30=y
-CONFIG_MACH_SMDK=y
-CONFIG_ARCH_SMDK2410=y
-CONFIG_ARCH_S3C2440=y
-CONFIG_SMDK2440_CPU2440=y
-CONFIG_SMDK2440_CPU2442=y
-CONFIG_MACH_S3C2413=y
-CONFIG_MACH_SMDK2413=y
-CONFIG_MACH_VR1000=y
-CONFIG_MACH_RX3715=y
+CONFIG_ARCH_BAST=y
 CONFIG_MACH_OTOM=y
-CONFIG_MACH_NEXCODER_2440=y
-CONFIG_MACH_VSTMS=y
-CONFIG_S3C2410_CLOCK=y
-CONFIG_S3C2410_PM=y
-CONFIG_CPU_S3C2410_DMA=y
-CONFIG_CPU_S3C2410=y
-CONFIG_S3C2412_PM=y
+CONFIG_MACH_AML_M5900=y
+CONFIG_BAST_PC104_IRQ=y
+CONFIG_MACH_VR1000=y
 CONFIG_CPU_S3C2412=y
-CONFIG_CPU_S3C244X=y
+CONFIG_S3C2412_DMA=y
+CONFIG_S3C2412_PM=y
+
+#
+# S3C2412 Machines
+#
+CONFIG_MACH_SMDK2413=y
+CONFIG_MACH_S3C2413=y
+CONFIG_MACH_VSTMS=y
 CONFIG_CPU_S3C2440=y
+CONFIG_S3C2440_DMA=y
+
+#
+# S3C2440 Machines
+#
+CONFIG_MACH_ANUBIS=y
+CONFIG_MACH_OSIRIS=y
+CONFIG_MACH_RX3715=y
+CONFIG_ARCH_S3C2440=y
+CONFIG_MACH_NEXCODER_2440=y
+CONFIG_SMDK2440_CPU2440=y
 CONFIG_CPU_S3C2442=y
 
 #
-# S3C2410 Boot
+# S3C2442 Machines
 #
-# CONFIG_S3C2410_BOOT_WATCHDOG is not set
-# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
+CONFIG_SMDK2440_CPU2442=y
+CONFIG_CPU_S3C2443=y
 
 #
-# S3C2410 Setup
+# S3C2443 Machines
 #
-CONFIG_S3C2410_DMA=y
-# CONFIG_S3C2410_DMA_DEBUG is not set
-# CONFIG_S3C2410_PM_DEBUG is not set
-# CONFIG_S3C2410_PM_CHECK is not set
-CONFIG_PM_SIMTEC=y
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+CONFIG_MACH_SMDK2443=y
 
 #
 # Processor Type
@@ -196,6 +221,7 @@ CONFIG_CPU_CP15_MMU=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
 
 #
 # Bus support
@@ -303,6 +329,7 @@ CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -385,6 +412,7 @@ CONFIG_MTD_CMDLINE_PARTS=y
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
@@ -530,6 +558,11 @@ CONFIG_BLK_DEV_IDE_BAST=y
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -682,7 +715,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
@@ -700,13 +733,14 @@ CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
 # CONFIG_SERIAL_8250_FOURPORT is not set
 # CONFIG_SERIAL_8250_ACCENT is not set
 # CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
 # CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -755,10 +789,6 @@ CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -863,6 +893,7 @@ CONFIG_SENSORS_LM85=m
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -870,6 +901,7 @@ CONFIG_SENSORS_LM85=m
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -951,6 +983,11 @@ CONFIG_FONT_8x16=y
 #
 # CONFIG_SOUND is not set
 
+#
+# HID Devices
+#
+CONFIG_HID=y
+
 #
 # USB support
 #
@@ -1028,6 +1065,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1179,9 +1217,6 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS_PROC_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1191,7 +1226,7 @@ CONFIG_JFFS2_FS_WRITEBUFFER=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
@@ -1284,6 +1319,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -1296,6 +1336,8 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1311,12 +1353,10 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
@@ -1339,6 +1379,7 @@ CONFIG_DEBUG_S3C2410_UART=0
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
@@ -1346,3 +1387,4 @@ CONFIG_CRC32=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
index ab06a86e85d58c71e17fb223e8e8ef4b45e22587..d5002889773e9156797bdf0a02e0a3dc799ee0dd 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_ARTHUR)          += arthur.o
 obj-$(CONFIG_ISA_DMA)          += dma-isa.o
 obj-$(CONFIG_PCI)              += bios32.o isa.o
 obj-$(CONFIG_SMP)              += smp.o
+obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_OABI_COMPAT)      += sys_oabi-compat.o
 
 obj-$(CONFIG_CRUNCH)           += crunch.o crunch-bits.o
index f7598cbc7ec5a788cf6f032a548372682f679feb..ae89cdd82b1677d2b29494bed10391bd0be7c587 100644 (file)
                CALL(sys_move_pages)
 /* 345 */      CALL(sys_getcpu)
                CALL(sys_ni_syscall)            /* eventually epoll_pwait */
+               CALL(sys_kexec_load)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index cec83783206e335a11f9a88f225ad3eba3ab6620..627d79414c9d68212382eaefe64af6f896035509 100644 (file)
@@ -75,6 +75,7 @@ static struct notifier_block crunch_notifier_block = {
 static int __init crunch_init(void)
 {
        thread_register_notifier(&crunch_notifier_block);
+       elf_hwcap |= HWCAP_CRUNCH;
 
        return 0;
 }
index 71257e3d513f4604ed1d01c3db5eb8fb565bcf47..f1c0fb974177803c0ec2510d79d4e9c72669164b 100644 (file)
@@ -1009,7 +1009,7 @@ ecard_probe(int slot, card_type_t type)
                ec->fiqmask = 4;
        }
 
-       for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++)
+       for (i = 0; i < ARRAY_SIZE(blacklist); i++)
                if (blacklist[i].manufacturer == ec->cid.manufacturer &&
                    blacklist[i].product == ec->cid.product) {
                        ec->card_desc = blacklist[i].type;
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..863c664
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned int relocate_new_kernel_size;
+
+extern void setup_mm_for_reboot(char mode);
+
+extern unsigned long kexec_start_address;
+extern unsigned long kexec_indirection_page;
+extern unsigned long kexec_mach_type;
+
+/*
+ * Provide a dummy crash_notes definition while crash dump arrives to arm.
+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
+ */
+
+int machine_kexec_prepare(struct kimage *image)
+{
+       return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+void machine_shutdown(void)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+void machine_kexec(struct kimage *image)
+{
+       unsigned long page_list;
+       unsigned long reboot_code_buffer_phys;
+       void *reboot_code_buffer;
+
+
+       page_list = image->head & PAGE_MASK;
+
+       /* we need both effective and real address here */
+       reboot_code_buffer_phys =
+           page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+       reboot_code_buffer = page_address(image->control_code_page);
+
+       /* Prepare parameters for reboot_code_buffer*/
+       kexec_start_address = image->start;
+       kexec_indirection_page = page_list;
+       kexec_mach_type = machine_arch_type;
+
+       /* copy our kernel relocation code to the control code page */
+       memcpy(reboot_code_buffer,
+              relocate_new_kernel, relocate_new_kernel_size);
+
+
+       flush_icache_range((unsigned long) reboot_code_buffer,
+                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
+       printk(KERN_INFO "Bye!\n");
+
+       cpu_proc_fin();
+       setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+       cpu_reset(reboot_code_buffer_phys);
+}
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..7baadae
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ */
+
+#include <asm/kexec.h>
+
+       .globl relocate_new_kernel
+relocate_new_kernel:
+
+       ldr     r0,kexec_indirection_page
+       ldr     r1,kexec_start_address
+
+
+0:     /* top, read another word for the indirection page */
+       ldr     r3, [r0],#4
+
+       /* Is it a destination page. Put destination address to r4 */
+       tst     r3,#1,0
+       beq     1f
+       bic     r4,r3,#1
+       b       0b
+1:
+       /* Is it an indirection page */
+       tst     r3,#2,0
+       beq     1f
+       bic     r0,r3,#2
+       b       0b
+1:
+
+       /* are we done ? */
+       tst     r3,#4,0
+       beq     1f
+       b       2f
+
+1:
+       /* is it source ? */
+       tst     r3,#8,0
+       beq     0b
+       bic r3,r3,#8
+       mov r6,#1024
+9:
+       ldr r5,[r3],#4
+       str r5,[r4],#4
+       subs r6,r6,#1
+       bne 9b
+       b 0b
+
+2:
+       /* Jump to relocated kernel */
+       mov lr,r1
+       mov r0,#0
+       ldr r1,kexec_mach_type
+       mov r2,#0
+       mov pc,lr
+
+       .globl kexec_start_address
+kexec_start_address:
+       .long   0x0
+
+       .globl kexec_indirection_page
+kexec_indirection_page:
+       .long   0x0
+
+       .globl kexec_mach_type
+kexec_mach_type:
+       .long   0x0
+
+relocate_new_kernel_end:
+
+       .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+       .long relocate_new_kernel_end - relocate_new_kernel
+
+
index bbab134cd82d3fa547d72d5d2514591da9f52d92..243aea45805740ec44e064e66ed0ec93e08cc487 100644 (file)
@@ -88,6 +88,9 @@ struct cpu_user_fns cpu_user;
 #ifdef MULTI_CACHE
 struct cpu_cache_fns cpu_cache;
 #endif
+#ifdef CONFIG_OUTER_CACHE
+struct outer_cache_fns outer_cache;
+#endif
 
 struct stack {
        u32 irq[3];
index 3c8cdcfe8d4a9f72c9ffb3762a72b260be85d73c..3825acd6687d5548cd9195d91a4d8479edf20fa3 100644 (file)
  */
 struct sys_timer *system_timer;
 
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
 /* this needs a better home */
 DEFINE_SPINLOCK(rtc_lock);
 
-#ifdef CONFIG_SA1100_RTC_MODULE
+#ifdef CONFIG_RTC_DRV_CMOS_MODULE
 EXPORT_SYMBOL(rtc_lock);
 #endif
+#endif /* pc-style 'CMOS' RTC support */
 
 /* change this if you have some constant time drift */
 #define USECS_PER_JIFFY        (1000000/HZ)
index 08ad782c1649fb116987f14914f36872c481cd93..f174d1a3b11c7333d18a19f3524e39256af05add 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <asm/div64.h>
 #include <asm/hardware.h>
@@ -124,7 +125,7 @@ static unsigned long calc_pll_rate(u32 config_word)
        return (unsigned long)rate;
 }
 
-void ep93xx_clock_init(void)
+static int __init ep93xx_clock_init(void)
 {
        u32 value;
 
@@ -153,4 +154,7 @@ void ep93xx_clock_init(void)
        printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
                clk_f.rate / 1000000, clk_h.rate / 1000000,
                clk_p.rate / 1000000);
+
+       return 0;
 }
+arch_initcall(ep93xx_clock_init);
index 6b26346191c040f9949094232a7cf8e072949161..829aed696d982420b094280e8ff6cd9b3a029c6b 100644 (file)
@@ -152,22 +152,30 @@ struct sys_timer ep93xx_timer = {
 /*************************************************************************
  * GPIO handling for EP93xx
  *************************************************************************/
-static unsigned char gpio_int_enable[2];
-static unsigned char gpio_int_type1[2];
-static unsigned char gpio_int_type2[2];
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
+static unsigned char gpio_int_type1[3];
+static unsigned char gpio_int_type2[3];
 
-static void update_gpio_ab_int_params(int port)
+static void update_gpio_int_params(int abf)
 {
-       if (port == 0) {
+       if (abf == 0) {
                __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
                __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
                __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
-               __raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE);
-       } else if (port == 1) {
+               __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
+       } else if (abf == 1) {
                __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
                __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
                __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
-               __raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE);
+               __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
+       } else if (abf == 2) {
+               __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
+               __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
+               __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
+               __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
+       } else {
+               BUG();
        }
 }
 
@@ -192,8 +200,13 @@ void gpio_line_config(int line, int direction)
        local_irq_save(flags);
        if (direction == GPIO_OUT) {
                if (line >= 0 && line < 16) {
-                       gpio_int_enable[line >> 3] &= ~(1 << (line & 7));
-                       update_gpio_ab_int_params(line >> 3);
+                       /* Port A/B.  */
+                       gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
+                       update_gpio_int_params(line >> 3);
+               } else if (line >= 40 && line < 48) {
+                       /* Port F.  */
+                       gpio_int_unmasked[2] &= ~(1 << (line & 7));
+                       update_gpio_int_params(2);
                }
 
                v = __raw_readb(data_direction_register);
@@ -244,8 +257,7 @@ EXPORT_SYMBOL(gpio_line_set);
 /*************************************************************************
  * EP93xx IRQ handling
  *************************************************************************/
-static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
-               struct irq_desc *desc)
+static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
        unsigned char status;
        int i;
@@ -267,37 +279,46 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
        }
 }
 
-static void ep93xx_gpio_ab_irq_mask_ack(unsigned int irq)
+static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
+
+       desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
+}
+
+static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
 {
        int line = irq - IRQ_EP93XX_GPIO(0);
        int port = line >> 3;
 
-       gpio_int_enable[port] &= ~(1 << (line & 7));
-       update_gpio_ab_int_params(port);
+       gpio_int_unmasked[port] &= ~(1 << (line & 7));
+       update_gpio_int_params(port);
 
-       if (line >> 3) {
-               __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
-       } else {
+       if (port == 0) {
                __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
+       } else if (port == 1) {
+               __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
+       } else if (port == 2) {
+               __raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
        }
 }
 
-static void ep93xx_gpio_ab_irq_mask(unsigned int irq)
+static void ep93xx_gpio_irq_mask(unsigned int irq)
 {
        int line = irq - IRQ_EP93XX_GPIO(0);
        int port = line >> 3;
 
-       gpio_int_enable[port] &= ~(1 << (line & 7));
-       update_gpio_ab_int_params(port);
+       gpio_int_unmasked[port] &= ~(1 << (line & 7));
+       update_gpio_int_params(port);
 }
 
-static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
+static void ep93xx_gpio_irq_unmask(unsigned int irq)
 {
        int line = irq - IRQ_EP93XX_GPIO(0);
        int port = line >> 3;
 
-       gpio_int_enable[port] |= 1 << (line & 7);
-       update_gpio_ab_int_params(port);
+       gpio_int_unmasked[port] |= 1 << (line & 7);
+       update_gpio_int_params(port);
 }
 
 
@@ -306,40 +327,51 @@ static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
  * edge (1) triggered, while gpio_int_type2 controls whether it
  * triggers on low/falling (0) or high/rising (1).
  */
-static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type)
+static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
 {
        int port;
        int line;
 
        line = irq - IRQ_EP93XX_GPIO(0);
-       gpio_line_config(line, GPIO_IN);
+       if (line >= 0 && line < 16) {
+               gpio_line_config(line, GPIO_IN);
+       } else {
+               gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN);
+       }
 
        port = line >> 3;
        line &= 7;
 
        if (type & IRQT_RISING) {
+               gpio_int_enabled[port] |= 1 << line;
                gpio_int_type1[port] |= 1 << line;
                gpio_int_type2[port] |= 1 << line;
        } else if (type & IRQT_FALLING) {
+               gpio_int_enabled[port] |= 1 << line;
                gpio_int_type1[port] |= 1 << line;
                gpio_int_type2[port] &= ~(1 << line);
        } else if (type & IRQT_HIGH) {
+               gpio_int_enabled[port] |= 1 << line;
                gpio_int_type1[port] &= ~(1 << line);
                gpio_int_type2[port] |= 1 << line;
        } else if (type & IRQT_LOW) {
+               gpio_int_enabled[port] |= 1 << line;
                gpio_int_type1[port] &= ~(1 << line);
                gpio_int_type2[port] &= ~(1 << line);
+       } else {
+               gpio_int_enabled[port] &= ~(1 << line);
        }
-       update_gpio_ab_int_params(port);
+       update_gpio_int_params(port);
 
        return 0;
 }
 
-static struct irq_chip ep93xx_gpio_ab_irq_chip = {
-       .ack            = ep93xx_gpio_ab_irq_mask_ack,
-       .mask           = ep93xx_gpio_ab_irq_mask,
-       .unmask         = ep93xx_gpio_ab_irq_unmask,
-       .set_type       = ep93xx_gpio_ab_irq_type,
+static struct irq_chip ep93xx_gpio_irq_chip = {
+       .name           = "GPIO",
+       .ack            = ep93xx_gpio_irq_mask_ack,
+       .mask           = ep93xx_gpio_irq_mask,
+       .unmask         = ep93xx_gpio_irq_unmask,
+       .set_type       = ep93xx_gpio_irq_type,
 };
 
 
@@ -350,12 +382,21 @@ void __init ep93xx_init_irq(void)
        vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
        vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
 
-       for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) {
-               set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip);
+       for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
+               set_irq_chip(irq, &ep93xx_gpio_irq_chip);
                set_irq_handler(irq, handle_level_irq);
                set_irq_flags(irq, IRQF_VALID);
        }
+
        set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
 }
 
 
@@ -461,8 +502,6 @@ void __init ep93xx_init_devices(void)
 {
        unsigned int v;
 
-       ep93xx_clock_init();
-
        /*
         * Disallow access to MaverickCrunch initially.
         */
@@ -477,8 +516,4 @@ void __init ep93xx_init_devices(void)
 
        platform_device_register(&ep93xx_rtc_device);
        platform_device_register(&ep93xx_ohci_device);
-
-#ifdef CONFIG_CRUNCH
-       elf_hwcap |= HWCAP_CRUNCH;
-#endif
 }
index 9de1278d234f86d655880c6f587e10b785cb843a..390524c4710f543384861206557a72cc514a1175 100644 (file)
@@ -338,6 +338,27 @@ static struct platform_device i2c_device = {
        .num_resources  = ARRAY_SIZE(i2c_resources),
 };
 
+#ifdef CONFIG_PXA27x
+static struct resource i2c_power_resources[] = {
+       {
+               .start  = 0x40f00180,
+               .end    = 0x40f001a3,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_PWRI2C,
+               .end    = IRQ_PWRI2C,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_power_device = {
+       .name           = "pxa2xx-i2c",
+       .id             = 1,
+       .resource       = i2c_power_resources,
+       .num_resources  = ARRAY_SIZE(i2c_resources),
+};
+#endif
+
 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
 {
        i2c_device.dev.platform_data = info;
@@ -392,6 +413,9 @@ static struct platform_device *devices[] __initdata = {
        &stuart_device,
        &pxaficp_device,
        &i2c_device,
+#ifdef CONFIG_PXA27x
+       &i2c_power_device,
+#endif
        &i2s_device,
        &pxartc_device,
 };
index 17f5f4439fe756a966391732a83a02018ed94bd7..35156ca39df77e6a62414f30f879119e12b513df 100644 (file)
@@ -10,10 +10,21 @@ config MACH_REALVIEW_EB
 config REALVIEW_MPCORE
        bool "Support MPcore tile"
        depends on MACH_REALVIEW_EB
+       select CACHE_L2X0
        help
          Enable support for the MPCore tile on the Realview platform.
          Since there are device address and interrupt differences, a
          kernel built with this option enabled is not compatible with
          other tiles.
 
+config REALVIEW_MPCORE_REVB
+       bool "Support MPcore RevB tile"
+       depends on REALVIEW_MPCORE
+       default n
+       help
+         Enable support for the MPCore RevB tile on the Realview platform.
+         Since there are device address differences, a
+         kernel built with this option enabled is not compatible with
+         other tiles.
+
 endmenu
index b8484e15dacb7f3e8f3d69ca09ea58334ea47b42..fce3596f9950a6aea5d8489d9d674a99759ad7b0 100644 (file)
@@ -52,13 +52,14 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+       gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
 
        /*
         * let the primary processor know we're out of the
         * pen, then head off into the C entry point
         */
        pen_release = -1;
+       smp_wmb();
 
        /*
         * Synchronise with the boot thread.
@@ -102,6 +103,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
+               smp_rmb();
                if (pen_release == -1)
                        break;
 
index 9741b4d3c9cfca9c938db2c23c3f1c3e29ba6876..3dba666151dbb7be39bc22757701adacc012a447 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach-types.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/icst307.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -57,7 +58,26 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
+       },
+#ifdef CONFIG_REALVIEW_MPCORE
+       {
+               .virtual        = IO_ADDRESS(REALVIEW_GIC1_CPU_BASE),
+               .pfn            = __phys_to_pfn(REALVIEW_GIC1_CPU_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = IO_ADDRESS(REALVIEW_GIC1_DIST_BASE),
+               .pfn            = __phys_to_pfn(REALVIEW_GIC1_DIST_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
        }, {
+               .virtual        = IO_ADDRESS(REALVIEW_MPCORE_L220_BASE),
+               .pfn            = __phys_to_pfn(REALVIEW_MPCORE_L220_BASE),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
+       },
+#endif
+       {
                .virtual        = IO_ADDRESS(REALVIEW_SCTL_BASE),
                .pfn            = __phys_to_pfn(REALVIEW_SCTL_BASE),
                .length         = SZ_4K,
@@ -138,19 +158,29 @@ static void __init gic_init_irq(void)
 #ifdef CONFIG_REALVIEW_MPCORE
        unsigned int pldctrl;
        writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
-       pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + 0xd8);
+       pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1);
        pldctrl |= 0x00800000;  /* New irq mode */
-       writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8);
+       writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1);
        writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
 #endif
-       gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
-       gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+       gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
+       gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
+#ifdef CONFIG_REALVIEW_MPCORE
+       gic_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64);
+       gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
+       gic_cascade_irq(1, IRQ_EB_IRQ1);
+#endif
 }
 
 static void __init realview_eb_init(void)
 {
        int i;
 
+#ifdef CONFIG_REALVIEW_MPCORE
+       /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
+        * Bits:  .... ...0 0111 1001 0000 .... .... .... */
+       l2x0_init(__io_address(REALVIEW_MPCORE_L220_BASE), 0x00790000, 0xfe000fff);
+#endif
        clk_register(&realview_clcd_clk);
 
        platform_device_register(&realview_flash_device);
diff --git a/arch/arm/mach-s3c2400/Kconfig b/arch/arm/mach-s3c2400/Kconfig
new file mode 100644 (file)
index 0000000..deab072
--- /dev/null
@@ -0,0 +1,13 @@
+# arch/arm/mach-s3c2400/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+
+
+menu "S3C2400 Machines"
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2400/Makefile b/arch/arm/mach-s3c2400/Makefile
new file mode 100644 (file)
index 0000000..7e23f4e
--- /dev/null
@@ -0,0 +1,15 @@
+# arch/arm/mach-s3c2400/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2400)      += gpio.o
+
+# Machine support
+
diff --git a/arch/arm/mach-s3c2400/gpio.c b/arch/arm/mach-s3c2400/gpio.c
new file mode 100644 (file)
index 0000000..758e160
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s3c2400/gpio.c
+ *
+ * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
+ *
+ * S3C2400 GPIO support
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-gpio.h>
+
+int s3c2400_gpio_getirq(unsigned int pin)
+{
+       if (pin < S3C2410_GPE0 || pin > S3C2400_GPE7_EINT7)
+               return -1;  /* not valid interrupts */
+
+       return (pin - S3C2410_GPE0) + IRQ_EINT0;
+}
+
+EXPORT_SYMBOL(s3c2400_gpio_getirq);
index eb4ec411312ba8684d7e6830b2be578c8abf2262..d4b013b283c3680f63be0b9b8b05b4120ebf3777 100644 (file)
@@ -1,54 +1,51 @@
-if ARCH_S3C2410
+# arch/arm/mach-s3c2410/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
 
-menu "S3C24XX Implementations"
+config CPU_S3C2410
+       bool
+       depends on ARCH_S3C2410
+       select S3C2410_CLOCK
+       select S3C2410_GPIO
+       select S3C2410_PM if PM
+       help
+         Support for S3C2410 and S3C2410A family from the S3C24XX line
+         of Samsung Mobile CPUs.
 
-config MACH_AML_M5900
-       bool "AML M5900 Series"
-       select CPU_S3C2410
-       select PM_SIMTEC if PM
+config CPU_S3C2410_DMA
+       bool
+       depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
+       default y if CPU_S3C2410 || CPU_S3C2442
        help
-          Say Y here if you are using the American Microsystems M5900 Series
-           <http://www.amltd.com>
+         DMA device selection for S3C2410 and compatible CPUs
 
-config MACH_ANUBIS
-       bool "Simtec Electronics ANUBIS"
-       select CPU_S3C2440
-       select PM_SIMTEC if PM
+config S3C2410_PM
+       bool
        help
-         Say Y here if you are using the Simtec Electronics ANUBIS
-         development system
+         Power Management code common to S3C2410 and better
 
-config MACH_OSIRIS
-       bool "Simtec IM2440D20 (OSIRIS) module"
-       select CPU_S3C2440
-       select PM_SIMTEC if PM
+config S3C2410_GPIO
+       bool
        help
-         Say Y here if you are using the Simtec IM2440D20 module, also
-         known as the Osiris.
+         GPIO code for S3C2410 and similar processors
 
-config ARCH_BAST
-       bool "Simtec Electronics BAST (EB2410ITX)"
-       select CPU_S3C2410
-       select PM_SIMTEC if PM
-       select ISA
+config S3C2410_CLOCK
+       bool
        help
-         Say Y here if you are using the Simtec Electronics EB2410ITX
-         development board (also known as BAST)
+         Clock code for the S3C2410, and similar processors
 
-         Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
 
-config BAST_PC104_IRQ
-       bool "BAST PC104 IRQ support"
-       depends on ARCH_BAST
-       default y
-       help
-         Say Y here to enable the PC104 IRQ routing on the
-         Simtec BAST (EB2410ITX)
+menu "S3C2410 Machines"
 
-config PM_H1940
-       bool
+config ARCH_SMDK2410
+       bool "SMDK2410/A9M2410"
+       select CPU_S3C2410
+       select MACH_SMDK
        help
-         Internal node for H1940 and related PM
+          Say Y here if you are using the SMDK2410 or the derived module A9M2410
+           <http://www.fsforth.de>
 
 config ARCH_H1940
        bool "IPAQ H1940"
@@ -57,7 +54,10 @@ config ARCH_H1940
        help
          Say Y here if you are using the HP IPAQ H1940
 
-         <http://www.handhelds.org/projects/h1940.html>.
+config PM_H1940
+       bool
+       help
+         Internal node for H1940 and related PM
 
 config MACH_N30
        bool "Acer N30"
@@ -65,53 +65,36 @@ config MACH_N30
        help
          Say Y here if you are using the Acer N30
 
-         <http://zoo.weinigel.se/n30>.
-
-config MACH_SMDK
-       bool
-       help
-         Common machine code for SMDK2410 and SMDK2440
-
-config ARCH_SMDK2410
-       bool "SMDK2410/A9M2410"
+config ARCH_BAST
+       bool "Simtec Electronics BAST (EB2410ITX)"
        select CPU_S3C2410
-       select MACH_SMDK
+       select PM_SIMTEC if PM
+       select ISA
        help
-          Say Y here if you are using the SMDK2410 or the derived module A9M2410
-           <http://www.fsforth.de>
+         Say Y here if you are using the Simtec Electronics EB2410ITX
+         development board (also known as BAST)
 
-config ARCH_S3C2440
-       bool "SMDK2440"
-       select CPU_S3C2440
-       select MACH_SMDK
+config MACH_OTOM
+       bool "NexVision OTOM Board"
+       select CPU_S3C2410
        help
-         Say Y here if you are using the SMDK2440.
-
-config SMDK2440_CPU2440
-       bool "SMDK2440 with S3C2440 CPU module"
-       depends on ARCH_S3C2440
-       default y if ARCH_S3C2440
-       select CPU_S3C2440
-
-config SMDK2440_CPU2442
-       bool "SMDM2440 with S3C2442 CPU module"
-       depends on ARCH_S3C2440
-       select CPU_S3C2442
+         Say Y here if you are using the Nex Vision OTOM board
 
-config MACH_S3C2413
-       bool
+config MACH_AML_M5900
+       bool "AML M5900 Series"
+       select CPU_S3C2410
+       select PM_SIMTEC if PM
        help
-         Internal node for S3C2413 version of SMDK2413, so that
-         machine_is_s3c2413() will work when MACH_SMDK2413 is
-         selected
+          Say Y here if you are using the American Microsystems M5900 Series
+           <http://www.amltd.com>
 
-config MACH_SMDK2413
-       bool "SMDK2413"
-       select CPU_S3C2412
-       select MACH_S3C2413
-       select MACH_SMDK
+config BAST_PC104_IRQ
+       bool "BAST PC104 IRQ support"
+       depends on ARCH_BAST
+       default y
        help
-         Say Y here if you are using an SMDK2413
+         Say Y here to enable the PC104 IRQ routing on the
+         Simtec BAST (EB2410ITX)
 
 config MACH_VR1000
        bool "Thorcom VR1000"
@@ -120,202 +103,11 @@ config MACH_VR1000
        help
          Say Y here if you are using the Thorcom VR1000 board.
 
-         This linux port is currently being maintained by Simtec, on behalf
-         of Thorcom. Any queries, please contact Thorcom first.
-
-config MACH_RX3715
-       bool "HP iPAQ rx3715"
-       select CPU_S3C2440
-       select PM_H1940 if PM
-       help
-         Say Y here if you are using the HP iPAQ rx3715.
-
-         See <http://www.handhelds.org/projects/rx3715.html> for more
-         information on this project
-
-config MACH_OTOM
-       bool "NexVision OTOM Board"
-       select CPU_S3C2410
-       help
-         Say Y here if you are using the Nex Vision OTOM board
-
-config MACH_NEXCODER_2440
-       bool "NexVision NEXCODER 2440 Light Board"
-       select CPU_S3C2440
-       help
-         Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
-
-config MACH_VSTMS
-       bool "VMSTMS"
-       select CPU_S3C2412
+config MACH_QT2410
+       bool "QT2410"
+       select CPU_S3C2410
        help
-         Say Y here if you are using an VSTMS board
+          Say Y here if you are using the Armzone QT2410
 
 endmenu
 
-config S3C2410_CLOCK
-       bool
-       help
-         Clock code for the S3C2410, and similar processors
-
-config S3C2410_PM
-       bool
-       help
-         Power Management code common to S3C2410 and better
-
-config CPU_S3C2410_DMA
-       bool
-       depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
-       default y if CPU_S3C2410 || CPU_S3C2442
-       help
-         DMA device selection for S3C2410 and compatible CPUs
-
-config CPU_S3C2410
-       bool
-       depends on ARCH_S3C2410
-       select S3C2410_CLOCK
-       select S3C2410_PM if PM
-       help
-         Support for S3C2410 and S3C2410A family from the S3C24XX line
-         of Samsung Mobile CPUs.
-
-# internal node to signify if we are only dealing with an S3C2412
-
-config CPU_S3C2412_ONLY
-       bool
-       depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-                  !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
-       default y if CPU_S3C2412
-
-config S3C2412_PM
-       bool
-       help
-         Internal config node to apply S3C2412 power management
-
-config CPU_S3C2412
-       bool
-       depends on ARCH_S3C2410
-       select S3C2412_PM if PM
-       help
-         Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
-
-config CPU_S3C244X
-       bool
-       depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
-       help
-         Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
-
-config CPU_S3C2440
-       bool
-       depends on ARCH_S3C2410
-       select S3C2410_CLOCK
-       select S3C2410_PM if PM
-       select CPU_S3C244X
-       help
-         Support for S3C2440 Samsung Mobile CPU based systems.
-
-config CPU_S3C2442
-       bool
-       depends on ARCH_S3C2420
-       select S3C2410_CLOCK
-       select S3C2410_PM if PM
-       select CPU_S3C244X
-       help
-         Support for S3C2442 Samsung Mobile CPU based systems.
-
-comment "S3C2410 Boot"
-
-config S3C2410_BOOT_WATCHDOG
-       bool "S3C2410 Initialisation watchdog"
-       depends on ARCH_S3C2410 && S3C2410_WATCHDOG
-       help
-         Say y to enable the watchdog during the kernel decompression
-         stage. If the kernel fails to uncompress, then the watchdog
-         will trigger a reset and the system should restart.
-
-         Although this uses the same hardware unit as the kernel watchdog
-         driver, it is not a replacement for it. If you use this option,
-         you will have to use the watchdg driver to either stop the timeout
-         or restart it. If you do not, then your kernel will reboot after
-         startup.
-
-         The driver uses a fixed timeout value, so the exact time till the
-         system resets depends on the value of PCLK. The timeout on an
-         200MHz s3c2410 should be about 30 seconds.
-
-config S3C2410_BOOT_ERROR_RESET
-       bool "S3C2410 Reboot on decompression error"
-       depends on ARCH_S3C2410
-       help
-         Say y here to use the watchdog to reset the system if the
-         kernel decompressor detects an error during decompression.
-
-
-comment "S3C2410 Setup"
-
-config S3C2410_DMA
-       bool "S3C2410 DMA support"
-       depends on ARCH_S3C2410
-       help
-         S3C2410 DMA support. This is needed for drivers like sound which
-         use the S3C2410's DMA system to move data to and from the
-         peripheral blocks.
-
-config S3C2410_DMA_DEBUG
-       bool "S3C2410 DMA support debug"
-       depends on ARCH_S3C2410 && S3C2410_DMA
-       help
-         Enable debugging output for the DMA code. This option sends info
-         to the kernel log, at priority KERN_DEBUG.
-
-         Note, it is easy to create and fill the log buffer in a small
-         amount of time, as well as using an significant percentage of
-         the CPU time doing so.
-
-
-config S3C2410_PM_DEBUG
-       bool "S3C2410 PM Suspend debug"
-       depends on ARCH_S3C2410 && PM
-       help
-         Say Y here if you want verbose debugging from the PM Suspend and
-         Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-         for more information.
-
-config S3C2410_PM_CHECK
-       bool "S3C2410 PM Suspend Memory CRC"
-       depends on ARCH_S3C2410 && PM && CRC32
-       help
-         Enable the PM code's memory area checksum over sleep. This option
-         will generate CRCs of all blocks of memory, and store them before
-         going to sleep. The blocks are then checked on resume for any
-         errors.
-
-config S3C2410_PM_CHECK_CHUNKSIZE
-       int "S3C2410 PM Suspend CRC Chunksize (KiB)"
-       depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
-       default 64
-       help
-         Set the chunksize in Kilobytes of the CRC for checking memory
-         corruption over suspend and resume. A smaller value will mean that
-         the CRC data block will take more memory, but wil identify any
-         faults with better precision.
-
-config PM_SIMTEC
-       bool
-       help
-         Common power management code for systems that are
-         compatible with the Simtec style of power management
-
-config S3C2410_LOWLEVEL_UART_PORT
-       int "S3C2410 UART to use for low-level messages"
-       default 0
-       help
-         Choice of which UART port to use for the low-level messages,
-         such as the `Uncompressing...` at start time. The value of
-         this configuration should be between zero and two. The port
-         must have been initialised by the boot-loader before use.
-
-         Note, this does not affect the port used by the debug messages,
-         which is a separate configuration.
-
-endif
index 27663e28cc8881bd49aefd1a59fba40b3b337862..9a3d3d24c08446621523649b89273e8564cb577d 100644 (file)
@@ -1,92 +1,31 @@
-
+# arch/arm/mach-s3c2410/Makefile
 #
-# Makefile for the linux kernel.
+# Copyright 2007 Simtec Electronics
 #
+# Licensed under GPLv2
 
-# Object file lists.
-
-obj-y                  := cpu.o irq.o time.o gpio.o clock.o devs.o
-obj-m                  :=
-obj-n                  :=
-obj-                   :=
-obj-dma-y              :=
-obj-dma-n              :=
-
-# DMA
-obj-$(CONFIG_S3C2410_DMA)      += dma.o
-
-# S3C2400 support files
-obj-$(CONFIG_CPU_S3C2400)      += s3c2400-gpio.o
-
-# S3C2410 support files
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
 
 obj-$(CONFIG_CPU_S3C2410)      += s3c2410.o
-obj-$(CONFIG_CPU_S3C2410)      += s3c2410-gpio.o
-obj-$(CONFIG_CPU_S3C2410)      += s3c2410-irq.o
-
-obj-$(CONFIG_S3C2410_PM)       += s3c2410-pm.o s3c2410-sleep.o
-obj-$(CONFIG_CPU_S3C2410_DMA)  += s3c2410-dma.o
-
-# Power Management support
-
-obj-$(CONFIG_PM)               += pm.o sleep.o
-obj-$(CONFIG_PM_SIMTEC)                += pm-simtec.o
-obj-$(CONFIG_PM_H1940)         += pm-h1940.o
-
-# S3C2412 support
-obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o
-obj-$(CONFIG_CPU_S3C2412)      += s3c2412-irq.o
-obj-$(CONFIG_CPU_S3C2412)      += s3c2412-clock.o
-obj-dma-$(CONFIG_CPU_S3C2412)  += s3c2412-dma.o
-
-obj-$(CONFIG_S3C2412_PM)       += s3c2412-pm.o
-
-#
-# S3C244X support
-
-obj-$(CONFIG_CPU_S3C244X)      += s3c244x.o
-obj-$(CONFIG_CPU_S3C244X)      += s3c244x-irq.o
-
-# Clock control
-
-obj-$(CONFIG_S3C2410_CLOCK)    += s3c2410-clock.o
-
-# S3C2440 support
-
-obj-$(CONFIG_CPU_S3C2440)      += s3c2440.o s3c2440-dsc.o
-obj-$(CONFIG_CPU_S3C2440)      += s3c2440-irq.o
-obj-$(CONFIG_CPU_S3C2440)      += s3c2440-clock.o
-obj-$(CONFIG_CPU_S3C2440)      += s3c2410-gpio.o
-obj-dma-$(CONFIG_CPU_S3C2440)  += s3c2440-dma.o
+obj-$(CONFIG_CPU_S3C2410)      += irq.o
+obj-$(CONFIG_CPU_S3C2410_DMA)  += dma.o
+obj-$(CONFIG_CPU_S3C2410_DMA)  += dma.o
+obj-$(CONFIG_S3C2410_PM)       += pm.o sleep.o
+obj-$(CONFIG_S3C2410_GPIO)     += gpio.o
+obj-$(CONFIG_S3C2410_CLOCK)    += clock.o
 
-# S3C2442 support
+# Machine support
 
-obj-$(CONFIG_CPU_S3C2442)      += s3c2442.o
-obj-$(CONFIG_CPU_S3C2442)      += s3c2442-clock.o
-
-# bast extras
-
-obj-$(CONFIG_BAST_PC104_IRQ)   += bast-irq.o
-
-# merge in dma objects
-
-obj-y                          += $(obj-dma-y)
-
-# machine specific support
-
-obj-$(CONFIG_MACH_AML_M5900)   += mach-amlm5900.o
-obj-$(CONFIG_MACH_ANUBIS)      += mach-anubis.o
-obj-$(CONFIG_MACH_OSIRIS)      += mach-osiris.o
-obj-$(CONFIG_ARCH_BAST)                += mach-bast.o usb-simtec.o
+obj-$(CONFIG_ARCH_SMDK2410)    += mach-smdk2410.o
 obj-$(CONFIG_ARCH_H1940)       += mach-h1940.o
+obj-$(CONFIG_PM_H1940)         += pm-h1940.o
 obj-$(CONFIG_MACH_N30)         += mach-n30.o
-obj-$(CONFIG_ARCH_SMDK2410)    += mach-smdk2410.o
-obj-$(CONFIG_MACH_SMDK2413)    += mach-smdk2413.o
-obj-$(CONFIG_ARCH_S3C2440)     += mach-smdk2440.o
-obj-$(CONFIG_MACH_VR1000)      += mach-vr1000.o usb-simtec.o
-obj-$(CONFIG_MACH_RX3715)      += mach-rx3715.o
+obj-$(CONFIG_ARCH_BAST)                += mach-bast.o usb-simtec.o
 obj-$(CONFIG_MACH_OTOM)                += mach-otom.o
-obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
-obj-$(CONFIG_MACH_VSTMS)       += mach-vstms.o
-
-obj-$(CONFIG_MACH_SMDK)                += common-smdk.o
\ No newline at end of file
+obj-$(CONFIG_MACH_AML_M5900)   += mach-amlm5900.o
+obj-$(CONFIG_BAST_PC104_IRQ)   += bast-irq.o
+obj-$(CONFIG_MACH_VR1000)      += mach-vr1000.o usb-simtec.o
+obj-$(CONFIG_MACH_QT2410)      += mach-qt2410.o
index 379efe70778c6841d4b407d16b3a33c5f66070b5..daeba427d781bf9868396db7811941101e163c82 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/arch/bast-map.h>
 #include <asm/arch/bast-irq.h>
 
-#include "irq.h"
+#include <asm/plat-s3c24xx/irq.h>
 
 #if 0
 #include <asm/debug-ll.h>
index e5d03311752c06b4965c0c123112769f0b5ea1f4..e98543742eb936ae17da100530d63bf510999b5b 100644 (file)
@@ -1,2 +1,2 @@
-
+/* linux/arch/arm/mach-s3c2410/bast.h
 extern void bast_init_irq(void);
index e13fb6778890d6559f2a57e532cf16f4cf13dd38..5b4831c4c1d8dccb556c35a6502c92b238933672 100644 (file)
@@ -1,15 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/clock.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX Core clock control support
- *
- * Based on, and code from linux/arch/arm/mach-versatile/clock.c
- **
- **  Copyright (C) 2004 ARM Limited.
- **  Written by Deep Blue Solutions Limited.
- *
+ * S3C2410,S3C2440,S3C2442 Clock control support
  *
  * 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
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
 #include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
 
 #include <asm/hardware.h>
-#include <asm/irq.h>
 #include <asm/io.h>
 
+#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "clock.h"
-#include "cpu.h"
-
-/* clock information */
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-static LIST_HEAD(clocks);
-
-DEFINE_MUTEX(clocks_mutex);
-
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
+int s3c2410_clkcon_enable(struct clk *clk, int enable)
 {
-       return 0;
-}
-
-/* Clock API calls */
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
 
-struct clk *clk_get(struct device *dev, const char *id)
-{
-       struct clk *p;
-       struct clk *clk = ERR_PTR(-ENOENT);
-       int idno;
+       clkcon = __raw_readl(S3C2410_CLKCON);
 
-       if (dev == NULL || dev->bus != &platform_bus_type)
-               idno = -1;
+       if (enable)
+               clkcon |= clocks;
        else
-               idno = to_platform_device(dev)->id;
-
-       mutex_lock(&clocks_mutex);
-
-       list_for_each_entry(p, &clocks, list) {
-               if (p->id == idno &&
-                   strcmp(id, p->name) == 0 &&
-                   try_module_get(p->owner)) {
-                       clk = p;
-                       break;
-               }
-       }
-
-       /* check for the case where a device was supplied, but the
-        * clock that was being searched for is not device specific */
-
-       if (IS_ERR(clk)) {
-               list_for_each_entry(p, &clocks, list) {
-                       if (p->id == -1 && strcmp(id, p->name) == 0 &&
-                           try_module_get(p->owner)) {
-                               clk = p;
-                               break;
-                       }
-               }
-       }
+               clkcon &= ~clocks;
 
-       mutex_unlock(&clocks_mutex);
-       return clk;
-}
+       /* ensure none of the special function bits set */
+       clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
 
-void clk_put(struct clk *clk)
-{
-       module_put(clk->owner);
-}
+       __raw_writel(clkcon, S3C2410_CLKCON);
 
-int clk_enable(struct clk *clk)
-{
-       if (IS_ERR(clk) || clk == NULL)
-               return -EINVAL;
-
-       clk_enable(clk->parent);
-
-       mutex_lock(&clocks_mutex);
-
-       if ((clk->usage++) == 0)
-               (clk->enable)(clk, 1);
-
-       mutex_unlock(&clocks_mutex);
        return 0;
 }
 
-void clk_disable(struct clk *clk)
-{
-       if (IS_ERR(clk) || clk == NULL)
-               return;
-
-       mutex_lock(&clocks_mutex);
-
-       if ((--clk->usage) == 0)
-               (clk->enable)(clk, 0);
-
-       mutex_unlock(&clocks_mutex);
-       clk_disable(clk->parent);
-}
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       if (IS_ERR(clk))
-               return 0;
-
-       if (clk->rate != 0)
-               return clk->rate;
-
-       if (clk->get_rate != NULL)
-               return (clk->get_rate)(clk);
-
-       if (clk->parent != NULL)
-               return clk_get_rate(clk->parent);
-
-       return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (!IS_ERR(clk) && clk->round_rate)
-               return (clk->round_rate)(clk, rate);
-
-       return rate;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       int ret;
-
-       if (IS_ERR(clk))
-               return -EINVAL;
-
-       mutex_lock(&clocks_mutex);
-       ret = (clk->set_rate)(clk, rate);
-       mutex_unlock(&clocks_mutex);
-
-       return ret;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
+static int s3c2410_upll_enable(struct clk *clk, int enable)
 {
-       return clk->parent;
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       int ret = 0;
-
-       if (IS_ERR(clk))
-               return -EINVAL;
-
-       mutex_lock(&clocks_mutex);
-
-       if (clk->set_parent)
-               ret = (clk->set_parent)(clk, parent);
-
-       mutex_unlock(&clocks_mutex);
-
-       return ret;
-}
-
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
-EXPORT_SYMBOL(clk_enable);
-EXPORT_SYMBOL(clk_disable);
-EXPORT_SYMBOL(clk_get_rate);
-EXPORT_SYMBOL(clk_round_rate);
-EXPORT_SYMBOL(clk_set_rate);
-EXPORT_SYMBOL(clk_get_parent);
-EXPORT_SYMBOL(clk_set_parent);
-
-/* base clocks */
-
-struct clk clk_xtal = {
-       .name           = "xtal",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-};
-
-struct clk clk_mpll = {
-       .name           = "mpll",
-       .id             = -1,
-};
-
-struct clk clk_upll = {
-       .name           = "upll",
-       .id             = -1,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-};
-
-struct clk clk_f = {
-       .name           = "fclk",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = &clk_mpll,
-       .ctrlbit        = 0,
-};
-
-struct clk clk_h = {
-       .name           = "hclk",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-};
-
-struct clk clk_p = {
-       .name           = "pclk",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-};
-
-struct clk clk_usb_bus = {
-       .name           = "usb-bus",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = &clk_upll,
-};
-
-/* clocks that could be registered by external code */
-
-static int s3c24xx_dclk_enable(struct clk *clk, int enable)
-{
-       unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+       unsigned long orig = clkslow;
 
        if (enable)
-               dclkcon |= clk->ctrlbit;
+               clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
        else
-               dclkcon &= ~clk->ctrlbit;
+               clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
 
-       __raw_writel(dclkcon, S3C24XX_DCLKCON);
+       __raw_writel(clkslow, S3C2410_CLKSLOW);
 
-       return 0;
-}
+       /* if we started the UPLL, then allow to settle */
 
-static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
-{
-       unsigned long dclkcon;
-       unsigned int uclk;
-
-       if (parent == &clk_upll)
-               uclk = 1;
-       else if (parent == &clk_p)
-               uclk = 0;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-       if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
-               if (uclk)
-                       dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
-               else
-                       dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
-       } else {
-               if (uclk)
-                       dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
-               else
-                       dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
-       }
-
-       __raw_writel(dclkcon, S3C24XX_DCLKCON);
+       if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
+               udelay(200);
 
        return 0;
 }
 
-
-static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
-{
-       unsigned long mask;
-       unsigned long source;
-
-       /* calculate the MISCCR setting for the clock */
-
-       if (parent == &clk_xtal)
-               source = S3C2410_MISCCR_CLK0_MPLL;
-       else if (parent == &clk_upll)
-               source = S3C2410_MISCCR_CLK0_UPLL;
-       else if (parent == &clk_f)
-               source = S3C2410_MISCCR_CLK0_FCLK;
-       else if (parent == &clk_h)
-               source = S3C2410_MISCCR_CLK0_HCLK;
-       else if (parent == &clk_p)
-               source = S3C2410_MISCCR_CLK0_PCLK;
-       else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
-               source = S3C2410_MISCCR_CLK0_DCLK0;
-       else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
-               source = S3C2410_MISCCR_CLK0_DCLK0;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       if (clk == &s3c24xx_dclk0)
-               mask = S3C2410_MISCCR_CLK0_MASK;
-       else {
-               source <<= 4;
-               mask = S3C2410_MISCCR_CLK1_MASK;
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "nand",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_NAND,
+       }, {
+               .name           = "sdi",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_SDI,
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_IIC,
+       }, {
+               .name           = "iis",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_IIS,
+       }, {
+               .name           = "spi",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_SPI,
        }
-
-       s3c2410_modify_misccr(mask, source);
-       return 0;
-}
-
-/* external clock definitions */
-
-struct clk s3c24xx_dclk0 = {
-       .name           = "dclk0",
-       .id             = -1,
-       .ctrlbit        = S3C2410_DCLKCON_DCLK0EN,
-       .enable         = s3c24xx_dclk_enable,
-       .set_parent     = s3c24xx_dclk_setparent,
-};
-
-struct clk s3c24xx_dclk1 = {
-       .name           = "dclk1",
-       .id             = -1,
-       .ctrlbit        = S3C2410_DCLKCON_DCLK0EN,
-       .enable         = s3c24xx_dclk_enable,
-       .set_parent     = s3c24xx_dclk_setparent,
 };
 
-struct clk s3c24xx_clkout0 = {
-       .name           = "clkout0",
-       .id             = -1,
-       .set_parent     = s3c24xx_clkout_setparent,
+static struct clk init_clocks[] = {
+       {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_LCDC,
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_USBD,
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_PWMT,
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_UART2,
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2410_clkcon_enable,
+               .ctrlbit        = S3C2410_CLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = 0,
+       }, {
+               .name           = "usb-bus-host",
+               .id             = -1,
+               .parent         = &clk_usb_bus,
+       }, {
+               .name           = "usb-bus-gadget",
+               .id             = -1,
+               .parent         = &clk_usb_bus,
+       },
 };
 
-struct clk s3c24xx_clkout1 = {
-       .name           = "clkout1",
-       .id             = -1,
-       .set_parent     = s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_uclk = {
-       .name           = "uclk",
-       .id             = -1,
-};
-
-/* initialise the clock system */
-
-int s3c24xx_register_clock(struct clk *clk)
-{
-       clk->owner = THIS_MODULE;
-
-       if (clk->enable == NULL)
-               clk->enable = clk_null_enable;
-
-       /* add to the list of available clocks */
-
-       mutex_lock(&clocks_mutex);
-       list_add(&clk->list, &clocks);
-       mutex_unlock(&clocks_mutex);
-
-       return 0;
-}
-
-/* initalise all the clocks */
+/* s3c2410_baseclk_add()
+ *
+ * Add all the clocks used by the s3c2410 or compatible CPUs
+ * such as the S3C2440 and S3C2442.
+ *
+ * We cannot use a system device as we are needed before any
+ * of the init-calls that initialise the devices are actually
+ * done.
+*/
 
-int __init s3c24xx_setup_clocks(unsigned long xtal,
-                               unsigned long fclk,
-                               unsigned long hclk,
-                               unsigned long pclk)
+int __init s3c2410_baseclk_add(void)
 {
-       printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
+       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+       struct clk *clkp;
+       struct clk *xtal;
+       int ret;
+       int ptr;
 
-       /* initialise the main system clocks */
+       clk_upll.enable = s3c2410_upll_enable;
 
-       clk_xtal.rate = xtal;
-       clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
+       if (s3c24xx_register_clock(&clk_usb_bus) < 0)
+               printk(KERN_ERR "failed to register usb bus clock\n");
 
-       clk_mpll.rate = fclk;
-       clk_h.rate = hclk;
-       clk_p.rate = pclk;
-       clk_f.rate = fclk;
+       /* register clocks from clock array */
 
-       /* assume uart clocks are correctly setup */
+       clkp = init_clocks;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+               /* ensure that we note the clock state */
 
-       /* register our clocks */
+               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
 
-       if (s3c24xx_register_clock(&clk_xtal) < 0)
-               printk(KERN_ERR "failed to register master xtal\n");
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
 
-       if (s3c24xx_register_clock(&clk_mpll) < 0)
-               printk(KERN_ERR "failed to register mpll clock\n");
+       /* We must be careful disabling the clocks we are not intending to
+        * be using at boot time, as subsytems such as the LCD which do
+        * their own DMA requests to the bus can cause the system to lockup
+        * if they where in the middle of requesting bus access.
+        *
+        * Disabling the LCD clock if the LCD is active is very dangerous,
+        * and therefore the bootloader should be careful to not enable
+        * the LCD clock if it is not needed.
+       */
+
+       /* install (and disable) the clocks we do not need immediately */
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
 
-       if (s3c24xx_register_clock(&clk_upll) < 0)
-               printk(KERN_ERR "failed to register upll clock\n");
+               s3c2410_clkcon_enable(clkp, 0);
+       }
 
-       if (s3c24xx_register_clock(&clk_f) < 0)
-               printk(KERN_ERR "failed to register cpu fclk\n");
+       /* show the clock-slow value */
 
-       if (s3c24xx_register_clock(&clk_h) < 0)
-               printk(KERN_ERR "failed to register cpu hclk\n");
+       xtal = clk_get(NULL, "xtal");
 
-       if (s3c24xx_register_clock(&clk_p) < 0)
-               printk(KERN_ERR "failed to register cpu pclk\n");
+       printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
+              print_mhz(clk_get_rate(xtal) /
+                        ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
+              (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
+              (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
+              (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
 
        return 0;
 }
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
deleted file mode 100644 (file)
index 7f0ea03..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c2410/clock.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/SWLINUX/
- *     Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * 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.
-*/
-
-struct clk {
-       struct list_head      list;
-       struct module        *owner;
-       struct clk           *parent;
-       const char           *name;
-       int                   id;
-       int                   usage;
-       unsigned long         rate;
-       unsigned long         ctrlbit;
-
-       int                 (*enable)(struct clk *, int enable);
-       int                 (*set_rate)(struct clk *c, unsigned long rate);
-       unsigned long       (*get_rate)(struct clk *c);
-       unsigned long       (*round_rate)(struct clk *c, unsigned long rate);
-       int                 (*set_parent)(struct clk *c, struct clk *parent);
-};
-
-/* other clocks which may be registered by board support */
-
-extern struct clk s3c24xx_dclk0;
-extern struct clk s3c24xx_dclk1;
-extern struct clk s3c24xx_clkout0;
-extern struct clk s3c24xx_clkout1;
-extern struct clk s3c24xx_uclk;
-
-extern struct clk clk_usb_bus;
-
-/* core clock support */
-
-extern struct clk clk_f;
-extern struct clk clk_h;
-extern struct clk clk_p;
-extern struct clk clk_mpll;
-extern struct clk clk_upll;
-extern struct clk clk_xtal;
-
-/* exports for arch/arm/mach-s3c2410
- *
- * Please DO NOT use these outside of arch/arm/mach-s3c2410
-*/
-
-extern struct mutex clocks_mutex;
-
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-
-extern int s3c24xx_register_clock(struct clk *clk);
-
-extern int s3c24xx_setup_clocks(unsigned long xtal,
-                               unsigned long fclk,
-                               unsigned long hclk,
-                               unsigned long pclk);
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
deleted file mode 100644 (file)
index a40eaa6..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/common-smdk.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Common code for SMDK2410 and SMDK2440 boards
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/leds-gpio.h>
-
-#include <asm/arch/nand.h>
-
-#include "common-smdk.h"
-#include "devs.h"
-#include "pm.h"
-
-/* LED devices */
-
-static struct s3c24xx_led_platdata smdk_pdata_led4 = {
-       .gpio           = S3C2410_GPF4,
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led4",
-       .def_trigger    = "timer",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led5 = {
-       .gpio           = S3C2410_GPF5,
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led5",
-       .def_trigger    = "nand-disk",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led6 = {
-       .gpio           = S3C2410_GPF6,
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led6",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led7 = {
-       .gpio           = S3C2410_GPF7,
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led7",
-};
-
-static struct platform_device smdk_led4 = {
-       .name           = "s3c24xx_led",
-       .id             = 0,
-       .dev            = {
-               .platform_data = &smdk_pdata_led4,
-       },
-};
-
-static struct platform_device smdk_led5 = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data = &smdk_pdata_led5,
-       },
-};
-
-static struct platform_device smdk_led6 = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data = &smdk_pdata_led6,
-       },
-};
-
-static struct platform_device smdk_led7 = {
-       .name           = "s3c24xx_led",
-       .id             = 3,
-       .dev            = {
-               .platform_data = &smdk_pdata_led7,
-       },
-};
-
-/* NAND parititon from 2.4.18-swl5 */
-
-static struct mtd_partition smdk_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "S3C2410 flash partition 1",
-               .offset = 0,
-               .size   = SZ_2M,
-       },
-       [2] = {
-               .name   = "S3C2410 flash partition 2",
-               .offset = SZ_4M,
-               .size   = SZ_4M,
-       },
-       [3] = {
-               .name   = "S3C2410 flash partition 3",
-               .offset = SZ_8M,
-               .size   = SZ_2M,
-       },
-       [4] = {
-               .name   = "S3C2410 flash partition 4",
-               .offset = SZ_1M * 10,
-               .size   = SZ_4M,
-       },
-       [5] = {
-               .name   = "S3C2410 flash partition 5",
-               .offset = SZ_1M * 14,
-               .size   = SZ_1M * 10,
-       },
-       [6] = {
-               .name   = "S3C2410 flash partition 6",
-               .offset = SZ_1M * 24,
-               .size   = SZ_1M * 24,
-       },
-       [7] = {
-               .name   = "S3C2410 flash partition 7",
-               .offset = SZ_1M * 48,
-               .size   = SZ_16M,
-       }
-};
-
-static struct s3c2410_nand_set smdk_nand_sets[] = {
-       [0] = {
-               .name           = "NAND",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(smdk_default_nand_part),
-               .partitions     = smdk_default_nand_part,
-       },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
-*/
-
-static struct s3c2410_platform_nand smdk_nand_info = {
-       .tacls          = 20,
-       .twrph0         = 60,
-       .twrph1         = 20,
-       .nr_sets        = ARRAY_SIZE(smdk_nand_sets),
-       .sets           = smdk_nand_sets,
-};
-
-/* devices we initialise */
-
-static struct platform_device __initdata *smdk_devs[] = {
-       &s3c_device_nand,
-       &smdk_led4,
-       &smdk_led5,
-       &smdk_led6,
-       &smdk_led7,
-};
-
-void __init smdk_machine_init(void)
-{
-       /* Configure the LEDs (even if we have no LED support)*/
-
-       s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
-       s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
-       s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
-       s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
-
-       s3c2410_gpio_setpin(S3C2410_GPF4, 1);
-       s3c2410_gpio_setpin(S3C2410_GPF5, 1);
-       s3c2410_gpio_setpin(S3C2410_GPF6, 1);
-       s3c2410_gpio_setpin(S3C2410_GPF7, 1);
-
-       s3c_device_nand.dev.platform_data = &smdk_nand_info;
-
-       platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
-
-       s3c2410_pm_init();
-}
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/arch/arm/mach-s3c2410/common-smdk.h
deleted file mode 100644 (file)
index 0e3a3be..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/common-smdk.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Common code for SMDK2410 and SMDK2440 boards
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * 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.
-*/
-
-extern void smdk_machine_init(void);
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
deleted file mode 100644 (file)
index ae1f5bb..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/cpu.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/SWLINUX/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX CPU Support
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-serial.h>
-
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
-#include "s3c2400.h"
-#include "s3c2410.h"
-#include "s3c2412.h"
-#include "s3c244x.h"
-#include "s3c2440.h"
-#include "s3c2442.h"
-
-struct cpu_table {
-       unsigned long   idcode;
-       unsigned long   idmask;
-       void            (*map_io)(struct map_desc *mach_desc, int size);
-       void            (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
-       void            (*init_clocks)(int xtal);
-       int             (*init)(void);
-       const char      *name;
-};
-
-/* table of supported CPUs */
-
-static const char name_s3c2400[]  = "S3C2400";
-static const char name_s3c2410[]  = "S3C2410";
-static const char name_s3c2412[]  = "S3C2412";
-static const char name_s3c2440[]  = "S3C2440";
-static const char name_s3c2442[]  = "S3C2442";
-static const char name_s3c2410a[] = "S3C2410A";
-static const char name_s3c2440a[] = "S3C2440A";
-
-static struct cpu_table cpu_ids[] __initdata = {
-       {
-               .idcode         = 0x32410000,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c2410_map_io,
-               .init_clocks    = s3c2410_init_clocks,
-               .init_uarts     = s3c2410_init_uarts,
-               .init           = s3c2410_init,
-               .name           = name_s3c2410
-       },
-       {
-               .idcode         = 0x32410002,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c2410_map_io,
-               .init_clocks    = s3c2410_init_clocks,
-               .init_uarts     = s3c2410_init_uarts,
-               .init           = s3c2410_init,
-               .name           = name_s3c2410a
-       },
-       {
-               .idcode         = 0x32440000,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
-               .init_clocks    = s3c244x_init_clocks,
-               .init_uarts     = s3c244x_init_uarts,
-               .init           = s3c2440_init,
-               .name           = name_s3c2440
-       },
-       {
-               .idcode         = 0x32440001,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
-               .init_clocks    = s3c244x_init_clocks,
-               .init_uarts     = s3c244x_init_uarts,
-               .init           = s3c2440_init,
-               .name           = name_s3c2440a
-       },
-       {
-               .idcode         = 0x32440aaa,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c244x_map_io,
-               .init_clocks    = s3c244x_init_clocks,
-               .init_uarts     = s3c244x_init_uarts,
-               .init           = s3c2442_init,
-               .name           = name_s3c2442
-       },
-       {
-               .idcode         = 0x32412001,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c2412_map_io,
-               .init_clocks    = s3c2412_init_clocks,
-               .init_uarts     = s3c2412_init_uarts,
-               .init           = s3c2412_init,
-               .name           = name_s3c2412,
-       },
-       {                       /* a newer version of the s3c2412 */
-               .idcode         = 0x32412003,
-               .idmask         = 0xffffffff,
-               .map_io         = s3c2412_map_io,
-               .init_clocks    = s3c2412_init_clocks,
-               .init_uarts     = s3c2412_init_uarts,
-               .init           = s3c2412_init,
-               .name           = name_s3c2412,
-       },
-       {
-               .idcode         = 0x0,   /* S3C2400 doesn't have an idcode */
-               .idmask         = 0xffffffff,
-               .map_io         = s3c2400_map_io,
-               .init_clocks    = s3c2400_init_clocks,
-               .init_uarts     = s3c2400_init_uarts,
-               .init           = s3c2400_init,
-               .name           = name_s3c2400
-       },
-};
-
-/* minimal IO mapping */
-
-static struct map_desc s3c_iodesc[] __initdata = {
-       IODESC_ENT(GPIO),
-       IODESC_ENT(IRQ),
-       IODESC_ENT(MEMCTRL),
-       IODESC_ENT(UART)
-};
-
-
-static struct cpu_table *
-s3c_lookup_cpu(unsigned long idcode)
-{
-       struct cpu_table *tab;
-       int count;
-
-       tab = cpu_ids;
-       for (count = 0; count < ARRAY_SIZE(cpu_ids); count++, tab++) {
-               if ((idcode & tab->idmask) == tab->idcode)
-                       return tab;
-       }
-
-       return NULL;
-}
-
-/* board information */
-
-static struct s3c24xx_board *board;
-
-void s3c24xx_set_board(struct s3c24xx_board *b)
-{
-       int i;
-
-       board = b;
-
-       if (b->clocks_count != 0) {
-               struct clk **ptr = b->clocks;
-
-               for (i = b->clocks_count; i > 0; i--, ptr++)
-                       s3c24xx_register_clock(*ptr);
-       }
-}
-
-/* cpu information */
-
-static struct cpu_table *cpu;
-
-static unsigned long s3c24xx_read_idcode_v5(void)
-{
-#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
-       return __raw_readl(S3C2412_GSTATUS1);
-#else
-       return 1UL;     /* don't look like an 2400 */
-#endif
-}
-
-static unsigned long s3c24xx_read_idcode_v4(void)
-{
-#ifndef CONFIG_CPU_S3C2400
-       return __raw_readl(S3C2410_GSTATUS1);
-#else
-       return 0UL;
-#endif
-}
-
-void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
-{
-       unsigned long idcode = 0x0;
-
-       /* initialise the io descriptors we need for initialisation */
-       iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
-
-       if (cpu_architecture() >= CPU_ARCH_ARMv5) {
-               idcode = s3c24xx_read_idcode_v5();
-       } else {
-               idcode = s3c24xx_read_idcode_v4();
-       }
-
-       cpu = s3c_lookup_cpu(idcode);
-
-       if (cpu == NULL) {
-               printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
-               panic("Unknown S3C24XX CPU");
-       }
-
-       printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
-
-       if (cpu->map_io == NULL || cpu->init == NULL) {
-               printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
-               panic("Unsupported S3C24XX CPU");
-       }
-
-       (cpu->map_io)(mach_desc, size);
-}
-
-/* s3c24xx_init_clocks
- *
- * Initialise the clock subsystem and associated information from the
- * given master crystal value.
- *
- * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
- *      != 0 -> PLL crystal value in Hz
-*/
-
-void __init s3c24xx_init_clocks(int xtal)
-{
-       if (xtal == 0)
-               xtal = 12*1000*1000;
-
-       if (cpu == NULL)
-               panic("s3c24xx_init_clocks: no cpu setup?\n");
-
-       if (cpu->init_clocks == NULL)
-               panic("s3c24xx_init_clocks: cpu has no clock init\n");
-       else
-               (cpu->init_clocks)(xtal);
-}
-
-/* uart management */
-
-static int nr_uarts __initdata = 0;
-
-static struct s3c2410_uartcfg uart_cfgs[3];
-
-/* s3c24xx_init_uartdevs
- *
- * copy the specified platform data and configuration into our central
- * set of devices, before the data is thrown away after the init process.
- *
- * This also fills in the array passed to the serial driver for the
- * early initialisation of the console.
-*/
-
-void __init s3c24xx_init_uartdevs(char *name,
-                                 struct s3c24xx_uart_resources *res,
-                                 struct s3c2410_uartcfg *cfg, int no)
-{
-       struct platform_device *platdev;
-       struct s3c2410_uartcfg *cfgptr = uart_cfgs;
-       struct s3c24xx_uart_resources *resp;
-       int uart;
-
-       memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
-
-       for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
-               platdev = s3c24xx_uart_src[cfgptr->hwport];
-
-               resp = res + cfgptr->hwport;
-
-               s3c24xx_uart_devs[uart] = platdev;
-
-               platdev->name = name;
-               platdev->resource = resp->resources;
-               platdev->num_resources = resp->nr_resources;
-
-               platdev->dev.platform_data = cfgptr;
-       }
-
-       nr_uarts = no;
-}
-
-void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       if (cpu == NULL)
-               return;
-
-       if (cpu->init_uarts == NULL) {
-               printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
-       } else
-               (cpu->init_uarts)(cfg, no);
-}
-
-static int __init s3c_arch_init(void)
-{
-       int ret;
-
-       // do the correct init for cpu
-
-       if (cpu == NULL)
-               panic("s3c_arch_init: NULL cpu\n");
-
-       ret = (cpu->init)();
-       if (ret != 0)
-               return ret;
-
-       ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
-       if (ret != 0)
-               return ret;
-
-       if (board != NULL) {
-               struct platform_device **ptr = board->devices;
-               int i;
-
-               for (i = 0; i < board->devices_count; i++, ptr++) {
-                       ret = platform_device_register(*ptr);
-
-                       if (ret) {
-                               printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr);
-                       }
-               }
-
-               /* mask any error, we may not need all these board
-                * devices */
-               ret = 0;
-       }
-
-       return ret;
-}
-
-arch_initcall(s3c_arch_init);
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
deleted file mode 100644 (file)
index be42e40..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* arch/arm/mach-s3c2410/cpu.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU support
- *
- * 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.
-*/
-
-/* todo - fix when rmk changes iodescs to use `void __iomem *` */
-
-#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
-
-#ifndef MHZ
-#define MHZ (1000*1000)
-#endif
-
-#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
-
-/* forward declaration */
-struct s3c24xx_uart_resources;
-struct platform_device;
-struct s3c2410_uartcfg;
-struct map_desc;
-
-/* core initialisation functions */
-
-extern void s3c24xx_init_irq(void);
-
-extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
-
-extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c24xx_init_clocks(int xtal);
-
-extern void s3c24xx_init_uartdevs(char *name,
-                                 struct s3c24xx_uart_resources *res,
-                                 struct s3c2410_uartcfg *cfg, int no);
-
-/* the board structure is used at first initialsation time
- * to get info such as the devices to register for this
- * board. This is done because platfrom_add_devices() cannot
- * be called from the map_io entry.
-*/
-
-struct s3c24xx_board {
-       struct platform_device  **devices;
-       unsigned int              devices_count;
-
-       struct clk              **clocks;
-       unsigned int              clocks_count;
-};
-
-extern void s3c24xx_set_board(struct s3c24xx_board *board);
-
-/* timer for 2410/2440 */
-
-struct sys_timer;
-extern struct sys_timer s3c24xx_timer;
-
-/* system device classes */
-
-extern struct sysdev_class s3c2410_sysclass;
-extern struct sysdev_class s3c2412_sysclass;
-extern struct sysdev_class s3c2440_sysclass;
-extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
deleted file mode 100644 (file)
index faccde2..0000000
+++ /dev/null
@@ -1,585 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/devs.c
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Base S3C24XX platform device definitions
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/arch/fb.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-serial.h>
-
-#include "devs.h"
-#include "cpu.h"
-
-/* Serial port registrations */
-
-static struct resource s3c2410_uart0_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART0,
-               .end   = S3C2410_PA_UART0 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX0,
-               .end   = IRQ_S3CUART_ERR0,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c2410_uart1_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART1,
-               .end   = S3C2410_PA_UART1 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX1,
-               .end   = IRQ_S3CUART_ERR1,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c2410_uart2_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART2,
-               .end   = S3C2410_PA_UART2 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX2,
-               .end   = IRQ_S3CUART_ERR2,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
-       [0] = {
-               .resources      = s3c2410_uart0_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart0_resource),
-       },
-       [1] = {
-               .resources      = s3c2410_uart1_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart1_resource),
-       },
-       [2] = {
-               .resources      = s3c2410_uart2_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart2_resource),
-       },
-};
-
-/* yart devices */
-
-static struct platform_device s3c24xx_uart_device0 = {
-       .id             = 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-       .id             = 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-       .id             = 2,
-};
-
-struct platform_device *s3c24xx_uart_src[3] = {
-       &s3c24xx_uart_device0,
-       &s3c24xx_uart_device1,
-       &s3c24xx_uart_device2,
-};
-
-struct platform_device *s3c24xx_uart_devs[3] = {
-};
-
-/* USB Host Controller */
-
-static struct resource s3c_usb_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_USBHOST,
-               .end   = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBH,
-               .end   = IRQ_USBH,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_usb_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_usb = {
-       .name             = "s3c2410-ohci",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_usb_resource),
-       .resource         = s3c_usb_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_usb_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_usb);
-
-/* LCD Controller */
-
-static struct resource s3c_lcd_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_LCD,
-               .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_LCD,
-               .end   = IRQ_LCD,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_lcd = {
-       .name             = "s3c2410-lcd",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_lcd_resource),
-       .resource         = s3c_lcd_resource,
-       .dev              = {
-               .dma_mask               = &s3c_device_lcd_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_lcd);
-
-void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
-{
-       struct s3c2410fb_mach_info *npd;
-
-       npd = kmalloc(sizeof(*npd), GFP_KERNEL);
-       if (npd) {
-               memcpy(npd, pd, sizeof(*npd));
-               s3c_device_lcd.dev.platform_data = npd;
-       } else {
-               printk(KERN_ERR "no memory for LCD platform data\n");
-       }
-}
-
-/* NAND Controller */
-
-static struct resource s3c_nand_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_NAND,
-               .end   = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-struct platform_device s3c_device_nand = {
-       .name             = "s3c2410-nand",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_nand_resource),
-       .resource         = s3c_nand_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_nand);
-
-/* USB Device (Gadget)*/
-
-static struct resource s3c_usbgadget_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_USBDEV,
-               .end   = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBD,
-               .end   = IRQ_USBD,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_usbgadget = {
-       .name             = "s3c2410-usbgadget",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_usbgadget_resource),
-       .resource         = s3c_usbgadget_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_usbgadget);
-
-/* Watchdog */
-
-static struct resource s3c_wdt_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_WATCHDOG,
-               .end   = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_WDT,
-               .end   = IRQ_WDT,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_wdt = {
-       .name             = "s3c2410-wdt",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_wdt_resource),
-       .resource         = s3c_wdt_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_wdt);
-
-/* I2C */
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_IIC,
-               .end   = S3C24XX_PA_IIC + S3C24XX_SZ_IIC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IIC,
-               .end   = IRQ_IIC,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_i2c = {
-       .name             = "s3c2410-i2c",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
-       .resource         = s3c_i2c_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_i2c);
-
-/* IIS */
-
-static struct resource s3c_iis_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_IIS,
-               .end   = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static u64 s3c_device_iis_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_iis = {
-       .name             = "s3c2410-iis",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_iis_resource),
-       .resource         = s3c_iis_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_iis_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_iis);
-
-/* RTC */
-
-static struct resource s3c_rtc_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_RTC,
-               .end   = S3C24XX_PA_RTC + 0xff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_RTC,
-               .end   = IRQ_RTC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_TICK,
-               .end   = IRQ_TICK,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-struct platform_device s3c_device_rtc = {
-       .name             = "s3c2410-rtc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
-       .resource         = s3c_rtc_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_rtc);
-
-/* ADC */
-
-static struct resource s3c_adc_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_ADC,
-               .end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_ADC,
-               .end   = IRQ_ADC,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_adc = {
-       .name             = "s3c2410-adc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_adc_resource),
-       .resource         = s3c_adc_resource,
-};
-
-/* SDI */
-
-static struct resource s3c_sdi_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_SDI,
-               .end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SDI,
-               .end   = IRQ_SDI,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_sdi = {
-       .name             = "s3c2410-sdi",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_sdi_resource),
-       .resource         = s3c_sdi_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_sdi);
-
-/* SPI (0) */
-
-static struct resource s3c_spi0_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_SPI,
-               .end   = S3C24XX_PA_SPI + 0x1f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SPI0,
-               .end   = IRQ_SPI0,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_spi0 = {
-       .name             = "s3c2410-spi",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s3c_spi0_resource),
-       .resource         = s3c_spi0_resource,
-        .dev              = {
-                .dma_mask = &s3c_device_spi0_dmamask,
-                .coherent_dma_mask = 0xffffffffUL
-        }
-};
-
-EXPORT_SYMBOL(s3c_device_spi0);
-
-/* SPI (1) */
-
-static struct resource s3c_spi1_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_SPI + 0x20,
-               .end   = S3C24XX_PA_SPI + 0x20 + 0x1f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SPI1,
-               .end   = IRQ_SPI1,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_spi1 = {
-       .name             = "s3c2410-spi",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_spi1_resource),
-       .resource         = s3c_spi1_resource,
-        .dev              = {
-                .dma_mask = &s3c_device_spi1_dmamask,
-                .coherent_dma_mask = 0xffffffffUL
-        }
-};
-
-EXPORT_SYMBOL(s3c_device_spi1);
-
-/* pwm timer blocks */
-
-static struct resource s3c_timer0_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_TIMER + 0x0C,
-               .end   = S3C24XX_PA_TIMER + 0x0C + 0xB,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TIMER0,
-               .end   = IRQ_TIMER0,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_timer0 = {
-       .name             = "s3c2410-timer",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s3c_timer0_resource),
-       .resource         = s3c_timer0_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer0);
-
-/* timer 1 */
-
-static struct resource s3c_timer1_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_TIMER + 0x18,
-               .end   = S3C24XX_PA_TIMER + 0x23,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TIMER1,
-               .end   = IRQ_TIMER1,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_timer1 = {
-       .name             = "s3c2410-timer",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_timer1_resource),
-       .resource         = s3c_timer1_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer1);
-
-/* timer 2 */
-
-static struct resource s3c_timer2_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_TIMER + 0x24,
-               .end   = S3C24XX_PA_TIMER + 0x2F,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TIMER2,
-               .end   = IRQ_TIMER2,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_timer2 = {
-       .name             = "s3c2410-timer",
-       .id               = 2,
-       .num_resources    = ARRAY_SIZE(s3c_timer2_resource),
-       .resource         = s3c_timer2_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer2);
-
-/* timer 3 */
-
-static struct resource s3c_timer3_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_TIMER + 0x30,
-               .end   = S3C24XX_PA_TIMER + 0x3B,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TIMER3,
-               .end   = IRQ_TIMER3,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_timer3 = {
-       .name             = "s3c2410-timer",
-       .id               = 3,
-       .num_resources    = ARRAY_SIZE(s3c_timer3_resource),
-       .resource         = s3c_timer3_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_timer3);
-
-#ifdef CONFIG_CPU_S3C2440
-
-/* Camif Controller */
-
-static struct resource s3c_camif_resource[] = {
-       [0] = {
-               .start = S3C2440_PA_CAMIF,
-               .end   = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_CAM,
-               .end   = IRQ_CAM,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_camif_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_camif = {
-       .name             = "s3c2440-camif",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_camif_resource),
-       .resource         = s3c_camif_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_camif_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_camif);
-
-#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
deleted file mode 100644 (file)
index 14fb0ba..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* arch/arm/mach-s3c2410/devs.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 standard platform devices
- *
- * 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 <linux/platform_device.h>
-
-struct s3c24xx_uart_resources {
-       struct resource         *resources;
-       unsigned long            nr_resources;
-};
-
-extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
-
-extern struct platform_device *s3c24xx_uart_devs[];
-extern struct platform_device *s3c24xx_uart_src[];
-
-extern struct platform_device s3c_device_usb;
-extern struct platform_device s3c_device_lcd;
-extern struct platform_device s3c_device_wdt;
-extern struct platform_device s3c_device_i2c;
-extern struct platform_device s3c_device_iis;
-extern struct platform_device s3c_device_rtc;
-extern struct platform_device s3c_device_adc;
-extern struct platform_device s3c_device_sdi;
-
-extern struct platform_device s3c_device_spi0;
-extern struct platform_device s3c_device_spi1;
-
-extern struct platform_device s3c_device_nand;
-
-extern struct platform_device s3c_device_timer0;
-extern struct platform_device s3c_device_timer1;
-extern struct platform_device s3c_device_timer2;
-extern struct platform_device s3c_device_timer3;
-
-extern struct platform_device s3c_device_usbgadget;
-
-/* s3c2440 specific devices */
-
-#ifdef CONFIG_CPU_S3C2440
-
-extern struct platform_device s3c_device_camif;
-
-#endif
index fa860e716b4ff74e5af753a81ae3a2c8152b3e30..67d1ad36397344715a1c085a0abe0ce9b82632ea 100644 (file)
@@ -1,9 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/dma.c
  *
- * Copyright (c) 2003-2005,2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C2410 DMA core
+ * S3C2410 DMA selection
  *
  * http://armlinux.simtec.co.uk/
  *
  * published by the Free Software Foundation.
 */
 
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
 #include <linux/sysdev.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
+#include <linux/serial_core.h>
 
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
 #include <asm/dma.h>
-
-#include <asm/mach/dma.h>
-#include <asm/arch/map.h>
-
-#include "dma.h"
-
-/* io map for dma */
-static void __iomem *dma_base;
-static struct kmem_cache *dma_kmem;
-
-struct s3c24xx_dma_selection dma_sel;
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
-
-/* debugging functions */
-
-#define BUF_MAGIC (0xcafebabe)
-
-#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
-
-#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
-
-#if 1
-#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
-#else
-static inline void
-dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
-{
-       pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
-       writel(val, dma_regaddr(chan, reg));
-}
-#endif
-
-#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
-
-/* captured register state for debug */
-
-struct s3c2410_dma_regstate {
-       unsigned long         dcsrc;
-       unsigned long         disrc;
-       unsigned long         dstat;
-       unsigned long         dcon;
-       unsigned long         dmsktrig;
+#include <asm/arch/dma.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/dma.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
 };
 
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-
-/* dmadbg_showregs
- *
- * simple debug routine to print the current state of the dma registers
-*/
-
-static void
-dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
-{
-       regs->dcsrc    = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-       regs->disrc    = dma_rdreg(chan, S3C2410_DMA_DISRC);
-       regs->dstat    = dma_rdreg(chan, S3C2410_DMA_DSTAT);
-       regs->dcon     = dma_rdreg(chan, S3C2410_DMA_DCON);
-       regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-}
-
-static void
-dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
-                struct s3c2410_dma_regstate *regs)
-{
-       printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
-              chan->number, fname, line,
-              regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
-              regs->dcon);
-}
-
-static void
-dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
-       struct s3c2410_dma_regstate state;
-
-       dmadbg_capture(chan, &state);
-
-       printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
-              chan->number, fname, line, chan->load_state,
-              chan->curr, chan->next, chan->end);
-
-       dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-static void
-dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
-       struct s3c2410_dma_regstate state;
-
-       dmadbg_capture(chan, &state);
-       dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
-#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
-#else
-#define dbg_showregs(chan) do { } while(0)
-#define dbg_showchan(chan) do { } while(0)
-#endif /* CONFIG_S3C2410_DMA_DEBUG */
-
-static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
-
-/* lookup_dma_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
-{
-       if (channel & DMACH_LOW_LEVEL)
-               return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
-       else
-               return dma_chan_map[channel];
-}
-
-/* s3c2410_dma_stats_timeout
- *
- * Update DMA stats from timeout info
-*/
-
-static void
-s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
+static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
 {
-       if (stats == NULL)
-               return;
-
-       if (val > stats->timeout_longest)
-               stats->timeout_longest = val;
-       if (val < stats->timeout_shortest)
-               stats->timeout_shortest = val;
-
-       stats->timeout_avg += val;
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
 }
 
-/* s3c2410_dma_waitforload
- *
- * wait for the DMA engine to load a buffer, and update the state accordingly
-*/
-
-static int
-s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
-{
-       int timeout = chan->load_timeout;
-       int took;
-
-       if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
-               printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
-               return 0;
-       }
-
-       if (chan->stats != NULL)
-               chan->stats->loads++;
-
-       while (--timeout > 0) {
-               if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
-                       took = chan->load_timeout - timeout;
-
-                       s3c2410_dma_stats_timeout(chan->stats, took);
-
-                       switch (chan->load_state) {
-                       case S3C2410_DMALOAD_1LOADED:
-                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
-                               break;
-
-                       default:
-                               printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
-                       }
-
-                       return 1;
-               }
-       }
-
-       if (chan->stats != NULL) {
-               chan->stats->timeout_failed++;
-       }
-
-       return 0;
-}
-
-
-
-/* s3c2410_dma_loadbuffer
- *
- * load a buffer, and update the channel state
-*/
-
-static inline int
-s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
-                      struct s3c2410_dma_buf *buf)
-{
-       unsigned long reload;
-
-       pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
-                buf, (unsigned long)buf->data, buf->size);
-
-       if (buf == NULL) {
-               dmawarn("buffer is NULL\n");
-               return -EINVAL;
-       }
-
-       /* check the state of the channel before we do anything */
-
-       if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-               dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
-       }
-
-       if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
-               dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
-       }
-
-       /* it would seem sensible if we are the last buffer to not bother
-        * with the auto-reload bit, so that the DMA engine will not try
-        * and load another transfer after this one has finished...
-        */
-       if (chan->load_state == S3C2410_DMALOAD_NONE) {
-               pr_debug("load_state is none, checking for noreload (next=%p)\n",
-                        buf->next);
-               reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
-       } else {
-               //pr_debug("load_state is %d => autoreload\n", chan->load_state);
-               reload = S3C2410_DCON_AUTORELOAD;
-       }
-
-       if ((buf->data & 0xf0000000) != 0x30000000) {
-               dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
-       }
-
-       writel(buf->data, chan->addr_reg);
-
-       dma_wrreg(chan, S3C2410_DMA_DCON,
-                 chan->dcon | reload | (buf->size/chan->xfer_unit));
-
-       chan->next = buf->next;
-
-       /* update the state of the channel */
-
-       switch (chan->load_state) {
-       case S3C2410_DMALOAD_NONE:
-               chan->load_state = S3C2410_DMALOAD_1LOADED;
-               break;
-
-       case S3C2410_DMALOAD_1RUNNING:
-               chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
-               break;
-
-       default:
-               dmawarn("dmaload: unknown state %d in loadbuffer\n",
-                       chan->load_state);
-               break;
-       }
-
-       return 0;
-}
-
-/* s3c2410_dma_call_op
- *
- * small routine to call the op routine with the given op if it has been
- * registered
-*/
-
-static void
-s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
-{
-       if (chan->op_fn != NULL) {
-               (chan->op_fn)(chan, op);
-       }
-}
-
-/* s3c2410_dma_buffdone
- *
- * small wrapper to check if callback routine needs to be called, and
- * if so, call it
-*/
-
-static inline void
-s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
-                    enum s3c2410_dma_buffresult result)
-{
-#if 0
-       pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
-                chan->callback_fn, buf, buf->id, buf->size, result);
-#endif
-
-       if (chan->callback_fn != NULL) {
-               (chan->callback_fn)(chan, buf->id, buf->size, result);
-       }
-}
-
-/* s3c2410_dma_start
- *
- * start a dma channel going
-*/
-
-static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
-{
-       unsigned long tmp;
-       unsigned long flags;
-
-       pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
-
-       local_irq_save(flags);
-
-       if (chan->state == S3C2410_DMA_RUNNING) {
-               pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
-               local_irq_restore(flags);
-               return 0;
-       }
-
-       chan->state = S3C2410_DMA_RUNNING;
-
-       /* check wether there is anything to load, and if not, see
-        * if we can find anything to load
-        */
-
-       if (chan->load_state == S3C2410_DMALOAD_NONE) {
-               if (chan->next == NULL) {
-                       printk(KERN_ERR "dma%d: channel has nothing loaded\n",
-                              chan->number);
-                       chan->state = S3C2410_DMA_IDLE;
-                       local_irq_restore(flags);
-                       return -EINVAL;
-               }
-
-               s3c2410_dma_loadbuffer(chan, chan->next);
-       }
-
-       dbg_showchan(chan);
-
-       /* enable the channel */
-
-       if (!chan->irq_enabled) {
-               enable_irq(chan->irq);
-               chan->irq_enabled = 1;
-       }
-
-       /* start the channel going */
-
-       tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-       tmp &= ~S3C2410_DMASKTRIG_STOP;
-       tmp |= S3C2410_DMASKTRIG_ON;
-       dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-       pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
-
-#if 0
-       /* the dma buffer loads should take care of clearing the AUTO
-        * reloading feature */
-       tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-       tmp &= ~S3C2410_DCON_NORELOAD;
-       dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
-       s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
-
-       dbg_showchan(chan);
-
-       /* if we've only loaded one buffer onto the channel, then chec
-        * to see if we have another, and if so, try and load it so when
-        * the first buffer is finished, the new one will be loaded onto
-        * the channel */
-
-       if (chan->next != NULL) {
-               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
-                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-                               pr_debug("%s: buff not yet loaded, no more todo\n",
-                                        __FUNCTION__);
-                       } else {
-                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
-                               s3c2410_dma_loadbuffer(chan, chan->next);
-                       }
-
-               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
-                       s3c2410_dma_loadbuffer(chan, chan->next);
-               }
-       }
-
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-/* s3c2410_dma_canload
- *
- * work out if we can queue another buffer into the DMA engine
-*/
-
-static int
-s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
-{
-       if (chan->load_state == S3C2410_DMALOAD_NONE ||
-           chan->load_state == S3C2410_DMALOAD_1RUNNING)
-               return 1;
-
-       return 0;
-}
-
-/* s3c2410_dma_enqueue
- *
- * queue an given buffer for dma transfer.
- *
- * id         the device driver's id information for this buffer
- * data       the physical address of the buffer data
- * size       the size of the buffer in bytes
- *
- * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
- * is checked, and if set, the channel is started. If this flag isn't set,
- * then an error will be returned.
- *
- * It is possible to queue more than one DMA buffer onto a channel at
- * once, and the code will deal with the re-loading of the next buffer
- * when necessary.
-*/
-
-int s3c2410_dma_enqueue(unsigned int channel, void *id,
-                       dma_addr_t data, int size)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-       struct s3c2410_dma_buf *buf;
-       unsigned long flags;
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: id=%p, data=%08x, size=%d\n",
-                __FUNCTION__, id, (unsigned int)data, size);
-
-       buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
-       if (buf == NULL) {
-               pr_debug("%s: out of memory (%ld alloc)\n",
-                        __FUNCTION__, (long)sizeof(*buf));
-               return -ENOMEM;
-       }
-
-       //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
-       //dbg_showchan(chan);
-
-       buf->next  = NULL;
-       buf->data  = buf->ptr = data;
-       buf->size  = size;
-       buf->id    = id;
-       buf->magic = BUF_MAGIC;
-
-       local_irq_save(flags);
-
-       if (chan->curr == NULL) {
-               /* we've got nothing loaded... */
-               pr_debug("%s: buffer %p queued onto empty channel\n",
-                        __FUNCTION__, buf);
-
-               chan->curr = buf;
-               chan->end  = buf;
-               chan->next = NULL;
-       } else {
-               pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
-                        chan->number, __FUNCTION__, buf);
-
-               if (chan->end == NULL)
-                       pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
-                                chan->number, __FUNCTION__, chan);
-
-               chan->end->next = buf;
-               chan->end = buf;
-       }
-
-       /* if necessary, update the next buffer field */
-       if (chan->next == NULL)
-               chan->next = buf;
-
-       /* check to see if we can load a buffer */
-       if (chan->state == S3C2410_DMA_RUNNING) {
-               if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
-                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-                               printk(KERN_ERR "dma%d: loadbuffer:"
-                                      "timeout loading buffer\n",
-                                      chan->number);
-                               dbg_showchan(chan);
-                               local_irq_restore(flags);
-                               return -EINVAL;
-                       }
-               }
-
-               while (s3c2410_dma_canload(chan) && chan->next != NULL) {
-                       s3c2410_dma_loadbuffer(chan, chan->next);
-               }
-       } else if (chan->state == S3C2410_DMA_IDLE) {
-               if (chan->flags & S3C2410_DMAF_AUTOSTART) {
-                       s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
-               }
-       }
-
-       local_irq_restore(flags);
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-static inline void
-s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
-{
-       int magicok = (buf->magic == BUF_MAGIC);
-
-       buf->magic = -1;
-
-       if (magicok) {
-               kmem_cache_free(dma_kmem, buf);
-       } else {
-               printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
-       }
-}
-
-/* s3c2410_dma_lastxfer
- *
- * called when the system is out of buffers, to ensure that the channel
- * is prepared for shutdown.
-*/
-
-static inline void
-s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
-{
-#if 0
-       pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
-                chan->number, chan->load_state);
-#endif
-
-       switch (chan->load_state) {
-       case S3C2410_DMALOAD_NONE:
-               break;
-
-       case S3C2410_DMALOAD_1LOADED:
-               if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-                               /* flag error? */
-                       printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
-                              chan->number, __FUNCTION__);
-                       return;
-               }
-               break;
-
-       case S3C2410_DMALOAD_1LOADED_1RUNNING:
-               /* I belive in this case we do not have anything to do
-                * until the next buffer comes along, and we turn off the
-                * reload */
-               return;
-
-       default:
-               pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
-                        chan->number, chan->load_state);
-               return;
-
-       }
-
-       /* hopefully this'll shut the damned thing up after the transfer... */
-       dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
-}
-
-
-#define dmadbg2(x...)
-
-static irqreturn_t
-s3c2410_dma_irq(int irq, void *devpw)
-{
-       struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
-       struct s3c2410_dma_buf  *buf;
-
-       buf = chan->curr;
-
-       dbg_showchan(chan);
-
-       /* modify the channel state */
-
-       switch (chan->load_state) {
-       case S3C2410_DMALOAD_1RUNNING:
-               /* TODO - if we are running only one buffer, we probably
-                * want to reload here, and then worry about the buffer
-                * callback */
-
-               chan->load_state = S3C2410_DMALOAD_NONE;
-               break;
-
-       case S3C2410_DMALOAD_1LOADED:
-               /* iirc, we should go back to NONE loaded here, we
-                * had a buffer, and it was never verified as being
-                * loaded.
-                */
-
-               chan->load_state = S3C2410_DMALOAD_NONE;
-               break;
-
-       case S3C2410_DMALOAD_1LOADED_1RUNNING:
-               /* we'll worry about checking to see if another buffer is
-                * ready after we've called back the owner. This should
-                * ensure we do not wait around too long for the DMA
-                * engine to start the next transfer
-                */
-
-               chan->load_state = S3C2410_DMALOAD_1LOADED;
-               break;
-
-       case S3C2410_DMALOAD_NONE:
-               printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
-                      chan->number);
-               break;
-
-       default:
-               printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
-                      chan->number, chan->load_state);
-               break;
-       }
-
-       if (buf != NULL) {
-               /* update the chain to make sure that if we load any more
-                * buffers when we call the callback function, things should
-                * work properly */
-
-               chan->curr = buf->next;
-               buf->next  = NULL;
-
-               if (buf->magic != BUF_MAGIC) {
-                       printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
-                              chan->number, __FUNCTION__, buf);
-                       return IRQ_HANDLED;
-               }
-
-               s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
-
-               /* free resouces */
-               s3c2410_dma_freebuf(buf);
-       } else {
-       }
-
-       /* only reload if the channel is still running... our buffer done
-        * routine may have altered the state by requesting the dma channel
-        * to stop or shutdown... */
-
-       /* todo: check that when the channel is shut-down from inside this
-        * function, we cope with unsetting reload, etc */
-
-       if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
-               unsigned long flags;
-
-               switch (chan->load_state) {
-               case S3C2410_DMALOAD_1RUNNING:
-                       /* don't need to do anything for this state */
-                       break;
-
-               case S3C2410_DMALOAD_NONE:
-                       /* can load buffer immediately */
-                       break;
-
-               case S3C2410_DMALOAD_1LOADED:
-                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-                               /* flag error? */
-                               printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
-                                      chan->number, __FUNCTION__);
-                               return IRQ_HANDLED;
-                       }
-
-                       break;
-
-               case S3C2410_DMALOAD_1LOADED_1RUNNING:
-                       goto no_load;
-
-               default:
-                       printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
-                              chan->number, chan->load_state);
-                       return IRQ_HANDLED;
-               }
-
-               local_irq_save(flags);
-               s3c2410_dma_loadbuffer(chan, chan->next);
-               local_irq_restore(flags);
-       } else {
-               s3c2410_dma_lastxfer(chan);
-
-               /* see if we can stop this channel.. */
-               if (chan->load_state == S3C2410_DMALOAD_NONE) {
-                       pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
-                                chan->number, jiffies);
-                       s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
-                                        S3C2410_DMAOP_STOP);
-               }
-       }
-
- no_load:
-       return IRQ_HANDLED;
-}
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(unsigned int channel,
-                       struct s3c2410_dma_client *client,
-                       void *dev)
-{
-       struct s3c2410_dma_chan *chan;
-       unsigned long flags;
-       int err;
-
-       pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
-                channel, client->name, dev);
-
-       local_irq_save(flags);
-
-       chan = s3c2410_dma_map_channel(channel);
-       if (chan == NULL) {
-               local_irq_restore(flags);
-               return -EBUSY;
-       }
-
-       dbg_showchan(chan);
-
-       chan->client = client;
-       chan->in_use = 1;
-
-       if (!chan->irq_claimed) {
-               pr_debug("dma%d: %s : requesting irq %d\n",
-                        channel, __FUNCTION__, chan->irq);
-
-               chan->irq_claimed = 1;
-               local_irq_restore(flags);
-
-               err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
-                                 client->name, (void *)chan);
-
-               local_irq_save(flags);
-
-               if (err) {
-                       chan->in_use = 0;
-                       chan->irq_claimed = 0;
-                       local_irq_restore(flags);
-
-                       printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
-                              client->name, chan->irq, chan->number);
-                       return err;
-               }
-
-               chan->irq_enabled = 1;
-       }
-
-       local_irq_restore(flags);
-
-       /* need to setup */
-
-       pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
+static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+       .select         = s3c2410_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2410_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
+};
 
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
+static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+};
 
-int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
+static int s3c2410_dma_add(struct sys_device *sysdev)
 {
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-       unsigned long flags;
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       local_irq_save(flags);
-
-       if (chan->client != client) {
-               printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
-                      channel, chan->client, client);
-       }
-
-       /* sort out stopping and freeing the channel */
-
-       if (chan->state != S3C2410_DMA_IDLE) {
-               pr_debug("%s: need to stop dma channel %p\n",
-                      __FUNCTION__, chan);
-
-               /* possibly flush the channel */
-               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
-       }
-
-       chan->client = NULL;
-       chan->in_use = 0;
-
-       if (chan->irq_claimed)
-               free_irq(chan->irq, (void *)chan);
-
-       chan->irq_claimed = 0;
-
-       if (!(channel & DMACH_LOW_LEVEL))
-               dma_chan_map[channel] = NULL;
-
-       local_irq_restore(flags);
-
-       return 0;
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2410_dma_order);
+       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
 }
 
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
-{
-       unsigned long flags;
-       unsigned long tmp;
-
-       pr_debug("%s:\n", __FUNCTION__);
-
-       dbg_showchan(chan);
-
-       local_irq_save(flags);
-
-       s3c2410_dma_call_op(chan,  S3C2410_DMAOP_STOP);
-
-       tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-       tmp |= S3C2410_DMASKTRIG_STOP;
-       //tmp &= ~S3C2410_DMASKTRIG_ON;
-       dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-#if 0
-       /* should also clear interrupts, according to WinCE BSP */
-       tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-       tmp |= S3C2410_DCON_NORELOAD;
-       dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
-       /* should stop do this, or should we wait for flush? */
-       chan->state      = S3C2410_DMA_IDLE;
-       chan->load_state = S3C2410_DMALOAD_NONE;
-
-       local_irq_restore(flags);
-
-       return 0;
-}
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_dma_driver = {
+       .add    = s3c2410_dma_add,
+};
 
-void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+static int __init s3c2410_dma_drvinit(void)
 {
-       unsigned long tmp;
-       unsigned int timeout = 0x10000;
-
-       while (timeout-- > 0) {
-               tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-
-               if (!(tmp & S3C2410_DMASKTRIG_ON))
-                       return;
-       }
-
-       pr_debug("dma%d: failed to stop?\n", chan->number);
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
 }
 
-
-/* s3c2410_dma_flush
- *
- * stop the channel, and remove all current and pending transfers
-*/
-
-static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
-{
-       struct s3c2410_dma_buf *buf, *next;
-       unsigned long flags;
-
-       pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
-
-       dbg_showchan(chan);
-
-       local_irq_save(flags);
-
-       if (chan->state != S3C2410_DMA_IDLE) {
-               pr_debug("%s: stopping channel...\n", __FUNCTION__ );
-               s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
-       }
-
-       buf = chan->curr;
-       if (buf == NULL)
-               buf = chan->next;
-
-       chan->curr = chan->next = chan->end = NULL;
-
-       if (buf != NULL) {
-               for ( ; buf != NULL; buf = next) {
-                       next = buf->next;
-
-                       pr_debug("%s: free buffer %p, next %p\n",
-                              __FUNCTION__, buf, buf->next);
-
-                       s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
-                       s3c2410_dma_freebuf(buf);
-               }
-       }
-
-       dbg_showregs(chan);
-
-       s3c2410_dma_waitforstop(chan);
-
-#if 0
-       /* should also clear interrupts, according to WinCE BSP */
-       {
-               unsigned long tmp;
-
-               tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
-               tmp |= S3C2410_DCON_NORELOAD;
-               dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-       }
+arch_initcall(s3c2410_dma_drvinit);
 #endif
 
-       dbg_showregs(chan);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-int
-s3c2410_dma_started(struct s3c2410_dma_chan *chan)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       dbg_showchan(chan);
-
-       /* if we've only loaded one buffer onto the channel, then chec
-        * to see if we have another, and if so, try and load it so when
-        * the first buffer is finished, the new one will be loaded onto
-        * the channel */
-
-       if (chan->next != NULL) {
-               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
-                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
-                               pr_debug("%s: buff not yet loaded, no more todo\n",
-                                        __FUNCTION__);
-                       } else {
-                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
-                               s3c2410_dma_loadbuffer(chan, chan->next);
-                       }
-
-               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
-                       s3c2410_dma_loadbuffer(chan, chan->next);
-               }
-       }
-
-
-       local_irq_restore(flags);
-
-       return 0;
-
-}
-
-int
-s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       switch (op) {
-       case S3C2410_DMAOP_START:
-               return s3c2410_dma_start(chan);
-
-       case S3C2410_DMAOP_STOP:
-               return s3c2410_dma_dostop(chan);
-
-       case S3C2410_DMAOP_PAUSE:
-       case S3C2410_DMAOP_RESUME:
-               return -ENOENT;
-
-       case S3C2410_DMAOP_FLUSH:
-               return s3c2410_dma_flush(chan);
-
-       case S3C2410_DMAOP_STARTED:
-               return s3c2410_dma_started(chan);
-
-       case S3C2410_DMAOP_TIMEOUT:
-               return 0;
-
-       }
-
-       return -ENOENT;      /* unknown, don't bother */
-}
-
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* DMA configuration for each channel
- *
- * DISRCC -> source of the DMA (AHB,APB)
- * DISRC  -> source address of the DMA
- * DIDSTC -> destination of the DMA (AHB,APD)
- * DIDST  -> destination address of the DMA
-*/
-
-/* s3c2410_dma_config
- *
- * xfersize:     size of unit in bytes (1,2,4)
- * dcon:         base value of the DCONx register
-*/
-
-int s3c2410_dma_config(dmach_t channel,
-                      int xferunit,
-                      int dcon)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
-                __FUNCTION__, channel, xferunit, dcon);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
-
-       dcon |= chan->dcon & dma_sel.dcon_mask;
-
-       pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
-
-       switch (xferunit) {
-       case 1:
-               dcon |= S3C2410_DCON_BYTE;
-               break;
-
-       case 2:
-               dcon |= S3C2410_DCON_HALFWORD;
-               break;
-
-       case 4:
-               dcon |= S3C2410_DCON_WORD;
-               break;
-
-       default:
-               pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
-               return -EINVAL;
-       }
-
-       dcon |= S3C2410_DCON_HWTRIG;
-       dcon |= S3C2410_DCON_INTREQ;
-
-       pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
-
-       chan->dcon = dcon;
-       chan->xfer_unit = xferunit;
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
-
-       chan->flags = flags;
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_setflags);
-
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
-
-       chan->op_fn = rtn;
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
-
-       chan->callback_fn = rtn;
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-/* s3c2410_dma_devconfig
- *
- * configure the dma source/destination hardware type and address
- *
- * source:    S3C2410_DMASRC_HW: source is hardware
- *            S3C2410_DMASRC_MEM: source is memory
- *
- * hwcfg:     the value for xxxSTCn register,
- *            bit 0: 0=increment pointer, 1=leave pointer
- *            bit 1: 0=soucre is AHB, 1=soucre is APB
- *
- * devaddr:   physical address of the source
-*/
-
-int s3c2410_dma_devconfig(int channel,
-                         enum s3c2410_dmasrc source,
-                         int hwcfg,
-                         unsigned long devaddr)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
-                __FUNCTION__, (int)source, hwcfg, devaddr);
-
-       chan->source = source;
-       chan->dev_addr = devaddr;
-
-       switch (source) {
-       case S3C2410_DMASRC_HW:
-               /* source is hardware */
-               pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
-                        __FUNCTION__, devaddr, hwcfg);
-               dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
-               dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
-               dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
-
-               chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
-               return 0;
-
-       case S3C2410_DMASRC_MEM:
-               /* source is memory */
-               pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
-                         __FUNCTION__, devaddr, hwcfg);
-               dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
-               dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
-               dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
-
-               chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
-               return 0;
-       }
-
-       printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
-       return -EINVAL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-/* s3c2410_dma_getposition
- *
- * returns the current transfer points for the dma source and destination
-*/
-
-int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
-{
-       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
-
-       if (chan == NULL)
-               return -EINVAL;
-
-       if (src != NULL)
-               *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-
-       if (dst != NULL)
-               *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-
-/* system device class */
-
-#ifdef CONFIG_PM
-
-static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
-{
-       struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
-
-       printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
-
-       if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
-               /* the dma channel is still working, which is probably
-                * a bad thing to do over suspend/resume. We stop the
-                * channel and assume that the client is either going to
-                * retry after resume, or that it is broken.
-                */
-
-               printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
-                      cp->number);
-
-               s3c2410_dma_dostop(cp);
-       }
-
-       return 0;
-}
-
-static int s3c2410_dma_resume(struct sys_device *dev)
-{
-       return 0;
-}
-
-#else
-#define s3c2410_dma_suspend NULL
-#define s3c2410_dma_resume  NULL
-#endif /* CONFIG_PM */
-
-struct sysdev_class dma_sysclass = {
-       set_kset_name("s3c24xx-dma"),
-       .suspend        = s3c2410_dma_suspend,
-       .resume         = s3c2410_dma_resume,
+#if defined(CONFIG_CPU_S3C2442)
+/* S3C2442 DMA contains the same selection table as the S3C2410 */
+static struct sysdev_driver s3c2442_dma_driver = {
+       .add    = s3c2410_dma_add,
 };
 
-/* kmem cache implementation */
-
-static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
-{
-       memset(p, 0, sizeof(struct s3c2410_dma_buf));
-}
-
-/* initialisation code */
-
-static int __init s3c2410_init_dma(void)
-{
-       struct s3c2410_dma_chan *cp;
-       int channel;
-       int ret;
-
-       printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
-
-       dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
-       if (dma_base == NULL) {
-               printk(KERN_ERR "dma failed to remap register block\n");
-               return -ENOMEM;
-       }
-
-       printk("Registering sysclass\n");
-
-       ret = sysdev_class_register(&dma_sysclass);
-       if (ret != 0) {
-               printk(KERN_ERR "dma sysclass registration failed\n");
-               goto err;
-       }
-
-       dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
-                                    SLAB_HWCACHE_ALIGN,
-                                    s3c2410_dma_cache_ctor, NULL);
-
-       if (dma_kmem == NULL) {
-               printk(KERN_ERR "dma failed to make kmem cache\n");
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
-               cp = &s3c2410_chans[channel];
-
-               memset(cp, 0, sizeof(struct s3c2410_dma_chan));
-
-               /* dma channel irqs are in order.. */
-               cp->number = channel;
-               cp->irq    = channel + IRQ_DMA0;
-               cp->regs   = dma_base + (channel*0x40);
-
-               /* point current stats somewhere */
-               cp->stats  = &cp->stats_store;
-               cp->stats_store.timeout_shortest = LONG_MAX;
-
-               /* basic channel configuration */
-
-               cp->load_timeout = 1<<18;
-
-               /* register system device */
-
-               cp->dev.cls = &dma_sysclass;
-               cp->dev.id  = channel;
-               ret = sysdev_register(&cp->dev);
-
-               printk("DMA channel %d at %p, irq %d\n",
-                      cp->number, cp->regs, cp->irq);
-       }
-
-       return 0;
-
- err:
-       kmem_cache_destroy(dma_kmem);
-       iounmap(dma_base);
-       dma_base = NULL;
-       return ret;
-}
-
-core_initcall(s3c2410_init_dma);
-
-static inline int is_channel_valid(unsigned int channel)
+static int __init s3c2442_dma_drvinit(void)
 {
-       return (channel & DMA_CH_VALID);
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
 }
 
-/* s3c2410_dma_map_channel()
- *
- * turn the virtual channel number into a real, and un-used hardware
- * channel.
- *
- * currently this code uses first-free channel from the specified harware
- * map, not taking into account anything that the board setup code may
- * have to say about the likely peripheral set to be in use.
-*/
-
-struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
-{
-       struct s3c24xx_dma_map *ch_map;
-       struct s3c2410_dma_chan *dmach;
-       int ch;
-
-       if (dma_sel.map == NULL || channel > dma_sel.map_size)
-               return NULL;
-
-       ch_map = dma_sel.map + channel;
-
-       for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
-               if (!is_channel_valid(ch_map->channels[ch]))
-                       continue;
-
-               if (s3c2410_chans[ch].in_use == 0) {
-                       printk("mapped channel %d to %d\n", channel, ch);
-                       break;
-               }
-       }
-
-       if (ch >= S3C2410_DMA_CHANNELS)
-               return NULL;
-
-       /* update our channel mapping */
-
-       dmach = &s3c2410_chans[ch];
-       dma_chan_map[channel] = dmach;
-
-       /* select the channel */
-
-       (dma_sel.select)(dmach, ch_map);
-
-       return dmach;
-}
-
-static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
-{
-       /* show the channel configuration */
-
-       printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
-              (is_channel_valid(map->channels[0]) ? '0' : '-'),
-              (is_channel_valid(map->channels[1]) ? '1' : '-'),
-              (is_channel_valid(map->channels[2]) ? '2' : '-'),
-              (is_channel_valid(map->channels[3]) ? '3' : '-'));
-}
-
-static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
-{
-       if (1)
-               s3c24xx_dma_show_ch(map, ch);
-
-       return 0;
-}
-
-int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
-{
-       struct s3c24xx_dma_map *nmap;
-       size_t map_sz = sizeof(*nmap) * sel->map_size;
-       int ptr;
-
-       nmap = kmalloc(map_sz, GFP_KERNEL);
-       if (nmap == NULL)
-               return -ENOMEM;
-
-       memcpy(nmap, sel->map, map_sz);
-       memcpy(&dma_sel, sel, sizeof(*sel));
-
-       dma_sel.map = nmap;
-
-       for (ptr = 0; ptr < sel->map_size; ptr++)
-               s3c24xx_dma_check_entry(nmap+ptr, ptr);
+arch_initcall(s3c2442_dma_drvinit);
+#endif
 
-       return 0;
-}
diff --git a/arch/arm/mach-s3c2410/dma.h b/arch/arm/mach-s3c2410/dma.h
deleted file mode 100644 (file)
index 0ebfe0a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* arch/arm/mach-s3c2410/dma.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * 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.
-*/
-
-extern struct sysdev_class dma_sysclass;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
-
-#define DMA_CH_VALID           (1<<31)
-
-struct s3c24xx_dma_addr {
-       unsigned long           from;
-       unsigned long           to;
-};
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
-       const char              *name;
-       struct s3c24xx_dma_addr  hw_addr;
-
-       unsigned long            channels[S3C2410_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
-       struct s3c24xx_dma_map  *map;
-       unsigned long            map_size;
-       unsigned long            dcon_mask;
-
-       void    (*select)(struct s3c2410_dma_chan *chan,
-                         struct s3c24xx_dma_map *map);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
index f6fb215bb48c2a7d6f5dc108cc1ffe70ccd532c3..01e795d1146eec85691ff1d1f41495e94108a5bf 100644 (file)
@@ -1,9 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/gpio.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX GPIO support
+ * S3C2410 GPIO support
  *
  * 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
@@ -18,8 +18,7 @@
  * 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/kernel.h>
 #include <linux/init.h>
 
 #include <asm/arch/regs-gpio.h>
 
-void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long mask;
-       unsigned long con;
-       unsigned long flags;
-
-       if (pin < S3C2410_GPIO_BANKB) {
-               mask = 1 << S3C2410_GPIO_OFFSET(pin);
-       } else {
-               mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
-       }
-
-       switch (function) {
-       case S3C2410_GPIO_LEAVE:
-               mask = 0;
-               function = 0;
-               break;
-
-       case S3C2410_GPIO_INPUT:
-       case S3C2410_GPIO_OUTPUT:
-       case S3C2410_GPIO_SFN2:
-       case S3C2410_GPIO_SFN3:
-               if (pin < S3C2410_GPIO_BANKB) {
-                       function -= 1;
-                       function &= 1;
-                       function <<= S3C2410_GPIO_OFFSET(pin);
-               } else {
-                       function &= 3;
-                       function <<= S3C2410_GPIO_OFFSET(pin)*2;
-               }
-       }
-
-       /* modify the specified register wwith IRQs off */
-
-       local_irq_save(flags);
-
-       con  = __raw_readl(base + 0x00);
-       con &= ~mask;
-       con |= function;
-
-       __raw_writel(con, base + 0x00);
-
-       local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
-
-unsigned int s3c2410_gpio_getcfg(unsigned int pin)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long val = __raw_readl(base);
-
-       if (pin < S3C2410_GPIO_BANKB) {
-               val >>= S3C2410_GPIO_OFFSET(pin);
-               val &= 1;
-               val += 1;
-       } else {
-               val >>= S3C2410_GPIO_OFFSET(pin)*2;
-               val &= 3;
-       }
-
-       return val | S3C2410_GPIO_INPUT;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getcfg);
-
-void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
+int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+                          unsigned int config)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       void __iomem *reg = S3C24XX_EINFLT0;
        unsigned long flags;
-       unsigned long up;
-
-       if (pin < S3C2410_GPIO_BANKB)
-               return;
-
-       local_irq_save(flags);
-
-       up = __raw_readl(base + 0x08);
-       up &= ~(1L << offs);
-       up |= to << offs;
-       __raw_writel(up, base + 0x08);
+       unsigned long val;
 
-       local_irq_restore(flags);
-}
+       if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
+               return -1;
 
-EXPORT_SYMBOL(s3c2410_gpio_pullup);
+       config &= 0xff;
 
-void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-       unsigned long flags;
-       unsigned long dat;
+       pin -= S3C2410_GPG8;
+       reg += pin & ~3;
 
        local_irq_save(flags);
 
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offs);
-       dat |= to << offs;
-       __raw_writel(dat, base + 0x04);
-
-       local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_setpin);
-
-unsigned int s3c2410_gpio_getpin(unsigned int pin)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       /* update filter width and clock source */
 
-       return __raw_readl(base + 0x04) & (1<< offs);
-}
+       val = __raw_readl(reg);
+       val &= ~(0xff << ((pin & 3) * 8));
+       val |= config << ((pin & 3) * 8);
+       __raw_writel(val, reg);
 
-EXPORT_SYMBOL(s3c2410_gpio_getpin);
+       /* update filter enable */
 
-unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
-{
-       unsigned long flags;
-       unsigned long misccr;
+       val = __raw_readl(S3C24XX_EXTINT2);
+       val &= ~(1 << ((pin * 4) + 3));
+       val |= on << ((pin * 4) + 3);
+       __raw_writel(val, S3C24XX_EXTINT2);
 
-       local_irq_save(flags);
-       misccr = __raw_readl(S3C24XX_MISCCR);
-       misccr &= ~clear;
-       misccr ^= change;
-       __raw_writel(misccr, S3C24XX_MISCCR);
        local_irq_restore(flags);
 
-       return misccr;
-}
-
-EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-       if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
-               return -1;      /* not valid interrupts */
-
-       if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
-               return -1;      /* not valid pin */
-
-       if (pin < S3C2410_GPF4)
-               return (pin - S3C2410_GPF0) + IRQ_EINT0;
-
-       if (pin < S3C2410_GPG0)
-               return (pin - S3C2410_GPF4) + IRQ_EINT4;
-
-       return (pin - S3C2410_GPG0) + IRQ_EINT8;
+       return 0;
 }
 
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
+EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
index 3c0ed7871c55dc51c0c4dbf41a7a0d4e92fbb70f..53cbdaa43ac666a0d4ab5f2e05531c71910095ea 100644 (file)
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/irq.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Changelog:
- *
- *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
- *                Fixed compile warnings
- *
- *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
- *                Fixed s3c_extirq_type
- *
- *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
- *                Addition of ADC/TC demux
- *
- *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
- *               Fix for set_irq_type() on low EINT numbers
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *               Tidy up KF's patch and sort out new release
- *
- *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
- *               Add support for power management controls
- *
- *   04-Nov-2004  Ben Dooks
- *               Fix standard IRQ wake for EINT0..4 and RTC
- *
- *   22-Feb-2005  Ben Dooks
- *               Fixed edge-triggering on ADC IRQ
- *
- *   28-Jun-2005  Ben Dooks
- *               Mark IRQ_LCD valid
- *
- *   25-Jul-2005  Ben Dooks
- *               Split the S3C2440 IRQ code to seperate file
 */
 
 #include <linux/init.h>
 #include <linux/ptrace.h>
 #include <linux/sysdev.h>
 
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/mach/irq.h>
-
-#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
-
-/* wakeup irq control */
-
-#ifdef CONFIG_PM
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow     = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_intmask      = 0xffffffffL;
-unsigned long s3c_irqwake_eintallow    = 0x0000fff0L;
-unsigned long s3c_irqwake_eintmask     = 0xffffffffL;
-
-int
-s3c_irq_wake(unsigned int irqno, unsigned int state)
-{
-       unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
-
-       if (!(s3c_irqwake_intallow & irqbit))
-               return -ENOENT;
-
-       printk(KERN_INFO "wake %s for irq %d\n",
-              state ? "enabled" : "disabled", irqno);
-
-       if (!state)
-               s3c_irqwake_intmask |= irqbit;
-       else
-               s3c_irqwake_intmask &= ~irqbit;
-
-       return 0;
-}
-
-static int
-s3c_irqext_wake(unsigned int irqno, unsigned int state)
-{
-       unsigned long bit = 1L << (irqno - EXTINT_OFF);
-
-       if (!(s3c_irqwake_eintallow & bit))
-               return -ENOENT;
-
-       printk(KERN_INFO "wake %s for irq %d\n",
-              state ? "enabled" : "disabled", irqno);
-
-       if (!state)
-               s3c_irqwake_eintmask |= bit;
-       else
-               s3c_irqwake_eintmask &= ~bit;
-
-       return 0;
-}
-
-#else
-#define s3c_irqext_wake NULL
-#define s3c_irq_wake NULL
-#endif
-
-
-static void
-s3c_irq_mask(unsigned int irqno)
-{
-       unsigned long mask;
-
-       irqno -= IRQ_EINT0;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       mask |= 1UL << irqno;
-       __raw_writel(mask, S3C2410_INTMSK);
-}
-
-static inline void
-s3c_irq_ack(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-static inline void
-s3c_irq_maskack(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask|bitval, S3C2410_INTMSK);
-
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-
-static void
-s3c_irq_unmask(unsigned int irqno)
-{
-       unsigned long mask;
-
-       if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
-               irqdbf2("s3c_irq_unmask %d\n", irqno);
-
-       irqno -= IRQ_EINT0;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       mask &= ~(1UL << irqno);
-       __raw_writel(mask, S3C2410_INTMSK);
-}
-
-struct irq_chip s3c_irq_level_chip = {
-       .name           = "s3c-level",
-       .ack            = s3c_irq_maskack,
-       .mask           = s3c_irq_mask,
-       .unmask         = s3c_irq_unmask,
-       .set_wake       = s3c_irq_wake
-};
-
-static struct irq_chip s3c_irq_chip = {
-       .name           = "s3c",
-       .ack            = s3c_irq_ack,
-       .mask           = s3c_irq_mask,
-       .unmask         = s3c_irq_unmask,
-       .set_wake       = s3c_irq_wake
-};
-
-static void
-s3c_irqext_mask(unsigned int irqno)
-{
-       unsigned long mask;
-
-       irqno -= EXTINT_OFF;
-
-       mask = __raw_readl(S3C24XX_EINTMASK);
-       mask |= ( 1UL << irqno);
-       __raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-static void
-s3c_irqext_ack(unsigned int irqno)
-{
-       unsigned long req;
-       unsigned long bit;
-       unsigned long mask;
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
-       bit = 1UL << (irqno - EXTINT_OFF);
-
-       mask = __raw_readl(S3C24XX_EINTMASK);
-
-       __raw_writel(bit, S3C24XX_EINTPEND);
-
-       req = __raw_readl(S3C24XX_EINTPEND);
-       req &= ~mask;
-
-       /* not sure if we should be acking the parent irq... */
-
-       if (irqno <= IRQ_EINT7 ) {
-               if ((req & 0xf0) == 0)
-                       s3c_irq_ack(IRQ_EINT4t7);
-       } else {
-               if ((req >> 8) == 0)
-                       s3c_irq_ack(IRQ_EINT8t23);
-       }
-}
-
-static void
-s3c_irqext_unmask(unsigned int irqno)
+static int s3c2410_irq_add(struct sys_device *sysdev)
 {
-       unsigned long mask;
-
-       irqno -= EXTINT_OFF;
-
-       mask = __raw_readl(S3C24XX_EINTMASK);
-       mask &= ~( 1UL << irqno);
-       __raw_writel(mask, S3C24XX_EINTMASK);
-}
-
-int
-s3c_irqext_type(unsigned int irq, unsigned int type)
-{
-       void __iomem *extint_reg;
-       void __iomem *gpcon_reg;
-       unsigned long gpcon_offset, extint_offset;
-       unsigned long newvalue = 0, value;
-
-       if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
-       {
-               gpcon_reg = S3C2410_GPFCON;
-               extint_reg = S3C24XX_EXTINT0;
-               gpcon_offset = (irq - IRQ_EINT0) * 2;
-               extint_offset = (irq - IRQ_EINT0) * 4;
-       }
-       else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
-       {
-               gpcon_reg = S3C2410_GPFCON;
-               extint_reg = S3C24XX_EXTINT0;
-               gpcon_offset = (irq - (EXTINT_OFF)) * 2;
-               extint_offset = (irq - (EXTINT_OFF)) * 4;
-       }
-       else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
-       {
-               gpcon_reg = S3C2410_GPGCON;
-               extint_reg = S3C24XX_EXTINT1;
-               gpcon_offset = (irq - IRQ_EINT8) * 2;
-               extint_offset = (irq - IRQ_EINT8) * 4;
-       }
-       else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
-       {
-               gpcon_reg = S3C2410_GPGCON;
-               extint_reg = S3C24XX_EXTINT2;
-               gpcon_offset = (irq - IRQ_EINT8) * 2;
-               extint_offset = (irq - IRQ_EINT16) * 4;
-       } else
-               return -1;
-
-       /* Set the GPIO to external interrupt mode */
-       value = __raw_readl(gpcon_reg);
-       value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
-       __raw_writel(value, gpcon_reg);
-
-       /* Set the external interrupt to pointed trigger type */
-       switch (type)
-       {
-               case IRQT_NOEDGE:
-                       printk(KERN_WARNING "No edge setting!\n");
-                       break;
-
-               case IRQT_RISING:
-                       newvalue = S3C2410_EXTINT_RISEEDGE;
-                       break;
-
-               case IRQT_FALLING:
-                       newvalue = S3C2410_EXTINT_FALLEDGE;
-                       break;
-
-               case IRQT_BOTHEDGE:
-                       newvalue = S3C2410_EXTINT_BOTHEDGE;
-                       break;
-
-               case IRQT_LOW:
-                       newvalue = S3C2410_EXTINT_LOWLEV;
-                       break;
-
-               case IRQT_HIGH:
-                       newvalue = S3C2410_EXTINT_HILEV;
-                       break;
-
-               default:
-                       printk(KERN_ERR "No such irq type %d", type);
-                       return -1;
-       }
-
-       value = __raw_readl(extint_reg);
-       value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
-       __raw_writel(value, extint_reg);
-
        return 0;
 }
 
-static struct irq_chip s3c_irqext_chip = {
-       .name           = "s3c-ext",
-       .mask           = s3c_irqext_mask,
-       .unmask         = s3c_irqext_unmask,
-       .ack            = s3c_irqext_ack,
-       .set_type       = s3c_irqext_type,
-       .set_wake       = s3c_irqext_wake
-};
-
-static struct irq_chip s3c_irq_eint0t4 = {
-       .name           = "s3c-ext0",
-       .ack            = s3c_irq_ack,
-       .mask           = s3c_irq_mask,
-       .unmask         = s3c_irq_unmask,
-       .set_wake       = s3c_irq_wake,
-       .set_type       = s3c_irqext_type,
-};
-
-/* mask values for the parent registers for each of the interrupt types */
-
-#define INTMSK_UART0    (1UL << (IRQ_UART0 - IRQ_EINT0))
-#define INTMSK_UART1    (1UL << (IRQ_UART1 - IRQ_EINT0))
-#define INTMSK_UART2    (1UL << (IRQ_UART2 - IRQ_EINT0))
-#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-
-
-/* UART0 */
-
-static void
-s3c_irq_uart0_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
-}
-
-static void
-s3c_irq_uart0_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_UART0);
-}
-
-static void
-s3c_irq_uart0_ack(unsigned int irqno)
-{
-       s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
-}
-
-static struct irq_chip s3c_irq_uart0 = {
-       .name           = "s3c-uart0",
-       .mask           = s3c_irq_uart0_mask,
-       .unmask         = s3c_irq_uart0_unmask,
-       .ack            = s3c_irq_uart0_ack,
-};
-
-/* UART1 */
-
-static void
-s3c_irq_uart1_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
-}
-
-static void
-s3c_irq_uart1_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_UART1);
-}
-
-static void
-s3c_irq_uart1_ack(unsigned int irqno)
-{
-       s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
-}
-
-static struct irq_chip s3c_irq_uart1 = {
-       .name           = "s3c-uart1",
-       .mask           = s3c_irq_uart1_mask,
-       .unmask         = s3c_irq_uart1_unmask,
-       .ack            = s3c_irq_uart1_ack,
-};
-
-/* UART2 */
-
-static void
-s3c_irq_uart2_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
-}
-
-static void
-s3c_irq_uart2_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_UART2);
-}
-
-static void
-s3c_irq_uart2_ack(unsigned int irqno)
-{
-       s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
-}
-
-static struct irq_chip s3c_irq_uart2 = {
-       .name           = "s3c-uart2",
-       .mask           = s3c_irq_uart2_mask,
-       .unmask         = s3c_irq_uart2_unmask,
-       .ack            = s3c_irq_uart2_ack,
-};
-
-/* ADC and Touchscreen */
-
-static void
-s3c_irq_adc_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static void
-s3c_irq_adc_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
-}
-
-static void
-s3c_irq_adc_ack(unsigned int irqno)
-{
-       s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
-}
-
-static struct irq_chip s3c_irq_adc = {
-       .name           = "s3c-adc",
-       .mask           = s3c_irq_adc_mask,
-       .unmask         = s3c_irq_adc_unmask,
-       .ack            = s3c_irq_adc_ack,
-};
-
-/* irq demux for adc */
-static void s3c_irq_demux_adc(unsigned int irq,
-                             struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-       unsigned int offset = 9;
-       struct irq_desc *mydesc;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc &= ~submsk;
-       subsrc >>= offset;
-       subsrc &= 3;
-
-       if (subsrc != 0) {
-               if (subsrc & 1) {
-                       mydesc = irq_desc + IRQ_TC;
-                       desc_handle_irq(IRQ_TC, mydesc);
-               }
-               if (subsrc & 2) {
-                       mydesc = irq_desc + IRQ_ADC;
-                       desc_handle_irq(IRQ_ADC, mydesc);
-               }
-       }
-}
-
-static void s3c_irq_demux_uart(unsigned int start)
-{
-       unsigned int subsrc, submsk;
-       unsigned int offset = start - IRQ_S3CUART_RX0;
-       struct irq_desc *desc;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
-               start, offset, subsrc, submsk);
-
-       subsrc &= ~submsk;
-       subsrc >>= offset;
-       subsrc &= 7;
-
-       if (subsrc != 0) {
-               desc = irq_desc + start;
-
-               if (subsrc & 1)
-                       desc_handle_irq(start, desc);
-
-               desc++;
-
-               if (subsrc & 2)
-                       desc_handle_irq(start+1, desc);
-
-               desc++;
-
-               if (subsrc & 4)
-                       desc_handle_irq(start+2, desc);
-       }
-}
-
-/* uart demux entry points */
-
-static void
-s3c_irq_demux_uart0(unsigned int irq,
-                   struct irq_desc *desc)
-{
-       irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX0);
-}
-
-static void
-s3c_irq_demux_uart1(unsigned int irq,
-                   struct irq_desc *desc)
-{
-       irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX1);
-}
-
-static void
-s3c_irq_demux_uart2(unsigned int irq,
-                   struct irq_desc *desc)
-{
-       irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX2);
-}
-
-static void
-s3c_irq_demux_extint8(unsigned int irq,
-                     struct irq_desc *desc)
-{
-       unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-       unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-       eintpnd &= ~eintmsk;
-       eintpnd &= ~0xff;       /* ignore lower irqs */
-
-       /* we may as well handle all the pending IRQs here */
-
-       while (eintpnd) {
-               irq = __ffs(eintpnd);
-               eintpnd &= ~(1<<irq);
-
-               irq += (IRQ_EINT4 - 4);
-               desc_handle_irq(irq, irq_desc + irq);
-       }
-
-}
-
-static void
-s3c_irq_demux_extint4t7(unsigned int irq,
-                       struct irq_desc *desc)
-{
-       unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
-       unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
-
-       eintpnd &= ~eintmsk;
-       eintpnd &= 0xff;        /* only lower irqs */
-
-       /* we may as well handle all the pending IRQs here */
-
-       while (eintpnd) {
-               irq = __ffs(eintpnd);
-               eintpnd &= ~(1<<irq);
-
-               irq += (IRQ_EINT4 - 4);
-
-               desc_handle_irq(irq, irq_desc + irq);
-       }
-}
-
-#ifdef CONFIG_PM
-
-static struct sleep_save irq_save[] = {
-       SAVE_ITEM(S3C2410_INTMSK),
-       SAVE_ITEM(S3C2410_INTSUBMSK),
+static struct sysdev_driver s3c2410_irq_driver = {
+       .add            = s3c2410_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
 };
 
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+static int s3c2410_irq_init(void)
 {
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-               save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
-       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-               save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
-       s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
-       save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
-       return 0;
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
 }
 
-int s3c24xx_irq_resume(struct sys_device *dev)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
-               __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
-       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
-               __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
-       s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
-       __raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
-       return 0;
-}
-
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
-#endif
-
-/* s3c24xx_init_irq
- *
- * Initialise S3C2410 IRQ system
-*/
-
-void __init s3c24xx_init_irq(void)
-{
-       unsigned long pend;
-       unsigned long last;
-       int irqno;
-       int i;
-
-       irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
-
-       /* first, clear all interrupts pending... */
-
-       last = 0;
-       for (i = 0; i < 4; i++) {
-               pend = __raw_readl(S3C24XX_EINTPEND);
-
-               if (pend == 0 || pend == last)
-                       break;
-
-               __raw_writel(pend, S3C24XX_EINTPEND);
-               printk("irq: clearing pending ext status %08x\n", (int)pend);
-               last = pend;
-       }
-
-       last = 0;
-       for (i = 0; i < 4; i++) {
-               pend = __raw_readl(S3C2410_INTPND);
-
-               if (pend == 0 || pend == last)
-                       break;
-
-               __raw_writel(pend, S3C2410_SRCPND);
-               __raw_writel(pend, S3C2410_INTPND);
-               printk("irq: clearing pending status %08x\n", (int)pend);
-               last = pend;
-       }
-
-       last = 0;
-       for (i = 0; i < 4; i++) {
-               pend = __raw_readl(S3C2410_SUBSRCPND);
-
-               if (pend == 0 || pend == last)
-                       break;
-
-               printk("irq: clearing subpending status %08x\n", (int)pend);
-               __raw_writel(pend, S3C2410_SUBSRCPND);
-               last = pend;
-       }
-
-       /* register the main interrupts */
-
-       irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
-
-       for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
-               /* set all the s3c2410 internal irqs */
-
-               switch (irqno) {
-                       /* deal with the special IRQs (cascaded) */
-
-               case IRQ_EINT4t7:
-               case IRQ_EINT8t23:
-               case IRQ_UART0:
-               case IRQ_UART1:
-               case IRQ_UART2:
-               case IRQ_ADCPARENT:
-                       set_irq_chip(irqno, &s3c_irq_level_chip);
-                       set_irq_handler(irqno, handle_level_irq);
-                       break;
-
-               case IRQ_RESERVED6:
-               case IRQ_RESERVED24:
-                       /* no IRQ here */
-                       break;
-
-               default:
-                       //irqdbf("registering irq %d (s3c irq)\n", irqno);
-                       set_irq_chip(irqno, &s3c_irq_chip);
-                       set_irq_handler(irqno, handle_edge_irq);
-                       set_irq_flags(irqno, IRQF_VALID);
-               }
-       }
-
-       /* setup the cascade irq handlers */
-
-       set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
-       set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
-
-       set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
-       set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
-       set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
-       set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
-
-       /* external interrupts */
-
-       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-               irqdbf("registering irq %d (ext int)\n", irqno);
-               set_irq_chip(irqno, &s3c_irq_eint0t4);
-               set_irq_handler(irqno, handle_edge_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
-               irqdbf("registering irq %d (extended s3c irq)\n", irqno);
-               set_irq_chip(irqno, &s3c_irqext_chip);
-               set_irq_handler(irqno, handle_edge_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       /* register the uart interrupts */
-
-       irqdbf("s3c2410: registering external interrupts\n");
-
-       for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
-               irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
-               set_irq_chip(irqno, &s3c_irq_uart0);
-               set_irq_handler(irqno, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
-               irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
-               set_irq_chip(irqno, &s3c_irq_uart1);
-               set_irq_handler(irqno, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
-               irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
-               set_irq_chip(irqno, &s3c_irq_uart2);
-               set_irq_handler(irqno, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
-               irqdbf("registering irq %d (s3c adc irq)\n", irqno);
-               set_irq_chip(irqno, &s3c_irq_adc);
-               set_irq_handler(irqno, handle_edge_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       irqdbf("s3c2410: registered interrupt handlers\n");
-}
+arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h
deleted file mode 100644 (file)
index e5913da..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* arch/arm/mach-s3c2410/irq.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU IRQ support
- *
- * 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.
-*/
-
-#define irqdbf(x...)
-#define irqdbf2(x...)
-
-#define EXTINT_OFF (IRQ_EINT4 - 4)
-
-extern struct irq_chip s3c_irq_level_chip;
-
-static inline void
-s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
-               int subcheck)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
-
-       /* check to see if we need to mask the parent IRQ */
-
-       if ((submask  & subcheck) == subcheck) {
-               __raw_writel(mask | parentbit, S3C2410_INTMSK);
-       }
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-
-}
-
-static inline void
-s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
-       mask &= ~parentbit;
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-       __raw_writel(mask, S3C2410_INTMSK);
-}
-
-
-static inline void
-s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       s3c_irqsub_mask(irqno, parentmask, group);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-static inline void
-s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-/* exported for use in arch/arm/mach-s3c2410 */
-
-#ifdef CONFIG_PM
-extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
-#else
-#define s3c_irq_wake NULL
-#endif
-
-extern int s3c_irqext_type(unsigned int irq, unsigned int type);
index 817e2c684410bce25eeae0d383f296bad14cb644..72f2cc4fcd03b2cc901bdd02472f71ff21238809 100644 (file)
@@ -1,4 +1,4 @@
-/***********************************************************************
+/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
  *
  * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
  *
@@ -35,7 +35,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/proc_fs.h>
-
+#include <linux/serial_core.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -52,8 +52,8 @@
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
@@ -113,12 +113,6 @@ static struct platform_device amlm5900_device_nor = {
 #endif
 
 static struct map_desc amlm5900_iodesc[] __initdata = {
-       {
-               .virtual        = (u32)S3C24XX_VA_SPI,
-               .pfn            = __phys_to_pfn(S3C2410_PA_SPI),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE
-       }
 };
 
 #define UCON S3C2410_UCON_DEFAULT
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
deleted file mode 100644 (file)
index 0fad0c2..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-anubis.c
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/arch/anubis-map.h>
-#include <asm/arch/anubis-irq.h>
-#include <asm/arch/anubis-cpld.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/nand.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-#define COPYRIGHT ", (c) 2005 Simtec Electronics"
-
-static struct map_desc anubis_iodesc[] __initdata = {
-  /* ISA IO areas */
-
-  {
-       .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-       .pfn            = __phys_to_pfn(0x0),
-       .length         = SZ_4M,
-       .type           = MT_DEVICE,
-  }, {
-       .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-       .pfn            = __phys_to_pfn(0x0),
-       .length         = SZ_4M,
-       .type           = MT_DEVICE,
-  },
-
-  /* we could possibly compress the next set down into a set of smaller tables
-   * pagetables, but that would mean using an L2 section, and it still means
-   * we cannot actually feed the same register to an LDR due to 16K spacing
-   */
-
-  /* CPLD control registers */
-
-  {
-       .virtual        = (u32)ANUBIS_VA_CTRL1,
-       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL1),
-       .length         = SZ_4K,
-       .type           = MT_DEVICE,
-  }, {
-       .virtual        = (u32)ANUBIS_VA_CTRL2,
-       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL2),
-       .length         = SZ_4K,
-       .type           = MT_DEVICE,
-  },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
-       [0] = {
-               .name           = "uclk",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       },
-       [1] = {
-               .name           = "pclk",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       }
-};
-
-
-static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clocks      = anubis_serial_clocks,
-               .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
-       },
-       [1] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clocks      = anubis_serial_clocks,
-               .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
-       },
-};
-
-/* NAND Flash on Anubis board */
-
-static int external_map[]   = { 2 };
-static int chip0_map[]      = { 0 };
-static int chip1_map[]      = { 1 };
-
-static struct mtd_partition anubis_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_16K,
-               .offset = SZ_16K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-/* the Anubis has 3 selectable slots for nand-flash, the two
- * on-board chip areas, as well as the external slot.
- *
- * Note, there is no current hot-plug support for the External
- * socket.
-*/
-
-static struct s3c2410_nand_set anubis_nand_sets[] = {
-       [1] = {
-               .name           = "External",
-               .nr_chips       = 1,
-               .nr_map         = external_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-       [0] = {
-               .name           = "chip0",
-               .nr_chips       = 1,
-               .nr_map         = chip0_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-       [2] = {
-               .name           = "chip1",
-               .nr_chips       = 1,
-               .nr_map         = chip1_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-};
-
-static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
-{
-       unsigned int tmp;
-
-       slot = set->nr_map[slot] & 3;
-
-       pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
-                slot, set, set->nr_map);
-
-       tmp = __raw_readb(ANUBIS_VA_CTRL1);
-       tmp &= ~ANUBIS_CTRL1_NANDSEL;
-       tmp |= slot;
-
-       pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
-
-       __raw_writeb(tmp, ANUBIS_VA_CTRL1);
-}
-
-static struct s3c2410_platform_nand anubis_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 55,
-       .twrph1         = 40,
-       .nr_sets        = ARRAY_SIZE(anubis_nand_sets),
-       .sets           = anubis_nand_sets,
-       .select_chip    = anubis_nand_select,
-};
-
-/* IDE channels */
-
-static struct resource anubis_ide0_resource[] = {
-       {
-               .start  = S3C2410_CS3,
-               .end    = S3C2410_CS3 + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = S3C2410_CS3 + (1<<26),
-               .end    = S3C2410_CS3 + (1<<26) + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_IDE0,
-               .end    = IRQ_IDE0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device anubis_device_ide0 = {
-       .name           = "simtec-ide",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(anubis_ide0_resource),
-       .resource       = anubis_ide0_resource,
-};
-
-static struct resource anubis_ide1_resource[] = {
-       {
-               .start  = S3C2410_CS4,
-               .end    = S3C2410_CS4 + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = S3C2410_CS4 + (1<<26),
-               .end    = S3C2410_CS4 + (1<<26) + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_IDE0,
-               .end    = IRQ_IDE0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-
-static struct platform_device anubis_device_ide1 = {
-       .name           = "simtec-ide",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(anubis_ide1_resource),
-       .resource       = anubis_ide1_resource,
-};
-
-/* Standard Anubis devices */
-
-static struct platform_device *anubis_devices[] __initdata = {
-       &s3c_device_usb,
-       &s3c_device_wdt,
-       &s3c_device_adc,
-       &s3c_device_i2c,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-       &anubis_device_ide0,
-       &anubis_device_ide1,
-};
-
-static struct clk *anubis_clocks[] = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-static struct s3c24xx_board anubis_board __initdata = {
-       .devices       = anubis_devices,
-       .devices_count = ARRAY_SIZE(anubis_devices),
-       .clocks        = anubis_clocks,
-       .clocks_count  = ARRAY_SIZE(anubis_clocks),
-};
-
-static void __init anubis_map_io(void)
-{
-       /* initialise the clocks */
-
-       s3c24xx_dclk0.parent = NULL;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = NULL;
-       s3c24xx_dclk1.rate   = 24*1000*1000;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c_device_nand.dev.platform_data = &anubis_nand_info;
-
-       s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
-       s3c24xx_set_board(&anubis_board);
-
-       /* ensure that the GPIO is setup */
-       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
-}
-
-MACHINE_START(ANUBIS, "Simtec-Anubis")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-       .map_io         = anubis_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
index b8b76757ec54a70272a9107b06f5b554a50d299f..7b81296427ebc54ce28cc519575e57e23eb58a95 100644 (file)
@@ -50,9 +50,9 @@
 
 #include <linux/serial_8250.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 #include "usb-simtec.h"
 
 #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
index 15b625eae499e2e13b0d3e61dea07a7963347520..01c60d0923cd49d86da8d98b31e1c4dc85ed1f41 100644 (file)
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
 
 #include <asm/arch/h1940.h>
 #include <asm/arch/h1940-latch.h>
 #include <asm/arch/fb.h>
+#include <asm/arch/udc.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
        [0] = {
@@ -102,6 +103,32 @@ void h1940_latch_control(unsigned int clear, unsigned int set)
 
 EXPORT_SYMBOL_GPL(h1940_latch_control);
 
+static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+       printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
+
+       switch (cmd)
+       {
+               case S3C2410_UDC_P_ENABLE :
+                       h1940_latch_control(0, H1940_LATCH_USB_DP);
+                       break;
+               case S3C2410_UDC_P_DISABLE :
+                       h1940_latch_control(H1940_LATCH_USB_DP, 0);
+                       break;
+               case S3C2410_UDC_P_RESET :
+                       break;
+               default:
+                       break;
+       }
+}
+
+static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+       .udc_command            = h1940_udc_pullup,
+       .vbus_pin               = S3C2410_GPG5,
+       .vbus_pin_inverted      = 1,
+};
+
+
 
 /**
  * Set lcd on or off
@@ -146,12 +173,19 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
        .bpp=           {16,16,16},
 };
 
+static struct platform_device s3c_device_leds = {
+       .name             = "h1940-leds",
+       .id               = -1,
+};
+
 static struct platform_device *h1940_devices[] __initdata = {
        &s3c_device_usb,
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c,
        &s3c_device_iis,
+       &s3c_device_usbgadget,
+       &s3c_device_leds,
 };
 
 static struct s3c24xx_board h1940_board __initdata = {
@@ -179,7 +213,23 @@ static void __init h1940_init_irq(void)
 
 static void __init h1940_init(void)
 {
+       u32 tmp;
+
        s3c24xx_fb_set_platdata(&h1940_lcdcfg);
+       s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       tmp = (
+                0x78 << S3C2410_PLLCON_MDIVSHIFT)
+             | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
+             | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
+       writel(tmp, S3C2410_UPLLCON);
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
@@ -189,6 +239,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
        .map_io         = h1940_map_io,
        .init_irq       = h1940_init_irq,
-       .init_machine   = h1940_init,
+       .init_machine   = h1940_init,
        .timer          = &s3c24xx_timer,
 MACHINE_END
index 0411e9adb54d9b208682d849859a5dd16c97f08d..261aa4cc07700e509be8ee96907df184e9414307 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/iic.h>
 
-#include "s3c2410.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct map_desc n30_iodesc[] __initdata = {
        /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
deleted file mode 100644 (file)
index d6dfdad..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c
- *
- * Copyright (c) 2004 Nex Vision
- *   Guillaume GOURAT <guillaume.gourat@nexvision.tv>
- *
- * 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.
- *
- * Modifications:
- *     15-10-2004 GG  Created initial version
- *     12-03-2005 BJD Updated for release
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/map.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/setup.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-serial.h>
-
-#include "s3c2410.h"
-#include "s3c2440.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-static struct map_desc nexcoder_iodesc[] __initdata = {
-       /* nothing here yet */
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* NOR Flash on NexVision NexCoder 2440 board */
-
-static struct resource nexcoder_nor_resource[] = {
-       [0] = {
-               .start = S3C2410_CS0,
-               .end   = S3C2410_CS0 + (8*1024*1024) - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct map_info nexcoder_nor_map = {
-       .bankwidth = 2,
-};
-
-static struct platform_device nexcoder_device_nor = {
-       .name           = "mtd-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nexcoder_nor_resource),
-       .resource       = nexcoder_nor_resource,
-       .dev =
-       {
-               .platform_data = &nexcoder_nor_map,
-       }
-};
-
-/* Standard Nexcoder devices */
-
-static struct platform_device *nexcoder_devices[] __initdata = {
-       &s3c_device_usb,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &s3c_device_camif,
-       &s3c_device_spi0,
-       &s3c_device_spi1,
-       &nexcoder_device_nor,
-};
-
-static struct s3c24xx_board nexcoder_board __initdata = {
-       .devices       = nexcoder_devices,
-       .devices_count = ARRAY_SIZE(nexcoder_devices),
-};
-
-
-static void __init nexcoder_sensorboard_init(void)
-{
-       // Initialize SCCB bus
-       s3c2410_gpio_setpin(S3C2410_GPE14, 1); // IICSCL
-       s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_OUTP);
-       s3c2410_gpio_setpin(S3C2410_GPE15, 1); // IICSDA
-       s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_OUTP);
-
-       // Power up the sensor board
-       s3c2410_gpio_setpin(S3C2410_GPF1, 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); // CAM_GPIO7 => nLDO_PWRDN
-       s3c2410_gpio_setpin(S3C2410_GPF2, 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
-}
-
-static void __init nexcoder_map_io(void)
-{
-       s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
-       s3c24xx_set_board(&nexcoder_board);
-       nexcoder_sensorboard_init();
-}
-
-
-MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
-       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-       .map_io         = nexcoder_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c
deleted file mode 100644 (file)
index 37b4085..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-osiris.c
- *
- * Copyright (c) 2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/arch/osiris-map.h>
-#include <asm/arch/osiris-cpld.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/nand.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-/* onboard perihpheral map */
-
-static struct map_desc osiris_iodesc[] __initdata = {
-  /* ISA IO areas (may be over-written later) */
-
-  {
-         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
-         .pfn          = __phys_to_pfn(S3C2410_CS5),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
-         .pfn          = __phys_to_pfn(S3C2410_CS5),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  },
-
-  /* CPLD control registers */
-
-  {
-         .virtual      = (u32)OSIRIS_VA_CTRL1,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL1),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)OSIRIS_VA_CTRL2,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL2),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
-       [0] = {
-               .name           = "uclk",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       },
-       [1] = {
-               .name           = "pclk",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       }
-};
-
-static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clocks      = osiris_serial_clocks,
-               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clocks      = osiris_serial_clocks,
-               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clocks      = osiris_serial_clocks,
-               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
-       }
-};
-
-/* NAND Flash on Osiris board */
-
-static int external_map[]   = { 2 };
-static int chip0_map[]      = { 0 };
-static int chip1_map[]      = { 1 };
-
-static struct mtd_partition osiris_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_16K,
-               .offset = SZ_16K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-/* the Osiris has 3 selectable slots for nand-flash, the two
- * on-board chip areas, as well as the external slot.
- *
- * Note, there is no current hot-plug support for the External
- * socket.
-*/
-
-static struct s3c2410_nand_set osiris_nand_sets[] = {
-       [1] = {
-               .name           = "External",
-               .nr_chips       = 1,
-               .nr_map         = external_map,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-       [0] = {
-               .name           = "chip0",
-               .nr_chips       = 1,
-               .nr_map         = chip0_map,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-       [2] = {
-               .name           = "chip1",
-               .nr_chips       = 1,
-               .nr_map         = chip1_map,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-};
-
-static void osiris_nand_select(struct s3c2410_nand_set *set, int slot)
-{
-       unsigned int tmp;
-
-       slot = set->nr_map[slot] & 3;
-
-       pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n",
-                slot, set, set->nr_map);
-
-       tmp = __raw_readb(OSIRIS_VA_CTRL1);
-       tmp &= ~OSIRIS_CTRL1_NANDSEL;
-       tmp |= slot;
-
-       pr_debug("osiris_nand: ctrl1 now %02x\n", tmp);
-
-       __raw_writeb(tmp, OSIRIS_VA_CTRL1);
-}
-
-static struct s3c2410_platform_nand osiris_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 60,
-       .twrph1         = 60,
-       .nr_sets        = ARRAY_SIZE(osiris_nand_sets),
-       .sets           = osiris_nand_sets,
-       .select_chip    = osiris_nand_select,
-};
-
-/* PCMCIA control and configuration */
-
-static struct resource osiris_pcmcia_resource[] = {
-       [0] = {
-               .start  = 0x0f000000,
-               .end    = 0x0f100000,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = 0x0c000000,
-               .end    = 0x0c100000,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device osiris_pcmcia = {
-       .name           = "osiris-pcmcia",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(osiris_pcmcia_resource),
-       .resource       = osiris_pcmcia_resource,
-};
-
-/* Standard Osiris devices */
-
-static struct platform_device *osiris_devices[] __initdata = {
-       &s3c_device_i2c,
-       &s3c_device_nand,
-       &osiris_pcmcia,
-};
-
-static struct clk *osiris_clocks[] = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-static struct s3c24xx_board osiris_board __initdata = {
-       .devices       = osiris_devices,
-       .devices_count = ARRAY_SIZE(osiris_devices),
-       .clocks        = osiris_clocks,
-       .clocks_count  = ARRAY_SIZE(osiris_clocks),
-};
-
-static void __init osiris_map_io(void)
-{
-       unsigned long flags;
-
-       /* initialise the clocks */
-
-       s3c24xx_dclk0.parent = NULL;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = NULL;
-       s3c24xx_dclk1.rate   = 24*1000*1000;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c_device_nand.dev.platform_data = &osiris_nand_info;
-
-       s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
-       s3c24xx_set_board(&osiris_board);
-
-       /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
-
-       local_irq_save(flags);
-       __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
-       local_irq_restore(flags);
-
-       /* write-protect line to the NAND */
-       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
-}
-
-MACHINE_START(OSIRIS, "Simtec-OSIRIS")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-       .map_io         = osiris_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
index 2c738b375e4d6da64359154ea3f0073f6e6a2ea9..c78ab75b44f30cb33d198e4ba455baadd4af5aa2 100644 (file)
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "s3c2410.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
 static struct map_desc otom11_iodesc[] __initdata = {
   /* Device area */
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
new file mode 100644 (file)
index 0000000..c6a4159
--- /dev/null
@@ -0,0 +1,448 @@
+/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
+ *
+ * Copyright (C) 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/mmc/protocol.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/leds-gpio.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/fb.h>
+#include <asm/arch/nand.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/spi.h>
+#include <asm/arch/spi-gpio.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+static struct map_desc qt2410_iodesc[] __initdata = {
+       { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* LCD driver info */
+
+/* Configuration for 640x480 SHARP LQ080V3DG01 */
+static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
+       .regs   = {
+
+               .lcdcon1        = S3C2410_LCDCON1_TFT16BPP |
+                                 S3C2410_LCDCON1_TFT |
+                                 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
+
+               .lcdcon2        = S3C2410_LCDCON2_VBPD(18) |    /* 19 */
+                                 S3C2410_LCDCON2_LINEVAL(479) |
+                                 S3C2410_LCDCON2_VFPD(10) |    /* 11 */
+                                 S3C2410_LCDCON2_VSPW(14),     /* 15 */
+
+               .lcdcon3        = S3C2410_LCDCON3_HBPD(43) |    /* 44 */
+                                 S3C2410_LCDCON3_HOZVAL(639) | /* 640 */
+                                 S3C2410_LCDCON3_HFPD(115),    /* 116 */
+
+               .lcdcon4        = S3C2410_LCDCON4_MVAL(0) |
+                                 S3C2410_LCDCON4_HSPW(95),     /* 96 */
+
+               .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                                 S3C2410_LCDCON5_INVVLINE |
+                                 S3C2410_LCDCON5_INVVFRAME |
+                                 S3C2410_LCDCON5_PWREN |
+                                 S3C2410_LCDCON5_HWSWP,
+       },
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+
+       .width          = 640,
+       .height         = 480,
+
+       .xres           = {
+               .min    = 640,
+               .max    = 640,
+               .defval = 640,
+       },
+
+       .yres           = {
+               .min    = 480,
+               .max    = 480,
+               .defval = 480,
+       },
+
+       .bpp            = {
+               .min    = 16,
+               .max    = 16,
+               .defval = 16,
+       },
+};
+
+/* Configuration for 480x640 toppoly TD028TTEC1 */
+static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
+       .regs   = {
+
+               .lcdcon1        = S3C2410_LCDCON1_TFT16BPP |
+                                 S3C2410_LCDCON1_TFT |
+                                 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
+
+               .lcdcon2        = S3C2410_LCDCON2_VBPD(1) |     /* 2 */
+                                 S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
+                                 S3C2410_LCDCON2_VFPD(3) |     /* 4 */
+                                 S3C2410_LCDCON2_VSPW(1),      /* 2 */
+
+               .lcdcon3        = S3C2410_LCDCON3_HBPD(7) |     /* 8 */
+                                 S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
+                                 S3C2410_LCDCON3_HFPD(23),     /* 24 */
+
+               .lcdcon4        = S3C2410_LCDCON4_MVAL(0) |
+                                 S3C2410_LCDCON4_HSPW(7),      /* 8 */
+
+               .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                                 S3C2410_LCDCON5_INVVLINE |
+                                 S3C2410_LCDCON5_INVVFRAME |
+                                 S3C2410_LCDCON5_PWREN |
+                                 S3C2410_LCDCON5_HWSWP,
+       },
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+
+       .width          = 480,
+       .height         = 640,
+
+       .xres           = {
+               .min    = 480,
+               .max    = 480,
+               .defval = 480,
+       },
+
+       .yres           = {
+               .min    = 640,
+               .max    = 640,
+               .defval = 640,
+       },
+
+       .bpp            = {
+               .min    = 16,
+               .max    = 16,
+               .defval = 16,
+       },
+};
+
+/* Config for 240x320 LCD */
+static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
+       .regs   = {
+
+               .lcdcon1        = S3C2410_LCDCON1_TFT16BPP |
+                                 S3C2410_LCDCON1_TFT |
+                                 S3C2410_LCDCON1_CLKVAL(0x04),
+
+               .lcdcon2        = S3C2410_LCDCON2_VBPD(1) |
+                                 S3C2410_LCDCON2_LINEVAL(319) |
+                                 S3C2410_LCDCON2_VFPD(6) |
+                                 S3C2410_LCDCON2_VSPW(3),
+
+               .lcdcon3        = S3C2410_LCDCON3_HBPD(12) |
+                                 S3C2410_LCDCON3_HOZVAL(239) |
+                                 S3C2410_LCDCON3_HFPD(7),
+
+               .lcdcon4        = S3C2410_LCDCON4_MVAL(0) |
+                                 S3C2410_LCDCON4_HSPW(3),
+
+               .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                                 S3C2410_LCDCON5_INVVLINE |
+                                 S3C2410_LCDCON5_INVVFRAME |
+                                 S3C2410_LCDCON5_PWREN |
+                                 S3C2410_LCDCON5_HWSWP,
+       },
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+
+       .width          = 240,
+       .height         = 320,
+
+       .xres           = {
+               .min    = 240,
+               .max    = 240,
+               .defval = 240,
+       },
+
+       .yres           = {
+               .min    = 320,
+               .max    = 320,
+               .defval = 320,
+       },
+
+       .bpp            = {
+               .min    = 16,
+               .max    = 16,
+               .defval = 16,
+       },
+};
+
+/* CS8900 */
+
+static struct resource qt2410_cs89x0_resources[] = {
+       [0] = {
+               .start  = 0x19000000,
+               .end    = 0x19000000 + 16,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT9,
+               .end    = IRQ_EINT9,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device qt2410_cs89x0 = {
+       .name           = "cirrus-cs89x0",
+       .num_resources  = ARRAY_SIZE(qt2410_cs89x0_resources),
+       .resource       = qt2410_cs89x0_resources,
+};
+
+/* LED */
+
+static struct s3c24xx_led_platdata qt2410_pdata_led = {
+       .gpio           = S3C2410_GPB0,
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led",
+       .def_trigger    = "timer",
+};
+
+static struct platform_device qt2410_led = {
+       .name           = "s3c24xx_led",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &qt2410_pdata_led,
+       },
+};
+
+/* SPI */
+
+static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
+{
+       switch (cs) {
+       case BITBANG_CS_ACTIVE:
+               s3c2410_gpio_setpin(S3C2410_GPB5, 0);
+               break;
+       case BITBANG_CS_INACTIVE:
+               s3c2410_gpio_setpin(S3C2410_GPB5, 1);
+               break;
+       }
+}
+
+static struct s3c2410_spigpio_info spi_gpio_cfg = {
+       .pin_clk        = S3C2410_GPG7,
+       .pin_mosi       = S3C2410_GPG6,
+       .pin_miso       = S3C2410_GPG5,
+       .chip_select    = &spi_gpio_cs,
+};
+
+
+static struct platform_device qt2410_spi = {
+       .name             = "s3c24xx-spi-gpio",
+       .id               = 1,
+       .dev = {
+               .platform_data = &spi_gpio_cfg,
+       },
+};
+
+/* Board devices */
+
+static struct platform_device *qt2410_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_sdi,
+       &s3c_device_usbgadget,
+       &qt2410_spi,
+       &qt2410_cs89x0,
+       &qt2410_led,
+};
+
+static struct s3c24xx_board qt2410_board __initdata = {
+       .devices       = qt2410_devices,
+       .devices_count = ARRAY_SIZE(qt2410_devices)
+};
+
+static struct mtd_partition qt2410_nand_part[] = {
+       [0] = {
+               .name   = "U-Boot",
+               .size   = 0x30000,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "U-Boot environment",
+               .offset = 0x30000,
+               .size   = 0x4000,
+       },
+       [2] = {
+               .name   = "kernel",
+               .offset = 0x34000,
+               .size   = SZ_2M,
+       },
+       [3] = {
+               .name   = "initrd",
+               .offset = 0x234000,
+               .size   = SZ_4M,
+       },
+       [4] = {
+               .name   = "jffs2",
+               .offset = 0x634000,
+               .size   = 0x39cc000,
+       },
+};
+
+static struct s3c2410_nand_set qt2410_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(qt2410_nand_part),
+               .partitions     = qt2410_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+ */
+
+static struct s3c2410_platform_nand qt2410_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(qt2410_nand_sets),
+       .sets           = qt2410_nand_sets,
+};
+
+/* UDC */
+
+static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
+};
+
+static char tft_type = 's';
+
+static int __init qt2410_tft_setup(char *str)
+{
+       tft_type = str[0];
+       return 1;
+}
+
+__setup("tft=", qt2410_tft_setup);
+
+static void __init qt2410_map_io(void)
+{
+       s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
+       s3c24xx_init_clocks(12*1000*1000);
+       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+       s3c24xx_set_board(&qt2410_board);
+}
+
+static void __init qt2410_machine_init(void)
+{
+       s3c_device_nand.dev.platform_data = &qt2410_nand_info;
+
+       switch (tft_type) {
+       case 'p': /* production */
+               s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg);
+               break;
+       case 'b': /* big */
+               s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
+               break;
+       case 's': /* small */
+       default:
+               s3c24xx_fb_set_platdata(&qt2410_lcd_cfg);
+               break;
+       }
+
+       s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
+       s3c2410_gpio_setpin(S3C2410_GPB0, 1);
+
+       s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
+
+       s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
+
+       s3c2410_pm_init();
+}
+
+MACHINE_START(QT2410, "QT2410")
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = qt2410_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = qt2410_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
deleted file mode 100644 (file)
index ecbcdf7..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-rx3715.c
- *
- * Copyright (c) 2003,2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.handhelds.org/projects/rx3715.html
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-lcd.h>
-
-#include <asm/arch/h1940.h>
-#include <asm/arch/nand.h>
-#include <asm/arch/fb.h>
-
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
-
-static struct map_desc rx3715_iodesc[] __initdata = {
-       /* dump ISA space somewhere unused */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS3),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS3),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE,
-       },
-};
-
-
-static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
-       [0] = {
-               .name           = "fclk",
-               .divisor        = 0,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       }
-};
-
-static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-               .clocks      = rx3715_serial_clocks,
-               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x00,
-               .clocks      = rx3715_serial_clocks,
-               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .uart_flags  = UPF_CONS_FLOW,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-               .clocks      = rx3715_serial_clocks,
-               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
-       }
-};
-
-/* framebuffer lcd controller information */
-
-static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
-       .regs   = {
-               .lcdcon1 =      S3C2410_LCDCON1_TFT16BPP | \
-                               S3C2410_LCDCON1_TFT | \
-                               S3C2410_LCDCON1_CLKVAL(0x0C),
-
-               .lcdcon2 =      S3C2410_LCDCON2_VBPD(5) | \
-                               S3C2410_LCDCON2_LINEVAL(319) | \
-                               S3C2410_LCDCON2_VFPD(6) | \
-                               S3C2410_LCDCON2_VSPW(2),
-
-               .lcdcon3 =      S3C2410_LCDCON3_HBPD(35) | \
-                               S3C2410_LCDCON3_HOZVAL(239) | \
-                               S3C2410_LCDCON3_HFPD(35),
-
-               .lcdcon4 =      S3C2410_LCDCON4_MVAL(0) | \
-                               S3C2410_LCDCON4_HSPW(7),
-
-               .lcdcon5 =      S3C2410_LCDCON5_INVVLINE |
-                               S3C2410_LCDCON5_FRM565 |
-                               S3C2410_LCDCON5_HWSWP,
-       },
-
-       .lpcsel =       0xf82,
-
-       .gpccon =       0xaa955699,
-       .gpccon_mask =  0xffc003cc,
-       .gpcup =        0x0000ffff,
-       .gpcup_mask =   0xffffffff,
-
-       .gpdcon =       0xaa95aaa1,
-       .gpdcon_mask =  0xffc0fff0,
-       .gpdup =        0x0000faff,
-       .gpdup_mask =   0xffffffff,
-
-       .fixed_syncs =  1,
-       .width  =       240,
-       .height =       320,
-
-       .xres   = {
-               .min =          240,
-               .max =          240,
-               .defval =       240,
-       },
-
-       .yres   = {
-               .max =          320,
-               .min =          320,
-               .defval =       320,
-       },
-
-       .bpp    = {
-               .min =          16,
-               .max =          16,
-               .defval =       16,
-       },
-};
-
-static struct mtd_partition rx3715_nand_part[] = {
-       [0] = {
-               .name           = "Whole Flash",
-               .offset         = 0,
-               .size           = MTDPART_SIZ_FULL,
-               .mask_flags     = MTD_WRITEABLE,
-       }
-};
-
-static struct s3c2410_nand_set rx3715_nand_sets[] = {
-       [0] = {
-               .name           = "Internal",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(rx3715_nand_part),
-               .partitions     = rx3715_nand_part,
-       },
-};
-
-static struct s3c2410_platform_nand rx3715_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 50,
-       .twrph1         = 15,
-       .nr_sets        = ARRAY_SIZE(rx3715_nand_sets),
-       .sets           = rx3715_nand_sets,
-};
-
-static struct platform_device *rx3715_devices[] __initdata = {
-       &s3c_device_usb,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c,
-       &s3c_device_iis,
-       &s3c_device_nand,
-};
-
-static struct s3c24xx_board rx3715_board __initdata = {
-       .devices       = rx3715_devices,
-       .devices_count = ARRAY_SIZE(rx3715_devices)
-};
-
-static void __init rx3715_map_io(void)
-{
-       s3c_device_nand.dev.platform_data = &rx3715_nand_info;
-
-       s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
-       s3c24xx_init_clocks(16934000);
-       s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
-       s3c24xx_set_board(&rx3715_board);
-}
-
-static void __init rx3715_init_irq(void)
-{
-       s3c24xx_init_irq();
-}
-
-static void __init rx3715_init_machine(void)
-{
-       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
-       s3c2410_pm_init();
-
-       s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
-}
-
-
-MACHINE_START(RX3715, "IPAQ-RX3715")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-       .map_io         = rx3715_map_io,
-       .init_irq       = rx3715_init_irq,
-       .init_machine   = rx3715_init_machine,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
index 01c0c986d827de5d12f775aaf4abce49a7bd988e..57b8a80f33d0c53c2672d72c496b88255add8072 100644 (file)
@@ -1,4 +1,4 @@
-/***********************************************************************
+/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
  *
  * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
  *
 
 #include <asm/arch/regs-serial.h>
 
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 
-#include "common-smdk.h"
+#include <asm/plat-s3c24xx/common-smdk.h>
 
 static struct map_desc smdk2410_iodesc[] __initdata = {
   /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2410/mach-smdk2413.c
deleted file mode 100644 (file)
index 4f89abd..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
- * loans of SMDK2413 to work with.
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
-#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-lcd.h>
-
-#include <asm/arch/idle.h>
-#include <asm/arch/fb.h>
-
-#include "s3c2410.h"
-#include "s3c2412.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-#include "common-smdk.h"
-
-static struct map_desc smdk2413_iodesc[] __initdata = {
-};
-
-static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       }
-};
-
-static struct platform_device *smdk2413_devices[] __initdata = {
-       &s3c_device_usb,
-       //&s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c,
-       &s3c_device_iis,
-};
-
-static struct s3c24xx_board smdk2413_board __initdata = {
-       .devices       = smdk2413_devices,
-       .devices_count = ARRAY_SIZE(smdk2413_devices)
-};
-
-static void __init smdk2413_fixup(struct machine_desc *desc,
-                                 struct tag *tags, char **cmdline,
-                                 struct meminfo *mi)
-{
-       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
-               mi->nr_banks=1;
-               mi->bank[0].start = 0x30000000;
-               mi->bank[0].size = SZ_64M;
-               mi->bank[0].node = 0;
-       }
-}
-
-static void __init smdk2413_map_io(void)
-{
-       s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
-       s3c24xx_set_board(&smdk2413_board);
-}
-
-static void __init smdk2413_machine_init(void)
-{
-       smdk_machine_init();
-}
-
-MACHINE_START(S3C2413, "S3C2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-
-       .fixup          = smdk2413_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2413_map_io,
-       .init_machine   = smdk2413_machine_init,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
-
-MACHINE_START(SMDK2413, "SMDK2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-
-       .fixup          = smdk2413_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2413_map_io,
-       .init_machine   = smdk2413_machine_init,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
deleted file mode 100644 (file)
index 2b61f4e..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c
- *
- * Copyright (c) 2004,2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-lcd.h>
-
-#include <asm/arch/idle.h>
-#include <asm/arch/fb.h>
-
-#include "s3c2410.h"
-#include "s3c2440.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-#include "common-smdk.h"
-
-static struct map_desc smdk2440_iodesc[] __initdata = {
-       /* ISA IO Space map (memory space selected by A24) */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       }
-};
-
-/* LCD driver info */
-
-static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
-       .regs   = {
-
-               .lcdcon1        = S3C2410_LCDCON1_TFT16BPP |
-                                 S3C2410_LCDCON1_TFT |
-                                 S3C2410_LCDCON1_CLKVAL(0x04),
-
-               .lcdcon2        = S3C2410_LCDCON2_VBPD(7) |
-                                 S3C2410_LCDCON2_LINEVAL(319) |
-                                 S3C2410_LCDCON2_VFPD(6) |
-                                 S3C2410_LCDCON2_VSPW(3),
-
-               .lcdcon3        = S3C2410_LCDCON3_HBPD(19) |
-                                 S3C2410_LCDCON3_HOZVAL(239) |
-                                 S3C2410_LCDCON3_HFPD(7),
-
-               .lcdcon4        = S3C2410_LCDCON4_MVAL(0) |
-                                 S3C2410_LCDCON4_HSPW(3),
-
-               .lcdcon5        = S3C2410_LCDCON5_FRM565 |
-                                 S3C2410_LCDCON5_INVVLINE |
-                                 S3C2410_LCDCON5_INVVFRAME |
-                                 S3C2410_LCDCON5_PWREN |
-                                 S3C2410_LCDCON5_HWSWP,
-       },
-
-#if 0
-       /* currently setup by downloader */
-       .gpccon         = 0xaa940659,
-       .gpccon_mask    = 0xffffffff,
-       .gpcup          = 0x0000ffff,
-       .gpcup_mask     = 0xffffffff,
-       .gpdcon         = 0xaa84aaa0,
-       .gpdcon_mask    = 0xffffffff,
-       .gpdup          = 0x0000faff,
-       .gpdup_mask     = 0xffffffff,
-#endif
-
-       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
-
-       .width          = 240,
-       .height         = 320,
-
-       .xres           = {
-               .min    = 240,
-               .max    = 240,
-               .defval = 240,
-       },
-
-       .yres           = {
-               .min    = 320,
-               .max    = 320,
-               .defval = 320,
-       },
-
-       .bpp            = {
-               .min    = 16,
-               .max    = 16,
-               .defval = 16,
-       },
-};
-
-static struct platform_device *smdk2440_devices[] __initdata = {
-       &s3c_device_usb,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c,
-       &s3c_device_iis,
-};
-
-static struct s3c24xx_board smdk2440_board __initdata = {
-       .devices       = smdk2440_devices,
-       .devices_count = ARRAY_SIZE(smdk2440_devices)
-};
-
-static void __init smdk2440_map_io(void)
-{
-       s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
-       s3c24xx_init_clocks(16934400);
-       s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
-       s3c24xx_set_board(&smdk2440_board);
-}
-
-static void __init smdk2440_machine_init(void)
-{
-       s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
-
-       smdk_machine_init();
-}
-
-MACHINE_START(S3C2440, "SMDK2440")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2440_map_io,
-       .init_machine   = smdk2440_machine_init,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
index a382fc095110ec21b9b07563a0b140893e40db98..c947c75bcbf0f982f13566db3a0fe61b45ea7eb5 100644 (file)
@@ -43,9 +43,9 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/leds-gpio.h>
 
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
 #include "usb-simtec.h"
 
 /* macros for virtual address mods for the io space entries */
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2410/mach-vstms.c
deleted file mode 100644 (file)
index 0360e10..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-vstms.c
- *
- * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
- *
- * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/hardware/iomd.h>
-#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-lcd.h>
-
-#include <asm/arch/idle.h>
-#include <asm/arch/fb.h>
-
-#include <asm/arch/nand.h>
-
-#include "s3c2410.h"
-#include "s3c2412.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-
-
-static struct map_desc vstms_iodesc[] __initdata = {
-};
-
-static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       }
-};
-
-static struct mtd_partition vstms_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = 0x7C000,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "UBoot Config",
-               .offset = 0x7C000,
-               .size   = 0x4000,
-       },
-       [2] = {
-               .name   = "Kernel",
-               .offset = 0x80000,
-               .size   = 0x200000,
-       },
-       [3] = {
-               .name   = "RFS",
-               .offset = 0x280000,
-               .size   = 0x3d80000,
-       },
-};
-
-static struct s3c2410_nand_set vstms_nand_sets[] = {
-       [0] = {
-               .name           = "NAND",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(vstms_nand_part),
-               .partitions     = vstms_nand_part,
-       },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
-*/
-
-static struct s3c2410_platform_nand vstms_nand_info = {
-       .tacls          = 20,
-       .twrph0         = 60,
-       .twrph1         = 20,
-       .nr_sets        = ARRAY_SIZE(vstms_nand_sets),
-       .sets           = vstms_nand_sets,
-};
-
-static struct platform_device *vstms_devices[] __initdata = {
-       &s3c_device_usb,
-       &s3c_device_wdt,
-       &s3c_device_i2c,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-};
-
-static struct s3c24xx_board vstms_board __initdata = {
-       .devices       = vstms_devices,
-       .devices_count = ARRAY_SIZE(vstms_devices)
-};
-
-static void __init vstms_fixup(struct machine_desc *desc,
-                                 struct tag *tags, char **cmdline,
-                                 struct meminfo *mi)
-{
-       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
-               mi->nr_banks=1;
-               mi->bank[0].start = 0x30000000;
-               mi->bank[0].size = SZ_64M;
-               mi->bank[0].node = 0;
-       }
-}
-
-static void __init vstms_map_io(void)
-{
-       s3c_device_nand.dev.platform_data = &vstms_nand_info;
-
-       s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
-       s3c24xx_set_board(&vstms_board);
-}
-
-MACHINE_START(VSTMS, "VSTMS")
-       .phys_io        = S3C2410_PA_UART,
-       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
-       .boot_params    = S3C2410_SDRAM_PA + 0x100,
-
-       .fixup          = vstms_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = vstms_map_io,
-       .timer          = &s3c24xx_timer,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
deleted file mode 100644 (file)
index 619133e..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/pm-simtec.c
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/
- *
- * Power Management helpers for Simtec S3C24XX implementations
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/arch/map.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-mem.h>
-
-#include <asm/mach-types.h>
-
-#include "pm.h"
-
-#define COPYRIGHT ", (c) 2005 Simtec Electronics"
-
-/* pm_simtec_init
- *
- * enable the power management functions
-*/
-
-static __init int pm_simtec_init(void)
-{
-       unsigned long gstatus4;
-
-       /* check which machine we are running on */
-
-       if (!machine_is_bast() && !machine_is_vr1000() &&
-           !machine_is_anubis() && !machine_is_osiris() &&
-           !machine_is_aml_m5900())
-               return 0;
-
-       printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
-
-       gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
-       gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
-       gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
-
-       __raw_writel(gstatus4, S3C2410_GSTATUS4);
-
-       return s3c2410_pm_init();
-}
-
-arch_initcall(pm_simtec_init);
index ebf294dd31da7cf25410ac4327f58a230833a1b9..3b3a7db4e0dd961028ad43869fc22f5e6a2d365e 100644 (file)
@@ -1,11 +1,9 @@
 /* linux/arch/arm/mach-s3c2410/pm.c
  *
- * Copyright (c) 2004,2006 Simtec Electronics
+ * Copyright (c) 2006 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C24XX Power Manager (Suspend-To-RAM) support
- *
- * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+ * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
  *
  * 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
  * 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
- *
- * Parts based on arch/arm/mach-pxa/pm.c
- *
- * Thanks to Dimitry Andric for debugging
 */
 
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/errno.h>
 #include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/crc32.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
+#include <linux/sysdev.h>
 
-#include <asm/cacheflush.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-irq.h>
-
-#include <asm/mach/time.h>
-
-#include "pm.h"
-
-/* for external use */
-
-unsigned long s3c_pm_flags;
-
-#define PFX "s3c24xx-pm: "
-
-static struct sleep_save core_save[] = {
-       SAVE_ITEM(S3C2410_LOCKTIME),
-       SAVE_ITEM(S3C2410_CLKCON),
-
-       /* we restore the timings here, with the proviso that the board
-        * brings the system up in an slower, or equal frequency setting
-        * to the original system.
-        *
-        * if we cannot guarantee this, then things are going to go very
-        * wrong here, as we modify the refresh and both pll settings.
-        */
-
-       SAVE_ITEM(S3C2410_BWSCON),
-       SAVE_ITEM(S3C2410_BANKCON0),
-       SAVE_ITEM(S3C2410_BANKCON1),
-       SAVE_ITEM(S3C2410_BANKCON2),
-       SAVE_ITEM(S3C2410_BANKCON3),
-       SAVE_ITEM(S3C2410_BANKCON4),
-       SAVE_ITEM(S3C2410_BANKCON5),
-
-       SAVE_ITEM(S3C2410_CLKDIVN),
-       SAVE_ITEM(S3C2410_MPLLCON),
-       SAVE_ITEM(S3C2410_UPLLCON),
-       SAVE_ITEM(S3C2410_CLKSLOW),
-       SAVE_ITEM(S3C2410_REFRESH),
-};
-
-static struct sleep_save gpio_save[] = {
-       SAVE_ITEM(S3C2410_GPACON),
-       SAVE_ITEM(S3C2410_GPADAT),
-
-       SAVE_ITEM(S3C2410_GPBCON),
-       SAVE_ITEM(S3C2410_GPBDAT),
-       SAVE_ITEM(S3C2410_GPBUP),
-
-       SAVE_ITEM(S3C2410_GPCCON),
-       SAVE_ITEM(S3C2410_GPCDAT),
-       SAVE_ITEM(S3C2410_GPCUP),
-
-       SAVE_ITEM(S3C2410_GPDCON),
-       SAVE_ITEM(S3C2410_GPDDAT),
-       SAVE_ITEM(S3C2410_GPDUP),
-
-       SAVE_ITEM(S3C2410_GPECON),
-       SAVE_ITEM(S3C2410_GPEDAT),
-       SAVE_ITEM(S3C2410_GPEUP),
-
-       SAVE_ITEM(S3C2410_GPFCON),
-       SAVE_ITEM(S3C2410_GPFDAT),
-       SAVE_ITEM(S3C2410_GPFUP),
+#include <asm/mach-types.h>
 
-       SAVE_ITEM(S3C2410_GPGCON),
-       SAVE_ITEM(S3C2410_GPGDAT),
-       SAVE_ITEM(S3C2410_GPGUP),
-
-       SAVE_ITEM(S3C2410_GPHCON),
-       SAVE_ITEM(S3C2410_GPHDAT),
-       SAVE_ITEM(S3C2410_GPHUP),
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/h1940.h>
 
-       SAVE_ITEM(S3C2410_DCLKCON),
-};
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
 
 #ifdef CONFIG_S3C2410_PM_DEBUG
-
-#define SAVE_UART(va) \
-       SAVE_ITEM((va) + S3C2410_ULCON), \
-       SAVE_ITEM((va) + S3C2410_UCON), \
-       SAVE_ITEM((va) + S3C2410_UFCON), \
-       SAVE_ITEM((va) + S3C2410_UMCON), \
-       SAVE_ITEM((va) + S3C2410_UBRDIV)
-
-static struct sleep_save uart_save[] = {
-       SAVE_UART(S3C24XX_VA_UART0),
-       SAVE_UART(S3C24XX_VA_UART1),
-#ifndef CONFIG_CPU_S3C2400
-       SAVE_UART(S3C24XX_VA_UART2),
-#endif
-};
-
-/* debug
- *
- * we send the debug to printascii() to allow it to be seen if the
- * system never wakes up from the sleep
-*/
-
-extern void printascii(const char *);
-
-void pm_dbg(const char *fmt, ...)
-{
-       va_list va;
-       char buff[256];
-
-       va_start(va, fmt);
-       vsprintf(buff, fmt, va);
-       va_end(va);
-
-       printascii(buff);
-}
-
-static void s3c2410_pm_debug_init(void)
-{
-       unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
-       /* re-start uart clocks */
-       tmp |= S3C2410_CLKCON_UART0;
-       tmp |= S3C2410_CLKCON_UART1;
-       tmp |= S3C2410_CLKCON_UART2;
-
-       __raw_writel(tmp, S3C2410_CLKCON);
-       udelay(10);
-}
-
+extern void pm_dbg(const char *fmt, ...);
 #define DBG(fmt...) pm_dbg(fmt)
 #else
 #define DBG(fmt...) printk(KERN_DEBUG fmt)
-
-#define s3c2410_pm_debug_init() do { } while(0)
-
-static struct sleep_save uart_save[] = {};
 #endif
 
-#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
-
-/* suspend checking code...
- *
- * this next area does a set of crc checks over all the installed
- * memory, so the system can verify if the resume was ok.
- *
- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
- * increasing it will mean that the area corrupted will be less easy to spot,
- * and reducing the size will cause the CRC save area to grow
-*/
-
-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
-
-static u32 crc_size;   /* size needed for the crc block */
-static u32 *crcs;      /* allocated over suspend/resume */
-
-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
-
-/* s3c2410_pm_run_res
- *
- * go thorugh the given resource list, and look for system ram
-*/
-
-static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
-{
-       while (ptr != NULL) {
-               if (ptr->child != NULL)
-                       s3c2410_pm_run_res(ptr->child, fn, arg);
-
-               if ((ptr->flags & IORESOURCE_MEM) &&
-                   strcmp(ptr->name, "System RAM") == 0) {
-                       DBG("Found system RAM at %08lx..%08lx\n",
-                           ptr->start, ptr->end);
-                       arg = (fn)(ptr, arg);
-               }
-
-               ptr = ptr->sibling;
-       }
-}
-
-static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
-{
-       s3c2410_pm_run_res(&iomem_resource, fn, arg);
-}
-
-static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
-{
-       u32 size = (u32)(res->end - res->start)+1;
-
-       size += CHECK_CHUNKSIZE-1;
-       size /= CHECK_CHUNKSIZE;
-
-       DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
-
-       *val += size * sizeof(u32);
-       return val;
-}
-
-/* s3c2410_pm_prepare_check
- *
- * prepare the necessary information for creating the CRCs. This
- * must be done before the final save, as it will require memory
- * allocating, and thus touching bits of the kernel we do not
- * know about.
-*/
-
-static void s3c2410_pm_check_prepare(void)
+static void s3c2410_pm_prepare(void)
 {
-       crc_size = 0;
+       /* ensure at least GSTATUS3 has the resume address */
 
-       s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
+       __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
 
-       DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
+       DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+       DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
 
-       crcs = kmalloc(crc_size+4, GFP_KERNEL);
-       if (crcs == NULL)
-               printk(KERN_ERR "Cannot allocated CRC save area\n");
-}
+       if (machine_is_h1940()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
 
-static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
-{
-       unsigned long addr, left;
+               /* generate check for the bootloader to check on resume */
 
-       for (addr = res->start; addr < res->end;
-            addr += CHECK_CHUNKSIZE) {
-               left = res->end - addr;
+               for (ptr = 0; ptr < 0x40000; ptr += 0x400)
+                       calc += __raw_readl(base+ptr);
 
-               if (left > CHECK_CHUNKSIZE)
-                       left = CHECK_CHUNKSIZE;
-
-               *val = crc32_le(~0, phys_to_virt(addr), left);
-               val++;
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
        }
 
-       return val;
-}
-
-/* s3c2410_pm_check_store
- *
- * compute the CRC values for the memory blocks before the final
- * sleep.
-*/
-
-static void s3c2410_pm_check_store(void)
-{
-       if (crcs != NULL)
-               s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
-}
-
-/* in_region
- *
- * return TRUE if the area defined by ptr..ptr+size contatins the
- * what..what+whatsz
-*/
-
-static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
-{
-       if ((what+whatsz) < ptr)
-               return 0;
-
-       if (what > (ptr+size))
-               return 0;
-
-       return 1;
-}
-
-static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
-{
-       void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
-       unsigned long addr;
-       unsigned long left;
-       void *ptr;
-       u32 calc;
-
-       for (addr = res->start; addr < res->end;
-            addr += CHECK_CHUNKSIZE) {
-               left = res->end - addr;
+       /* the RX3715 uses similar code and the same H1940 and the
+        * same offsets for resume and checksum pointers */
 
-               if (left > CHECK_CHUNKSIZE)
-                       left = CHECK_CHUNKSIZE;
+       if (machine_is_rx3715()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
 
-               ptr = phys_to_virt(addr);
+               /* generate check for the bootloader to check on resume */
 
-               if (in_region(ptr, left, crcs, crc_size)) {
-                       DBG("skipping %08lx, has crc block in\n", addr);
-                       goto skip_check;
-               }
+               for (ptr = 0; ptr < 0x40000; ptr += 0x4)
+                       calc += __raw_readl(base+ptr);
 
-               if (in_region(ptr, left, save_at, 32*4 )) {
-                       DBG("skipping %08lx, has save block in\n", addr);
-                       goto skip_check;
-               }
-
-               /* calculate and check the checksum */
-
-               calc = crc32_le(~0, ptr, left);
-               if (calc != *val) {
-                       printk(KERN_ERR PFX "Restore CRC error at "
-                              "%08lx (%08x vs %08x)\n", addr, calc, *val);
-
-                       DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
-                           addr, calc, *val);
-               }
-
-       skip_check:
-               val++;
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
        }
 
-       return val;
-}
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF2, 1);
 
-/* s3c2410_pm_check_restore
- *
- * check the CRCs after the restore event and free the memory used
- * to hold them
-*/
-
-static void s3c2410_pm_check_restore(void)
-{
-       if (crcs != NULL) {
-               s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
-               kfree(crcs);
-               crcs = NULL;
-       }
 }
 
-#else
-
-#define s3c2410_pm_check_prepare() do { } while(0)
-#define s3c2410_pm_check_restore() do { } while(0)
-#define s3c2410_pm_check_store()   do { } while(0)
-#endif
-
-/* helper functions to save and restore register state */
-
-void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
+static int s3c2410_pm_resume(struct sys_device *dev)
 {
-       for (; count > 0; count--, ptr++) {
-               ptr->val = __raw_readl(ptr->reg);
-               DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
-       }
-}
+       unsigned long tmp;
 
-/* s3c2410_pm_do_restore
- *
- * restore the system from the given list of saved registers
- *
- * Note, we do not use DBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
+       /* unset the return-from-sleep flag, to ensure reset */
 
-void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
-{
-       for (; count > 0; count--, ptr++) {
-               printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
-                      ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
-               __raw_writel(ptr->val, ptr->reg);
-       }
-}
+       tmp = __raw_readl(S3C2410_GSTATUS2);
+       tmp &= S3C2410_GSTATUS2_OFFRESET;
+       __raw_writel(tmp, S3C2410_GSTATUS2);
 
-/* s3c2410_pm_do_restore_core
- *
- * similar to s3c2410_pm_do_restore_core
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF2, 0);
 
-static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
-{
-       for (; count > 0; count--, ptr++) {
-               __raw_writel(ptr->val, ptr->reg);
-       }
+       return 0;
 }
 
-/* s3c2410_pm_show_resume_irqs
- *
- * print any IRQs asserted at resume time (ie, we woke from)
-*/
-
-static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
-                                       unsigned long mask)
+static int s3c2410_pm_add(struct sys_device *dev)
 {
-       int i;
+       pm_cpu_prep = s3c2410_pm_prepare;
+       pm_cpu_sleep = s3c2410_cpu_suspend;
 
-       which &= ~mask;
-
-       for (i = 0; i <= 31; i++) {
-               if ((which) & (1L<<i)) {
-                       DBG("IRQ %d asserted at resume\n", start+i);
-               }
-       }
+       return 0;
 }
 
-/* s3c2410_pm_check_resume_pin
- *
- * check to see if the pin is configured correctly for sleep mode, and
- * make any necessary adjustments if it is not
-*/
-
-static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
-{
-       unsigned long irqstate;
-       unsigned long pinstate;
-       int irq = s3c2410_gpio_getirq(pin);
-
-       if (irqoffs < 4)
-               irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
-       else
-               irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
-
-       pinstate = s3c2410_gpio_getcfg(pin);
-
-       if (!irqstate) {
-               if (pinstate == S3C2410_GPIO_IRQ)
-                       DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
-       } else {
-               if (pinstate == S3C2410_GPIO_IRQ) {
-                       DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
-                       s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
-               }
-       }
-}
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
+};
 
-/* s3c2410_pm_configure_extint
- *
- * configure all external interrupt pins
-*/
+/* register ourselves */
 
-static void s3c2410_pm_configure_extint(void)
+static int __init s3c2410_pm_drvinit(void)
 {
-       int pin;
-
-       /* for each of the external interrupts (EINT0..EINT15) we
-        * need to check wether it is an external interrupt source,
-        * and then configure it as an input if it is not
-       */
-
-       for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
-               s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
-       }
-
-       for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
-               s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
-       }
+       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
 }
 
-void (*pm_cpu_prep)(void);
-void (*pm_cpu_sleep)(void);
-
-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
-
-/* s3c2410_pm_enter
- *
- * central control for sleep/resume process
-*/
-
-static int s3c2410_pm_enter(suspend_state_t state)
-{
-       unsigned long regs_save[16];
-
-       /* ensure the debug is initialised (if enabled) */
-
-       s3c2410_pm_debug_init();
-
-       DBG("s3c2410_pm_enter(%d)\n", state);
-
-       if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
-               printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
-               return -EINVAL;
-       }
-
-       if (state != PM_SUSPEND_MEM) {
-               printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
-               return -EINVAL;
-       }
-
-       /* check if we have anything to wake-up with... bad things seem
-        * to happen if you suspend with no wakeup (system will often
-        * require a full power-cycle)
-       */
-
-       if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
-           !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
-               printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
-               printk(KERN_ERR PFX "Aborting sleep\n");
-               return -EINVAL;
-       }
-
-       /* prepare check area if configured */
-
-       s3c2410_pm_check_prepare();
-
-       /* store the physical address of the register recovery block */
-
-       s3c2410_sleep_save_phys = virt_to_phys(regs_save);
-
-       DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
-
-       /* save all necessary core registers not covered by the drivers */
-
-       s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
-       s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
-       s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
-
-       /* set the irq configuration for wake */
-
-       s3c2410_pm_configure_extint();
-
-       DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
-           s3c_irqwake_intmask, s3c_irqwake_eintmask);
-
-       __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
-       __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
-       /* ack any outstanding external interrupts before we go to sleep */
-
-       __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
-       __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
-       __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
-       /* call cpu specific preperation */
-
-       pm_cpu_prep();
-
-       /* flush cache back to ram */
-
-       flush_cache_all();
-
-       s3c2410_pm_check_store();
-
-       /* send the cpu to sleep... */
-
-       __raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
-
-       /* s3c2410_cpu_save will also act as our return point from when
-        * we resume as it saves its own register state, so use the return
-        * code to differentiate return from save and return from sleep */
-
-       if (s3c2410_cpu_save(regs_save) == 0) {
-               flush_cache_all();
-               pm_cpu_sleep();
-       }
-
-       /* restore the cpu state */
-
-       cpu_init();
-
-       /* restore the system state */
-
-       s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-       s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
-       s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
-
-       s3c2410_pm_debug_init();
-
-       /* check what irq (if any) restored the system */
-
-       DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
-           __raw_readl(S3C2410_SRCPND),
-           __raw_readl(S3C2410_EINTPEND));
-
-       s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
-                                   s3c_irqwake_intmask);
-
-       s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
-                                   s3c_irqwake_eintmask);
-
-       DBG("post sleep, preparing to return\n");
-
-       s3c2410_pm_check_restore();
-
-       /* ok, let's return from sleep */
+arch_initcall(s3c2410_pm_drvinit);
+#endif
 
-       DBG("S3C2410 PM Resume (post-restore)\n");
-       return 0;
-}
+#if defined(CONFIG_CPU_S3C2440)
+static struct sysdev_driver s3c2440_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
+};
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int s3c2410_pm_prepare(suspend_state_t state)
+static int __init s3c2440_pm_drvinit(void)
 {
-       return 0;
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
 }
 
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int s3c2410_pm_finish(suspend_state_t state)
-{
-       return 0;
-}
+arch_initcall(s3c2440_pm_drvinit);
+#endif
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
-static struct pm_ops s3c2410_pm_ops = {
-       .pm_disk_mode   = PM_DISK_FIRMWARE,
-       .prepare        = s3c2410_pm_prepare,
-       .enter          = s3c2410_pm_enter,
-       .finish         = s3c2410_pm_finish,
+#if defined(CONFIG_CPU_S3C2442)
+static struct sysdev_driver s3c2442_pm_driver = {
+       .add            = s3c2410_pm_add,
+       .resume         = s3c2410_pm_resume,
 };
 
-/* s3c2410_pm_init
- *
- * Attach the power management functions. This should be called
- * from the board specific initialisation if the board supports
- * it.
-*/
-
-int __init s3c2410_pm_init(void)
+static int __init s3c2442_pm_drvinit(void)
 {
-       printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
-
-       pm_set_ops(&s3c2410_pm_ops);
-       return 0;
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
 }
+
+arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c2410/pm.h b/arch/arm/mach-s3c2410/pm.h
deleted file mode 100644 (file)
index ffe197a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/pm.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * 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.
-*/
-
-/* s3c2410_pm_init
- *
- * called from board at initialisation time to setup the power
- * management
-*/
-
-#ifdef CONFIG_PM
-
-extern __init int s3c2410_pm_init(void);
-
-#else
-
-static inline int s3c2410_pm_init(void)
-{
-       return 0;
-}
-#endif
-
-/* configuration for the IRQ mask over sleep */
-extern unsigned long s3c_irqwake_intmask;
-extern unsigned long s3c_irqwake_eintmask;
-
-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
-extern unsigned long s3c_irqwake_intallow;
-extern unsigned long s3c_irqwake_eintallow;
-
-/* per-cpu sleep functions */
-
-extern void (*pm_cpu_prep)(void);
-extern void (*pm_cpu_sleep)(void);
-
-/* Flags for PM Control */
-
-extern unsigned long s3c_pm_flags;
-
-/* from sleep.S */
-
-extern int  s3c2410_cpu_save(unsigned long *saveblk);
-extern void s3c2410_cpu_suspend(void);
-extern void s3c2410_cpu_resume(void);
-
-extern unsigned long s3c2410_sleep_save_phys;
-
-/* sleep save info */
-
-struct sleep_save {
-       void __iomem    *reg;
-       unsigned long   val;
-};
-
-#define SAVE_ITEM(x) \
-       { .reg = (x) }
-
-extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
-extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
-
-#ifdef CONFIG_PM
-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
-extern int s3c24xx_irq_resume(struct sys_device *dev);
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume  NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2410/s3c2400-gpio.c
deleted file mode 100644 (file)
index 1576d01..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c
- *
- * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
- *
- * S3C2400 GPIO support
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-gpio.h>
-
-int s3c2400_gpio_getirq(unsigned int pin)
-{
-       if (pin < S3C2410_GPE0 || pin > S3C2400_GPE7_EINT7)
-               return -1;  /* not valid interrupts */
-
-       return (pin - S3C2410_GPE0) + IRQ_EINT0;
-}
-
-EXPORT_SYMBOL(s3c2400_gpio_getirq);
diff --git a/arch/arm/mach-s3c2410/s3c2400.h b/arch/arm/mach-s3c2410/s3c2400.h
deleted file mode 100644 (file)
index 8b2394e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c2400.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2400 cpu support
- *
- * 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.
- *
- * Modifications:
- *     09-Fev-2006 LCVR  First version, based on s3c2410.h
-*/
-
-#ifdef CONFIG_CPU_S3C2400
-
-extern  int s3c2400_init(void);
-
-extern void s3c2400_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c2400_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2400_init_clocks(int xtal);
-
-#else
-#define s3c2400_init_clocks NULL
-#define s3c2400_init_uarts NULL
-#define s3c2400_map_io NULL
-#define s3c2400_init NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
deleted file mode 100644 (file)
index 992cc6a..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410,S3C2440,S3C2442 Clock control support
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-
-#include <asm/mach/map.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "s3c2410.h"
-#include "clock.h"
-#include "cpu.h"
-
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
-{
-       unsigned int clocks = clk->ctrlbit;
-       unsigned long clkcon;
-
-       clkcon = __raw_readl(S3C2410_CLKCON);
-
-       if (enable)
-               clkcon |= clocks;
-       else
-               clkcon &= ~clocks;
-
-       /* ensure none of the special function bits set */
-       clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
-
-       __raw_writel(clkcon, S3C2410_CLKCON);
-
-       return 0;
-}
-
-static int s3c2410_upll_enable(struct clk *clk, int enable)
-{
-       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-       unsigned long orig = clkslow;
-
-       if (enable)
-               clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
-       else
-               clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
-
-       __raw_writel(clkslow, S3C2410_CLKSLOW);
-
-       /* if we started the UPLL, then allow to settle */
-
-       if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
-               udelay(200);
-
-       return 0;
-}
-
-/* standard clock definitions */
-
-static struct clk init_clocks_disable[] = {
-       {
-               .name           = "nand",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_NAND,
-       }, {
-               .name           = "sdi",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_SDI,
-       }, {
-               .name           = "adc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_ADC,
-       }, {
-               .name           = "i2c",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_IIC,
-       }, {
-               .name           = "iis",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_IIS,
-       }, {
-               .name           = "spi",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_SPI,
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "lcd",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_LCDC,
-       }, {
-               .name           = "gpio",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_GPIO,
-       }, {
-               .name           = "usb-host",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_USBH,
-       }, {
-               .name           = "usb-device",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_USBD,
-       }, {
-               .name           = "timers",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_PWMT,
-       }, {
-               .name           = "uart",
-               .id             = 0,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_UART0,
-       }, {
-               .name           = "uart",
-               .id             = 1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_UART1,
-       }, {
-               .name           = "uart",
-               .id             = 2,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_UART2,
-       }, {
-               .name           = "rtc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2410_clkcon_enable,
-               .ctrlbit        = S3C2410_CLKCON_RTC,
-       }, {
-               .name           = "watchdog",
-               .id             = -1,
-               .parent         = &clk_p,
-               .ctrlbit        = 0,
-       }, {
-               .name           = "usb-bus-host",
-               .id             = -1,
-               .parent         = &clk_usb_bus,
-       }, {
-               .name           = "usb-bus-gadget",
-               .id             = -1,
-               .parent         = &clk_usb_bus,
-       },
-};
-
-/* s3c2410_baseclk_add()
- *
- * Add all the clocks used by the s3c2410 or compatible CPUs
- * such as the S3C2440 and S3C2442.
- *
- * We cannot use a system device as we are needed before any
- * of the init-calls that initialise the devices are actually
- * done.
-*/
-
-int __init s3c2410_baseclk_add(void)
-{
-       unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-       struct clk *clkp;
-       struct clk *xtal;
-       int ret;
-       int ptr;
-
-       clk_upll.enable = s3c2410_upll_enable;
-
-       if (s3c24xx_register_clock(&clk_usb_bus) < 0)
-               printk(KERN_ERR "failed to register usb bus clock\n");
-
-       /* register clocks from clock array */
-
-       clkp = init_clocks;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-               /* ensure that we note the clock state */
-
-               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
-
-       /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
-        * their own DMA requests to the bus can cause the system to lockup
-        * if they where in the middle of requesting bus access.
-        *
-        * Disabling the LCD clock if the LCD is active is very dangerous,
-        * and therefore the bootloader should be careful to not enable
-        * the LCD clock if it is not needed.
-       */
-
-       /* install (and disable) the clocks we do not need immediately */
-
-       clkp = init_clocks_disable;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-
-               s3c2410_clkcon_enable(clkp, 0);
-       }
-
-       /* show the clock-slow value */
-
-       xtal = clk_get(NULL, "xtal");
-
-       printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
-              print_mhz(clk_get_rate(xtal) /
-                        ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
-              (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
-              (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
-              (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
-
-       return 0;
-}
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
deleted file mode 100644 (file)
index e67ba39..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-
-#include <asm/dma.h>
-#include <asm/arch/dma.h>
-#include "dma.h"
-
-#include "cpu.h"
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
-       },
-};
-
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
-       .select         = s3c2410_dma_select,
-       .dcon_mask      = 7 << 24,
-       .map            = s3c2410_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
-};
-
-static int s3c2410_dma_add(struct sys_device *sysdev)
-{
-       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct sysdev_driver s3c2410_dma_driver = {
-       .add    = s3c2410_dma_add,
-};
-
-static int __init s3c2410_dma_init(void)
-{
-       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
-}
-
-arch_initcall(s3c2410_dma_init);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct sysdev_driver s3c2442_dma_driver = {
-       .add    = s3c2410_dma_add,
-};
-
-static int __init s3c2442_dma_init(void)
-{
-       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
-}
-
-arch_initcall(s3c2442_dma_init);
-#endif
-
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
deleted file mode 100644 (file)
index ec3a276..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 GPIO support
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-gpio.h>
-
-int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
-                          unsigned int config)
-{
-       void __iomem *reg = S3C24XX_EINFLT0;
-       unsigned long flags;
-       unsigned long val;
-
-       if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
-               return -1;
-
-       config &= 0xff;
-
-       pin -= S3C2410_GPG8;
-       reg += pin & ~3;
-
-       local_irq_save(flags);
-
-       /* update filter width and clock source */
-
-       val = __raw_readl(reg);
-       val &= ~(0xff << ((pin & 3) * 8));
-       val |= config << ((pin & 3) * 8);
-       __raw_writel(val, reg);
-
-       /* update filter enable */
-
-       val = __raw_readl(S3C24XX_EXTINT2);
-       val &= ~(1 << ((pin * 4) + 3));
-       val |= on << ((pin * 4) + 3);
-       __raw_writel(val, S3C24XX_EXTINT2);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c
deleted file mode 100644 (file)
index c796c9c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/sysdev.h>
-
-#include "cpu.h"
-#include "pm.h"
-
-static int s3c2410_irq_add(struct sys_device *sysdev)
-{
-       return 0;
-}
-
-static struct sysdev_driver s3c2410_irq_driver = {
-       .add            = s3c2410_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
-};
-
-static int s3c2410_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
-}
-
-arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
deleted file mode 100644 (file)
index 8bb6e5e..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
- *
- * 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/init.h>
-#include <linux/suspend.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/sysdev.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/h1940.h>
-
-#include "cpu.h"
-#include "pm.h"
-
-#ifdef CONFIG_S3C2410_PM_DEBUG
-extern void pm_dbg(const char *fmt, ...);
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
-static void s3c2410_pm_prepare(void)
-{
-       /* ensure at least GSTATUS3 has the resume address */
-
-       __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
-
-       DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
-       DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
-
-       if (machine_is_h1940()) {
-               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-               unsigned long ptr;
-               unsigned long calc = 0;
-
-               /* generate check for the bootloader to check on resume */
-
-               for (ptr = 0; ptr < 0x40000; ptr += 0x400)
-                       calc += __raw_readl(base+ptr);
-
-               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-       }
-
-       /* the RX3715 uses similar code and the same H1940 and the
-        * same offsets for resume and checksum pointers */
-
-       if (machine_is_rx3715()) {
-               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-               unsigned long ptr;
-               unsigned long calc = 0;
-
-               /* generate check for the bootloader to check on resume */
-
-               for (ptr = 0; ptr < 0x40000; ptr += 0x4)
-                       calc += __raw_readl(base+ptr);
-
-               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-       }
-
-       if ( machine_is_aml_m5900() )
-               s3c2410_gpio_setpin(S3C2410_GPF2, 1);
-
-}
-
-static int s3c2410_pm_resume(struct sys_device *dev)
-{
-       unsigned long tmp;
-
-       /* unset the return-from-sleep flag, to ensure reset */
-
-       tmp = __raw_readl(S3C2410_GSTATUS2);
-       tmp &= S3C2410_GSTATUS2_OFFRESET;
-       __raw_writel(tmp, S3C2410_GSTATUS2);
-
-       if ( machine_is_aml_m5900() )
-               s3c2410_gpio_setpin(S3C2410_GPF2, 0);
-
-       return 0;
-}
-
-static int s3c2410_pm_add(struct sys_device *dev)
-{
-       pm_cpu_prep = s3c2410_pm_prepare;
-       pm_cpu_sleep = s3c2410_cpu_suspend;
-
-       return 0;
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct sysdev_driver s3c2410_pm_driver = {
-       .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
-};
-
-/* register ourselves */
-
-static int __init s3c2410_pm_drvinit(void)
-{
-       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
-}
-
-arch_initcall(s3c2410_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2440)
-static struct sysdev_driver s3c2440_pm_driver = {
-       .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
-};
-
-static int __init s3c2440_pm_drvinit(void)
-{
-       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
-}
-
-arch_initcall(s3c2440_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-static struct sysdev_driver s3c2442_pm_driver = {
-       .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
-};
-
-static int __init s3c2442_pm_drvinit(void)
-{
-       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
-}
-
-arch_initcall(s3c2442_pm_drvinit);
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S
deleted file mode 100644 (file)
index 9179a10..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 Power Manager (Suspend-To-RAM) support
- *
- * Based on PXA/SA1100 sleep code by:
- *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- *     Cliff Brake, (c) 2001
- *
- * 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/linkage.h>
-#include <asm/assembler.h>
-#include <asm/hardware.h>
-#include <asm/arch/map.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-serial.h>
-
-       /* s3c2410_cpu_suspend
-        *
-        * put the cpu into sleep mode
-       */
-
-ENTRY(s3c2410_cpu_suspend)
-       @@ prepare cpu to sleep
-
-       ldr     r4, =S3C2410_REFRESH
-       ldr     r5, =S3C24XX_MISCCR
-       ldr     r6, =S3C2410_CLKCON
-       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
-       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
-       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
-
-       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
-       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
-       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
-
-       teq     pc, #0                  @ first as a trial-run to load cache
-       bl      s3c2410_do_sleep
-       teq     r0, r0                  @ now do it for real
-       b       s3c2410_do_sleep        @
-
-       @@ align next bit of code to cache line
-       .align  8
-s3c2410_do_sleep:
-       streq   r7, [ r4 ]                      @ SDRAM sleep command
-       streq   r8, [ r5 ]                      @ SDRAM power-down config
-       streq   r9, [ r6 ]                      @ CPU sleep
-1:     beq     1b
-       mov     pc, r14
index 4cdc0d70c19f3fa6203440a6ea2f3082575c9861..1a86a9803753470acb87ea3476d30c9ece2a87d8 100644 (file)
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
 
 /* Initial IO mappings */
 
@@ -110,7 +110,7 @@ static struct sys_device s3c2410_sysdev = {
 
 /* need to register class before we actually register the device, and
  * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
+ * drivers even try to use it (even if not on an s3c2410 based system)
  * as a driver which may support both 2410 and 2440 may try and use it.
 */
 
diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h
deleted file mode 100644 (file)
index fbed084..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c2410.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 machine directory
- *
- * 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.
- *
-*/
-
-#ifdef CONFIG_CPU_S3C2410
-
-extern  int s3c2410_init(void);
-
-extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2410_init_clocks(int xtal);
-
-extern  int s3c2410_baseclk_add(void);
-
-#else
-#define s3c2410_init_clocks NULL
-#define s3c2410_init_uarts NULL
-#define s3c2410_map_io NULL
-#define s3c2410_init NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2412-clock.c b/arch/arm/mach-s3c2410/s3c2412-clock.c
deleted file mode 100644 (file)
index 8f94ad8..0000000
+++ /dev/null
@@ -1,716 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412,S3C2413 Clock control support
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-
-#include <asm/mach/map.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "s3c2412.h"
-#include "clock.h"
-#include "cpu.h"
-
-/* We currently have to assume that the system is running
- * from the XTPll input, and that all ***REFCLKs are being
- * fed from it, as we cannot read the state of OM[4] from
- * software.
- *
- * It would be possible for each board initialisation to
- * set the correct muxing at initialisation
-*/
-
-static int s3c2412_clkcon_enable(struct clk *clk, int enable)
-{
-       unsigned int clocks = clk->ctrlbit;
-       unsigned long clkcon;
-
-       clkcon = __raw_readl(S3C2410_CLKCON);
-
-       if (enable)
-               clkcon |= clocks;
-       else
-               clkcon &= ~clocks;
-
-       __raw_writel(clkcon, S3C2410_CLKCON);
-
-       return 0;
-}
-
-static int s3c2412_upll_enable(struct clk *clk, int enable)
-{
-       unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
-       unsigned long orig = upllcon;
-
-       if (!enable)
-               upllcon |= S3C2412_PLLCON_OFF;
-       else
-               upllcon &= ~S3C2412_PLLCON_OFF;
-
-       __raw_writel(upllcon, S3C2410_UPLLCON);
-
-       /* allow ~150uS for the PLL to settle and lock */
-
-       if (enable && (orig & S3C2412_PLLCON_OFF))
-               udelay(150);
-
-       return 0;
-}
-
-/* clock selections */
-
-/* CPU EXTCLK input */
-static struct clk clk_ext = {
-       .name           = "extclk",
-       .id             = -1,
-};
-
-static struct clk clk_erefclk = {
-       .name           = "erefclk",
-       .id             = -1,
-};
-
-static struct clk clk_urefclk = {
-       .name           = "urefclk",
-       .id             = -1,
-};
-
-static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_urefclk)
-               clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
-       else if (parent == &clk_upll)
-               clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static struct clk clk_usysclk = {
-       .name           = "usysclk",
-       .id             = -1,
-       .parent         = &clk_xtal,
-       .set_parent     = s3c2412_setparent_usysclk,
-};
-
-static struct clk clk_mrefclk = {
-       .name           = "mrefclk",
-       .parent         = &clk_xtal,
-       .id             = -1,
-};
-
-static struct clk clk_mdivclk = {
-       .name           = "mdivclk",
-       .parent         = &clk_xtal,
-       .id             = -1,
-};
-
-static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_usysclk)
-               clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
-       else if (parent == &clk_h)
-               clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       div = parent_rate / rate;
-       if (div > 2)
-               div = 2;
-
-       return parent_rate / div;
-}
-
-static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
-}
-
-static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_usbsrc(clk, rate);
-
-       if ((parent_rate / rate) == 2)
-               clkdivn |= S3C2412_CLKDIVN_USB48DIV;
-       else
-               clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_usbsrc = {
-       .name           = "usbsrc",
-       .id             = -1,
-       .get_rate       = s3c2412_getrate_usbsrc,
-       .set_rate       = s3c2412_setrate_usbsrc,
-       .round_rate     = s3c2412_roundrate_usbsrc,
-       .set_parent     = s3c2412_setparent_usbsrc,
-};
-
-static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_mdivclk)
-               clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
-       else if (parent == &clk_upll)
-               clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static struct clk clk_msysclk = {
-       .name           = "msysclk",
-       .id             = -1,
-       .set_parent     = s3c2412_setparent_msysclk,
-};
-
-/* these next clocks have an divider immediately after them,
- * so we can register them with their divider and leave out the
- * intermediate clock stage
-*/
-static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       /* note, we remove the +/- 1 calculations as they cancel out */
-
-       div = (rate / parent_rate);
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / div;
-}
-
-static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_erefclk)
-               clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
-       else if (parent == &clk_mpll)
-               clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_getrate_uart(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_UARTDIV_MASK;
-       div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_uart = {
-       .name           = "uartclk",
-       .id             = -1,
-       .get_rate       = s3c2412_getrate_uart,
-       .set_rate       = s3c2412_setrate_uart,
-       .set_parent     = s3c2412_setparent_uart,
-       .round_rate     = s3c2412_roundrate_clksrc,
-};
-
-static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_erefclk)
-               clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
-       else if (parent == &clk_mpll)
-               clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_getrate_i2s(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_I2SDIV_MASK;
-       div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_i2s = {
-       .name           = "i2sclk",
-       .id             = -1,
-       .get_rate       = s3c2412_getrate_i2s,
-       .set_rate       = s3c2412_setrate_i2s,
-       .set_parent     = s3c2412_setparent_i2s,
-       .round_rate     = s3c2412_roundrate_clksrc,
-};
-
-static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_usysclk)
-               clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
-       else if (parent == &clk_h)
-               clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-static unsigned long s3c2412_getrate_cam(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_CAMDIV_MASK;
-       div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_cam = {
-       .name           = "camif-upll", /* same as 2440 name */
-       .id             = -1,
-       .get_rate       = s3c2412_getrate_cam,
-       .set_rate       = s3c2412_setrate_cam,
-       .set_parent     = s3c2412_setparent_cam,
-       .round_rate     = s3c2412_roundrate_clksrc,
-};
-
-/* standard clock definitions */
-
-static struct clk init_clocks_disable[] = {
-       {
-               .name           = "nand",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_NAND,
-       }, {
-               .name           = "sdi",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_SDI,
-       }, {
-               .name           = "adc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_ADC,
-       }, {
-               .name           = "i2c",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_IIC,
-       }, {
-               .name           = "iis",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_IIS,
-       }, {
-               .name           = "spi",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_SPI,
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "dma",
-               .id             = 0,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA0,
-       }, {
-               .name           = "dma",
-               .id             = 1,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA1,
-       }, {
-               .name           = "dma",
-               .id             = 2,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA2,
-       }, {
-               .name           = "dma",
-               .id             = 3,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA3,
-       }, {
-               .name           = "lcd",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_LCDC,
-       }, {
-               .name           = "gpio",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_GPIO,
-       }, {
-               .name           = "usb-host",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USBH,
-       }, {
-               .name           = "usb-device",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USBD,
-       }, {
-               .name           = "timers",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_PWMT,
-       }, {
-               .name           = "uart",
-               .id             = 0,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART0,
-       }, {
-               .name           = "uart",
-               .id             = 1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART1,
-       }, {
-               .name           = "uart",
-               .id             = 2,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART2,
-       }, {
-               .name           = "rtc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_RTC,
-       }, {
-               .name           = "watchdog",
-               .id             = -1,
-               .parent         = &clk_p,
-               .ctrlbit        = 0,
-       }, {
-               .name           = "usb-bus-gadget",
-               .id             = -1,
-               .parent         = &clk_usb_bus,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USB_DEV48,
-       }, {
-               .name           = "usb-bus-host",
-               .id             = -1,
-               .parent         = &clk_usb_bus,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USB_HOST48,
-       }
-};
-
-/* clocks to add where we need to check their parentage */
-
-struct clk_init {
-       struct clk      *clk;
-       unsigned int     bit;
-       struct clk      *src_0;
-       struct clk      *src_1;
-};
-
-static struct clk_init clks_src[] __initdata = {
-       {
-               .clk    = &clk_usysclk,
-               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
-               .src_0  = &clk_urefclk,
-               .src_1  = &clk_upll,
-       }, {
-               .clk    = &clk_i2s,
-               .bit    = S3C2412_CLKSRC_I2SCLK_MPLL,
-               .src_0  = &clk_erefclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_cam,
-               .bit    = S3C2412_CLKSRC_CAMCLK_HCLK,
-               .src_0  = &clk_usysclk,
-               .src_1  = &clk_h,
-       }, {
-               .clk    = &clk_msysclk,
-               .bit    = S3C2412_CLKSRC_MSYSCLK_MPLL,
-               .src_0  = &clk_mdivclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_uart,
-               .bit    = S3C2412_CLKSRC_UARTCLK_MPLL,
-               .src_0  = &clk_erefclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_usbsrc,
-               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
-               .src_0  = &clk_usysclk,
-               .src_1  = &clk_h,
-       },
-};
-
-/* s3c2412_clk_initparents
- *
- * Initialise the parents for the clocks that we get at start-time
-*/
-
-static void __init s3c2412_clk_initparents(void)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-       struct clk_init *cip = clks_src;
-       struct clk *src;
-       int ptr;
-       int ret;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
-               ret = s3c24xx_register_clock(cip->clk);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              cip->clk->name, ret);
-               }
-
-               src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
-
-               printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
-               clk_set_parent(cip->clk, src);
-       }
-}
-
-/* clocks to add straight away */
-
-static struct clk *clks[] __initdata = {
-       &clk_ext,
-       &clk_usb_bus,
-       &clk_erefclk,
-       &clk_urefclk,
-       &clk_mrefclk,
-};
-
-int __init s3c2412_baseclk_add(void)
-{
-       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-       struct clk *clkp;
-       int ret;
-       int ptr;
-
-       clk_upll.enable = s3c2412_upll_enable;
-       clk_usb_bus.parent = &clk_usbsrc;
-       clk_usb_bus.rate = 0x0;
-
-       s3c2412_clk_initparents();
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
-               clkp = clks[ptr];
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
-
-       /* ensure usb bus clock is within correct rate of 48MHz */
-
-       if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
-               printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
-
-               /* for the moment, let's use the UPLL, and see if we can
-                * get 48MHz */
-
-               clk_set_parent(&clk_usysclk, &clk_upll);
-               clk_set_parent(&clk_usbsrc, &clk_usysclk);
-               clk_set_rate(&clk_usbsrc, 48*1000*1000);
-       }
-
-       printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
-              (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
-              print_mhz(clk_get_rate(&clk_upll)),
-              print_mhz(clk_get_rate(&clk_usb_bus)));
-
-       /* register clocks from clock array */
-
-       clkp = init_clocks;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-               /* ensure that we note the clock state */
-
-               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
-
-       /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
-        * their own DMA requests to the bus can cause the system to lockup
-        * if they where in the middle of requesting bus access.
-        *
-        * Disabling the LCD clock if the LCD is active is very dangerous,
-        * and therefore the bootloader should be careful to not enable
-        * the LCD clock if it is not needed.
-       */
-
-       /* install (and disable) the clocks we do not need immediately */
-
-       clkp = init_clocks_disable;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-
-               s3c2412_clkcon_enable(clkp, 0);
-       }
-
-       return 0;
-}
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2410/s3c2412-dma.c
deleted file mode 100644 (file)
index 138f726..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-
-#include <asm/dma.h>
-#include <asm/arch/dma.h>
-#include <asm/io.h>
-
-#include "dma.h"
-#include "cpu.h"
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
-
-#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
-
-static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
-       },
-       [DMACH_UART0_SRC2] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
-       },
-       [DMACH_UART1_SRC2] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
-       },
-       [DMACH_UART2_SRC2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
-       },
-};
-
-static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       writel(map->channels[0] | S3C2412_DMAREQSEL_HW,
-              chan->regs + S3C2412_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
-       .select         = s3c2412_dma_select,
-       .dcon_mask      = 0,
-       .map            = s3c2412_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
-};
-
-static int s3c2412_dma_add(struct sys_device *sysdev)
-{
-       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
-}
-
-static struct sysdev_driver s3c2412_dma_driver = {
-       .add    = s3c2412_dma_add,
-};
-
-static int __init s3c2412_dma_init(void)
-{
-       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
-}
-
-arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c
deleted file mode 100644 (file)
index ffcc30b..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/s3c2412-irq.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/sysdev.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/mach/irq.h>
-
-#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "cpu.h"
-#include "irq.h"
-#include "pm.h"
-
-/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
- * having them turn up in both the INT* and the EINT* registers. Whilst
- * both show the status, they both now need to be acked when the IRQs
- * go off.
-*/
-
-static void
-s3c2412_irq_mask(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask | bitval, S3C2410_INTMSK);
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask | bitval, S3C2412_EINTMASK);
-}
-
-static inline void
-s3c2412_irq_ack(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-
-       __raw_writel(bitval, S3C2412_EINTPEND);
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-static inline void
-s3c2412_irq_maskack(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask|bitval, S3C2410_INTMSK);
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask | bitval, S3C2412_EINTMASK);
-
-       __raw_writel(bitval, S3C2412_EINTPEND);
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-static void
-s3c2412_irq_unmask(unsigned int irqno)
-{
-       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask & ~bitval, S3C2410_INTMSK);
-}
-
-static struct irq_chip s3c2412_irq_eint0t4 = {
-       .ack       = s3c2412_irq_ack,
-       .mask      = s3c2412_irq_mask,
-       .unmask    = s3c2412_irq_unmask,
-       .set_wake  = s3c_irq_wake,
-       .set_type  = s3c_irqext_type,
-};
-
-static int s3c2412_irq_add(struct sys_device *sysdev)
-{
-       unsigned int irqno;
-
-       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-               set_irq_chip(irqno, &s3c2412_irq_eint0t4);
-               set_irq_handler(irqno, handle_edge_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static struct sysdev_driver s3c2412_irq_driver = {
-       .add            = s3c2412_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
-};
-
-static int s3c2412_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_irq_driver);
-}
-
-arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2410/s3c2412-pm.c
deleted file mode 100644 (file)
index 19b6332..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/.
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/platform_device.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-power.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-dsc.h>
-
-#include "cpu.h"
-#include "pm.h"
-
-#include "s3c2412.h"
-
-static void s3c2412_cpu_suspend(void)
-{
-       unsigned long tmp;
-
-       /* set our standby method to sleep */
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       /* issue the standby signal into the pm unit. Note, we
-        * issue a write-buffer drain just in case */
-
-       tmp = 0;
-
-       asm("b 1f\n\t"
-           ".align 5\n\t"
-           "1:\n\t"
-           "mcr p15, 0, %0, c7, c10, 4\n\t"
-           "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
-
-       /* we should never get past here */
-
-       panic("sleep resumed to originator?");
-}
-
-static void s3c2412_pm_prepare(void)
-{
-}
-
-static int s3c2412_pm_add(struct sys_device *sysdev)
-{
-       pm_cpu_prep = s3c2412_pm_prepare;
-       pm_cpu_sleep = s3c2412_cpu_suspend;
-
-       return 0;
-}
-
-static struct sleep_save s3c2412_sleep[] = {
-       SAVE_ITEM(S3C2412_DSC0),
-       SAVE_ITEM(S3C2412_DSC1),
-       SAVE_ITEM(S3C2413_GPJDAT),
-       SAVE_ITEM(S3C2413_GPJCON),
-       SAVE_ITEM(S3C2413_GPJUP),
-
-       /* save the PWRCFG to get back to original sleep method */
-
-       SAVE_ITEM(S3C2412_PWRCFG),
-
-       /* save the sleep configuration anyway, just in case these
-        * get damaged during wakeup */
-
-       SAVE_ITEM(S3C2412_GPBSLPCON),
-       SAVE_ITEM(S3C2412_GPCSLPCON),
-       SAVE_ITEM(S3C2412_GPDSLPCON),
-       SAVE_ITEM(S3C2412_GPESLPCON),
-       SAVE_ITEM(S3C2412_GPFSLPCON),
-       SAVE_ITEM(S3C2412_GPGSLPCON),
-       SAVE_ITEM(S3C2412_GPHSLPCON),
-       SAVE_ITEM(S3C2413_GPJSLPCON),
-};
-
-static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
-{
-       s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
-}
-
-static int s3c2412_pm_resume(struct sys_device *dev)
-{
-       unsigned long tmp;
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
-       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
-}
-
-static struct sysdev_driver s3c2412_pm_driver = {
-       .add            = s3c2412_pm_add,
-       .suspend        = s3c2412_pm_suspend,
-       .resume         = s3c2412_pm_resume,
-};
-
-static __init int s3c2412_pm_init(void)
-{
-       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
-}
-
-arch_initcall(s3c2412_pm_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
deleted file mode 100644 (file)
index 2f651a8..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2412.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/.
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/proc-fns.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/idle.h>
-
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-power.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
-
-#include "s3c2412.h"
-#include "cpu.h"
-#include "devs.h"
-#include "clock.h"
-#include "pm.h"
-
-#ifndef CONFIG_CPU_S3C2412_ONLY
-void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
-
-static inline void s3c2412_init_gpio2(void)
-{
-       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
-}
-#else
-#define s3c2412_init_gpio2() do { } while(0)
-#endif
-
-/* Initial IO mappings */
-
-static struct map_desc s3c2412_iodesc[] __initdata = {
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(LCD),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(WATCHDOG),
-};
-
-/* uart registration process */
-
-void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
-
-       /* rename devices that are s3c2412/s3c2413 specific */
-       s3c_device_sdi.name  = "s3c2412-sdi";
-       s3c_device_lcd.name  = "s3c2412-lcd";
-       s3c_device_nand.name = "s3c2412-nand";
-}
-
-/* s3c2412_idle
- *
- * use the standard idle call by ensuring the idle mode
- * in power config, then issuing the idle co-processor
- * instruction
-*/
-
-static void s3c2412_idle(void)
-{
-       unsigned long tmp;
-
-       /* ensure our idle mode is to go to idle */
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
-       tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       cpu_do_idle();
-}
-
-/* s3c2412_map_io
- *
- * register the standard cpu IO areas, and any passed in from the
- * machine specific initialisation.
-*/
-
-void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
-{
-       /* move base of IO */
-
-       s3c2412_init_gpio2();
-
-       /* set our idle function */
-
-       s3c24xx_idle = s3c2412_idle;
-
-       /* register our io-tables */
-
-       iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
-       iotable_init(mach_desc, mach_size);
-}
-
-void __init s3c2412_init_clocks(int xtal)
-{
-       unsigned long tmp;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long pclk;
-
-       /* now we've got our machine bits initialised, work out what
-        * clocks we've got */
-
-       fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
-
-       tmp = __raw_readl(S3C2410_CLKDIVN);
-
-       /* work out clock scalings */
-
-       hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
-       hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1);
-       pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
-
-       /* print brieft summary of clocks, etc */
-
-       printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-       /* initialise the clocks here, to allow other things like the
-        * console to use them
-        */
-
-       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
-       s3c2412_baseclk_add();
-}
-
-/* need to register class before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2412 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-struct sysdev_class s3c2412_sysclass = {
-       set_kset_name("s3c2412-core"),
-};
-
-static int __init s3c2412_core_init(void)
-{
-       return sysdev_class_register(&s3c2412_sysclass);
-}
-
-core_initcall(s3c2412_core_init);
-
-static struct sys_device s3c2412_sysdev = {
-       .cls            = &s3c2412_sysclass,
-};
-
-int __init s3c2412_init(void)
-{
-       printk("S3C2412: Initialising architecture\n");
-
-       return sysdev_register(&s3c2412_sysdev);
-}
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/arch/arm/mach-s3c2410/s3c2412.h
deleted file mode 100644 (file)
index c6e5603..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c2412.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2412 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2412
-
-extern  int s3c2412_init(void);
-
-extern void s3c2412_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2412_init_clocks(int xtal);
-
-extern  int s3c2412_baseclk_add(void);
-#else
-#define s3c2412_init_clocks NULL
-#define s3c2412_init_uarts NULL
-#define s3c2412_map_io NULL
-#define s3c2412_init NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c
deleted file mode 100644 (file)
index ba13c1d..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 Clock support
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-
-#include <asm/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-clock.h>
-
-#include "clock.h"
-#include "cpu.h"
-
-/* S3C2440 extended clock support */
-
-static unsigned long s3c2440_camif_upll_round(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       /* note, we remove the +/- 1 calculations for the divisor */
-
-       div = (parent_rate / rate) / 2;
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / (div * 2);
-}
-
-static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-       rate = s3c2440_camif_upll_round(clk, rate);
-
-       camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
-
-       if (rate != parent_rate) {
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= (((parent_rate / rate) / 2) - 1);
-       }
-
-       __raw_writel(camdivn, S3C2440_CAMDIVN);
-
-       return 0;
-}
-
-/* Extra S3C2440 clocks */
-
-static struct clk s3c2440_clk_cam = {
-       .name           = "camif",
-       .id             = -1,
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2440_clk_cam_upll = {
-       .name           = "camif-upll",
-       .id             = -1,
-       .set_rate       = s3c2440_camif_upll_setrate,
-       .round_rate     = s3c2440_camif_upll_round,
-};
-
-static struct clk s3c2440_clk_ac97 = {
-       .name           = "ac97",
-       .id             = -1,
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static int s3c2440_clk_add(struct sys_device *sysdev)
-{
-       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-       unsigned long clkdivn;
-       struct clk *clock_h;
-       struct clk *clock_p;
-       struct clk *clock_upll;
-
-       printk("S3C2440: Clock Support, DVS %s\n",
-              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-       clock_p = clk_get(NULL, "pclk");
-       clock_h = clk_get(NULL, "hclk");
-       clock_upll = clk_get(NULL, "upll");
-
-       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-               printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
-               return -EINVAL;
-       }
-
-       /* check rate of UPLL, and if it is near 96MHz, then change
-        * to using half the UPLL rate for the system */
-
-       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-               mutex_lock(&clocks_mutex);
-
-               clkdivn = __raw_readl(S3C2410_CLKDIVN);
-               clkdivn |= S3C2440_CLKDIVN_UCLK;
-               __raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-               mutex_unlock(&clocks_mutex);
-       }
-
-       s3c2440_clk_cam.parent = clock_h;
-       s3c2440_clk_ac97.parent = clock_p;
-       s3c2440_clk_cam_upll.parent = clock_upll;
-
-       s3c24xx_register_clock(&s3c2440_clk_ac97);
-       s3c24xx_register_clock(&s3c2440_clk_cam);
-       s3c24xx_register_clock(&s3c2440_clk_cam_upll);
-
-       clk_disable(&s3c2440_clk_ac97);
-       clk_disable(&s3c2440_clk_cam);
-
-       return 0;
-}
-
-static struct sysdev_driver s3c2440_clk_driver = {
-       .add    = s3c2440_clk_add,
-};
-
-static __init int s3c24xx_clk_driver(void)
-{
-       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
-}
-
-arch_initcall(s3c24xx_clk_driver);
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2410/s3c2440-dma.c
deleted file mode 100644 (file)
index 47b861b..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sysdev.h>
-#include <linux/serial_core.h>
-
-#include <asm/dma.h>
-#include <asm/arch/dma.h>
-#include "dma.h"
-
-#include "cpu.h"
-
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
-#include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-lcd.h>
-#include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
-               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
-               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
-               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
-       },
-       [DMACH_PCM_IN] = {
-               .name           = "pcm-in",
-               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
-               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
-       },
-       [DMACH_PCM_OUT] = {
-               .name           = "pcm-out",
-               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
-               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
-               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
-       },
-       [DMACH_MIC_IN] = {
-               .name           = "mic-in",
-               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
-               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
-               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
-       },
-};
-
-static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
-       .select         = s3c2440_dma_select,
-       .dcon_mask      = 7 << 24,
-       .map            = s3c2440_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
-};
-
-static int s3c2440_dma_add(struct sys_device *sysdev)
-{
-       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
-}
-
-static struct sysdev_driver s3c2440_dma_driver = {
-       .add    = s3c2440_dma_add,
-};
-
-static int __init s3c2440_dma_init(void)
-{
-       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver);
-}
-
-arch_initcall(s3c2440_dma_init);
-
diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c
deleted file mode 100644 (file)
index c92ea66..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 Drive Strength Control support
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-dsc.h>
-
-#include "cpu.h"
-#include "s3c2440.h"
-
-int s3c2440_set_dsc(unsigned int pin, unsigned int value)
-{
-       void __iomem *base;
-       unsigned long val;
-       unsigned long flags;
-       unsigned long mask;
-
-       base = (pin & S3C2440_SELECT_DSC1) ? S3C2440_DSC1 : S3C2440_DSC0;
-       mask = 3 << S3C2440_DSC_GETSHIFT(pin);
-
-       local_irq_save(flags);
-
-       val = __raw_readl(base);
-       val &= ~mask;
-       val |= value & mask;
-       __raw_writel(val, base);
-
-       local_irq_restore(flags);
-       return 0;
-}
-
-EXPORT_SYMBOL(s3c2440_set_dsc);
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
deleted file mode 100644 (file)
index 1ba19b2..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
- *
- * Copyright (c) 2003,2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/sysdev.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/mach/irq.h>
-
-#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
-
-/* WDT/AC97 */
-
-static void s3c_irq_demux_wdtac97(unsigned int irq,
-                                 struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-       struct irq_desc *mydesc;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc &= ~submsk;
-       subsrc >>= 13;
-       subsrc &= 3;
-
-       if (subsrc != 0) {
-               if (subsrc & 1) {
-                       mydesc = irq_desc + IRQ_S3C2440_WDT;
-                       desc_handle_irq(IRQ_S3C2440_WDT, mydesc);
-               }
-               if (subsrc & 2) {
-                       mydesc = irq_desc + IRQ_S3C2440_AC97;
-                       desc_handle_irq(IRQ_S3C2440_AC97, mydesc);
-               }
-       }
-}
-
-
-#define INTMSK_WDT      (1UL << (IRQ_WDT - IRQ_EINT0))
-
-static void
-s3c_irq_wdtac97_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
-}
-
-static void
-s3c_irq_wdtac97_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_WDT);
-}
-
-static void
-s3c_irq_wdtac97_ack(unsigned int irqno)
-{
-       s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
-}
-
-static struct irq_chip s3c_irq_wdtac97 = {
-       .mask       = s3c_irq_wdtac97_mask,
-       .unmask     = s3c_irq_wdtac97_unmask,
-       .ack        = s3c_irq_wdtac97_ack,
-};
-
-static int s3c2440_irq_add(struct sys_device *sysdev)
-{
-       unsigned int irqno;
-
-       printk("S3C2440: IRQ Support\n");
-
-       /* add new chained handler for wdt, ac7 */
-
-       set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
-       set_irq_handler(IRQ_WDT, handle_level_irq);
-       set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
-
-       for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
-               set_irq_chip(irqno, &s3c_irq_wdtac97);
-               set_irq_handler(irqno, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static struct sysdev_driver s3c2440_irq_driver = {
-       .add            = s3c2440_irq_add,
-};
-
-static int s3c2440_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
-}
-
-arch_initcall(s3c2440_irq_init);
-
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
deleted file mode 100644 (file)
index 344eb27..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2440.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 Mobile CPU support
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "s3c2440.h"
-#include "devs.h"
-#include "cpu.h"
-
-static struct sys_device s3c2440_sysdev = {
-       .cls            = &s3c2440_sysclass,
-};
-
-int __init s3c2440_init(void)
-{
-       printk("S3C2440: Initialising architecture\n");
-
-       /* change irq for watchdog */
-
-       s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
-       s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
-
-       /* register our system device for everything else */
-
-       return sysdev_register(&s3c2440_sysdev);
-}
diff --git a/arch/arm/mach-s3c2410/s3c2440.h b/arch/arm/mach-s3c2410/s3c2440.h
deleted file mode 100644 (file)
index dcd3160..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c2440.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2440 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-#else
-#define s3c2440_init NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2410/s3c2442-clock.c
deleted file mode 100644 (file)
index 4e292ca..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2442 Clock support
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-
-#include <asm/hardware.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/arch/regs-clock.h>
-
-#include "clock.h"
-#include "cpu.h"
-
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       div = parent_rate / rate;
-
-       if (div == 3)
-               return parent_rate / 3;
-
-       /* note, we remove the +/- 1 calculations for the divisor */
-
-       div /= 2;
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-       rate = s3c2442_camif_upll_round(clk, rate);
-
-       camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
-       if (rate == parent_rate) {
-               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
-       } else if ((parent_rate / rate) == 3) {
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
-       } else {
-               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= (((parent_rate / rate) / 2) - 1);
-       }
-
-       __raw_writel(camdivn, S3C2440_CAMDIVN);
-
-       return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
-       .name           = "camif",
-       .id             = -1,
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
-       .name           = "camif-upll",
-       .id             = -1,
-       .set_rate       = s3c2442_camif_upll_setrate,
-       .round_rate     = s3c2442_camif_upll_round,
-};
-
-static int s3c2442_clk_add(struct sys_device *sysdev)
-{
-       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-       unsigned long clkdivn;
-       struct clk *clock_h;
-       struct clk *clock_p;
-       struct clk *clock_upll;
-
-       printk("S3C2442: Clock Support, DVS %s\n",
-              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-       clock_p = clk_get(NULL, "pclk");
-       clock_h = clk_get(NULL, "hclk");
-       clock_upll = clk_get(NULL, "upll");
-
-       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-               printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
-               return -EINVAL;
-       }
-
-       /* check rate of UPLL, and if it is near 96MHz, then change
-        * to using half the UPLL rate for the system */
-
-       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-               mutex_lock(&clocks_mutex);
-
-               clkdivn = __raw_readl(S3C2410_CLKDIVN);
-               clkdivn |= S3C2440_CLKDIVN_UCLK;
-               __raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-               mutex_unlock(&clocks_mutex);
-       }
-
-       s3c2442_clk_cam.parent = clock_h;
-       s3c2442_clk_cam_upll.parent = clock_upll;
-
-       s3c24xx_register_clock(&s3c2442_clk_cam);
-       s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
-       clk_disable(&s3c2442_clk_cam);
-
-       return 0;
-}
-
-static struct sysdev_driver s3c2442_clk_driver = {
-       .add    = s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
-       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2410/s3c2442.c
deleted file mode 100644 (file)
index 428732e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2442.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2442 Mobile CPU support
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/sysdev.h>
-
-#include "s3c2442.h"
-#include "cpu.h"
-
-static struct sys_device s3c2442_sysdev = {
-       .cls            = &s3c2442_sysclass,
-};
-
-int __init s3c2442_init(void)
-{
-       printk("S3C2442: Initialising architecture\n");
-
-       return sysdev_register(&s3c2442_sysdev);
-}
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/arch/arm/mach-s3c2410/s3c2442.h
deleted file mode 100644 (file)
index 0ae37d2..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c2442.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2442 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2442
-extern  int s3c2442_init(void);
-#else
-#define s3c2442_init NULL
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
deleted file mode 100644 (file)
index ede9463..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c
- *
- * Copyright (c) 2003,2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * 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/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/sysdev.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/mach/irq.h>
-
-#include <asm/arch/regs-irq.h>
-#include <asm/arch/regs-gpio.h>
-
-#include "cpu.h"
-#include "pm.h"
-#include "irq.h"
-
-/* camera irq */
-
-static void s3c_irq_demux_cam(unsigned int irq,
-                             struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-       struct irq_desc *mydesc;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc &= ~submsk;
-       subsrc >>= 11;
-       subsrc &= 3;
-
-       if (subsrc != 0) {
-               if (subsrc & 1) {
-                       mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-                       desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc);
-               }
-               if (subsrc & 2) {
-                       mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-                       desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc);
-               }
-       }
-}
-
-#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
-
-static void
-s3c_irq_cam_mask(unsigned int irqno)
-{
-       s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
-}
-
-static void
-s3c_irq_cam_unmask(unsigned int irqno)
-{
-       s3c_irqsub_unmask(irqno, INTMSK_CAM);
-}
-
-static void
-s3c_irq_cam_ack(unsigned int irqno)
-{
-       s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
-}
-
-static struct irq_chip s3c_irq_cam = {
-       .mask       = s3c_irq_cam_mask,
-       .unmask     = s3c_irq_cam_unmask,
-       .ack        = s3c_irq_cam_ack,
-};
-
-static int s3c244x_irq_add(struct sys_device *sysdev)
-{
-       unsigned int irqno;
-
-       set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
-       set_irq_handler(IRQ_NFCON, handle_level_irq);
-       set_irq_flags(IRQ_NFCON, IRQF_VALID);
-
-       /* add chained handler for camera */
-
-       set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
-       set_irq_handler(IRQ_CAM, handle_level_irq);
-       set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
-
-       for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
-               set_irq_chip(irqno, &s3c_irq_cam);
-               set_irq_handler(irqno, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static struct sysdev_driver s3c2440_irq_driver = {
-       .add            = s3c244x_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
-};
-
-static int s3c2440_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
-}
-
-arch_initcall(s3c2440_irq_init);
-
-static struct sysdev_driver s3c2442_irq_driver = {
-       .add            = s3c244x_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
-};
-
-
-static int s3c2442_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
-}
-
-arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/mach-s3c2410/s3c244x.c
deleted file mode 100644 (file)
index 23c7494..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c244x.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 and S3C2442 Mobile CPU support
- *
- * 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 <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/clk.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-gpioj.h>
-#include <asm/arch/regs-dsc.h>
-
-#include "s3c2410.h"
-#include "s3c2440.h"
-#include "s3c244x.h"
-#include "clock.h"
-#include "devs.h"
-#include "cpu.h"
-#include "pm.h"
-
-static struct map_desc s3c244x_iodesc[] __initdata = {
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(WATCHDOG),
-       IODESC_ENT(LCD),
-};
-
-/* uart initialisation */
-
-void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-}
-
-void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
-{
-       /* register our io-tables */
-
-       iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
-       iotable_init(mach_desc, size);
-
-       /* rename any peripherals used differing from the s3c2410 */
-
-       s3c_device_i2c.name  = "s3c2440-i2c";
-       s3c_device_nand.name = "s3c2440-nand";
-       s3c_device_usbgadget.name = "s3c2440-usbgadget";
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
-       unsigned long clkdiv;
-       unsigned long camdiv;
-       unsigned long hclk, fclk, pclk;
-       int hdiv = 1;
-
-       /* now we've got our machine bits initialised, work out what
-        * clocks we've got */
-
-       fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
-       clkdiv = __raw_readl(S3C2410_CLKDIVN);
-       camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-       /* work out clock scalings */
-
-       switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
-       case S3C2440_CLKDIVN_HDIVN_1:
-               hdiv = 1;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_2:
-               hdiv = 2;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_4_8:
-               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_3_6:
-               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
-               break;
-       }
-
-       hclk = fclk / hdiv;
-       pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
-
-       /* print brief summary of clocks, etc */
-
-       printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-       /* initialise the clocks here, to allow other things like the
-        * console to use them, and to add new ones after the initialisation
-        */
-
-       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
-       s3c2410_baseclk_add();
-}
-
-#ifdef CONFIG_PM
-
-static struct sleep_save s3c244x_sleep[] = {
-       SAVE_ITEM(S3C2440_DSC0),
-       SAVE_ITEM(S3C2440_DSC1),
-       SAVE_ITEM(S3C2440_GPJDAT),
-       SAVE_ITEM(S3C2440_GPJCON),
-       SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
-{
-       s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-       return 0;
-}
-
-static int s3c244x_resume(struct sys_device *dev)
-{
-       s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-       return 0;
-}
-
-#else
-#define s3c244x_suspend NULL
-#define s3c244x_resume  NULL
-#endif
-
-/* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
-
-struct sysdev_class s3c2440_sysclass = {
-       set_kset_name("s3c2440-core"),
-       .suspend        = s3c244x_suspend,
-       .resume         = s3c244x_resume
-};
-
-struct sysdev_class s3c2442_sysclass = {
-       set_kset_name("s3c2442-core"),
-       .suspend        = s3c244x_suspend,
-       .resume         = s3c244x_resume
-};
-
-/* need to register class before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2440_core_init(void)
-{
-       return sysdev_class_register(&s3c2440_sysclass);
-}
-
-core_initcall(s3c2440_core_init);
-
-static int __init s3c2442_core_init(void)
-{
-       return sysdev_class_register(&s3c2442_sysclass);
-}
-
-core_initcall(s3c2442_core_init);
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/mach-s3c2410/s3c244x.h
deleted file mode 100644 (file)
index 1488c1e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* arch/arm/mach-s3c2410/s3c244x.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2440 and S3C2442 cpu support
- *
- * 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.
-*/
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
-
-extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c244x_init_clocks(int xtal);
-
-#else
-#define s3c244x_init_clocks NULL
-#define s3c244x_init_uarts NULL
-#define s3c244x_map_io NULL
-#endif
index 2018c2e1dcc5aecc97a9c9ec1825fc3c6b2fc29c..637aaba653901a23f640edfdfa7c2569c0a41c93 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-s3c2410/sleep.S
+/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
  *
  * Copyright (c) 2004 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-serial.h>
 
-/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
- * reset the UART configuration, only enable if you really need this!
-*/
-//#define CONFIG_DEBUG_RESUME
-
-       .text
-
-       /* s3c2410_cpu_save
-        *
-        * save enough of the CPU state to allow us to re-start
-        * pm.c code. as we store items like the sp/lr, we will
-        * end up returning from this function when the cpu resumes
-        * so the return value is set to mark this.
-        *
-        * This arangement means we avoid having to flush the cache
-        * from this code.
-        *
-        * entry:
-        *      r0 = pointer to save block
-        *
-        * exit:
-        *      r0 = 0 => we stored everything
-        *           1 => resumed from sleep
-       */
-
-ENTRY(s3c2410_cpu_save)
-       stmfd   sp!, { r4 - r12, lr }
-
-       @@ store co-processor registers
-
-       mrc     p15, 0, r4, c15, c1, 0  @ CP access register
-       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 address
-       mrc     p15, 0, r8, c1, c0, 0   @ control register
-
-       stmia   r0, { r4 - r13 }
-
-       mov     r0, #0
-       ldmfd   sp, { r4 - r12, pc }
-
-       @@ return to the caller, after having the MMU
-       @@ turned on, this restores the last bits from the
-       @@ stack
-resume_with_mmu:
-       mov     r0, #1
-       ldmfd   sp!, { r4 - r12, pc }
-
-       .ltorg
-
-       @@ the next bits sit in the .data segment, even though they
-       @@ happen to be code... the s3c2410_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 s3c2410_sleep_save_phys
-s3c2410_sleep_save_phys:
-       .word   0
-
-       /* s3c2410_cpu_resume
+       /* s3c2410_cpu_suspend
         *
-        * 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)
+        * put the cpu into sleep mode
        */
 
-ENTRY(s3c2410_cpu_resume)
-       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
-       msr     cpsr_c, r0
-
-       @@ load UART to allow us to print the two characters for
-       @@ resume debug
-
-       mov     r2, #S3C24XX_PA_UART & 0xff000000
-       orr     r2, r2, #S3C24XX_PA_UART & 0xff000
-
-#if 0
-       /* SMDK2440 LED set */
-       mov     r14, #S3C24XX_PA_GPIO
-       ldr     r12, [ r14, #0x54 ]
-       bic     r12, r12, #3<<4
-       orr     r12, r12, #1<<7
-       str     r12, [ r14, #0x54 ]
-#endif
-
-#ifdef CONFIG_DEBUG_RESUME
-       mov     r3, #'L'
-       strb    r3, [ r2, #S3C2410_UTXH ]
-1001:
-       ldrb    r14, [ r3, #S3C2410_UTRSTAT ]
-       tst     r14, #S3C2410_UTRSTAT_TXE
-       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, s3c2410_sleep_save_phys     @ address of restore block
-       ldmia   r0, { r4 - r13 }
-
-       mcr     p15, 0, r4, c15, c1, 0          @ CP access register
-       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
-
-#ifdef CONFIG_DEBUG_RESUME
-       mov     r3, #'R'
-       strb    r3, [ r2, #S3C2410_UTXH ]
-#endif
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r8, c1, c0, 0           @ turn on MMU, etc
-       nop                                     @ second-to-last before mmu
-       mov     pc, r2                          @ go back to virtual address
-
-       .ltorg
+ENTRY(s3c2410_cpu_suspend)
+       @@ prepare cpu to sleep
+
+       ldr     r4, =S3C2410_REFRESH
+       ldr     r5, =S3C24XX_MISCCR
+       ldr     r6, =S3C2410_CLKCON
+       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
+       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
+       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
+
+       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
+       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
+       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
+
+       teq     pc, #0                  @ first as a trial-run to load cache
+       bl      s3c2410_do_sleep
+       teq     r0, r0                  @ now do it for real
+       b       s3c2410_do_sleep        @
+
+       @@ align next bit of code to cache line
+       .align  5
+s3c2410_do_sleep:
+       streq   r7, [ r4 ]                      @ SDRAM sleep command
+       streq   r8, [ r5 ]                      @ SDRAM power-down config
+       streq   r9, [ r6 ]                      @ CPU sleep
+1:     beq     1b
+       mov     pc, r14
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
deleted file mode 100644 (file)
index 9910bf0..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/time.c
- *
- * Copyright (C) 2003-2005 Simtec Electronics
- *     Ben Dooks, <ben@simtec.co.uk>
- *
- * 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/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-
-#include <asm/system.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/arch/map.h>
-#include <asm/arch/regs-timer.h>
-#include <asm/arch/regs-irq.h>
-#include <asm/mach/time.h>
-
-#include "clock.h"
-#include "cpu.h"
-
-static unsigned long timer_startval;
-static unsigned long timer_usec_ticks;
-
-#define TIMER_USEC_SHIFT 16
-
-/* we use the shifted arithmetic to work out the ratio of timer ticks
- * to usecs, as often the peripheral clock is not a nice even multiple
- * of 1MHz.
- *
- * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
- * for the current HZ value of 200 without producing overflows.
- *
- * Original patch by Dimitry Andric, updated by Ben Dooks
-*/
-
-
-/* timer_mask_usec_ticks
- *
- * given a clock and divisor, make the value to pass into timer_ticks_to_usec
- * to scale the ticks into usecs
-*/
-
-static inline unsigned long
-timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
-{
-       unsigned long den = pclk / 1000;
-
-       return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
-}
-
-/* timer_ticks_to_usec
- *
- * convert timer ticks to usec.
-*/
-
-static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
-{
-       unsigned long res;
-
-       res = ticks * timer_usec_ticks;
-       res += 1 << (TIMER_USEC_SHIFT - 4);     /* round up slightly */
-
-       return res >> TIMER_USEC_SHIFT;
-}
-
-/***
- * Returns microsecond  since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- * IRQs are disabled before entering here from do_gettimeofday()
- */
-
-#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
-
-static unsigned long s3c2410_gettimeoffset (void)
-{
-       unsigned long tdone;
-       unsigned long irqpend;
-       unsigned long tval;
-
-       /* work out how many ticks have gone since last timer interrupt */
-
-        tval =  __raw_readl(S3C2410_TCNTO(4));
-       tdone = timer_startval - tval;
-
-       /* check to see if there is an interrupt pending */
-
-       irqpend = __raw_readl(S3C2410_SRCPND);
-       if (irqpend & SRCPND_TIMER4) {
-               /* re-read the timer, and try and fix up for the missed
-                * interrupt. Note, the interrupt may go off before the
-                * timer has re-loaded from wrapping.
-                */
-
-               tval =  __raw_readl(S3C2410_TCNTO(4));
-               tdone = timer_startval - tval;
-
-               if (tval != 0)
-                       tdone += timer_startval;
-       }
-
-       return timer_ticks_to_usec(tdone);
-}
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-s3c2410_timer_interrupt(int irq, void *dev_id)
-{
-       write_seqlock(&xtime_lock);
-       timer_tick();
-       write_sequnlock(&xtime_lock);
-       return IRQ_HANDLED;
-}
-
-static struct irqaction s3c2410_timer_irq = {
-       .name           = "S3C2410 Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
-       .handler        = s3c2410_timer_interrupt,
-};
-
-#define use_tclk1_12() ( \
-       machine_is_bast()       || \
-       machine_is_vr1000()     || \
-       machine_is_anubis()     || \
-       machine_is_osiris() )
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- *
- * Currently we only use timer4, as it is the only timer which has no
- * other function that can be exploited externally
- */
-static void s3c2410_timer_setup (void)
-{
-       unsigned long tcon;
-       unsigned long tcnt;
-       unsigned long tcfg1;
-       unsigned long tcfg0;
-
-       tcnt = 0xffff;  /* default value for tcnt */
-
-       /* read the current timer configuration bits */
-
-       tcon = __raw_readl(S3C2410_TCON);
-       tcfg1 = __raw_readl(S3C2410_TCFG1);
-       tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-       /* configure the system for whichever machine is in use */
-
-       if (use_tclk1_12()) {
-               /* timer is at 12MHz, scaler is 1 */
-               timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
-               tcnt = 12000000 / HZ;
-
-               tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
-               tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
-       } else {
-               unsigned long pclk;
-               struct clk *clk;
-
-               /* for the h1940 (and others), we use the pclk from the core
-                * to generate the timer values. since values around 50 to
-                * 70MHz are not values we can directly generate the timer
-                * value from, we need to pre-scale and divide before using it.
-                *
-                * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
-                * (8.45 ticks per usec)
-                */
-
-               /* this is used as default if no other timer can be found */
-
-               clk = clk_get(NULL, "timers");
-               if (IS_ERR(clk))
-                       panic("failed to get clock for system timer");
-
-               clk_enable(clk);
-
-               pclk = clk_get_rate(clk);
-
-               /* configure clock tick */
-
-               timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
-
-               tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
-               tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
-
-               tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
-               tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
-
-               tcnt = (pclk / 6) / HZ;
-       }
-
-       /* timers reload after counting zero, so reduce the count by 1 */
-
-       tcnt--;
-
-       printk("timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
-              tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
-
-       /* check to see if timer is within 16bit range... */
-       if (tcnt > 0xffff) {
-               panic("setup_timer: HZ is too small, cannot configure timer!");
-               return;
-       }
-
-       __raw_writel(tcfg1, S3C2410_TCFG1);
-       __raw_writel(tcfg0, S3C2410_TCFG0);
-
-       timer_startval = tcnt;
-       __raw_writel(tcnt, S3C2410_TCNTB(4));
-
-       /* ensure timer is stopped... */
-
-       tcon &= ~(7<<20);
-       tcon |= S3C2410_TCON_T4RELOAD;
-       tcon |= S3C2410_TCON_T4MANUALUPD;
-
-       __raw_writel(tcon, S3C2410_TCON);
-       __raw_writel(tcnt, S3C2410_TCNTB(4));
-       __raw_writel(tcnt, S3C2410_TCMPB(4));
-
-       /* start the timer running */
-       tcon |= S3C2410_TCON_T4START;
-       tcon &= ~S3C2410_TCON_T4MANUALUPD;
-       __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void __init s3c2410_timer_init (void)
-{
-       s3c2410_timer_setup();
-       setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
-}
-
-struct sys_timer s3c24xx_timer = {
-       .init           = s3c2410_timer_init,
-       .offset         = s3c2410_gettimeoffset,
-       .resume         = s3c2410_timer_setup
-};
index 22b0e1cdd4bf3d4e584588b4399c54646c673847..bcd562ac1d3da4899dca3b73ac3e9184e6c2d55e 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "devs.h"
+#include <asm/plat-s3c24xx/devs.h>
 #include "usb-simtec.h"
 
 /* control power and monitor over-current events on various Simtec
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
new file mode 100644 (file)
index 0000000..befc5fd
--- /dev/null
@@ -0,0 +1,58 @@
+# arch/arm/mach-s3c2412/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2412
+       bool
+       depends on ARCH_S3C2410
+       select S3C2412_PM if PM
+       select S3C2412_DMA if S3C2410_DMA
+       help
+         Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2412_ONLY
+       bool
+       depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
+                  !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
+       default y if CPU_S3C2412
+
+config S3C2412_DMA
+       bool
+       depends on CPU_S3C2412
+       help
+         Internal config node for S3C2412 DMA support
+
+config S3C2412_PM
+       bool
+       help
+         Internal config node to apply S3C2412 power management
+
+
+menu "S3C2412 Machines"
+
+config MACH_SMDK2413
+       bool "SMDK2413"
+       select CPU_S3C2412
+       select MACH_S3C2413
+       select MACH_SMDK
+       help
+         Say Y here if you are using an SMDK2413
+
+config MACH_S3C2413
+       bool
+       help
+         Internal node for S3C2413 version of SMDK2413, so that
+         machine_is_s3c2413() will work when MACH_SMDK2413 is
+         selected
+
+config MACH_VSTMS
+       bool "VMSTMS"
+       select CPU_S3C2412
+       help
+         Say Y here if you are using an VSTMS board
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
new file mode 100644 (file)
index 0000000..f8e0116
--- /dev/null
@@ -0,0 +1,21 @@
+# arch/arm/mach-s3c2412/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o
+obj-$(CONFIG_CPU_S3C2412)      += irq.o
+obj-$(CONFIG_CPU_S3C2412)      += clock.o
+obj-$(CONFIG_S3C2412_DMA)      += dma.o
+obj-$(CONFIG_S3C2412_PM)       += pm.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2413)    += mach-smdk2413.o
+obj-$(CONFIG_MACH_VSTMS)       += mach-vstms.o
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
new file mode 100644 (file)
index 0000000..6a8e444
--- /dev/null
@@ -0,0 +1,716 @@
+/* linux/arch/arm/mach-s3c2412/clock.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412,S3C2413 Clock control support
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2412_clkcon_enable(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
+
+       clkcon = __raw_readl(S3C2410_CLKCON);
+
+       if (enable)
+               clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
+
+       __raw_writel(clkcon, S3C2410_CLKCON);
+
+       return 0;
+}
+
+static int s3c2412_upll_enable(struct clk *clk, int enable)
+{
+       unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+       unsigned long orig = upllcon;
+
+       if (!enable)
+               upllcon |= S3C2412_PLLCON_OFF;
+       else
+               upllcon &= ~S3C2412_PLLCON_OFF;
+
+       __raw_writel(upllcon, S3C2410_UPLLCON);
+
+       /* allow ~150uS for the PLL to settle and lock */
+
+       if (enable && (orig & S3C2412_PLLCON_OFF))
+               udelay(150);
+
+       return 0;
+}
+
+/* clock selections */
+
+/* CPU EXTCLK input */
+static struct clk clk_ext = {
+       .name           = "extclk",
+       .id             = -1,
+};
+
+static struct clk clk_erefclk = {
+       .name           = "erefclk",
+       .id             = -1,
+};
+
+static struct clk clk_urefclk = {
+       .name           = "urefclk",
+       .id             = -1,
+};
+
+static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_urefclk)
+               clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
+       else if (parent == &clk_upll)
+               clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static struct clk clk_usysclk = {
+       .name           = "usysclk",
+       .id             = -1,
+       .parent         = &clk_xtal,
+       .set_parent     = s3c2412_setparent_usysclk,
+};
+
+static struct clk clk_mrefclk = {
+       .name           = "mrefclk",
+       .parent         = &clk_xtal,
+       .id             = -1,
+};
+
+static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_xtal,
+       .id             = -1,
+};
+
+static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_usysclk)
+               clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
+       else if (parent == &clk_h)
+               clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       div = parent_rate / rate;
+       if (div > 2)
+               div = 2;
+
+       return parent_rate / div;
+}
+
+static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
+}
+
+static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_usbsrc(clk, rate);
+
+       if ((parent_rate / rate) == 2)
+               clkdivn |= S3C2412_CLKDIVN_USB48DIV;
+       else
+               clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_usbsrc = {
+       .name           = "usbsrc",
+       .id             = -1,
+       .get_rate       = s3c2412_getrate_usbsrc,
+       .set_rate       = s3c2412_setrate_usbsrc,
+       .round_rate     = s3c2412_roundrate_usbsrc,
+       .set_parent     = s3c2412_setparent_usbsrc,
+};
+
+static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_mdivclk)
+               clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
+       else if (parent == &clk_upll)
+               clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static struct clk clk_msysclk = {
+       .name           = "msysclk",
+       .id             = -1,
+       .set_parent     = s3c2412_setparent_msysclk,
+};
+
+/* these next clocks have an divider immediately after them,
+ * so we can register them with their divider and leave out the
+ * intermediate clock stage
+*/
+static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       /* note, we remove the +/- 1 calculations as they cancel out */
+
+       div = (rate / parent_rate);
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / div;
+}
+
+static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_erefclk)
+               clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
+       else if (parent == &clk_mpll)
+               clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_getrate_uart(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_UARTDIV_MASK;
+       div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_uart = {
+       .name           = "uartclk",
+       .id             = -1,
+       .get_rate       = s3c2412_getrate_uart,
+       .set_rate       = s3c2412_setrate_uart,
+       .set_parent     = s3c2412_setparent_uart,
+       .round_rate     = s3c2412_roundrate_clksrc,
+};
+
+static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_erefclk)
+               clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
+       else if (parent == &clk_mpll)
+               clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_getrate_i2s(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_I2SDIV_MASK;
+       div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_i2s = {
+       .name           = "i2sclk",
+       .id             = -1,
+       .get_rate       = s3c2412_getrate_i2s,
+       .set_rate       = s3c2412_setrate_i2s,
+       .set_parent     = s3c2412_setparent_i2s,
+       .round_rate     = s3c2412_roundrate_clksrc,
+};
+
+static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_usysclk)
+               clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
+       else if (parent == &clk_h)
+               clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+static unsigned long s3c2412_getrate_cam(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_CAMDIV_MASK;
+       div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_cam = {
+       .name           = "camif-upll", /* same as 2440 name */
+       .id             = -1,
+       .get_rate       = s3c2412_getrate_cam,
+       .set_rate       = s3c2412_setrate_cam,
+       .set_parent     = s3c2412_setparent_cam,
+       .round_rate     = s3c2412_roundrate_clksrc,
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "nand",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_NAND,
+       }, {
+               .name           = "sdi",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_SDI,
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_IIC,
+       }, {
+               .name           = "iis",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_IIS,
+       }, {
+               .name           = "spi",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_SPI,
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .id             = 0,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .id             = 1,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .id             = 2,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .id             = 3,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA3,
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_LCDC,
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USBD,
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_PWMT,
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART2,
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = 0,
+       }, {
+               .name           = "usb-bus-gadget",
+               .id             = -1,
+               .parent         = &clk_usb_bus,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USB_DEV48,
+       }, {
+               .name           = "usb-bus-host",
+               .id             = -1,
+               .parent         = &clk_usb_bus,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USB_HOST48,
+       }
+};
+
+/* clocks to add where we need to check their parentage */
+
+struct clk_init {
+       struct clk      *clk;
+       unsigned int     bit;
+       struct clk      *src_0;
+       struct clk      *src_1;
+};
+
+static struct clk_init clks_src[] __initdata = {
+       {
+               .clk    = &clk_usysclk,
+               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
+               .src_0  = &clk_urefclk,
+               .src_1  = &clk_upll,
+       }, {
+               .clk    = &clk_i2s,
+               .bit    = S3C2412_CLKSRC_I2SCLK_MPLL,
+               .src_0  = &clk_erefclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_cam,
+               .bit    = S3C2412_CLKSRC_CAMCLK_HCLK,
+               .src_0  = &clk_usysclk,
+               .src_1  = &clk_h,
+       }, {
+               .clk    = &clk_msysclk,
+               .bit    = S3C2412_CLKSRC_MSYSCLK_MPLL,
+               .src_0  = &clk_mdivclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_uart,
+               .bit    = S3C2412_CLKSRC_UARTCLK_MPLL,
+               .src_0  = &clk_erefclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_usbsrc,
+               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
+               .src_0  = &clk_usysclk,
+               .src_1  = &clk_h,
+       },
+};
+
+/* s3c2412_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static void __init s3c2412_clk_initparents(void)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+       struct clk_init *cip = clks_src;
+       struct clk *src;
+       int ptr;
+       int ret;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
+               ret = s3c24xx_register_clock(cip->clk);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              cip->clk->name, ret);
+               }
+
+               src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
+
+               printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
+               clk_set_parent(cip->clk, src);
+       }
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_usb_bus,
+       &clk_erefclk,
+       &clk_urefclk,
+       &clk_mrefclk,
+};
+
+int __init s3c2412_baseclk_add(void)
+{
+       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       clk_upll.enable = s3c2412_upll_enable;
+       clk_usb_bus.parent = &clk_usbsrc;
+       clk_usb_bus.rate = 0x0;
+
+       s3c2412_clk_initparents();
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+               clkp = clks[ptr];
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       /* ensure usb bus clock is within correct rate of 48MHz */
+
+       if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
+
+               /* for the moment, let's use the UPLL, and see if we can
+                * get 48MHz */
+
+               clk_set_parent(&clk_usysclk, &clk_upll);
+               clk_set_parent(&clk_usbsrc, &clk_usysclk);
+               clk_set_rate(&clk_usbsrc, 48*1000*1000);
+       }
+
+       printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
+              print_mhz(clk_get_rate(&clk_upll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+
+       /* register clocks from clock array */
+
+       clkp = init_clocks;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+               /* ensure that we note the clock state */
+
+               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       /* We must be careful disabling the clocks we are not intending to
+        * be using at boot time, as subsytems such as the LCD which do
+        * their own DMA requests to the bus can cause the system to lockup
+        * if they where in the middle of requesting bus access.
+        *
+        * Disabling the LCD clock if the LCD is active is very dangerous,
+        * and therefore the bootloader should be careful to not enable
+        * the LCD clock if it is not needed.
+       */
+
+       /* install (and disable) the clocks we do not need immediately */
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+
+               s3c2412_clkcon_enable(clkp, 0);
+       }
+
+       return 0;
+}
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
new file mode 100644 (file)
index 0000000..d0f4695
--- /dev/null
@@ -0,0 +1,162 @@
+/* linux/arch/arm/mach-s3c2412/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include <asm/io.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
+
+static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
+       },
+};
+
+static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       writel(map->channels[0] | S3C2412_DMAREQSEL_HW,
+              chan->regs + S3C2412_DMA_DMAREQSEL);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
+       .select         = s3c2412_dma_select,
+       .dcon_mask      = 0,
+       .map            = s3c2412_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
+};
+
+static int s3c2412_dma_add(struct sys_device *sysdev)
+{
+       s3c2410_dma_init();
+       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
+}
+
+static struct sysdev_driver s3c2412_dma_driver = {
+       .add    = s3c2412_dma_add,
+};
+
+static int __init s3c2412_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
+}
+
+arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
new file mode 100644 (file)
index 0000000..e89dbdc
--- /dev/null
@@ -0,0 +1,133 @@
+/* linux/arch/arm/mach-s3c2412/irq.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/irq.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
+ * having them turn up in both the INT* and the EINT* registers. Whilst
+ * both show the status, they both now need to be acked when the IRQs
+ * go off.
+*/
+
+static void
+s3c2412_irq_mask(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask | bitval, S3C2410_INTMSK);
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+}
+
+static inline void
+s3c2412_irq_ack(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c2412_irq_maskack(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static void
+s3c2412_irq_unmask(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask & ~bitval, S3C2410_INTMSK);
+}
+
+static struct irq_chip s3c2412_irq_eint0t4 = {
+       .ack       = s3c2412_irq_ack,
+       .mask      = s3c2412_irq_mask,
+       .unmask    = s3c2412_irq_unmask,
+       .set_wake  = s3c_irq_wake,
+       .set_type  = s3c_irqext_type,
+};
+
+static int s3c2412_irq_add(struct sys_device *sysdev)
+{
+       unsigned int irqno;
+
+       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+               set_irq_chip(irqno, &s3c2412_irq_eint0t4);
+               set_irq_handler(irqno, handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2412_irq_driver = {
+       .add            = s3c2412_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
+};
+
+static int s3c2412_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_irq_driver);
+}
+
+arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
new file mode 100644 (file)
index 0000000..b5befce
--- /dev/null
@@ -0,0 +1,192 @@
+/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
+ * loans of SMDK2413 to work with.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/fb.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+
+static struct map_desc smdk2413_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+       printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
+
+       switch (cmd)
+       {
+               case S3C2410_UDC_P_ENABLE :
+                       s3c2410_gpio_setpin(S3C2410_GPF2, 1);
+                       break;
+               case S3C2410_UDC_P_DISABLE :
+                       s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+                       break;
+               case S3C2410_UDC_P_RESET :
+                       break;
+               default:
+                       break;
+       }
+}
+
+
+static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
+       .udc_command            = smdk2413_udc_pullup,
+};
+
+
+static struct platform_device *smdk2413_devices[] __initdata = {
+       &s3c_device_usb,
+       //&s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_usbgadget,
+};
+
+static struct s3c24xx_board smdk2413_board __initdata = {
+       .devices       = smdk2413_devices,
+       .devices_count = ARRAY_SIZE(smdk2413_devices)
+};
+
+static void __init smdk2413_fixup(struct machine_desc *desc,
+                                 struct tag *tags, char **cmdline,
+                                 struct meminfo *mi)
+{
+       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+               mi->nr_banks=1;
+               mi->bank[0].start = 0x30000000;
+               mi->bank[0].size = SZ_64M;
+               mi->bank[0].node = 0;
+       }
+}
+
+static void __init smdk2413_map_io(void)
+{
+       s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+       s3c24xx_set_board(&smdk2413_board);
+}
+
+static void __init smdk2413_machine_init(void)
+{      /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+       s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPIO_OUTPUT);
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+
+       s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
+
+       smdk_machine_init();
+}
+
+MACHINE_START(S3C2413, "S3C2413")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
+
+MACHINE_START(SMDK2412, "SMDK2412")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
+
+MACHINE_START(SMDK2413, "SMDK2413")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
new file mode 100644 (file)
index 0000000..4231b54
--- /dev/null
@@ -0,0 +1,168 @@
+/* linux/arch/arm/mach-s3c2412/mach-vstms.c
+ *
+ * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include <asm/arch/nand.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+
+static struct map_desc vstms_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       }
+};
+
+static struct mtd_partition vstms_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = 0x7C000,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "UBoot Config",
+               .offset = 0x7C000,
+               .size   = 0x4000,
+       },
+       [2] = {
+               .name   = "Kernel",
+               .offset = 0x80000,
+               .size   = 0x200000,
+       },
+       [3] = {
+               .name   = "RFS",
+               .offset = 0x280000,
+               .size   = 0x3d80000,
+       },
+};
+
+static struct s3c2410_nand_set vstms_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(vstms_nand_part),
+               .partitions     = vstms_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand vstms_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(vstms_nand_sets),
+       .sets           = vstms_nand_sets,
+};
+
+static struct platform_device *vstms_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+};
+
+static struct s3c24xx_board vstms_board __initdata = {
+       .devices       = vstms_devices,
+       .devices_count = ARRAY_SIZE(vstms_devices)
+};
+
+static void __init vstms_fixup(struct machine_desc *desc,
+                                 struct tag *tags, char **cmdline,
+                                 struct meminfo *mi)
+{
+       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+               mi->nr_banks=1;
+               mi->bank[0].start = 0x30000000;
+               mi->bank[0].size = SZ_64M;
+               mi->bank[0].node = 0;
+       }
+}
+
+static void __init vstms_map_io(void)
+{
+       s3c_device_nand.dev.platform_data = &vstms_nand_info;
+
+       s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+       s3c24xx_set_board(&vstms_board);
+}
+
+MACHINE_START(VSTMS, "VSTMS")
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .fixup          = vstms_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = vstms_map_io,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
new file mode 100644 (file)
index 0000000..8988dac
--- /dev/null
@@ -0,0 +1,128 @@
+/* linux/arch/arm/mach-s3c2412/pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-power.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-dsc.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+#include <asm/plat-s3c24xx/s3c2412.h>
+
+static void s3c2412_cpu_suspend(void)
+{
+       unsigned long tmp;
+
+       /* set our standby method to sleep */
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       /* issue the standby signal into the pm unit. Note, we
+        * issue a write-buffer drain just in case */
+
+       tmp = 0;
+
+       asm("b 1f\n\t"
+           ".align 5\n\t"
+           "1:\n\t"
+           "mcr p15, 0, %0, c7, c10, 4\n\t"
+           "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+       /* we should never get past here */
+
+       panic("sleep resumed to originator?");
+}
+
+static void s3c2412_pm_prepare(void)
+{
+}
+
+static int s3c2412_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = s3c2412_pm_prepare;
+       pm_cpu_sleep = s3c2412_cpu_suspend;
+
+       return 0;
+}
+
+static struct sleep_save s3c2412_sleep[] = {
+       SAVE_ITEM(S3C2412_DSC0),
+       SAVE_ITEM(S3C2412_DSC1),
+       SAVE_ITEM(S3C2413_GPJDAT),
+       SAVE_ITEM(S3C2413_GPJCON),
+       SAVE_ITEM(S3C2413_GPJUP),
+
+       /* save the PWRCFG to get back to original sleep method */
+
+       SAVE_ITEM(S3C2412_PWRCFG),
+
+       /* save the sleep configuration anyway, just in case these
+        * get damaged during wakeup */
+
+       SAVE_ITEM(S3C2412_GPBSLPCON),
+       SAVE_ITEM(S3C2412_GPCSLPCON),
+       SAVE_ITEM(S3C2412_GPDSLPCON),
+       SAVE_ITEM(S3C2412_GPESLPCON),
+       SAVE_ITEM(S3C2412_GPFSLPCON),
+       SAVE_ITEM(S3C2412_GPGSLPCON),
+       SAVE_ITEM(S3C2412_GPHSLPCON),
+       SAVE_ITEM(S3C2413_GPJSLPCON),
+};
+
+static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+       s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+}
+
+static int s3c2412_pm_resume(struct sys_device *dev)
+{
+       unsigned long tmp;
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+}
+
+static struct sysdev_driver s3c2412_pm_driver = {
+       .add            = s3c2412_pm_add,
+       .suspend        = s3c2412_pm_suspend,
+       .resume         = s3c2412_pm_resume,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
+}
+
+arch_initcall(s3c2412_pm_init);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
new file mode 100644 (file)
index 0000000..aafe0bc
--- /dev/null
@@ -0,0 +1,181 @@
+/* linux/arch/arm/mach-s3c2412/s3c2412.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/idle.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-power.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+#ifndef CONFIG_CPU_S3C2412_ONLY
+void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
+
+static inline void s3c2412_init_gpio2(void)
+{
+       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+}
+#else
+#define s3c2412_init_gpio2() do { } while(0)
+#endif
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2412_iodesc[] __initdata = {
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(LCD),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(WATCHDOG),
+};
+
+/* uart registration process */
+
+void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
+
+       /* rename devices that are s3c2412/s3c2413 specific */
+       s3c_device_sdi.name  = "s3c2412-sdi";
+       s3c_device_lcd.name  = "s3c2412-lcd";
+       s3c_device_nand.name = "s3c2412-nand";
+}
+
+/* s3c2412_idle
+ *
+ * use the standard idle call by ensuring the idle mode
+ * in power config, then issuing the idle co-processor
+ * instruction
+*/
+
+static void s3c2412_idle(void)
+{
+       unsigned long tmp;
+
+       /* ensure our idle mode is to go to idle */
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       cpu_do_idle();
+}
+
+/* s3c2412_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
+{
+       /* move base of IO */
+
+       s3c2412_init_gpio2();
+
+       /* set our idle function */
+
+       s3c24xx_idle = s3c2412_idle;
+
+       /* register our io-tables */
+
+       iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
+       iotable_init(mach_desc, mach_size);
+}
+
+void __init s3c2412_init_clocks(int xtal)
+{
+       unsigned long tmp;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long pclk;
+
+       /* now we've got our machine bits initialised, work out what
+        * clocks we've got */
+
+       fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
+
+       tmp = __raw_readl(S3C2410_CLKDIVN);
+
+       /* work out clock scalings */
+
+       hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
+       hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1);
+       pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
+
+       /* print brieft summary of clocks, etc */
+
+       printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+       /* initialise the clocks here, to allow other things like the
+        * console to use them
+        */
+
+       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+       s3c2412_baseclk_add();
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2412 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+struct sysdev_class s3c2412_sysclass = {
+       set_kset_name("s3c2412-core"),
+};
+
+static int __init s3c2412_core_init(void)
+{
+       return sysdev_class_register(&s3c2412_sysclass);
+}
+
+core_initcall(s3c2412_core_init);
+
+static struct sys_device s3c2412_sysdev = {
+       .cls            = &s3c2412_sysclass,
+};
+
+int __init s3c2412_init(void)
+{
+       printk("S3C2412: Initialising architecture\n");
+
+       return sysdev_register(&s3c2412_sysdev);
+}
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
new file mode 100644 (file)
index 0000000..e3bfda0
--- /dev/null
@@ -0,0 +1,71 @@
+# arch/arm/mach-s3c2440/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2440
+       bool
+       depends on ARCH_S3C2410
+       select S3C2410_CLOCK
+       select S3C2410_PM if PM
+       select S3C2410_GPIO
+       select S3C2440_DMA if S3C2410_DMA
+       select CPU_S3C244X
+       help
+         Support for S3C2440 Samsung Mobile CPU based systems.
+
+config S3C2440_DMA
+       bool
+       depends on ARCH_S3C2410 && CPU_S3C24405B
+       help
+         Support for S3C2440 specific DMA code5A
+
+
+menu "S3C2440 Machines"
+
+config MACH_ANUBIS
+       bool "Simtec Electronics ANUBIS"
+       select CPU_S3C2440
+       select PM_SIMTEC if PM
+       help
+         Say Y here if you are using the Simtec Electronics ANUBIS
+         development system
+
+config MACH_OSIRIS
+       bool "Simtec IM2440D20 (OSIRIS) module"
+       select CPU_S3C2440
+       select PM_SIMTEC if PM
+       help
+         Say Y here if you are using the Simtec IM2440D20 module, also
+         known as the Osiris.
+
+config MACH_RX3715
+       bool "HP iPAQ rx3715"
+       select CPU_S3C2440
+       select PM_H1940 if PM
+       help
+         Say Y here if you are using the HP iPAQ rx3715.
+
+config ARCH_S3C2440
+       bool "SMDK2440"
+       select CPU_S3C2440
+       select MACH_SMDK
+       help
+         Say Y here if you are using the SMDK2440.
+
+config MACH_NEXCODER_2440
+       bool "NexVision NEXCODER 2440 Light Board"
+       select CPU_S3C2440
+       help
+         Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config SMDK2440_CPU2440
+       bool "SMDK2440 with S3C2440 CPU module"
+       depends on ARCH_S3C2440
+       default y if ARCH_S3C2440
+       select CPU_S3C2440
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
new file mode 100644 (file)
index 0000000..c81ed62
--- /dev/null
@@ -0,0 +1,23 @@
+# arch/arm/mach-s3c2440/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2440)      += s3c2440.o dsc.o
+obj-$(CONFIG_CPU_S3C2440)      += irq.o
+obj-$(CONFIG_CPU_S3C2440)      += clock.o
+obj-$(CONFIG_S3C2440_DMA)      += dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANUBIS)      += mach-anubis.o
+obj-$(CONFIG_MACH_OSIRIS)      += mach-osiris.o
+obj-$(CONFIG_MACH_RX3715)      += mach-rx3715.o
+obj-$(CONFIG_ARCH_S3C2440)     += mach-smdk2440.o
+obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
new file mode 100644 (file)
index 0000000..79e2ea4
--- /dev/null
@@ -0,0 +1,170 @@
+/* linux/arch/arm/mach-s3c2440/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 Clock support
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* S3C2440 extended clock support */
+
+static unsigned long s3c2440_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       /* note, we remove the +/- 1 calculations for the divisor */
+
+       div = (parent_rate / rate) / 2;
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / (div * 2);
+}
+
+static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+       rate = s3c2440_camif_upll_round(clk, rate);
+
+       camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
+
+       if (rate != parent_rate) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+       return 0;
+}
+
+/* Extra S3C2440 clocks */
+
+static struct clk s3c2440_clk_cam = {
+       .name           = "camif",
+       .id             = -1,
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2440_clk_cam_upll = {
+       .name           = "camif-upll",
+       .id             = -1,
+       .set_rate       = s3c2440_camif_upll_setrate,
+       .round_rate     = s3c2440_camif_upll_round,
+};
+
+static struct clk s3c2440_clk_ac97 = {
+       .name           = "ac97",
+       .id             = -1,
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static int s3c2440_clk_add(struct sys_device *sysdev)
+{
+       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+       unsigned long clkdivn;
+       struct clk *clock_h;
+       struct clk *clock_p;
+       struct clk *clock_upll;
+
+       printk("S3C2440: Clock Support, DVS %s\n",
+              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+
+       /* check rate of UPLL, and if it is near 96MHz, then change
+        * to using half the UPLL rate for the system */
+
+       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+               mutex_lock(&clocks_mutex);
+
+               clkdivn = __raw_readl(S3C2410_CLKDIVN);
+               clkdivn |= S3C2440_CLKDIVN_UCLK;
+               __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+               mutex_unlock(&clocks_mutex);
+       }
+
+       s3c2440_clk_cam.parent = clock_h;
+       s3c2440_clk_ac97.parent = clock_p;
+       s3c2440_clk_cam_upll.parent = clock_upll;
+
+       s3c24xx_register_clock(&s3c2440_clk_ac97);
+       s3c24xx_register_clock(&s3c2440_clk_cam);
+       s3c24xx_register_clock(&s3c2440_clk_cam_upll);
+
+       clk_disable(&s3c2440_clk_ac97);
+       clk_disable(&s3c2440_clk_cam);
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+       .add    = s3c2440_clk_add,
+};
+
+static __init int s3c24xx_clk_driver(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c24xx_clk_driver);
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
new file mode 100644 (file)
index 0000000..cd035a3
--- /dev/null
@@ -0,0 +1,210 @@
+/* linux/arch/arm/mach-s3c2440/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
+               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
+               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+};
+
+static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
+       .select         = s3c2440_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2440_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
+};
+
+static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 1 | DMA_CH_VALID,
+                               [3]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_OUT] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_IN] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_OUT] = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 3 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_MIC_IN] = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+};
+
+static int s3c2440_dma_add(struct sys_device *sysdev)
+{
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2440_dma_order);
+       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
+}
+
+static struct sysdev_driver s3c2440_dma_driver = {
+       .add    = s3c2440_dma_add,
+};
+
+static int __init s3c2440_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver);
+}
+
+arch_initcall(s3c2440_dma_init);
+
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c
new file mode 100644 (file)
index 0000000..2995ff5
--- /dev/null
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s3c2440/dsc.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 Drive Strength Control support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-dsc.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+
+int s3c2440_set_dsc(unsigned int pin, unsigned int value)
+{
+       void __iomem *base;
+       unsigned long val;
+       unsigned long flags;
+       unsigned long mask;
+
+       base = (pin & S3C2440_SELECT_DSC1) ? S3C2440_DSC1 : S3C2440_DSC0;
+       mask = 3 << S3C2440_DSC_GETSHIFT(pin);
+
+       local_irq_save(flags);
+
+       val = __raw_readl(base);
+       val &= ~mask;
+       val |= value & mask;
+       __raw_writel(val, base);
+
+       local_irq_restore(flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2440_set_dsc);
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
new file mode 100644 (file)
index 0000000..1069d13
--- /dev/null
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s3c2440/irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+                                 struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+       struct irq_desc *mydesc;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc &= ~submsk;
+       subsrc >>= 13;
+       subsrc &= 3;
+
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       mydesc = irq_desc + IRQ_S3C2440_WDT;
+                       desc_handle_irq(IRQ_S3C2440_WDT, mydesc);
+               }
+               if (subsrc & 2) {
+                       mydesc = irq_desc + IRQ_S3C2440_AC97;
+                       desc_handle_irq(IRQ_S3C2440_AC97, mydesc);
+               }
+       }
+}
+
+
+#define INTMSK_WDT      (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+}
+
+static void
+s3c_irq_wdtac97_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+}
+
+static struct irq_chip s3c_irq_wdtac97 = {
+       .mask       = s3c_irq_wdtac97_mask,
+       .unmask     = s3c_irq_wdtac97_unmask,
+       .ack        = s3c_irq_wdtac97_ack,
+};
+
+static int s3c2440_irq_add(struct sys_device *sysdev)
+{
+       unsigned int irqno;
+
+       printk("S3C2440: IRQ Support\n");
+
+       /* add new chained handler for wdt, ac7 */
+
+       set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
+       set_irq_handler(IRQ_WDT, handle_level_irq);
+       set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+       for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+               set_irq_chip(irqno, &s3c_irq_wdtac97);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+       .add            = s3c2440_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
new file mode 100644 (file)
index 0000000..3f0288e
--- /dev/null
@@ -0,0 +1,325 @@
+/* linux/arch/arm/mach-s3c2440/mach-anubis.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/anubis-map.h>
+#include <asm/arch/anubis-irq.h>
+#include <asm/arch/anubis-cpld.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+
+static struct map_desc anubis_iodesc[] __initdata = {
+  /* ISA IO areas */
+
+  {
+       .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+       .pfn            = __phys_to_pfn(0x0),
+       .length         = SZ_4M,
+       .type           = MT_DEVICE,
+  }, {
+       .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+       .pfn            = __phys_to_pfn(0x0),
+       .length         = SZ_4M,
+       .type           = MT_DEVICE,
+  },
+
+  /* we could possibly compress the next set down into a set of smaller tables
+   * pagetables, but that would mean using an L2 section, and it still means
+   * we cannot actually feed the same register to an LDR due to 16K spacing
+   */
+
+  /* CPLD control registers */
+
+  {
+       .virtual        = (u32)ANUBIS_VA_CTRL1,
+       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL1),
+       .length         = SZ_4K,
+       .type           = MT_DEVICE,
+  }, {
+       .virtual        = (u32)ANUBIS_VA_CTRL2,
+       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL2),
+       .length         = SZ_4K,
+       .type           = MT_DEVICE,
+  },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
+       [0] = {
+               .name           = "uclk",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       },
+       [1] = {
+               .name           = "pclk",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       }
+};
+
+
+static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clocks      = anubis_serial_clocks,
+               .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+       },
+       [1] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clocks      = anubis_serial_clocks,
+               .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+       },
+};
+
+/* NAND Flash on Anubis board */
+
+static int external_map[]   = { 2 };
+static int chip0_map[]      = { 0 };
+static int chip1_map[]      = { 1 };
+
+static struct mtd_partition anubis_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_16K,
+               .offset = SZ_16K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+/* the Anubis has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set anubis_nand_sets[] = {
+       [1] = {
+               .name           = "External",
+               .nr_chips       = 1,
+               .nr_map         = external_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+       [0] = {
+               .name           = "chip0",
+               .nr_chips       = 1,
+               .nr_map         = chip0_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+       [2] = {
+               .name           = "chip1",
+               .nr_chips       = 1,
+               .nr_map         = chip1_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+};
+
+static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+       unsigned int tmp;
+
+       slot = set->nr_map[slot] & 3;
+
+       pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
+                slot, set, set->nr_map);
+
+       tmp = __raw_readb(ANUBIS_VA_CTRL1);
+       tmp &= ~ANUBIS_CTRL1_NANDSEL;
+       tmp |= slot;
+
+       pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
+
+       __raw_writeb(tmp, ANUBIS_VA_CTRL1);
+}
+
+static struct s3c2410_platform_nand anubis_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .nr_sets        = ARRAY_SIZE(anubis_nand_sets),
+       .sets           = anubis_nand_sets,
+       .select_chip    = anubis_nand_select,
+};
+
+/* IDE channels */
+
+static struct resource anubis_ide0_resource[] = {
+       {
+               .start  = S3C2410_CS3,
+               .end    = S3C2410_CS3 + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = S3C2410_CS3 + (1<<26),
+               .end    = S3C2410_CS3 + (1<<26) + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_IDE0,
+               .end    = IRQ_IDE0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device anubis_device_ide0 = {
+       .name           = "simtec-ide",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_ide0_resource),
+       .resource       = anubis_ide0_resource,
+};
+
+static struct resource anubis_ide1_resource[] = {
+       {
+               .start  = S3C2410_CS4,
+               .end    = S3C2410_CS4 + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = S3C2410_CS4 + (1<<26),
+               .end    = S3C2410_CS4 + (1<<26) + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_IDE0,
+               .end    = IRQ_IDE0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+
+static struct platform_device anubis_device_ide1 = {
+       .name           = "simtec-ide",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(anubis_ide1_resource),
+       .resource       = anubis_ide1_resource,
+};
+
+/* Standard Anubis devices */
+
+static struct platform_device *anubis_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_wdt,
+       &s3c_device_adc,
+       &s3c_device_i2c,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &anubis_device_ide0,
+       &anubis_device_ide1,
+};
+
+static struct clk *anubis_clocks[] = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+static struct s3c24xx_board anubis_board __initdata = {
+       .devices       = anubis_devices,
+       .devices_count = ARRAY_SIZE(anubis_devices),
+       .clocks        = anubis_clocks,
+       .clocks_count  = ARRAY_SIZE(anubis_clocks),
+};
+
+static void __init anubis_map_io(void)
+{
+       /* initialise the clocks */
+
+       s3c24xx_dclk0.parent = NULL;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = NULL;
+       s3c24xx_dclk1.rate   = 24*1000*1000;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c_device_nand.dev.platform_data = &anubis_nand_info;
+
+       s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+       s3c24xx_set_board(&anubis_board);
+
+       /* ensure that the GPIO is setup */
+       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+}
+
+MACHINE_START(ANUBIS, "Simtec-Anubis")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = anubis_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
new file mode 100644 (file)
index 0000000..6d551d8
--- /dev/null
@@ -0,0 +1,158 @@
+/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
+ *
+ * Copyright (c) 2004 Nex Vision
+ *   Guillaume GOURAT <guillaume.gourat@nexvision.tv>
+ *
+ * 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.
+ *
+ * Modifications:
+ *     15-10-2004 GG  Created initial version
+ *     12-03-2005 BJD Updated for release
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/setup.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-serial.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct map_desc nexcoder_iodesc[] __initdata = {
+       /* nothing here yet */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* NOR Flash on NexVision NexCoder 2440 board */
+
+static struct resource nexcoder_nor_resource[] = {
+       [0] = {
+               .start = S3C2410_CS0,
+               .end   = S3C2410_CS0 + (8*1024*1024) - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct map_info nexcoder_nor_map = {
+       .bankwidth = 2,
+};
+
+static struct platform_device nexcoder_device_nor = {
+       .name           = "mtd-flash",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(nexcoder_nor_resource),
+       .resource       = nexcoder_nor_resource,
+       .dev =
+       {
+               .platform_data = &nexcoder_nor_map,
+       }
+};
+
+/* Standard Nexcoder devices */
+
+static struct platform_device *nexcoder_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_camif,
+       &s3c_device_spi0,
+       &s3c_device_spi1,
+       &nexcoder_device_nor,
+};
+
+static struct s3c24xx_board nexcoder_board __initdata = {
+       .devices       = nexcoder_devices,
+       .devices_count = ARRAY_SIZE(nexcoder_devices),
+};
+
+
+static void __init nexcoder_sensorboard_init(void)
+{
+       // Initialize SCCB bus
+       s3c2410_gpio_setpin(S3C2410_GPE14, 1); // IICSCL
+       s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_OUTP);
+       s3c2410_gpio_setpin(S3C2410_GPE15, 1); // IICSDA
+       s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_OUTP);
+
+       // Power up the sensor board
+       s3c2410_gpio_setpin(S3C2410_GPF1, 1);
+       s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); // CAM_GPIO7 => nLDO_PWRDN
+       s3c2410_gpio_setpin(S3C2410_GPF2, 0);
+       s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
+}
+
+static void __init nexcoder_map_io(void)
+{
+       s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+       s3c24xx_set_board(&nexcoder_board);
+       nexcoder_sensorboard_init();
+}
+
+
+MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
+       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = nexcoder_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
new file mode 100644 (file)
index 0000000..2ed8e51
--- /dev/null
@@ -0,0 +1,303 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris.c
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/osiris-map.h>
+#include <asm/arch/osiris-cpld.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* onboard perihpheral map */
+
+static struct map_desc osiris_iodesc[] __initdata = {
+  /* ISA IO areas (may be over-written later) */
+
+  {
+         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
+         .pfn          = __phys_to_pfn(S3C2410_CS5),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
+         .pfn          = __phys_to_pfn(S3C2410_CS5),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  },
+
+  /* CPLD control registers */
+
+  {
+         .virtual      = (u32)OSIRIS_VA_CTRL1,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL1),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)OSIRIS_VA_CTRL2,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL2),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
+       [0] = {
+               .name           = "uclk",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       },
+       [1] = {
+               .name           = "pclk",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       }
+};
+
+static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clocks      = osiris_serial_clocks,
+               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clocks      = osiris_serial_clocks,
+               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clocks      = osiris_serial_clocks,
+               .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+       }
+};
+
+/* NAND Flash on Osiris board */
+
+static int external_map[]   = { 2 };
+static int chip0_map[]      = { 0 };
+static int chip1_map[]      = { 1 };
+
+static struct mtd_partition osiris_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_16K,
+               .offset = SZ_16K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+/* the Osiris has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set osiris_nand_sets[] = {
+       [1] = {
+               .name           = "External",
+               .nr_chips       = 1,
+               .nr_map         = external_map,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+       [0] = {
+               .name           = "chip0",
+               .nr_chips       = 1,
+               .nr_map         = chip0_map,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+       [2] = {
+               .name           = "chip1",
+               .nr_chips       = 1,
+               .nr_map         = chip1_map,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+};
+
+static void osiris_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+       unsigned int tmp;
+
+       slot = set->nr_map[slot] & 3;
+
+       pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n",
+                slot, set, set->nr_map);
+
+       tmp = __raw_readb(OSIRIS_VA_CTRL1);
+       tmp &= ~OSIRIS_CTRL1_NANDSEL;
+       tmp |= slot;
+
+       pr_debug("osiris_nand: ctrl1 now %02x\n", tmp);
+
+       __raw_writeb(tmp, OSIRIS_VA_CTRL1);
+}
+
+static struct s3c2410_platform_nand osiris_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 60,
+       .twrph1         = 60,
+       .nr_sets        = ARRAY_SIZE(osiris_nand_sets),
+       .sets           = osiris_nand_sets,
+       .select_chip    = osiris_nand_select,
+};
+
+/* PCMCIA control and configuration */
+
+static struct resource osiris_pcmcia_resource[] = {
+       [0] = {
+               .start  = 0x0f000000,
+               .end    = 0x0f100000,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 0x0c000000,
+               .end    = 0x0c100000,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device osiris_pcmcia = {
+       .name           = "osiris-pcmcia",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(osiris_pcmcia_resource),
+       .resource       = osiris_pcmcia_resource,
+};
+
+/* Standard Osiris devices */
+
+static struct platform_device *osiris_devices[] __initdata = {
+       &s3c_device_i2c,
+       &s3c_device_nand,
+       &osiris_pcmcia,
+};
+
+static struct clk *osiris_clocks[] = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+static struct s3c24xx_board osiris_board __initdata = {
+       .devices       = osiris_devices,
+       .devices_count = ARRAY_SIZE(osiris_devices),
+       .clocks        = osiris_clocks,
+       .clocks_count  = ARRAY_SIZE(osiris_clocks),
+};
+
+static void __init osiris_map_io(void)
+{
+       unsigned long flags;
+
+       /* initialise the clocks */
+
+       s3c24xx_dclk0.parent = NULL;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = NULL;
+       s3c24xx_dclk1.rate   = 24*1000*1000;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c_device_nand.dev.platform_data = &osiris_nand_info;
+
+       s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+       s3c24xx_set_board(&osiris_board);
+
+       /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
+
+       local_irq_save(flags);
+       __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
+       local_irq_restore(flags);
+
+       /* write-protect line to the NAND */
+       s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+}
+
+MACHINE_START(OSIRIS, "Simtec-OSIRIS")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = osiris_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
new file mode 100644 (file)
index 0000000..480ccde
--- /dev/null
@@ -0,0 +1,243 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.handhelds.org/projects/rx3715.html
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/h1940.h>
+#include <asm/arch/nand.h>
+#include <asm/arch/fb.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+static struct map_desc rx3715_iodesc[] __initdata = {
+       /* dump ISA space somewhere unused */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS3),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS3),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE,
+       },
+};
+
+
+static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
+       [0] = {
+               .name           = "fclk",
+               .divisor        = 0,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       }
+};
+
+static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+               .clocks      = rx3715_serial_clocks,
+               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x00,
+               .clocks      = rx3715_serial_clocks,
+               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .uart_flags  = UPF_CONS_FLOW,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+               .clocks      = rx3715_serial_clocks,
+               .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+       }
+};
+
+/* framebuffer lcd controller information */
+
+static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
+       .regs   = {
+               .lcdcon1 =      S3C2410_LCDCON1_TFT16BPP | \
+                               S3C2410_LCDCON1_TFT | \
+                               S3C2410_LCDCON1_CLKVAL(0x0C),
+
+               .lcdcon2 =      S3C2410_LCDCON2_VBPD(5) | \
+                               S3C2410_LCDCON2_LINEVAL(319) | \
+                               S3C2410_LCDCON2_VFPD(6) | \
+                               S3C2410_LCDCON2_VSPW(2),
+
+               .lcdcon3 =      S3C2410_LCDCON3_HBPD(35) | \
+                               S3C2410_LCDCON3_HOZVAL(239) | \
+                               S3C2410_LCDCON3_HFPD(35),
+
+               .lcdcon4 =      S3C2410_LCDCON4_MVAL(0) | \
+                               S3C2410_LCDCON4_HSPW(7),
+
+               .lcdcon5 =      S3C2410_LCDCON5_INVVLINE |
+                               S3C2410_LCDCON5_FRM565 |
+                               S3C2410_LCDCON5_HWSWP,
+       },
+
+       .lpcsel =       0xf82,
+
+       .gpccon =       0xaa955699,
+       .gpccon_mask =  0xffc003cc,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+
+       .gpdcon =       0xaa95aaa1,
+       .gpdcon_mask =  0xffc0fff0,
+       .gpdup =        0x0000faff,
+       .gpdup_mask =   0xffffffff,
+
+       .fixed_syncs =  1,
+       .width  =       240,
+       .height =       320,
+
+       .xres   = {
+               .min =          240,
+               .max =          240,
+               .defval =       240,
+       },
+
+       .yres   = {
+               .max =          320,
+               .min =          320,
+               .defval =       320,
+       },
+
+       .bpp    = {
+               .min =          16,
+               .max =          16,
+               .defval =       16,
+       },
+};
+
+static struct mtd_partition rx3715_nand_part[] = {
+       [0] = {
+               .name           = "Whole Flash",
+               .offset         = 0,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = MTD_WRITEABLE,
+       }
+};
+
+static struct s3c2410_nand_set rx3715_nand_sets[] = {
+       [0] = {
+               .name           = "Internal",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(rx3715_nand_part),
+               .partitions     = rx3715_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand rx3715_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 50,
+       .twrph1         = 15,
+       .nr_sets        = ARRAY_SIZE(rx3715_nand_sets),
+       .sets           = rx3715_nand_sets,
+};
+
+static struct platform_device *rx3715_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+       &s3c_device_nand,
+};
+
+static struct s3c24xx_board rx3715_board __initdata = {
+       .devices       = rx3715_devices,
+       .devices_count = ARRAY_SIZE(rx3715_devices)
+};
+
+static void __init rx3715_map_io(void)
+{
+       s3c_device_nand.dev.platform_data = &rx3715_nand_info;
+
+       s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+       s3c24xx_set_board(&rx3715_board);
+}
+
+static void __init rx3715_init_irq(void)
+{
+       s3c24xx_init_irq();
+}
+
+static void __init rx3715_init_machine(void)
+{
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+       s3c2410_pm_init();
+
+       s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
+}
+
+
+MACHINE_START(RX3715, "IPAQ-RX3715")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+       .map_io         = rx3715_map_io,
+       .init_irq       = rx3715_init_irq,
+       .init_machine   = rx3715_init_machine,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
new file mode 100644 (file)
index 0000000..c17eb5b
--- /dev/null
@@ -0,0 +1,207 @@
+/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
+ *
+ * Copyright (c) 2004,2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+
+static struct map_desc smdk2440_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
+       .regs   = {
+
+               .lcdcon1        = S3C2410_LCDCON1_TFT16BPP |
+                                 S3C2410_LCDCON1_TFT |
+                                 S3C2410_LCDCON1_CLKVAL(0x04),
+
+               .lcdcon2        = S3C2410_LCDCON2_VBPD(7) |
+                                 S3C2410_LCDCON2_LINEVAL(319) |
+                                 S3C2410_LCDCON2_VFPD(6) |
+                                 S3C2410_LCDCON2_VSPW(3),
+
+               .lcdcon3        = S3C2410_LCDCON3_HBPD(19) |
+                                 S3C2410_LCDCON3_HOZVAL(239) |
+                                 S3C2410_LCDCON3_HFPD(7),
+
+               .lcdcon4        = S3C2410_LCDCON4_MVAL(0) |
+                                 S3C2410_LCDCON4_HSPW(3),
+
+               .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                                 S3C2410_LCDCON5_INVVLINE |
+                                 S3C2410_LCDCON5_INVVFRAME |
+                                 S3C2410_LCDCON5_PWREN |
+                                 S3C2410_LCDCON5_HWSWP,
+       },
+
+#if 0
+       /* currently setup by downloader */
+       .gpccon         = 0xaa940659,
+       .gpccon_mask    = 0xffffffff,
+       .gpcup          = 0x0000ffff,
+       .gpcup_mask     = 0xffffffff,
+       .gpdcon         = 0xaa84aaa0,
+       .gpdcon_mask    = 0xffffffff,
+       .gpdup          = 0x0000faff,
+       .gpdup_mask     = 0xffffffff,
+#endif
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+       .type           = S3C2410_LCDCON1_TFT16BPP,
+
+       .width          = 240,
+       .height         = 320,
+
+       .xres           = {
+               .min    = 240,
+               .max    = 240,
+               .defval = 240,
+       },
+
+       .yres           = {
+               .min    = 320,
+               .max    = 320,
+               .defval = 320,
+       },
+
+       .bpp            = {
+               .min    = 16,
+               .max    = 16,
+               .defval = 16,
+       },
+};
+
+static struct platform_device *smdk2440_devices[] __initdata = {
+       &s3c_device_usb,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+       &s3c_device_iis,
+};
+
+static struct s3c24xx_board smdk2440_board __initdata = {
+       .devices       = smdk2440_devices,
+       .devices_count = ARRAY_SIZE(smdk2440_devices)
+};
+
+static void __init smdk2440_map_io(void)
+{
+       s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
+       s3c24xx_init_clocks(16934400);
+       s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+       s3c24xx_set_board(&smdk2440_board);
+}
+
+static void __init smdk2440_machine_init(void)
+{
+       s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
+
+       smdk_machine_init();
+}
+
+MACHINE_START(S3C2440, "SMDK2440")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2440_map_io,
+       .init_machine   = smdk2440_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
new file mode 100644 (file)
index 0000000..90e1da6
--- /dev/null
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-s3c2440/s3c2440.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 Mobile CPU support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct sys_device s3c2440_sysdev = {
+       .cls            = &s3c2440_sysclass,
+};
+
+int __init s3c2440_init(void)
+{
+       printk("S3C2440: Initialising architecture\n");
+
+       /* change irq for watchdog */
+
+       s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
+       s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
+
+       /* register our system device for everything else */
+
+       return sysdev_register(&s3c2440_sysdev);
+}
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
new file mode 100644 (file)
index 0000000..bf8d87a
--- /dev/null
@@ -0,0 +1,27 @@
+# arch/arm/mach-s3c2442/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2442
+       bool
+       depends on ARCH_S3C2420
+       select S3C2410_CLOCK
+       select S3C2410_GPIO
+       select S3C2410_PM if PM
+       select CPU_S3C244X
+       help
+         Support for S3C2442 Samsung Mobile CPU based systems.
+
+
+menu "S3C2442 Machines"
+
+config SMDK2440_CPU2442
+       bool "SMDM2440 with S3C2442 CPU module"
+       depends on ARCH_S3C2440
+       select CPU_S3C2442
+
+
+endmenu
+
diff --git a/arch/arm/mach-s3c2442/Makefile b/arch/arm/mach-s3c2442/Makefile
new file mode 100644 (file)
index 0000000..2a909c6
--- /dev/null
@@ -0,0 +1,16 @@
+# arch/arm/mach-s3c2442/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2442)      += s3c2442.o
+obj-$(CONFIG_CPU_S3C2442)      += clock.o
+
+# Machine support
+
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
new file mode 100644 (file)
index 0000000..5b9e830
--- /dev/null
@@ -0,0 +1,171 @@
+/* linux/arch/arm/mach-s3c2442/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 Clock support
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       div = parent_rate / rate;
+
+       if (div == 3)
+               return parent_rate / 3;
+
+       /* note, we remove the +/- 1 calculations for the divisor */
+
+       div /= 2;
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+       rate = s3c2442_camif_upll_round(clk, rate);
+
+       camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+       if (rate == parent_rate) {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+       } else if ((parent_rate / rate) == 3) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+       } else {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+       return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+       .name           = "camif",
+       .id             = -1,
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+       .name           = "camif-upll",
+       .id             = -1,
+       .set_rate       = s3c2442_camif_upll_setrate,
+       .round_rate     = s3c2442_camif_upll_round,
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+       unsigned long clkdivn;
+       struct clk *clock_h;
+       struct clk *clock_p;
+       struct clk *clock_upll;
+
+       printk("S3C2442: Clock Support, DVS %s\n",
+              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+
+       /* check rate of UPLL, and if it is near 96MHz, then change
+        * to using half the UPLL rate for the system */
+
+       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+               mutex_lock(&clocks_mutex);
+
+               clkdivn = __raw_readl(S3C2410_CLKDIVN);
+               clkdivn |= S3C2440_CLKDIVN_UCLK;
+               __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+               mutex_unlock(&clocks_mutex);
+       }
+
+       s3c2442_clk_cam.parent = clock_h;
+       s3c2442_clk_cam_upll.parent = clock_upll;
+
+       s3c24xx_register_clock(&s3c2442_clk_cam);
+       s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+       clk_disable(&s3c2442_clk_cam);
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+       .add    = s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2442/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c
new file mode 100644 (file)
index 0000000..fbf8264
--- /dev/null
@@ -0,0 +1,34 @@
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2442 Mobile CPU support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+
+#include <asm/plat-s3c24xx/s3c2442.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct sys_device s3c2442_sysdev = {
+       .cls            = &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+       printk("S3C2442: Initialising architecture\n");
+
+       return sysdev_register(&s3c2442_sysdev);
+}
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
new file mode 100644 (file)
index 0000000..c649bb2
--- /dev/null
@@ -0,0 +1,29 @@
+# arch/arm/mach-s3c2443/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2443
+       bool
+       depends on ARCH_S3C2410
+       select S3C2443_DMA if S3C2410_DMA
+       help
+         Support for the S3C2443 SoC from the S3C24XX line
+
+config S3C2443_DMA
+       bool
+       depends on CPU_S3C2443
+       help
+         Internal config node for S3C2443 DMA support
+
+menu "S3C2443 Machines"
+
+config MACH_SMDK2443
+       bool "SMDK2443"
+       select CPU_S3C2443
+       select MACH_SMDK
+       help
+         Say Y here if you are using an SMDK2443
+
+endmenu
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
new file mode 100644 (file)
index 0000000..d1843c9
--- /dev/null
@@ -0,0 +1,20 @@
+# arch/arm/mach-s3c2443/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2443)      += s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)      += irq.o
+obj-$(CONFIG_CPU_S3C2443)      += clock.o
+
+obj-$(CONFIG_S3C2443_DMA)      += dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2443)    += mach-smdk2443.o
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
new file mode 100644 (file)
index 0000000..dd2272f
--- /dev/null
@@ -0,0 +1,1007 @@
+/* linux/arch/arm/mach-s3c2443/clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control support
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-s3c2443-clock.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
+
+       clkcon = __raw_readl(S3C2443_HCLKCON);
+
+       if (enable)
+               clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
+
+       __raw_writel(clkcon, S3C2443_HCLKCON);
+
+       return 0;
+}
+
+static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
+
+       clkcon = __raw_readl(S3C2443_PCLKCON);
+
+       if (enable)
+               clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
+
+       __raw_writel(clkcon, S3C2443_HCLKCON);
+
+       return 0;
+}
+
+static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
+
+       clkcon = __raw_readl(S3C2443_SCLKCON);
+
+       if (enable)
+               clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
+
+       __raw_writel(clkcon, S3C2443_SCLKCON);
+
+       return 0;
+}
+
+static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
+                                             unsigned long rate,
+                                             unsigned int max)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       /* note, we remove the +/- 1 calculations as they cancel out */
+
+       div = (rate / parent_rate);
+
+       if (div < 1)
+               div = 1;
+       else if (div > max)
+               div = max;
+
+       return parent_rate / div;
+}
+
+static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
+                                              unsigned long rate)
+{
+       return s3c2443_roundrate_clksrc(clk, rate, 4);
+}
+
+static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
+                                               unsigned long rate)
+{
+       return s3c2443_roundrate_clksrc(clk, rate, 16);
+}
+
+static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
+                                                unsigned long rate)
+{
+       return s3c2443_roundrate_clksrc(clk, rate, 256);
+}
+
+/* clock selections */
+
+/* CPU EXTCLK input */
+static struct clk clk_ext = {
+       .name           = "ext",
+       .id             = -1,
+};
+
+static struct clk clk_mpllref = {
+       .name           = "mpllref",
+       .parent         = &clk_xtal,
+       .id             = -1,
+};
+
+#if 0
+static struct clk clk_mpll = {
+       .name           = "mpll",
+       .parent         = &clk_mpllref,
+       .id             = -1,
+};
+#endif
+
+static struct clk clk_epllref;
+
+static struct clk clk_epll = {
+       .name           = "epll",
+       .parent         = &clk_epllref,
+       .id             = -1,
+};
+
+static struct clk clk_i2s_ext = {
+       .name           = "i2s-ext",
+       .id             = -1,
+};
+
+static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+       clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
+
+       if (parent == &clk_xtal)
+               clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
+       else if (parent == &clk_ext)
+               clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
+       else if (parent != &clk_mpllref)
+               return -EINVAL;
+
+       __raw_writel(clksrc, S3C2443_CLKSRC);
+       clk->parent = parent;
+
+       return 0;
+}
+
+static struct clk clk_epllref = {
+       .name           = "epllref",
+       .id             = -1,
+       .set_parent     = s3c2443_setparent_epllref,
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
+
+       return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_mpllref,
+       .id             = -1,
+       .get_rate       = s3c2443_getrate_mdivclk,
+};
+
+
+static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+       clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
+                   S3C2443_CLKSRC_EXTCLK_DIV);
+
+       if (parent == &clk_mpll)
+               clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
+       else if (parent == &clk_mdivclk)
+               clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
+       else if (parent != &clk_mpllref)
+               return -EINVAL;
+
+       __raw_writel(clksrc, S3C2443_CLKSRC);
+       clk->parent = parent;
+
+       return 0;
+}
+
+static struct clk clk_msysclk = {
+       .name           = "msysclk",
+       .parent         = &clk_xtal,
+       .id             = -1,
+       .set_parent     = s3c2443_setparent_msysclk,
+};
+
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+       if (parent == &clk_epll)
+               clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
+       else if (parent == &clk_epllref)
+               clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
+       else
+               return -EINVAL;
+
+       __raw_writel(clksrc, S3C2443_CLKSRC);
+       clk->parent = parent;
+
+       return 0;
+}
+
+static struct clk clk_esysclk = {
+       .name           = "esysclk",
+       .parent         = &clk_epll,
+       .id             = -1,
+       .set_parent     = s3c2443_setparent_esysclk,
+};
+
+/* uartclk
+ *
+ * UART baud-rate clock sourced from esysclk via a divisor
+*/
+
+static unsigned long s3c2443_getrate_uart(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_UARTDIV_MASK;
+       div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc16(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_uart = {
+       .name           = "uartclk",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .get_rate       = s3c2443_getrate_uart,
+       .set_rate       = s3c2443_setrate_uart,
+       .round_rate     = s3c2443_roundrate_clksrc16,
+};
+
+/* hsspi
+ *
+ * high-speed spi clock, sourced from esysclk
+*/
+
+static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
+       div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+
+static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc4(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_hsspi = {
+       .name           = "hsspi",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .ctrlbit        = S3C2443_SCLKCON_HSSPICLK,
+       .enable         = s3c2443_clkcon_enable_s,
+       .get_rate       = s3c2443_getrate_hsspi,
+       .set_rate       = s3c2443_setrate_hsspi,
+       .round_rate     = s3c2443_roundrate_clksrc4,
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+       div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc4(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+struct clk clk_usb_bus_host = {
+       .name           = "usb-bus-host-parent",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .ctrlbit        = S3C2443_SCLKCON_USBHOST,
+       .enable         = s3c2443_clkcon_enable_s,
+       .get_rate       = s3c2443_getrate_usbhost,
+       .set_rate       = s3c2443_setrate_usbhost,
+       .round_rate     = s3c2443_roundrate_clksrc4,
+};
+
+/* clk_hsmcc_div
+ *
+ * this clock is sourced from epll, and is fed through a divider,
+ * to a mux controlled by sclkcon where either it or a extclk can
+ * be fed to the hsmmc block
+*/
+
+static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
+       div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc4(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_hsmmc_div = {
+       .name           = "hsmmc-div",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .get_rate       = s3c2443_getrate_hsmmc_div,
+       .set_rate       = s3c2443_setrate_hsmmc_div,
+       .round_rate     = s3c2443_roundrate_clksrc4,
+};
+
+static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
+
+       clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
+                   S3C2443_SCLKCON_HSMMCCLK_EPLL);
+
+       if (parent == &clk_epll)
+               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
+       else if (parent == &clk_ext)
+               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
+       else
+               return -EINVAL;
+
+       if (clk->usage > 0) {
+               __raw_writel(clksrc, S3C2443_SCLKCON);
+       }
+
+       clk->parent = parent;
+       return 0;
+}
+
+static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
+{
+       return s3c2443_setparent_hsmmc(clk, clk->parent);
+}
+
+static struct clk clk_hsmmc = {
+       .name           = "hsmmc-if",
+       .id             = -1,
+       .parent         = &clk_hsmmc_div,
+       .enable         = s3c2443_enable_hsmmc,
+       .set_parent     = s3c2443_setparent_hsmmc,
+};
+
+/* i2s_eplldiv
+ *
+ * this clock is the output from the i2s divisor of esysclk
+*/
+
+static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_I2SDIV_MASK;
+       div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc16(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_i2s_eplldiv = {
+       .name           = "i2s-eplldiv",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .get_rate       = s3c2443_getrate_i2s_eplldiv,
+       .set_rate       = s3c2443_setrate_i2s_eplldiv,
+       .round_rate     = s3c2443_roundrate_clksrc16,
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+*/
+
+static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+
+       clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
+
+       if (parent == &clk_epllref)
+               clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
+       else if (parent == &clk_i2s_ext)
+               clksrc |= S3C2443_CLKSRC_I2S_EXT;
+       else if (parent != &clk_i2s_eplldiv)
+               return -EINVAL;
+
+       clk->parent = parent;
+       __raw_writel(clksrc, S3C2443_CLKSRC);
+
+       return 0;
+}
+
+static struct clk clk_i2s = {
+       .name           = "i2s-if",
+       .id             = -1,
+       .parent         = &clk_i2s_eplldiv,
+       .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
+       .enable         = s3c2443_clkcon_enable_s,
+       .set_parent     = s3c2443_setparent_i2s,
+};
+
+/* cam-if
+ *
+ * camera interface bus-clock, divided down from esysclk
+*/
+
+static unsigned long s3c2443_getrate_cam(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div  &= S3C2443_CLKDIV1_CAMDIV_MASK;
+       div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc16(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
+       clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
+
+       __raw_writel(clkdiv1, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_cam = {
+       .name           = "camif-upll",         /* same as 2440 name */
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
+       .enable         = s3c2443_clkcon_enable_s,
+       .get_rate       = s3c2443_getrate_cam,
+       .set_rate       = s3c2443_setrate_cam,
+       .round_rate     = s3c2443_roundrate_clksrc16,
+};
+
+/* display-if
+ *
+ * display interface clock, divided from esysclk
+*/
+
+static unsigned long s3c2443_getrate_display(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV1);
+
+       div &= S3C2443_CLKDIV1_DISPDIV_MASK;
+       div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
+
+       rate = s3c2443_roundrate_clksrc256(clk, rate);
+       rate = parent_rate / rate;
+
+       clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
+       clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2443_CLKDIV1);
+       return 0;
+}
+
+static struct clk clk_display = {
+       .name           = "display-if",
+       .id             = -1,
+       .parent         = &clk_esysclk,
+       .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
+       .enable         = s3c2443_clkcon_enable_s,
+       .get_rate       = s3c2443_getrate_display,
+       .set_rate       = s3c2443_setrate_display,
+       .round_rate     = s3c2443_roundrate_clksrc256,
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "nand",
+               .id             = -1,
+               .parent         = &clk_h,
+       }, {
+               .name           = "sdi",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SDI,
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIC,
+       }, {
+               .name           = "iis",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIS,
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SPI0,
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SPI1,
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .id             = 0,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .id             = 1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .id             = 2,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .id             = 3,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA3,
+       }, {
+               .name           = "dma",
+               .id             = 4,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA4,
+       }, {
+               .name           = "dma",
+               .id             = 5,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA5,
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_LCDC,
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBD,
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_PWMT,
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART2,
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART3,
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_WDT,
+       }, {
+               .name           = "usb-bus-host",
+               .id             = -1,
+               .parent         = &clk_usb_bus_host,
+       }
+};
+
+/* clocks to add where we need to check their parentage */
+
+/* s3c2443_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
+{
+       printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
+       return clk_set_parent(clk, parent);
+}
+
+static void __init s3c2443_clk_initparents(void)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
+       struct clk *parent;
+
+       switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
+       case S3C2443_CLKSRC_EPLLREF_EXTCLK:
+               parent = &clk_ext;
+               break;
+
+       case S3C2443_CLKSRC_EPLLREF_XTAL:
+       default:
+               parent = &clk_xtal;
+               break;
+
+       case S3C2443_CLKSRC_EPLLREF_MPLLREF:
+       case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
+               parent = &clk_mpllref;
+               break;
+       }
+
+       clk_init_set_parent(&clk_epllref, parent);
+
+       switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
+       case S3C2443_CLKSRC_I2S_EXT:
+               parent = &clk_i2s_ext;
+               break;
+
+       case S3C2443_CLKSRC_I2S_EPLLDIV:
+       default:
+               parent = &clk_i2s_eplldiv;
+               break;
+
+       case S3C2443_CLKSRC_I2S_EPLLREF:
+       case S3C2443_CLKSRC_I2S_EPLLREF3:
+               parent = &clk_epllref;
+       }
+
+       clk_init_set_parent(&clk_i2s, &clk_epllref);
+
+       /* esysclk source */
+
+       parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
+               &clk_epll : &clk_epllref;
+
+       clk_init_set_parent(&clk_esysclk, parent);
+
+       /* msysclk source */
+
+       if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
+               parent = &clk_mpll;
+       } else {
+               parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
+                       &clk_mdivclk : &clk_mpllref;
+       }
+
+       clk_init_set_parent(&clk_msysclk, parent);
+}
+
+/* armdiv divisor table */
+
+static unsigned int armdiv[16] = {
+       [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 1,
+       [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 2,
+       [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 3,
+       [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 4,
+       [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 6,
+       [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 8,
+       [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 12,
+       [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 16,
+};
+
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+{
+       clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+
+       return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
+{
+       clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+       clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+       return clkcon0 + 1;
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_epll,
+       &clk_usb_bus_host,
+       &clk_usb_bus,
+       &clk_esysclk,
+       &clk_epllref,
+       &clk_mpllref,
+       &clk_msysclk,
+       &clk_uart,
+       &clk_display,
+       &clk_cam,
+       &clk_i2s_eplldiv,
+       &clk_i2s,
+       &clk_hsspi,
+       &clk_hsmmc_div,
+       &clk_hsmmc,
+};
+
+void __init s3c2443_init_clocks(int xtal)
+{
+       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+       unsigned long pll;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long pclk;
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       pll = s3c2443_get_mpll(mpllcon, xtal);
+
+       fclk = pll / s3c2443_fclk_div(clkdiv0);
+       hclk = fclk / s3c2443_get_prediv(clkdiv0);
+       hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
+       pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+
+       printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+              (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+              print_mhz(pll), print_mhz(fclk),
+              print_mhz(hclk), print_mhz(pclk));
+
+       s3c2443_clk_initparents();
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+               clkp = clks[ptr];
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+
+       clk_usb_bus.parent = &clk_usb_bus_host;
+
+       /* ensure usb bus clock is within correct rate of 48MHz */
+
+       if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+               clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
+       }
+
+       printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+              print_mhz(clk_get_rate(&clk_epll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+
+       /* register clocks from clock array */
+
+       clkp = init_clocks;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       /* We must be careful disabling the clocks we are not intending to
+        * be using at boot time, as subsytems such as the LCD which do
+        * their own DMA requests to the bus can cause the system to lockup
+        * if they where in the middle of requesting bus access.
+        *
+        * Disabling the LCD clock if the LCD is active is very dangerous,
+        * and therefore the bootloader should be careful to not enable
+        * the LCD clock if it is not needed.
+       */
+
+       /* install (and disable) the clocks we do not need immediately */
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+
+               (clkp->enable)(clkp, 0);
+       }
+}
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
new file mode 100644 (file)
index 0000000..f70e8cc
--- /dev/null
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s3c2443/dma.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+#include <asm/io.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-ac97.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/regs-sdi.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-spi.h>
+
+#define MAP(x) { \
+               [0]     = (x) | DMA_CH_VALID,   \
+               [1]     = (x) | DMA_CH_VALID,   \
+               [2]     = (x) | DMA_CH_VALID,   \
+               [3]     = (x) | DMA_CH_VALID,   \
+               [4]     = (x) | DMA_CH_VALID,   \
+               [5]     = (x) | DMA_CH_VALID,   \
+       }
+
+static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_SDI),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI0TX),
+               .hw_addr.to     = S3C2410_PA_SPI + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + S3C2410_SPRDAT,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI1TX),
+               .hw_addr.to     = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+               .hw_addr.from   = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_0),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_0),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_0),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_UART3] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_0),
+               .hw_addr.to     = S3C2443_PA_UART3 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2443_PA_UART3 + S3C2410_URXH,
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_1),
+               .hw_addr.to     = S3C2410_PA_UART0 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART0 + S3C2410_URXH,
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_1),
+               .hw_addr.to     = S3C2410_PA_UART1 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART1 + S3C2410_URXH,
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_1),
+               .hw_addr.to     = S3C2410_PA_UART2 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2410_PA_UART2 + S3C2410_URXH,
+       },
+       [DMACH_UART3_SRC2] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_1),
+               .hw_addr.to     = S3C2443_PA_UART3 + S3C2410_UTXH,
+               .hw_addr.from   = S3C2443_PA_UART3 + S3C2410_URXH,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2443_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2SRX),
+               .hw_addr.from   = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2STX),
+               .hw_addr.to     = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMIN),
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMOUT),
+               .hw_addr.to     = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_MICIN),
+               .hw_addr.from   = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+       },
+};
+
+static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+              chan->regs + S3C2443_DMA_DMAREQSEL);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
+       .select         = s3c2443_dma_select,
+       .dcon_mask      = 0,
+       .map            = s3c2443_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2443_dma_mappings),
+};
+
+static int s3c2443_dma_add(struct sys_device *sysdev)
+{
+       s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
+       return s3c24xx_dma_init_map(&s3c2443_dma_sel);
+}
+
+static struct sysdev_driver s3c2443_dma_driver = {
+       .add    = s3c2443_dma_add,
+};
+
+static int __init s3c2443_dma_init(void)
+{
+       return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver);
+}
+
+arch_initcall(s3c2443_dma_init);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
new file mode 100644 (file)
index 0000000..7a45b6d
--- /dev/null
@@ -0,0 +1,290 @@
+/* linux/arch/arm/mach-s3c2443/irq.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+       unsigned int subsrc, submsk;
+       unsigned int end;
+       struct irq_desc *mydesc;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+
+       end = len + irq;
+       mydesc = irq_desc + irq;
+
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       desc_handle_irq(irq, mydesc);
+
+               mydesc++;
+               subsrc >>= 1;
+       }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+       .mask       = s3c2443_irq_wdtac97_mask,
+       .unmask     = s3c2443_irq_wdtac97_unmask,
+       .ack        = s3c2443_irq_wdtac97_ack,
+};
+
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+       .mask       = s3c2443_irq_lcd_mask,
+       .unmask     = s3c2443_irq_lcd_unmask,
+       .ack        = s3c2443_irq_lcd_ack,
+};
+
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6);
+}
+
+#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2443_irq_dma_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+       .mask       = s3c2443_irq_dma_mask,
+       .unmask     = s3c2443_irq_dma_unmask,
+       .ack        = s3c2443_irq_dma_ack,
+};
+
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_UART3, 3);
+}
+
+#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3   (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+
+static void s3c2443_irq_uart3_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+       .mask       = s3c2443_irq_uart3_mask,
+       .unmask     = s3c2443_irq_uart3_unmask,
+       .ack        = s3c2443_irq_uart3_ack,
+};
+
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM     (1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM     INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+       .mask       = s3c2443_irq_cam_mask,
+       .unmask     = s3c2443_irq_cam_unmask,
+       .ack        = s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2443_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+{
+       unsigned int irqno;
+
+       set_irq_chip(base, &s3c_irq_level_chip);
+       set_irq_handler(base, handle_level_irq);
+       set_irq_chained_handler(base, demux);
+
+       for (irqno = start; irqno <= end; irqno++) {
+               set_irq_chip(irqno, chip);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static int s3c2443_irq_add(struct sys_device *sysdev)
+{
+       printk("S3C2443: IRQ Support\n");
+
+       s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+                       IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+       s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+                       IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+       s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+                       &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+       s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+                       &s3c2443_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+       s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+                       &s3c2443_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2443_irq_driver = {
+       .add            = s3c2443_irq_add,
+};
+
+static int s3c2443_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
+}
+
+arch_initcall(s3c2443_irq_init);
+
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
new file mode 100644 (file)
index 0000000..e82aaff
--- /dev/null
@@ -0,0 +1,137 @@
+/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2443/
+ *
+ * Thanks to Samsung for the loan of an SMDK2443
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-lcd.h>
+
+#include <asm/arch/idle.h>
+#include <asm/arch/fb.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+
+static struct map_desc smdk2443_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+static struct platform_device *smdk2443_devices[] __initdata = {
+       &s3c_device_wdt,
+       &s3c_device_i2c,
+};
+
+static struct s3c24xx_board smdk2443_board __initdata = {
+       .devices       = smdk2443_devices,
+       .devices_count = ARRAY_SIZE(smdk2443_devices)
+};
+
+static void __init smdk2443_map_io(void)
+{
+       s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+       s3c24xx_set_board(&smdk2443_board);
+}
+
+static void __init smdk2443_machine_init(void)
+{
+       smdk_machine_init();
+}
+
+MACHINE_START(SMDK2443, "SMDK2443")
+       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2443_map_io,
+       .init_machine   = smdk2443_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
new file mode 100644 (file)
index 0000000..11b1d0b
--- /dev/null
@@ -0,0 +1,97 @@
+/* linux/arch/arm/mach-s3c2443/s3c2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2443 Mobile CPU support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-s3c2443-clock.h>
+#include <asm/arch/reset.h>
+
+#include <asm/plat-s3c24xx/s3c2443.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+       IODESC_ENT(WATCHDOG),
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2443_sysclass = {
+       set_kset_name("s3c2443-core"),
+};
+
+static struct sys_device s3c2443_sysdev = {
+       .cls            = &s3c2443_sysclass,
+};
+
+static void s3c2443_hard_reset(void)
+{
+       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2443_init(void)
+{
+       printk("S3C2443: Initialising architecture\n");
+
+       s3c24xx_reset_hook = s3c2443_hard_reset;
+
+       s3c_device_nand.name = "s3c2412-nand";
+
+       return sysdev_register(&s3c2443_sysdev);
+}
+
+void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2443_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size)
+{
+       iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+       iotable_init(mach_desc, mach_size);
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2443 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2443_core_init(void)
+{
+       return sysdev_class_register(&s3c2443_sysclass);
+}
+
+core_initcall(s3c2443_core_init);
index b305cbda8b877f3bcd11ed7f4814228529c9b19f..da8f043dc2cc3e9a3f281bcf9d98c1eb11b8556b 100644 (file)
@@ -609,3 +609,10 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
          Forget about fast user space cmpxchg support.
          It is just not possible.
 
+config OUTER_CACHE
+       bool
+       default n
+
+config CACHE_L2X0
+       bool
+       select OUTER_CACHE
index d2f5672ecf62e2a06967884f9edf1c7b53975ab6..2f8b95947774dc8d263ce753ba7cb64e2299d241 100644 (file)
@@ -66,3 +66,5 @@ obj-$(CONFIG_CPU_SA1100)      += proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)       += proc-xscale.o
 obj-$(CONFIG_CPU_XSC3)         += proc-xsc3.o
 obj-$(CONFIG_CPU_V6)           += proc-v6.o
+
+obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
new file mode 100644 (file)
index 0000000..08a36f1
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
+ *
+ * Copyright (C) 2007 ARM 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
+ */
+#include <linux/init.h>
+
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CACHE_LINE_SIZE                32
+
+static void __iomem *l2x0_base;
+
+static inline void sync_writel(unsigned long val, unsigned long reg,
+                              unsigned long complete_mask)
+{
+       writel(val, l2x0_base + reg);
+       /* wait for the operation to complete */
+       while (readl(l2x0_base + reg) & complete_mask)
+               ;
+}
+
+static inline void cache_sync(void)
+{
+       sync_writel(0, L2X0_CACHE_SYNC, 1);
+}
+
+static inline void l2x0_inv_all(void)
+{
+       /* invalidate all ways */
+       sync_writel(0xff, L2X0_INV_WAY, 0xff);
+       cache_sync();
+}
+
+static void l2x0_inv_range(unsigned long start, unsigned long end)
+{
+       unsigned long addr;
+
+       start &= ~(CACHE_LINE_SIZE - 1);
+       for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+               sync_writel(addr, L2X0_INV_LINE_PA, 1);
+       cache_sync();
+}
+
+static void l2x0_clean_range(unsigned long start, unsigned long end)
+{
+       unsigned long addr;
+
+       start &= ~(CACHE_LINE_SIZE - 1);
+       for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+               sync_writel(addr, L2X0_CLEAN_LINE_PA, 1);
+       cache_sync();
+}
+
+static void l2x0_flush_range(unsigned long start, unsigned long end)
+{
+       unsigned long addr;
+
+       start &= ~(CACHE_LINE_SIZE - 1);
+       for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
+               sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1);
+       cache_sync();
+}
+
+void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+{
+       __u32 aux;
+
+       l2x0_base = base;
+
+       /* disable L2X0 */
+       writel(0, l2x0_base + L2X0_CTRL);
+
+       aux = readl(l2x0_base + L2X0_AUX_CTRL);
+       aux &= aux_mask;
+       aux |= aux_val;
+       writel(aux, l2x0_base + L2X0_AUX_CTRL);
+
+       l2x0_inv_all();
+
+       /* enable L2X0 */
+       writel(1, l2x0_base + L2X0_CTRL);
+
+       outer_cache.inv_range = l2x0_inv_range;
+       outer_cache.clean_range = l2x0_clean_range;
+       outer_cache.flush_range = l2x0_flush_range;
+
+       printk(KERN_INFO "L2X0 cache controller enabled\n");
+}
index 6a9c362fef5e241969c42c6133456fb901ce31a2..1f9f94f9af4bac8d99137cad55204afcc279c0e4 100644 (file)
@@ -205,9 +205,10 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
         * kernel direct-mapped region for device DMA.
         */
        {
-               unsigned long kaddr = (unsigned long)page_address(page);
-               memset(page_address(page), 0, size);
-               dmac_flush_range(kaddr, kaddr + size);
+               void *ptr = page_address(page);
+               memset(ptr, 0, size);
+               dmac_flush_range(ptr, ptr + size);
+               outer_flush_range(__pa(ptr), __pa(ptr) + size);
        }
 
        /*
@@ -480,20 +481,24 @@ core_initcall(consistent_init);
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-void consistent_sync(void *vaddr, size_t size, int direction)
+void consistent_sync(const void *start, size_t size, int direction)
 {
-       unsigned long start = (unsigned long)vaddr;
-       unsigned long end   = start + size;
+       const void *end = start + size;
+
+       BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1));
 
        switch (direction) {
        case DMA_FROM_DEVICE:           /* invalidate only */
                dmac_inv_range(start, end);
+               outer_inv_range(__pa(start), __pa(end));
                break;
        case DMA_TO_DEVICE:             /* writeback only */
                dmac_clean_range(start, end);
+               outer_clean_range(__pa(start), __pa(end));
                break;
        case DMA_BIDIRECTIONAL:         /* writeback and invalidate */
                dmac_flush_range(start, end);
+               outer_flush_range(__pa(start), __pa(end));
                break;
        default:
                BUG();
index 79e8002024240238aa86ff5086ad165b0bb91aa5..9da43a0fdcdffc5ff09b4e8fd1bdf6d95ac0452b 100644 (file)
@@ -19,7 +19,8 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS };
 /*
  * We fork()ed a process, and we need a new context for the child
  * to run in.  We reserve version 0 for initial tasks so we will
- * always allocate an ASID.
+ * always allocate an ASID. The ASID 0 is reserved for the TTBR
+ * register changing sequence.
  */
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
@@ -38,8 +39,15 @@ void __new_context(struct mm_struct *mm)
         * If we've used up all our ASIDs, we need
         * to start a new version and flush the TLB.
         */
-       if ((asid & ~ASID_MASK) == 0)
+       if ((asid & ~ASID_MASK) == 0) {
+               asid = ++cpu_last_asid;
+               /* set the reserved ASID before flushing the TLB */
+               asm("mcr        p15, 0, %0, c13, c0, 1  @ set reserved context ID\n"
+                   :
+                   : "r" (0));
+               isb();
                flush_tlb_all();
+       }
 
        mm->context.id = asid;
 }
index cf95c5d0ce4cdb60f4ea317f07cde2c8de0764ba..44558d5f9313c0e22d476bc07cd995c466666e66 100644 (file)
@@ -119,8 +119,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne
                flush_cache_page(vma, addr, pfn);
 }
 
-void __flush_dcache_page(struct address_space *mapping, struct page *page);
-
 /*
  * Take care of architecture specific things when placing a new PTE into
  * a page table, or changing an existing PTE.  Basically, there are two
index 655c8376f0b57b73ee48dca75ce0197e619605ac..94fd4bf5cb9e4f31dcd0c41f68b31dfce332b15a 100644 (file)
@@ -49,8 +49,10 @@ pmd_t *top_pmd;
 
 static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
 static unsigned int ecc_mask __initdata = 0;
+pgprot_t pgprot_user;
 pgprot_t pgprot_kernel;
 
+EXPORT_SYMBOL(pgprot_user);
 EXPORT_SYMBOL(pgprot_kernel);
 
 struct cachepolicy {
@@ -345,6 +347,7 @@ static void __init build_mem_type_table(void)
                mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
        }
 
+       pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
        pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
                                 L_PTE_DIRTY | L_PTE_WRITE |
                                 L_PTE_EXEC | kern_pgprot);
index 7b1843befb9c2deb693947e5cac5e1f5f8823d57..eb42e5b948630d106372b6296d71bdf02e7943d6 100644 (file)
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 #include <asm/elf.h>
-#include <asm/hardware/arm_scu.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_SMP
+#include <asm/hardware/arm_scu.h>
+#endif
+
 #include "proc-macros.S"
 
 #define D_CACHE_LINE_SIZE      32
 #define TTB_RGN_WT     (2 << 3)
 #define TTB_RGN_WB     (3 << 3)
 
+#ifndef CONFIG_SMP
+#define TTB_FLAGS      TTB_RGN_WBWA
+#else
+#define TTB_FLAGS      TTB_RGN_WBWA|TTB_S
+#endif
+
 ENTRY(cpu_v6_proc_init)
        mov     pc, lr
 
@@ -92,9 +101,7 @@ ENTRY(cpu_v6_switch_mm)
 #ifdef CONFIG_MMU
        mov     r2, #0
        ldr     r1, [r1, #MM_CONTEXT_ID]        @ get mm->context.id
-#ifdef CONFIG_SMP
-       orr     r0, r0, #TTB_RGN_WBWA|TTB_S     @ mark PTWs shared, outer cacheable
-#endif
+       orr     r0, r0, #TTB_FLAGS
        mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
        mcr     p15, 0, r2, c7, c10, 4          @ drain write buffer
        mcr     p15, 0, r0, c2, c0, 0           @ set TTB 0
@@ -183,8 +190,7 @@ __v6_setup:
        /* Set up the SCU on core 0 only */
        mrc     p15, 0, r0, c0, c0, 5           @ CPU core number
        ands    r0, r0, #15
-       moveq   r0, #0x10000000 @ SCU_BASE
-       orreq   r0, r0, #0x00100000
+       ldreq   r0, =SCU_BASE
        ldreq   r5, [r0, #SCU_CTRL]
        orreq   r5, r5, #1
        streq   r5, [r0, #SCU_CTRL]
@@ -204,9 +210,7 @@ __v6_setup:
 #ifdef CONFIG_MMU
        mcr     p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
        mcr     p15, 0, r0, c2, c0, 2           @ TTB control register
-#ifdef CONFIG_SMP
-       orr     r4, r4, #TTB_RGN_WBWA|TTB_S     @ mark PTWs shared, outer cacheable
-#endif
+       orr     r4, r4, #TTB_FLAGS
        mcr     p15, 0, r4, c2, c0, 1           @ load TTB1
 #endif /* CONFIG_MMU */
        adr     r5, v6_crval
index 94a58455f346cca45fd759af3cb899b03594efd0..d95921a2ab99b81cc0c17cdab5cc433df6b9a9cc 100644 (file)
@@ -5,23 +5,23 @@
  * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
  *
  * Copyright 2004 (C) Intel Corp.
- * Copyright 2005 (c) MontaVista Software, Inc.
+ * Copyright 2005 (C) MontaVista Software, Inc.
  *
  * 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.
  *
- * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is an
- * extension to Intel's original XScale core that adds the following
+ * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is
+ * an extension to Intel's original XScale core that adds the following
  * features:
  *
  * - ARMv6 Supersections
  * - Low Locality Reference pages (replaces mini-cache)
  * - 36-bit addressing
  * - L2 cache
- * - Cache-coherency if chipset supports it
+ * - Cache coherency if chipset supports it
  *
- * Based on orignal XScale code by Nicolas Pitre
+ * Based on original XScale code by Nicolas Pitre.
  */
 
 #include <linux/linkage.h>
 #define MAX_AREA_SIZE  32768
 
 /*
- * The cache line size of the I and D cache.
+ * The cache line size of the L1 I, L1 D and unified L2 cache.
  */
 #define CACHELINESIZE  32
 
 /*
- * The size of the data cache.
+ * The size of the L1 D cache.
  */
 #define CACHESIZE      32768
 
@@ -57,9 +57,9 @@
 #define L2_CACHE_ENABLE        1
 
 /*
- * This macro is used to wait for a CP15 write and is needed
- * when we have to ensure that the last operation to the co-pro
- * was completed before continuing with operation.
+ * This macro is used to wait for a CP15 write and is needed when we
+ * have to ensure that the last operation to the coprocessor was
+ * completed before continuing with operation.
  */
        .macro  cpwait_ret, lr, rd
        mrc     p15, 0, \rd, c2, c0, 0          @ arbitrary read of cp15
        .endm
 
 /*
- * This macro cleans & invalidates the entire xsc3 dcache by set & way.
+ * This macro cleans and invalidates the entire L1 D cache.
  */
 
        .macro  clean_d_cache rd, rs
        mov     \rd, #0x1f00
        orr     \rd, \rd, #0x00e0
-1:     mcr     p15, 0, \rd, c7, c14, 2         @ clean/inv set/way
+1:     mcr     p15, 0, \rd, c7, c14, 2         @ clean/invalidate L1 D line
        adds    \rd, \rd, #0x40000000
        bcc     1b
        subs    \rd, \rd, #0x20
@@ -119,15 +119,15 @@ ENTRY(cpu_xsc3_reset)
        mov     r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
        msr     cpsr_c, r1                      @ reset CPSR
        mrc     p15, 0, r1, c1, c0, 0           @ ctrl register
-       bic     r1, r1, #0x0086                 @ ........B....CA.
        bic     r1, r1, #0x3900                 @ ..VIZ..S........
+       bic     r1, r1, #0x0086                 @ ........B....CA.
        mcr     p15, 0, r1, c1, c0, 0           @ ctrl register
-       mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches & BTB
+       mcr     p15, 0, ip, c7, c7, 0           @ invalidate L1 caches and BTB
        bic     r1, r1, #0x0001                 @ ...............M
        mcr     p15, 0, r1, c1, c0, 0           @ ctrl register
        @ CAUTION: MMU turned off from this point.  We count on the pipeline
        @ already containing those two last instructions to survive.
-       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
+       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I and D TLBs
        mov     pc, r0
 
 /*
@@ -139,14 +139,12 @@ ENTRY(cpu_xsc3_reset)
  *
  * XScale supports clock switching, but using idle mode support
  * allows external hardware to react to system state changes.
-
- MMG: Come back to this one.
  */
        .align  5
 
 ENTRY(cpu_xsc3_do_idle)
        mov     r0, #1
-       mcr     p14, 0, r0, c7, c0, 0           @ Go to IDLE
+       mcr     p14, 0, r0, c7, c0, 0           @ go to idle
        mov     pc, lr
 
 /* ================================= CACHE ================================ */
@@ -171,9 +169,9 @@ ENTRY(xsc3_flush_kern_cache_all)
 __flush_whole_cache:
        clean_d_cache r0, r1
        tst     r2, #VM_EXEC
-       mcrne   p15, 0, ip, c7, c5, 0           @ Invalidate I cache & BTB
-       mcrne   p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
-       mcrne   p15, 0, ip, c7, c5, 4           @ Prefetch Flush
+       mcrne   p15, 0, ip, c7, c5, 0           @ invalidate L1 I cache and BTB
+       mcrne   p15, 0, ip, c7, c10, 4          @ data write barrier
+       mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
        mov     pc, lr
 
 /*
@@ -194,21 +192,21 @@ ENTRY(xsc3_flush_user_cache_range)
        bhs     __flush_whole_cache
 
 1:     tst     r2, #VM_EXEC
-       mcrne   p15, 0, r0, c7, c5, 1           @ Invalidate I cache line
-       mcr     p15, 0, r0, c7, c14, 1          @ Clean/invalidate D cache line
+       mcrne   p15, 0, r0, c7, c5, 1           @ invalidate L1 I line
+       mcr     p15, 0, r0, c7, c14, 1          @ clean/invalidate L1 D line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
        tst     r2, #VM_EXEC
-       mcrne   p15, 0, ip, c7, c5, 6           @ Invalidate BTB
-       mcrne   p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
-       mcrne   p15, 0, ip, c7, c5, 4           @ Prefetch Flush
+       mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
+       mcrne   p15, 0, ip, c7, c10, 4          @ data write barrier
+       mcrne   p15, 0, ip, c7, c5, 4           @ prefetch flush
        mov     pc, lr
 
 /*
  *     coherent_kern_range(start, end)
  *
- *     Ensure coherency between the Icache and the Dcache in the
+ *     Ensure coherency between the I cache and the D cache in the
  *     region described by start.  If you have non-snooping
  *     Harvard caches, you need to implement this function.
  *
@@ -222,34 +220,34 @@ ENTRY(xsc3_coherent_kern_range)
 /* FALLTHROUGH */
 ENTRY(xsc3_coherent_user_range)
        bic     r0, r0, #CACHELINESIZE - 1
-1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
        mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
-       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
-       mcr     p15, 0, r0, c7, c5, 4           @ Prefetch Flush
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate L1 I cache and BTB
+       mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
+       mcr     p15, 0, r0, c7, c5, 4           @ prefetch flush
        mov     pc, lr
 
 /*
  *     flush_kern_dcache_page(void *page)
  *
  *     Ensure no D cache aliasing occurs, either with itself or
- *     the I cache
+ *     the I cache.
  *
  *     - addr  - page aligned address
  */
 ENTRY(xsc3_flush_kern_dcache_page)
        add     r1, r0, #PAGE_SZ
-1:     mcr     p15, 0, r0, c7, c14, 1          @ Clean/Invalidate D Cache line
+1:     mcr     p15, 0, r0, c7, c14, 1          @ clean/invalidate L1 D line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
        mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
-       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
-       mcr     p15, 0, r0, c7, c5, 4           @ Prefetch Flush
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate L1 I cache and BTB
+       mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
+       mcr     p15, 0, r0, c7, c5, 4           @ prefetch flush
        mov     pc, lr
 
 /*
@@ -266,17 +264,17 @@ ENTRY(xsc3_flush_kern_dcache_page)
 ENTRY(xsc3_dma_inv_range)
        tst     r0, #CACHELINESIZE - 1
        bic     r0, r0, #CACHELINESIZE - 1
-       mcrne   p15, 0, r0, c7, c10, 1          @ clean L1 D entry
-       mcrne   p15, 1, r0, c7, c11, 1          @ clean L2 D entry
+       mcrne   p15, 0, r0, c7, c10, 1          @ clean L1 D line
+       mcrne   p15, 1, r0, c7, c11, 1          @ clean L2 line
        tst     r1, #CACHELINESIZE - 1
-       mcrne   p15, 0, r1, c7, c10, 1          @ clean L1 D entry
-       mcrne   p15, 1, r1, c7, c11, 1          @ clean L2 D entry
-1:     mcr     p15, 0, r0, c7, c6, 1           @ invalidate L1 D entry
-       mcr     p15, 1, r0, c7, c7, 1           @ Invalidate L2 D cache line
+       mcrne   p15, 0, r1, c7, c10, 1          @ clean L1 D line
+       mcrne   p15, 1, r1, c7, c11, 1          @ clean L2 line
+1:     mcr     p15, 0, r0, c7, c6, 1           @ invalidate L1 D line
+       mcr     p15, 1, r0, c7, c7, 1           @ invalidate L2 line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
+       mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
 /*
@@ -289,12 +287,12 @@ ENTRY(xsc3_dma_inv_range)
  */
 ENTRY(xsc3_dma_clean_range)
        bic     r0, r0, #CACHELINESIZE - 1
-1:     mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D entry
-       mcr     p15, 1, r0, c7, c11, 1          @ clean L2 D entry
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
+       mcr     p15, 1, r0, c7, c11, 1          @ clean L2 line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
+       mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
 /*
@@ -307,13 +305,13 @@ ENTRY(xsc3_dma_clean_range)
  */
 ENTRY(xsc3_dma_flush_range)
        bic     r0, r0, #CACHELINESIZE - 1
-1:     mcr     p15, 0, r0, c7, c14, 1  @ Clean/invalidate L1 D cache line
-       mcr     p15, 1, r0, c7, c11, 1  @ Clean L2 D cache line
-       mcr     p15, 1, r0, c7, c7, 1   @ Invalidate L2 D cache line
+1:     mcr     p15, 0, r0, c7, c14, 1          @ clean/invalidate L1 D line
+       mcr     p15, 1, r0, c7, c11, 1          @ clean L2 line
+       mcr     p15, 1, r0, c7, c7, 1           @ invalidate L2 line
        add     r0, r0, #CACHELINESIZE
        cmp     r0, r1
        blo     1b
-       mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
+       mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
 ENTRY(xsc3_cache_fns)
@@ -328,7 +326,7 @@ ENTRY(xsc3_cache_fns)
        .long   xsc3_dma_flush_range
 
 ENTRY(cpu_xsc3_dcache_clean_area)
-1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
+1:     mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
        add     r0, r0, #CACHELINESIZE
        subs    r1, r1, #CACHELINESIZE
        bhi     1b
@@ -346,14 +344,14 @@ ENTRY(cpu_xsc3_dcache_clean_area)
        .align  5
 ENTRY(cpu_xsc3_switch_mm)
        clean_d_cache r1, r2
-       mcr     p15, 0, ip, c7, c5, 0           @ Invalidate I cache & BTB
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
-       mcr     p15, 0, ip, c7, c5, 4           @ Prefetch Flush
+       mcr     p15, 0, ip, c7, c5, 0           @ invalidate L1 I cache and BTB
+       mcr     p15, 0, ip, c7, c10, 4          @ data write barrier
+       mcr     p15, 0, ip, c7, c5, 4           @ prefetch flush
 #ifdef L2_CACHE_ENABLE
        orr     r0, r0, #0x18                   @ cache the page table in L2
 #endif
        mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
-       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
+       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I and D TLBs
        cpwait_ret lr, ip
 
 /*
@@ -366,34 +364,34 @@ ENTRY(cpu_xsc3_switch_mm)
 ENTRY(cpu_xsc3_set_pte_ext)
        str     r1, [r0], #-2048                @ linux version
 
-       bic     r2, r1, #0xff0                  @ Keep C, B bits
+       bic     r2, r1, #0xff0                  @ keep C, B bits
        orr     r2, r2, #PTE_TYPE_EXT           @ extended page
-       tst     r1, #L_PTE_SHARED               @ Shared?
+       tst     r1, #L_PTE_SHARED               @ shared?
        orrne   r2, r2, #0x200
 
        eor     r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
 
-       tst     r3, #L_PTE_USER                 @ User?
+       tst     r3, #L_PTE_USER                 @ user?
        orrne   r2, r2, #PTE_EXT_AP_URO_SRW     @ yes -> user r/o, system r/w
 
-       tst     r3, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
+       tst     r3, #L_PTE_WRITE | L_PTE_DIRTY  @ write and dirty?
        orreq   r2, r2, #PTE_EXT_AP_UNO_SRW     @ yes -> user n/a, system r/w
                                                @ combined with user -> user r/w
 
 #if L2_CACHE_ENABLE
-       @ If its cacheable it needs to be in L2 also.
+       @ If it's cacheable, it needs to be in L2 also.
        eor     ip, r1, #L_PTE_CACHEABLE
        tst     ip, #L_PTE_CACHEABLE
        orreq   r2, r2, #PTE_EXT_TEX(0x5)
 #endif
 
-       tst     r3, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
+       tst     r3, #L_PTE_PRESENT | L_PTE_YOUNG        @ present and young?
        movne   r2, #0                          @ no -> fault
 
        str     r2, [r0]                        @ hardware version
        mov     ip, #0
-       mcr     p15, 0, r0, c7, c10, 1          @ Clean D cache line mcr
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
+       mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
+       mcr     p15, 0, ip, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
        .ltorg
@@ -406,17 +404,18 @@ ENTRY(cpu_xsc3_set_pte_ext)
 __xsc3_setup:
        mov     r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
        msr     cpsr_c, r0
-       mcr     p15, 0, ip, c7, c7, 0           @ invalidate I, D caches & BTB
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
-       mcr     p15, 0, ip, c7, c5, 4           @ Prefetch Flush
-       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I, D TLBs
+       mcr     p15, 0, ip, c7, c7, 0           @ invalidate L1 caches and BTB
+       mcr     p15, 0, ip, c7, c10, 4          @ data write barrier
+       mcr     p15, 0, ip, c7, c5, 4           @ prefetch flush
+       mcr     p15, 0, ip, c8, c7, 0           @ invalidate I and D TLBs
 #if L2_CACHE_ENABLE
        orr     r4, r4, #0x18                   @ cache the page table in L2
 #endif
        mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
-       mov     r0, #1                          @ Allow access to CP0 and CP13
-       orr     r0, r0, #1 << 13                @ Its undefined whether this
-       mcr     p15, 0, r0, c15, c1, 0          @ affects USR or SVC modes
+
+       mov     r0, #0                          @ don't allow CP access
+       mcr     p15, 0, r0, c15, c1, 0          @ write CP access register
+
        mrc     p15, 0, r0, c1, c0, 1           @ get auxiliary control reg
        and     r0, r0, #2                      @ preserve bit P bit setting
 #if L2_CACHE_ENABLE
@@ -427,9 +426,9 @@ __xsc3_setup:
        adr     r5, xsc3_crval
        ldmia   r5, {r5, r6}
        mrc     p15, 0, r0, c1, c0, 0           @ get control register
-       bic     r0, r0, r5                      @ .... .... .... ..A.
-       orr     r0, r0, r6                      @ .... .... .... .C.M
-       orr     r0, r0, #0x00000800             @ ..VI Z..S .... ....
+       bic     r0, r0, r5                      @ ..V. ..R. .... ..A.
+       orr     r0, r0, r6                      @ ..VI Z..S .... .C.M (mmu)
+                                               @ ...I Z..S .... .... (uc)
 #if L2_CACHE_ENABLE
        orr     r0, r0, #0x04000000             @ L2 enable
 #endif
@@ -439,7 +438,7 @@ __xsc3_setup:
 
        .type   xsc3_crval, #object
 xsc3_crval:
-       crval   clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100
+       crval   clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
 
        __INITDATA
 
@@ -474,7 +473,7 @@ cpu_elf_name:
 
        .type   cpu_xsc3_name, #object
 cpu_xsc3_name:
-       .asciz  "XScale-Core3"
+       .asciz  "XScale-V3 based processor"
        .size   cpu_xsc3_name, . - cpu_xsc3_name
 
        .align
@@ -490,7 +489,7 @@ __xsc3_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
-       .long   PMD_TYPE_SECT | \
+       .long   PMD_TYPE_SECT | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
        b       __xsc3_setup
index fd6adde39091ef28cadf0d4fa273d8376fbbe707..20f84bbaa9bbc7c1f5cfe1fbadf532c8f10947d1 100644 (file)
@@ -53,6 +53,8 @@ ENTRY(v6wbi_flush_user_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
+       mcr     p15, 0, ip, c7, c5, 6           @ flush BTAC/BTB
+       mcr     p15, 0, ip, c7, c10, 4          @ data synchronization barrier
        mov     pc, lr
 
 /*
@@ -80,7 +82,9 @@ ENTRY(v6wbi_flush_kern_tlb_range)
        add     r0, r0, #PAGE_SZ
        cmp     r0, r1
        blo     1b
+       mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
        mcr     p15, 0, r2, c7, c10, 4          @ data synchronization barrier
+       mcr     p15, 0, r2, c7, c5, 4           @ prefetch flush
        mov     pc, lr
 
        .section ".text.init", #alloc, #execinstr
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
new file mode 100644 (file)
index 0000000..e223431
--- /dev/null
@@ -0,0 +1,99 @@
+# arch/arm/plat-s3c24xx/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_S3C24XX
+       bool
+       depends on ARCH_S3C2410
+       default y if ARCH_S3C2410
+       help
+         Base platform code for any Samsung S3C device
+
+if PLAT_S3C24XX
+
+config CPU_S3C244X
+       bool
+       depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+       help
+         Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+config PM_SIMTEC
+       bool
+       help
+         Common power management code for systems that are
+         compatible with the Simtec style of power management
+
+config S3C2410_BOOT_WATCHDOG
+       bool "S3C2410 Initialisation watchdog"
+       depends on ARCH_S3C2410 && S3C2410_WATCHDOG
+       help
+         Say y to enable the watchdog during the kernel decompression
+         stage. If the kernel fails to uncompress, then the watchdog
+         will trigger a reset and the system should restart.
+
+config S3C2410_BOOT_ERROR_RESET
+       bool "S3C2410 Reboot on decompression error"
+       depends on ARCH_S3C2410
+       help
+         Say y here to use the watchdog to reset the system if the
+         kernel decompressor detects an error during decompression.
+
+config S3C2410_PM_DEBUG
+       bool "S3C2410 PM Suspend debug"
+       depends on ARCH_S3C2410 && PM
+       help
+         Say Y here if you want verbose debugging from the PM Suspend and
+         Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+         for more information.
+
+config S3C2410_PM_CHECK
+       bool "S3C2410 PM Suspend Memory CRC"
+       depends on ARCH_S3C2410 && PM && CRC32
+       help
+         Enable the PM code's memory area checksum over sleep. This option
+         will generate CRCs of all blocks of memory, and store them before
+         going to sleep. The blocks are then checked on resume for any
+         errors.
+
+config S3C2410_PM_CHECK_CHUNKSIZE
+       int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+       depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
+       default 64
+       help
+         Set the chunksize in Kilobytes of the CRC for checking memory
+         corruption over suspend and resume. A smaller value will mean that
+         the CRC data block will take more memory, but wil identify any
+         faults with better precision.
+
+config S3C2410_LOWLEVEL_UART_PORT
+       int "S3C2410 UART to use for low-level messages"
+       default 0
+       help
+         Choice of which UART port to use for the low-level messages,
+         such as the `Uncompressing...` at start time. The value of
+         this configuration should be between zero and two. The port
+         must have been initialised by the boot-loader before use.
+
+config S3C2410_DMA
+       bool "S3C2410 DMA support"
+       depends on ARCH_S3C2410
+       help
+         S3C2410 DMA support. This is needed for drivers like sound which
+         use the S3C2410's DMA system to move data to and from the
+         peripheral blocks.
+
+config S3C2410_DMA_DEBUG
+       bool "S3C2410 DMA support debug"
+       depends on ARCH_S3C2410 && S3C2410_DMA
+       help
+         Enable debugging output for the DMA code. This option sends info
+         to the kernel log, at priority KERN_DEBUG.
+
+config MACH_SMDK
+       bool
+       help
+         Common machine code for SMDK2410 and SMDK2440
+
+endif
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
new file mode 100644 (file)
index 0000000..8e5ccaa
--- /dev/null
@@ -0,0 +1,30 @@
+# arch/arm/plat-s3c24xx/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+
+# Core files
+
+obj-y                          += cpu.o
+obj-y                          += irq.o
+obj-y                          += devs.o
+obj-y                          += gpio.o
+obj-y                          += time.o
+obj-y                          += clock.o
+
+# Architecture dependant builds
+
+obj-$(CONFIG_CPU_S3C244X)      += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)      += s3c244x-irq.o
+obj-$(CONFIG_PM_SIMTEC)                += pm-simtec.o
+obj-$(CONFIG_PM)               += pm.o
+obj-$(CONFIG_PM)               += sleep.o
+obj-$(CONFIG_S3C2410_DMA)      += dma.o
+obj-$(CONFIG_MACH_SMDK)                += common-smdk.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
new file mode 100644 (file)
index 0000000..d3dc03a
--- /dev/null
@@ -0,0 +1,449 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ **  Copyright (C) 2004 ARM Limited.
+ **  Written by Deep Blue Solutions 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
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* clock information */
+
+static LIST_HEAD(clocks);
+
+DEFINE_MUTEX(clocks_mutex);
+
+/* enable and disable calls for use with the clk struct */
+
+static int clk_null_enable(struct clk *clk, int enable)
+{
+       return 0;
+}
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+       struct clk *p;
+       struct clk *clk = ERR_PTR(-ENOENT);
+       int idno;
+
+       if (dev == NULL || dev->bus != &platform_bus_type)
+               idno = -1;
+       else
+               idno = to_platform_device(dev)->id;
+
+       mutex_lock(&clocks_mutex);
+
+       list_for_each_entry(p, &clocks, list) {
+               if (p->id == idno &&
+                   strcmp(id, p->name) == 0 &&
+                   try_module_get(p->owner)) {
+                       clk = p;
+                       break;
+               }
+       }
+
+       /* check for the case where a device was supplied, but the
+        * clock that was being searched for is not device specific */
+
+       if (IS_ERR(clk)) {
+               list_for_each_entry(p, &clocks, list) {
+                       if (p->id == -1 && strcmp(id, p->name) == 0 &&
+                           try_module_get(p->owner)) {
+                               clk = p;
+                               break;
+                       }
+               }
+       }
+
+       mutex_unlock(&clocks_mutex);
+       return clk;
+}
+
+void clk_put(struct clk *clk)
+{
+       module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+       if (IS_ERR(clk) || clk == NULL)
+               return -EINVAL;
+
+       clk_enable(clk->parent);
+
+       mutex_lock(&clocks_mutex);
+
+       if ((clk->usage++) == 0)
+               (clk->enable)(clk, 1);
+
+       mutex_unlock(&clocks_mutex);
+       return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+       if (IS_ERR(clk) || clk == NULL)
+               return;
+
+       mutex_lock(&clocks_mutex);
+
+       if ((--clk->usage) == 0)
+               (clk->enable)(clk, 0);
+
+       mutex_unlock(&clocks_mutex);
+       clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       if (IS_ERR(clk))
+               return 0;
+
+       if (clk->rate != 0)
+               return clk->rate;
+
+       if (clk->get_rate != NULL)
+               return (clk->get_rate)(clk);
+
+       if (clk->parent != NULL)
+               return clk_get_rate(clk->parent);
+
+       return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (!IS_ERR(clk) && clk->round_rate)
+               return (clk->round_rate)(clk, rate);
+
+       return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret;
+
+       if (IS_ERR(clk))
+               return -EINVAL;
+
+       mutex_lock(&clocks_mutex);
+       ret = (clk->set_rate)(clk, rate);
+       mutex_unlock(&clocks_mutex);
+
+       return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       int ret = 0;
+
+       if (IS_ERR(clk))
+               return -EINVAL;
+
+       mutex_lock(&clocks_mutex);
+
+       if (clk->set_parent)
+               ret = (clk->set_parent)(clk, parent);
+
+       mutex_unlock(&clocks_mutex);
+
+       return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+struct clk clk_xtal = {
+       .name           = "xtal",
+       .id             = -1,
+       .rate           = 0,
+       .parent         = NULL,
+       .ctrlbit        = 0,
+};
+
+struct clk clk_mpll = {
+       .name           = "mpll",
+       .id             = -1,
+};
+
+struct clk clk_upll = {
+       .name           = "upll",
+       .id             = -1,
+       .parent         = NULL,
+       .ctrlbit        = 0,
+};
+
+struct clk clk_f = {
+       .name           = "fclk",
+       .id             = -1,
+       .rate           = 0,
+       .parent         = &clk_mpll,
+       .ctrlbit        = 0,
+};
+
+struct clk clk_h = {
+       .name           = "hclk",
+       .id             = -1,
+       .rate           = 0,
+       .parent         = NULL,
+       .ctrlbit        = 0,
+};
+
+struct clk clk_p = {
+       .name           = "pclk",
+       .id             = -1,
+       .rate           = 0,
+       .parent         = NULL,
+       .ctrlbit        = 0,
+};
+
+struct clk clk_usb_bus = {
+       .name           = "usb-bus",
+       .id             = -1,
+       .rate           = 0,
+       .parent         = &clk_upll,
+};
+
+/* clocks that could be registered by external code */
+
+static int s3c24xx_dclk_enable(struct clk *clk, int enable)
+{
+       unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+       if (enable)
+               dclkcon |= clk->ctrlbit;
+       else
+               dclkcon &= ~clk->ctrlbit;
+
+       __raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+       return 0;
+}
+
+static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+{
+       unsigned long dclkcon;
+       unsigned int uclk;
+
+       if (parent == &clk_upll)
+               uclk = 1;
+       else if (parent == &clk_p)
+               uclk = 0;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+       if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
+               if (uclk)
+                       dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
+               else
+                       dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
+       } else {
+               if (uclk)
+                       dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
+               else
+                       dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+       }
+
+       __raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+       return 0;
+}
+
+
+static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
+{
+       unsigned long mask;
+       unsigned long source;
+
+       /* calculate the MISCCR setting for the clock */
+
+       if (parent == &clk_xtal)
+               source = S3C2410_MISCCR_CLK0_MPLL;
+       else if (parent == &clk_upll)
+               source = S3C2410_MISCCR_CLK0_UPLL;
+       else if (parent == &clk_f)
+               source = S3C2410_MISCCR_CLK0_FCLK;
+       else if (parent == &clk_h)
+               source = S3C2410_MISCCR_CLK0_HCLK;
+       else if (parent == &clk_p)
+               source = S3C2410_MISCCR_CLK0_PCLK;
+       else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
+               source = S3C2410_MISCCR_CLK0_DCLK0;
+       else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
+               source = S3C2410_MISCCR_CLK0_DCLK0;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       if (clk == &s3c24xx_dclk0)
+               mask = S3C2410_MISCCR_CLK0_MASK;
+       else {
+               source <<= 4;
+               mask = S3C2410_MISCCR_CLK1_MASK;
+       }
+
+       s3c2410_modify_misccr(mask, source);
+       return 0;
+}
+
+/* external clock definitions */
+
+struct clk s3c24xx_dclk0 = {
+       .name           = "dclk0",
+       .id             = -1,
+       .ctrlbit        = S3C2410_DCLKCON_DCLK0EN,
+       .enable         = s3c24xx_dclk_enable,
+       .set_parent     = s3c24xx_dclk_setparent,
+};
+
+struct clk s3c24xx_dclk1 = {
+       .name           = "dclk1",
+       .id             = -1,
+       .ctrlbit        = S3C2410_DCLKCON_DCLK0EN,
+       .enable         = s3c24xx_dclk_enable,
+       .set_parent     = s3c24xx_dclk_setparent,
+};
+
+struct clk s3c24xx_clkout0 = {
+       .name           = "clkout0",
+       .id             = -1,
+       .set_parent     = s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_clkout1 = {
+       .name           = "clkout1",
+       .id             = -1,
+       .set_parent     = s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_uclk = {
+       .name           = "uclk",
+       .id             = -1,
+};
+
+/* initialise the clock system */
+
+int s3c24xx_register_clock(struct clk *clk)
+{
+       clk->owner = THIS_MODULE;
+
+       if (clk->enable == NULL)
+               clk->enable = clk_null_enable;
+
+       /* add to the list of available clocks */
+
+       mutex_lock(&clocks_mutex);
+       list_add(&clk->list, &clocks);
+       mutex_unlock(&clocks_mutex);
+
+       return 0;
+}
+
+/* initalise all the clocks */
+
+int __init s3c24xx_setup_clocks(unsigned long xtal,
+                               unsigned long fclk,
+                               unsigned long hclk,
+                               unsigned long pclk)
+{
+       printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
+
+       /* initialise the main system clocks */
+
+       clk_xtal.rate = xtal;
+       clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
+
+       clk_mpll.rate = fclk;
+       clk_h.rate = hclk;
+       clk_p.rate = pclk;
+       clk_f.rate = fclk;
+
+       /* assume uart clocks are correctly setup */
+
+       /* register our clocks */
+
+       if (s3c24xx_register_clock(&clk_xtal) < 0)
+               printk(KERN_ERR "failed to register master xtal\n");
+
+       if (s3c24xx_register_clock(&clk_mpll) < 0)
+               printk(KERN_ERR "failed to register mpll clock\n");
+
+       if (s3c24xx_register_clock(&clk_upll) < 0)
+               printk(KERN_ERR "failed to register upll clock\n");
+
+       if (s3c24xx_register_clock(&clk_f) < 0)
+               printk(KERN_ERR "failed to register cpu fclk\n");
+
+       if (s3c24xx_register_clock(&clk_h) < 0)
+               printk(KERN_ERR "failed to register cpu hclk\n");
+
+       if (s3c24xx_register_clock(&clk_p) < 0)
+               printk(KERN_ERR "failed to register cpu pclk\n");
+
+       return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
new file mode 100644 (file)
index 0000000..908efa7
--- /dev/null
@@ -0,0 +1,200 @@
+/* linux/arch/arm/plat-s3c24xx/common-smdk.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/leds-gpio.h>
+
+#include <asm/arch/nand.h>
+
+#include <asm/plat-s3c24xx/common-smdk.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+/* LED devices */
+
+static struct s3c24xx_led_platdata smdk_pdata_led4 = {
+       .gpio           = S3C2410_GPF4,
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led4",
+       .def_trigger    = "timer",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led5 = {
+       .gpio           = S3C2410_GPF5,
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led5",
+       .def_trigger    = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led6 = {
+       .gpio           = S3C2410_GPF6,
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led6",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led7 = {
+       .gpio           = S3C2410_GPF7,
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led7",
+};
+
+static struct platform_device smdk_led4 = {
+       .name           = "s3c24xx_led",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &smdk_pdata_led4,
+       },
+};
+
+static struct platform_device smdk_led5 = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data = &smdk_pdata_led5,
+       },
+};
+
+static struct platform_device smdk_led6 = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data = &smdk_pdata_led6,
+       },
+};
+
+static struct platform_device smdk_led7 = {
+       .name           = "s3c24xx_led",
+       .id             = 3,
+       .dev            = {
+               .platform_data = &smdk_pdata_led7,
+       },
+};
+
+/* NAND parititon from 2.4.18-swl5 */
+
+static struct mtd_partition smdk_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "S3C2410 flash partition 1",
+               .offset = 0,
+               .size   = SZ_2M,
+       },
+       [2] = {
+               .name   = "S3C2410 flash partition 2",
+               .offset = SZ_4M,
+               .size   = SZ_4M,
+       },
+       [3] = {
+               .name   = "S3C2410 flash partition 3",
+               .offset = SZ_8M,
+               .size   = SZ_2M,
+       },
+       [4] = {
+               .name   = "S3C2410 flash partition 4",
+               .offset = SZ_1M * 10,
+               .size   = SZ_4M,
+       },
+       [5] = {
+               .name   = "S3C2410 flash partition 5",
+               .offset = SZ_1M * 14,
+               .size   = SZ_1M * 10,
+       },
+       [6] = {
+               .name   = "S3C2410 flash partition 6",
+               .offset = SZ_1M * 24,
+               .size   = SZ_1M * 24,
+       },
+       [7] = {
+               .name   = "S3C2410 flash partition 7",
+               .offset = SZ_1M * 48,
+               .size   = SZ_16M,
+       }
+};
+
+static struct s3c2410_nand_set smdk_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(smdk_default_nand_part),
+               .partitions     = smdk_default_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand smdk_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(smdk_nand_sets),
+       .sets           = smdk_nand_sets,
+};
+
+/* devices we initialise */
+
+static struct platform_device __initdata *smdk_devs[] = {
+       &s3c_device_nand,
+       &smdk_led4,
+       &smdk_led5,
+       &smdk_led6,
+       &smdk_led7,
+};
+
+void __init smdk_machine_init(void)
+{
+       /* Configure the LEDs (even if we have no LED support)*/
+
+       s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
+       s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
+       s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
+       s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
+
+       s3c2410_gpio_setpin(S3C2410_GPF4, 1);
+       s3c2410_gpio_setpin(S3C2410_GPF5, 1);
+       s3c2410_gpio_setpin(S3C2410_GPF6, 1);
+       s3c2410_gpio_setpin(S3C2410_GPF7, 1);
+
+       s3c_device_nand.dev.platform_data = &smdk_nand_info;
+
+       platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
+
+       s3c2410_pm_init();
+}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
new file mode 100644 (file)
index 0000000..6a2d107
--- /dev/null
@@ -0,0 +1,368 @@
+/* linux/arch/arm/plat-s3c24xx/cpu.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/SWLINUX/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Support
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-serial.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/s3c2400.h>
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2412.h>
+#include "s3c244x.h"
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include <asm/plat-s3c24xx/s3c2442.h>
+#include <asm/plat-s3c24xx/s3c2443.h>
+
+struct cpu_table {
+       unsigned long   idcode;
+       unsigned long   idmask;
+       void            (*map_io)(struct map_desc *mach_desc, int size);
+       void            (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+       void            (*init_clocks)(int xtal);
+       int             (*init)(void);
+       const char      *name;
+};
+
+/* table of supported CPUs */
+
+static const char name_s3c2400[]  = "S3C2400";
+static const char name_s3c2410[]  = "S3C2410";
+static const char name_s3c2412[]  = "S3C2412";
+static const char name_s3c2440[]  = "S3C2440";
+static const char name_s3c2442[]  = "S3C2442";
+static const char name_s3c2443[]  = "S3C2443";
+static const char name_s3c2410a[] = "S3C2410A";
+static const char name_s3c2440a[] = "S3C2440A";
+
+static struct cpu_table cpu_ids[] __initdata = {
+       {
+               .idcode         = 0x32410000,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2410_map_io,
+               .init_clocks    = s3c2410_init_clocks,
+               .init_uarts     = s3c2410_init_uarts,
+               .init           = s3c2410_init,
+               .name           = name_s3c2410
+       },
+       {
+               .idcode         = 0x32410002,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2410_map_io,
+               .init_clocks    = s3c2410_init_clocks,
+               .init_uarts     = s3c2410_init_uarts,
+               .init           = s3c2410_init,
+               .name           = name_s3c2410a
+       },
+       {
+               .idcode         = 0x32440000,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c244x_map_io,
+               .init_clocks    = s3c244x_init_clocks,
+               .init_uarts     = s3c244x_init_uarts,
+               .init           = s3c2440_init,
+               .name           = name_s3c2440
+       },
+       {
+               .idcode         = 0x32440001,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c244x_map_io,
+               .init_clocks    = s3c244x_init_clocks,
+               .init_uarts     = s3c244x_init_uarts,
+               .init           = s3c2440_init,
+               .name           = name_s3c2440a
+       },
+       {
+               .idcode         = 0x32440aaa,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c244x_map_io,
+               .init_clocks    = s3c244x_init_clocks,
+               .init_uarts     = s3c244x_init_uarts,
+               .init           = s3c2442_init,
+               .name           = name_s3c2442
+       },
+       {
+               .idcode         = 0x32412001,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2412_map_io,
+               .init_clocks    = s3c2412_init_clocks,
+               .init_uarts     = s3c2412_init_uarts,
+               .init           = s3c2412_init,
+               .name           = name_s3c2412,
+       },
+       {                       /* a newer version of the s3c2412 */
+               .idcode         = 0x32412003,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2412_map_io,
+               .init_clocks    = s3c2412_init_clocks,
+               .init_uarts     = s3c2412_init_uarts,
+               .init           = s3c2412_init,
+               .name           = name_s3c2412,
+       },
+       {
+               .idcode         = 0x32443001,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2443_map_io,
+               .init_clocks    = s3c2443_init_clocks,
+               .init_uarts     = s3c2443_init_uarts,
+               .init           = s3c2443_init,
+               .name           = name_s3c2443,
+       },
+       {
+               .idcode         = 0x0,   /* S3C2400 doesn't have an idcode */
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2400_map_io,
+               .init_clocks    = s3c2400_init_clocks,
+               .init_uarts     = s3c2400_init_uarts,
+               .init           = s3c2400_init,
+               .name           = name_s3c2400
+       },
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s3c_iodesc[] __initdata = {
+       IODESC_ENT(GPIO),
+       IODESC_ENT(IRQ),
+       IODESC_ENT(MEMCTRL),
+       IODESC_ENT(UART)
+};
+
+
+static struct cpu_table *
+s3c_lookup_cpu(unsigned long idcode)
+{
+       struct cpu_table *tab;
+       int count;
+
+       tab = cpu_ids;
+       for (count = 0; count < ARRAY_SIZE(cpu_ids); count++, tab++) {
+               if ((idcode & tab->idmask) == tab->idcode)
+                       return tab;
+       }
+
+       return NULL;
+}
+
+/* board information */
+
+static struct s3c24xx_board *board;
+
+void s3c24xx_set_board(struct s3c24xx_board *b)
+{
+       int i;
+
+       board = b;
+
+       if (b->clocks_count != 0) {
+               struct clk **ptr = b->clocks;
+
+               for (i = b->clocks_count; i > 0; i--, ptr++)
+                       s3c24xx_register_clock(*ptr);
+       }
+}
+
+/* cpu information */
+
+static struct cpu_table *cpu;
+
+static unsigned long s3c24xx_read_idcode_v5(void)
+{
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+       return __raw_readl(S3C2412_GSTATUS1);
+#else
+       return 1UL;     /* don't look like an 2400 */
+#endif
+}
+
+static unsigned long s3c24xx_read_idcode_v4(void)
+{
+#ifndef CONFIG_CPU_S3C2400
+       return __raw_readl(S3C2410_GSTATUS1);
+#else
+       return 0UL;
+#endif
+}
+
+void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
+{
+       unsigned long idcode = 0x0;
+
+       /* initialise the io descriptors we need for initialisation */
+       iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+
+       if (cpu_architecture() >= CPU_ARCH_ARMv5) {
+               idcode = s3c24xx_read_idcode_v5();
+       } else {
+               idcode = s3c24xx_read_idcode_v4();
+       }
+
+       cpu = s3c_lookup_cpu(idcode);
+
+       if (cpu == NULL) {
+               printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
+               panic("Unknown S3C24XX CPU");
+       }
+
+       printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
+
+       if (cpu->map_io == NULL || cpu->init == NULL) {
+               printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
+               panic("Unsupported S3C24XX CPU");
+       }
+
+       (cpu->map_io)(mach_desc, size);
+}
+
+/* s3c24xx_init_clocks
+ *
+ * Initialise the clock subsystem and associated information from the
+ * given master crystal value.
+ *
+ * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
+ *      != 0 -> PLL crystal value in Hz
+*/
+
+void __init s3c24xx_init_clocks(int xtal)
+{
+       if (xtal == 0)
+               xtal = 12*1000*1000;
+
+       if (cpu == NULL)
+               panic("s3c24xx_init_clocks: no cpu setup?\n");
+
+       if (cpu->init_clocks == NULL)
+               panic("s3c24xx_init_clocks: cpu has no clock init\n");
+       else
+               (cpu->init_clocks)(xtal);
+}
+
+/* uart management */
+
+static int nr_uarts __initdata = 0;
+
+static struct s3c2410_uartcfg uart_cfgs[3];
+
+/* s3c24xx_init_uartdevs
+ *
+ * copy the specified platform data and configuration into our central
+ * set of devices, before the data is thrown away after the init process.
+ *
+ * This also fills in the array passed to the serial driver for the
+ * early initialisation of the console.
+*/
+
+void __init s3c24xx_init_uartdevs(char *name,
+                                 struct s3c24xx_uart_resources *res,
+                                 struct s3c2410_uartcfg *cfg, int no)
+{
+       struct platform_device *platdev;
+       struct s3c2410_uartcfg *cfgptr = uart_cfgs;
+       struct s3c24xx_uart_resources *resp;
+       int uart;
+
+       memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
+
+       for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
+               platdev = s3c24xx_uart_src[cfgptr->hwport];
+
+               resp = res + cfgptr->hwport;
+
+               s3c24xx_uart_devs[uart] = platdev;
+
+               platdev->name = name;
+               platdev->resource = resp->resources;
+               platdev->num_resources = resp->nr_resources;
+
+               platdev->dev.platform_data = cfgptr;
+       }
+
+       nr_uarts = no;
+}
+
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       if (cpu == NULL)
+               return;
+
+       if (cpu->init_uarts == NULL) {
+               printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
+       } else
+               (cpu->init_uarts)(cfg, no);
+}
+
+static int __init s3c_arch_init(void)
+{
+       int ret;
+
+       // do the correct init for cpu
+
+       if (cpu == NULL)
+               panic("s3c_arch_init: NULL cpu\n");
+
+       ret = (cpu->init)();
+       if (ret != 0)
+               return ret;
+
+       ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+       if (ret != 0)
+               return ret;
+
+       if (board != NULL) {
+               struct platform_device **ptr = board->devices;
+               int i;
+
+               for (i = 0; i < board->devices_count; i++, ptr++) {
+                       ret = platform_device_register(*ptr);
+
+                       if (ret) {
+                               printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr);
+                       }
+               }
+
+               /* mask any error, we may not need all these board
+                * devices */
+               ret = 0;
+       }
+
+       return ret;
+}
+
+arch_initcall(s3c_arch_init);
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
new file mode 100644 (file)
index 0000000..0fe53b3
--- /dev/null
@@ -0,0 +1,600 @@
+/* linux/arch/arm/plat-s3c24xx/devs.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX platform device definitions
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/fb.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/udc.h>
+
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+/* Serial port registrations */
+
+static struct resource s3c2410_uart0_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART0,
+               .end   = S3C2410_PA_UART0 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX0,
+               .end   = IRQ_S3CUART_ERR0,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART1,
+               .end   = S3C2410_PA_UART1 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX1,
+               .end   = IRQ_S3CUART_ERR1,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART2,
+               .end   = S3C2410_PA_UART2 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX2,
+               .end   = IRQ_S3CUART_ERR2,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = s3c2410_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart0_resource),
+       },
+       [1] = {
+               .resources      = s3c2410_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart1_resource),
+       },
+       [2] = {
+               .resources      = s3c2410_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart2_resource),
+       },
+};
+
+/* yart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+       .id             = 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+       .id             = 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+       .id             = 2,
+};
+
+struct platform_device *s3c24xx_uart_src[3] = {
+       &s3c24xx_uart_device0,
+       &s3c24xx_uart_device1,
+       &s3c24xx_uart_device2,
+};
+
+struct platform_device *s3c24xx_uart_devs[3] = {
+};
+
+/* USB Host Controller */
+
+static struct resource s3c_usb_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_USBHOST,
+               .end   = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_USBH,
+               .end   = IRQ_USBH,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_usb = {
+       .name             = "s3c2410-ohci",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_usb_resource),
+       .resource         = s3c_usb_resource,
+       .dev              = {
+               .dma_mask = &s3c_device_usb_dmamask,
+               .coherent_dma_mask = 0xffffffffUL
+       }
+};
+
+EXPORT_SYMBOL(s3c_device_usb);
+
+/* LCD Controller */
+
+static struct resource s3c_lcd_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_LCD,
+               .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_LCD,
+               .end   = IRQ_LCD,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_lcd = {
+       .name             = "s3c2410-lcd",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_lcd_resource),
+       .resource         = s3c_lcd_resource,
+       .dev              = {
+               .dma_mask               = &s3c_device_lcd_dmamask,
+               .coherent_dma_mask      = 0xffffffffUL
+       }
+};
+
+EXPORT_SYMBOL(s3c_device_lcd);
+
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+{
+       struct s3c2410fb_mach_info *npd;
+
+       npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+       if (npd) {
+               memcpy(npd, pd, sizeof(*npd));
+               s3c_device_lcd.dev.platform_data = npd;
+       } else {
+               printk(KERN_ERR "no memory for LCD platform data\n");
+       }
+}
+
+/* NAND Controller */
+
+static struct resource s3c_nand_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_NAND,
+               .end   = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+struct platform_device s3c_device_nand = {
+       .name             = "s3c2410-nand",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_nand_resource),
+       .resource         = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
+
+/* USB Device (Gadget)*/
+
+static struct resource s3c_usbgadget_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_USBDEV,
+               .end   = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_USBD,
+               .end   = IRQ_USBD,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_usbgadget = {
+       .name             = "s3c2410-usbgadget",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_usbgadget_resource),
+       .resource         = s3c_usbgadget_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_usbgadget);
+
+void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
+{
+       struct s3c2410_udc_mach_info *npd;
+
+       npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+       if (npd) {
+               memcpy(npd, pd, sizeof(*npd));
+               s3c_device_usbgadget.dev.platform_data = npd;
+       } else {
+               printk(KERN_ERR "no memory for udc platform data\n");
+       }
+}
+
+
+/* Watchdog */
+
+static struct resource s3c_wdt_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_WATCHDOG,
+               .end   = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_WDT,
+               .end   = IRQ_WDT,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_wdt = {
+       .name             = "s3c2410-wdt",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_wdt_resource),
+       .resource         = s3c_wdt_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_wdt);
+
+/* I2C */
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_IIC,
+               .end   = S3C24XX_PA_IIC + S3C24XX_SZ_IIC - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_IIC,
+               .end   = IRQ_IIC,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_i2c = {
+       .name             = "s3c2410-i2c",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
+       .resource         = s3c_i2c_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_i2c);
+
+/* IIS */
+
+static struct resource s3c_iis_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_IIS,
+               .end   = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static u64 s3c_device_iis_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_iis = {
+       .name             = "s3c2410-iis",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_iis_resource),
+       .resource         = s3c_iis_resource,
+       .dev              = {
+               .dma_mask = &s3c_device_iis_dmamask,
+               .coherent_dma_mask = 0xffffffffUL
+       }
+};
+
+EXPORT_SYMBOL(s3c_device_iis);
+
+/* RTC */
+
+static struct resource s3c_rtc_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_RTC,
+               .end   = S3C24XX_PA_RTC + 0xff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_RTC,
+               .end   = IRQ_RTC,
+               .flags = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start = IRQ_TICK,
+               .end   = IRQ_TICK,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+struct platform_device s3c_device_rtc = {
+       .name             = "s3c2410-rtc",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
+       .resource         = s3c_rtc_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_rtc);
+
+/* ADC */
+
+static struct resource s3c_adc_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_ADC,
+               .end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start = IRQ_ADC,
+               .end   = IRQ_ADC,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_adc = {
+       .name             = "s3c2410-adc",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_adc_resource),
+       .resource         = s3c_adc_resource,
+};
+
+/* SDI */
+
+static struct resource s3c_sdi_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_SDI,
+               .end   = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_SDI,
+               .end   = IRQ_SDI,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_sdi = {
+       .name             = "s3c2410-sdi",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_sdi_resource),
+       .resource         = s3c_sdi_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_sdi);
+
+/* SPI (0) */
+
+static struct resource s3c_spi0_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_SPI,
+               .end   = S3C24XX_PA_SPI + 0x1f,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_SPI0,
+               .end   = IRQ_SPI0,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_spi0 = {
+       .name             = "s3c2410-spi",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s3c_spi0_resource),
+       .resource         = s3c_spi0_resource,
+        .dev              = {
+                .dma_mask = &s3c_device_spi0_dmamask,
+                .coherent_dma_mask = 0xffffffffUL
+        }
+};
+
+EXPORT_SYMBOL(s3c_device_spi0);
+
+/* SPI (1) */
+
+static struct resource s3c_spi1_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_SPI + 0x20,
+               .end   = S3C24XX_PA_SPI + 0x20 + 0x1f,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_SPI1,
+               .end   = IRQ_SPI1,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_spi1 = {
+       .name             = "s3c2410-spi",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s3c_spi1_resource),
+       .resource         = s3c_spi1_resource,
+        .dev              = {
+                .dma_mask = &s3c_device_spi1_dmamask,
+                .coherent_dma_mask = 0xffffffffUL
+        }
+};
+
+EXPORT_SYMBOL(s3c_device_spi1);
+
+/* pwm timer blocks */
+
+static struct resource s3c_timer0_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_TIMER + 0x0C,
+               .end   = S3C24XX_PA_TIMER + 0x0C + 0xB,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TIMER0,
+               .end   = IRQ_TIMER0,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_timer0 = {
+       .name             = "s3c2410-timer",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s3c_timer0_resource),
+       .resource         = s3c_timer0_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_timer0);
+
+/* timer 1 */
+
+static struct resource s3c_timer1_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_TIMER + 0x18,
+               .end   = S3C24XX_PA_TIMER + 0x23,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TIMER1,
+               .end   = IRQ_TIMER1,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_timer1 = {
+       .name             = "s3c2410-timer",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s3c_timer1_resource),
+       .resource         = s3c_timer1_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_timer1);
+
+/* timer 2 */
+
+static struct resource s3c_timer2_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_TIMER + 0x24,
+               .end   = S3C24XX_PA_TIMER + 0x2F,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TIMER2,
+               .end   = IRQ_TIMER2,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_timer2 = {
+       .name             = "s3c2410-timer",
+       .id               = 2,
+       .num_resources    = ARRAY_SIZE(s3c_timer2_resource),
+       .resource         = s3c_timer2_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_timer2);
+
+/* timer 3 */
+
+static struct resource s3c_timer3_resource[] = {
+       [0] = {
+               .start = S3C24XX_PA_TIMER + 0x30,
+               .end   = S3C24XX_PA_TIMER + 0x3B,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TIMER3,
+               .end   = IRQ_TIMER3,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+struct platform_device s3c_device_timer3 = {
+       .name             = "s3c2410-timer",
+       .id               = 3,
+       .num_resources    = ARRAY_SIZE(s3c_timer3_resource),
+       .resource         = s3c_timer3_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_timer3);
+
+#ifdef CONFIG_CPU_S3C2440
+
+/* Camif Controller */
+
+static struct resource s3c_camif_resource[] = {
+       [0] = {
+               .start = S3C2440_PA_CAMIF,
+               .end   = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_CAM,
+               .end   = IRQ_CAM,
+               .flags = IORESOURCE_IRQ,
+       }
+
+};
+
+static u64 s3c_device_camif_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_camif = {
+       .name             = "s3c2440-camif",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s3c_camif_resource),
+       .resource         = s3c_camif_resource,
+       .dev              = {
+               .dma_mask = &s3c_device_camif_dmamask,
+               .coherent_dma_mask = 0xffffffffUL
+       }
+};
+
+EXPORT_SYMBOL(s3c_device_camif);
+
+#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
new file mode 100644 (file)
index 0000000..4540a80
--- /dev/null
@@ -0,0 +1,1499 @@
+/* linux/arch/arm/plat-s3c24xx/dma.c
+ *
+ * Copyright (c) 2003-2005,2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA core
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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.
+*/
+
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+#include <asm/arch/map.h>
+
+#include <asm/plat-s3c24xx/dma.h>
+
+/* io map for dma */
+static void __iomem *dma_base;
+static struct kmem_cache *dma_kmem;
+
+static int dma_channels;
+
+struct s3c24xx_dma_selection dma_sel;
+
+/* dma channel state information */
+struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+/* debugging functions */
+
+#define BUF_MAGIC (0xcafebabe)
+
+#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
+
+#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
+
+#if 1
+#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
+#else
+static inline void
+dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
+{
+       pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
+       writel(val, dma_regaddr(chan, reg));
+}
+#endif
+
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
+
+/* captured register state for debug */
+
+struct s3c2410_dma_regstate {
+       unsigned long         dcsrc;
+       unsigned long         disrc;
+       unsigned long         dstat;
+       unsigned long         dcon;
+       unsigned long         dmsktrig;
+};
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+
+/* dmadbg_showregs
+ *
+ * simple debug routine to print the current state of the dma registers
+*/
+
+static void
+dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
+{
+       regs->dcsrc    = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+       regs->disrc    = dma_rdreg(chan, S3C2410_DMA_DISRC);
+       regs->dstat    = dma_rdreg(chan, S3C2410_DMA_DSTAT);
+       regs->dcon     = dma_rdreg(chan, S3C2410_DMA_DCON);
+       regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+}
+
+static void
+dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
+                struct s3c2410_dma_regstate *regs)
+{
+       printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
+              chan->number, fname, line,
+              regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
+              regs->dcon);
+}
+
+static void
+dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+       struct s3c2410_dma_regstate state;
+
+       dmadbg_capture(chan, &state);
+
+       printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
+              chan->number, fname, line, chan->load_state,
+              chan->curr, chan->next, chan->end);
+
+       dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+       struct s3c2410_dma_regstate state;
+
+       dmadbg_capture(chan, &state);
+       dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
+#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
+#else
+#define dbg_showregs(chan) do { } while(0)
+#define dbg_showchan(chan) do { } while(0)
+#endif /* CONFIG_S3C2410_DMA_DEBUG */
+
+static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
+
+/* lookup_dma_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
+{
+       if (channel & DMACH_LOW_LEVEL)
+               return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+       else
+               return dma_chan_map[channel];
+}
+
+/* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+*/
+
+static void
+s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
+{
+       if (stats == NULL)
+               return;
+
+       if (val > stats->timeout_longest)
+               stats->timeout_longest = val;
+       if (val < stats->timeout_shortest)
+               stats->timeout_shortest = val;
+
+       stats->timeout_avg += val;
+}
+
+/* s3c2410_dma_waitforload
+ *
+ * wait for the DMA engine to load a buffer, and update the state accordingly
+*/
+
+static int
+s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
+{
+       int timeout = chan->load_timeout;
+       int took;
+
+       if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
+               printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
+               return 0;
+       }
+
+       if (chan->stats != NULL)
+               chan->stats->loads++;
+
+       while (--timeout > 0) {
+               if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
+                       took = chan->load_timeout - timeout;
+
+                       s3c2410_dma_stats_timeout(chan->stats, took);
+
+                       switch (chan->load_state) {
+                       case S3C2410_DMALOAD_1LOADED:
+                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
+                               break;
+
+                       default:
+                               printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
+                       }
+
+                       return 1;
+               }
+       }
+
+       if (chan->stats != NULL) {
+               chan->stats->timeout_failed++;
+       }
+
+       return 0;
+}
+
+
+
+/* s3c2410_dma_loadbuffer
+ *
+ * load a buffer, and update the channel state
+*/
+
+static inline int
+s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
+                      struct s3c2410_dma_buf *buf)
+{
+       unsigned long reload;
+
+       pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
+                buf, (unsigned long)buf->data, buf->size);
+
+       if (buf == NULL) {
+               dmawarn("buffer is NULL\n");
+               return -EINVAL;
+       }
+
+       /* check the state of the channel before we do anything */
+
+       if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+               dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
+       }
+
+       if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
+               dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
+       }
+
+       /* it would seem sensible if we are the last buffer to not bother
+        * with the auto-reload bit, so that the DMA engine will not try
+        * and load another transfer after this one has finished...
+        */
+       if (chan->load_state == S3C2410_DMALOAD_NONE) {
+               pr_debug("load_state is none, checking for noreload (next=%p)\n",
+                        buf->next);
+               reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
+       } else {
+               //pr_debug("load_state is %d => autoreload\n", chan->load_state);
+               reload = S3C2410_DCON_AUTORELOAD;
+       }
+
+       if ((buf->data & 0xf0000000) != 0x30000000) {
+               dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+       }
+
+       writel(buf->data, chan->addr_reg);
+
+       dma_wrreg(chan, S3C2410_DMA_DCON,
+                 chan->dcon | reload | (buf->size/chan->xfer_unit));
+
+       chan->next = buf->next;
+
+       /* update the state of the channel */
+
+       switch (chan->load_state) {
+       case S3C2410_DMALOAD_NONE:
+               chan->load_state = S3C2410_DMALOAD_1LOADED;
+               break;
+
+       case S3C2410_DMALOAD_1RUNNING:
+               chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
+               break;
+
+       default:
+               dmawarn("dmaload: unknown state %d in loadbuffer\n",
+                       chan->load_state);
+               break;
+       }
+
+       return 0;
+}
+
+/* s3c2410_dma_call_op
+ *
+ * small routine to call the op routine with the given op if it has been
+ * registered
+*/
+
+static void
+s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
+{
+       if (chan->op_fn != NULL) {
+               (chan->op_fn)(chan, op);
+       }
+}
+
+/* s3c2410_dma_buffdone
+ *
+ * small wrapper to check if callback routine needs to be called, and
+ * if so, call it
+*/
+
+static inline void
+s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
+                    enum s3c2410_dma_buffresult result)
+{
+#if 0
+       pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
+                chan->callback_fn, buf, buf->id, buf->size, result);
+#endif
+
+       if (chan->callback_fn != NULL) {
+               (chan->callback_fn)(chan, buf->id, buf->size, result);
+       }
+}
+
+/* s3c2410_dma_start
+ *
+ * start a dma channel going
+*/
+
+static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
+{
+       unsigned long tmp;
+       unsigned long flags;
+
+       pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
+
+       local_irq_save(flags);
+
+       if (chan->state == S3C2410_DMA_RUNNING) {
+               pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
+               local_irq_restore(flags);
+               return 0;
+       }
+
+       chan->state = S3C2410_DMA_RUNNING;
+
+       /* check wether there is anything to load, and if not, see
+        * if we can find anything to load
+        */
+
+       if (chan->load_state == S3C2410_DMALOAD_NONE) {
+               if (chan->next == NULL) {
+                       printk(KERN_ERR "dma%d: channel has nothing loaded\n",
+                              chan->number);
+                       chan->state = S3C2410_DMA_IDLE;
+                       local_irq_restore(flags);
+                       return -EINVAL;
+               }
+
+               s3c2410_dma_loadbuffer(chan, chan->next);
+       }
+
+       dbg_showchan(chan);
+
+       /* enable the channel */
+
+       if (!chan->irq_enabled) {
+               enable_irq(chan->irq);
+               chan->irq_enabled = 1;
+       }
+
+       /* start the channel going */
+
+       tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+       tmp &= ~S3C2410_DMASKTRIG_STOP;
+       tmp |= S3C2410_DMASKTRIG_ON;
+       dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+       pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
+
+#if 0
+       /* the dma buffer loads should take care of clearing the AUTO
+        * reloading feature */
+       tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+       tmp &= ~S3C2410_DCON_NORELOAD;
+       dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+       s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
+
+       dbg_showchan(chan);
+
+       /* if we've only loaded one buffer onto the channel, then chec
+        * to see if we have another, and if so, try and load it so when
+        * the first buffer is finished, the new one will be loaded onto
+        * the channel */
+
+       if (chan->next != NULL) {
+               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               pr_debug("%s: buff not yet loaded, no more todo\n",
+                                        __FUNCTION__);
+                       } else {
+                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
+                               s3c2410_dma_loadbuffer(chan, chan->next);
+                       }
+
+               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+                       s3c2410_dma_loadbuffer(chan, chan->next);
+               }
+       }
+
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+/* s3c2410_dma_canload
+ *
+ * work out if we can queue another buffer into the DMA engine
+*/
+
+static int
+s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
+{
+       if (chan->load_state == S3C2410_DMALOAD_NONE ||
+           chan->load_state == S3C2410_DMALOAD_1RUNNING)
+               return 1;
+
+       return 0;
+}
+
+/* s3c2410_dma_enqueue
+ *
+ * queue an given buffer for dma transfer.
+ *
+ * id         the device driver's id information for this buffer
+ * data       the physical address of the buffer data
+ * size       the size of the buffer in bytes
+ *
+ * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
+ * is checked, and if set, the channel is started. If this flag isn't set,
+ * then an error will be returned.
+ *
+ * It is possible to queue more than one DMA buffer onto a channel at
+ * once, and the code will deal with the re-loading of the next buffer
+ * when necessary.
+*/
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+                       dma_addr_t data, int size)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+       struct s3c2410_dma_buf *buf;
+       unsigned long flags;
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: id=%p, data=%08x, size=%d\n",
+                __FUNCTION__, id, (unsigned int)data, size);
+
+       buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
+       if (buf == NULL) {
+               pr_debug("%s: out of memory (%ld alloc)\n",
+                        __FUNCTION__, (long)sizeof(*buf));
+               return -ENOMEM;
+       }
+
+       //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
+       //dbg_showchan(chan);
+
+       buf->next  = NULL;
+       buf->data  = buf->ptr = data;
+       buf->size  = size;
+       buf->id    = id;
+       buf->magic = BUF_MAGIC;
+
+       local_irq_save(flags);
+
+       if (chan->curr == NULL) {
+               /* we've got nothing loaded... */
+               pr_debug("%s: buffer %p queued onto empty channel\n",
+                        __FUNCTION__, buf);
+
+               chan->curr = buf;
+               chan->end  = buf;
+               chan->next = NULL;
+       } else {
+               pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
+                        chan->number, __FUNCTION__, buf);
+
+               if (chan->end == NULL)
+                       pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
+                                chan->number, __FUNCTION__, chan);
+
+               chan->end->next = buf;
+               chan->end = buf;
+       }
+
+       /* if necessary, update the next buffer field */
+       if (chan->next == NULL)
+               chan->next = buf;
+
+       /* check to see if we can load a buffer */
+       if (chan->state == S3C2410_DMA_RUNNING) {
+               if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               printk(KERN_ERR "dma%d: loadbuffer:"
+                                      "timeout loading buffer\n",
+                                      chan->number);
+                               dbg_showchan(chan);
+                               local_irq_restore(flags);
+                               return -EINVAL;
+                       }
+               }
+
+               while (s3c2410_dma_canload(chan) && chan->next != NULL) {
+                       s3c2410_dma_loadbuffer(chan, chan->next);
+               }
+       } else if (chan->state == S3C2410_DMA_IDLE) {
+               if (chan->flags & S3C2410_DMAF_AUTOSTART) {
+                       s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
+               }
+       }
+
+       local_irq_restore(flags);
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+static inline void
+s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
+{
+       int magicok = (buf->magic == BUF_MAGIC);
+
+       buf->magic = -1;
+
+       if (magicok) {
+               kmem_cache_free(dma_kmem, buf);
+       } else {
+               printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
+       }
+}
+
+/* s3c2410_dma_lastxfer
+ *
+ * called when the system is out of buffers, to ensure that the channel
+ * is prepared for shutdown.
+*/
+
+static inline void
+s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
+{
+#if 0
+       pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
+                chan->number, chan->load_state);
+#endif
+
+       switch (chan->load_state) {
+       case S3C2410_DMALOAD_NONE:
+               break;
+
+       case S3C2410_DMALOAD_1LOADED:
+               if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               /* flag error? */
+                       printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+                              chan->number, __FUNCTION__);
+                       return;
+               }
+               break;
+
+       case S3C2410_DMALOAD_1LOADED_1RUNNING:
+               /* I belive in this case we do not have anything to do
+                * until the next buffer comes along, and we turn off the
+                * reload */
+               return;
+
+       default:
+               pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
+                        chan->number, chan->load_state);
+               return;
+
+       }
+
+       /* hopefully this'll shut the damned thing up after the transfer... */
+       dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
+}
+
+
+#define dmadbg2(x...)
+
+static irqreturn_t
+s3c2410_dma_irq(int irq, void *devpw)
+{
+       struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
+       struct s3c2410_dma_buf  *buf;
+
+       buf = chan->curr;
+
+       dbg_showchan(chan);
+
+       /* modify the channel state */
+
+       switch (chan->load_state) {
+       case S3C2410_DMALOAD_1RUNNING:
+               /* TODO - if we are running only one buffer, we probably
+                * want to reload here, and then worry about the buffer
+                * callback */
+
+               chan->load_state = S3C2410_DMALOAD_NONE;
+               break;
+
+       case S3C2410_DMALOAD_1LOADED:
+               /* iirc, we should go back to NONE loaded here, we
+                * had a buffer, and it was never verified as being
+                * loaded.
+                */
+
+               chan->load_state = S3C2410_DMALOAD_NONE;
+               break;
+
+       case S3C2410_DMALOAD_1LOADED_1RUNNING:
+               /* we'll worry about checking to see if another buffer is
+                * ready after we've called back the owner. This should
+                * ensure we do not wait around too long for the DMA
+                * engine to start the next transfer
+                */
+
+               chan->load_state = S3C2410_DMALOAD_1LOADED;
+               break;
+
+       case S3C2410_DMALOAD_NONE:
+               printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
+                      chan->number);
+               break;
+
+       default:
+               printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
+                      chan->number, chan->load_state);
+               break;
+       }
+
+       if (buf != NULL) {
+               /* update the chain to make sure that if we load any more
+                * buffers when we call the callback function, things should
+                * work properly */
+
+               chan->curr = buf->next;
+               buf->next  = NULL;
+
+               if (buf->magic != BUF_MAGIC) {
+                       printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
+                              chan->number, __FUNCTION__, buf);
+                       return IRQ_HANDLED;
+               }
+
+               s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
+
+               /* free resouces */
+               s3c2410_dma_freebuf(buf);
+       } else {
+       }
+
+       /* only reload if the channel is still running... our buffer done
+        * routine may have altered the state by requesting the dma channel
+        * to stop or shutdown... */
+
+       /* todo: check that when the channel is shut-down from inside this
+        * function, we cope with unsetting reload, etc */
+
+       if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
+               unsigned long flags;
+
+               switch (chan->load_state) {
+               case S3C2410_DMALOAD_1RUNNING:
+                       /* don't need to do anything for this state */
+                       break;
+
+               case S3C2410_DMALOAD_NONE:
+                       /* can load buffer immediately */
+                       break;
+
+               case S3C2410_DMALOAD_1LOADED:
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               /* flag error? */
+                               printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+                                      chan->number, __FUNCTION__);
+                               return IRQ_HANDLED;
+                       }
+
+                       break;
+
+               case S3C2410_DMALOAD_1LOADED_1RUNNING:
+                       goto no_load;
+
+               default:
+                       printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
+                              chan->number, chan->load_state);
+                       return IRQ_HANDLED;
+               }
+
+               local_irq_save(flags);
+               s3c2410_dma_loadbuffer(chan, chan->next);
+               local_irq_restore(flags);
+       } else {
+               s3c2410_dma_lastxfer(chan);
+
+               /* see if we can stop this channel.. */
+               if (chan->load_state == S3C2410_DMALOAD_NONE) {
+                       pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
+                                chan->number, jiffies);
+                       s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+                                        S3C2410_DMAOP_STOP);
+               }
+       }
+
+ no_load:
+       return IRQ_HANDLED;
+}
+
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(unsigned int channel,
+                       struct s3c2410_dma_client *client,
+                       void *dev)
+{
+       struct s3c2410_dma_chan *chan;
+       unsigned long flags;
+       int err;
+
+       pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+                channel, client->name, dev);
+
+       local_irq_save(flags);
+
+       chan = s3c2410_dma_map_channel(channel);
+       if (chan == NULL) {
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       dbg_showchan(chan);
+
+       chan->client = client;
+       chan->in_use = 1;
+
+       if (!chan->irq_claimed) {
+               pr_debug("dma%d: %s : requesting irq %d\n",
+                        channel, __FUNCTION__, chan->irq);
+
+               chan->irq_claimed = 1;
+               local_irq_restore(flags);
+
+               err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
+                                 client->name, (void *)chan);
+
+               local_irq_save(flags);
+
+               if (err) {
+                       chan->in_use = 0;
+                       chan->irq_claimed = 0;
+                       local_irq_restore(flags);
+
+                       printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
+                              client->name, chan->irq, chan->number);
+                       return err;
+               }
+
+               chan->irq_enabled = 1;
+       }
+
+       local_irq_restore(flags);
+
+       /* need to setup */
+
+       pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+       unsigned long flags;
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       if (chan->client != client) {
+               printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+                      channel, chan->client, client);
+       }
+
+       /* sort out stopping and freeing the channel */
+
+       if (chan->state != S3C2410_DMA_IDLE) {
+               pr_debug("%s: need to stop dma channel %p\n",
+                      __FUNCTION__, chan);
+
+               /* possibly flush the channel */
+               s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
+       }
+
+       chan->client = NULL;
+       chan->in_use = 0;
+
+       if (chan->irq_claimed)
+               free_irq(chan->irq, (void *)chan);
+
+       chan->irq_claimed = 0;
+
+       if (!(channel & DMACH_LOW_LEVEL))
+               dma_chan_map[channel] = NULL;
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
+{
+       unsigned long flags;
+       unsigned long tmp;
+
+       pr_debug("%s:\n", __FUNCTION__);
+
+       dbg_showchan(chan);
+
+       local_irq_save(flags);
+
+       s3c2410_dma_call_op(chan,  S3C2410_DMAOP_STOP);
+
+       tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+       tmp |= S3C2410_DMASKTRIG_STOP;
+       //tmp &= ~S3C2410_DMASKTRIG_ON;
+       dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+#if 0
+       /* should also clear interrupts, according to WinCE BSP */
+       tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+       tmp |= S3C2410_DCON_NORELOAD;
+       dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+       /* should stop do this, or should we wait for flush? */
+       chan->state      = S3C2410_DMA_IDLE;
+       chan->load_state = S3C2410_DMALOAD_NONE;
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+{
+       unsigned long tmp;
+       unsigned int timeout = 0x10000;
+
+       while (timeout-- > 0) {
+               tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+               if (!(tmp & S3C2410_DMASKTRIG_ON))
+                       return;
+       }
+
+       pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
+/* s3c2410_dma_flush
+ *
+ * stop the channel, and remove all current and pending transfers
+*/
+
+static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
+{
+       struct s3c2410_dma_buf *buf, *next;
+       unsigned long flags;
+
+       pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
+
+       dbg_showchan(chan);
+
+       local_irq_save(flags);
+
+       if (chan->state != S3C2410_DMA_IDLE) {
+               pr_debug("%s: stopping channel...\n", __FUNCTION__ );
+               s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+       }
+
+       buf = chan->curr;
+       if (buf == NULL)
+               buf = chan->next;
+
+       chan->curr = chan->next = chan->end = NULL;
+
+       if (buf != NULL) {
+               for ( ; buf != NULL; buf = next) {
+                       next = buf->next;
+
+                       pr_debug("%s: free buffer %p, next %p\n",
+                              __FUNCTION__, buf, buf->next);
+
+                       s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
+                       s3c2410_dma_freebuf(buf);
+               }
+       }
+
+       dbg_showregs(chan);
+
+       s3c2410_dma_waitforstop(chan);
+
+#if 0
+       /* should also clear interrupts, according to WinCE BSP */
+       {
+               unsigned long tmp;
+
+               tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+               tmp |= S3C2410_DCON_NORELOAD;
+               dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+       }
+#endif
+
+       dbg_showregs(chan);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+int
+s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       dbg_showchan(chan);
+
+       /* if we've only loaded one buffer onto the channel, then chec
+        * to see if we have another, and if so, try and load it so when
+        * the first buffer is finished, the new one will be loaded onto
+        * the channel */
+
+       if (chan->next != NULL) {
+               if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+                       if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+                               pr_debug("%s: buff not yet loaded, no more todo\n",
+                                        __FUNCTION__);
+                       } else {
+                               chan->load_state = S3C2410_DMALOAD_1RUNNING;
+                               s3c2410_dma_loadbuffer(chan, chan->next);
+                       }
+
+               } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+                       s3c2410_dma_loadbuffer(chan, chan->next);
+               }
+       }
+
+
+       local_irq_restore(flags);
+
+       return 0;
+
+}
+
+int
+s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       switch (op) {
+       case S3C2410_DMAOP_START:
+               return s3c2410_dma_start(chan);
+
+       case S3C2410_DMAOP_STOP:
+               return s3c2410_dma_dostop(chan);
+
+       case S3C2410_DMAOP_PAUSE:
+       case S3C2410_DMAOP_RESUME:
+               return -ENOENT;
+
+       case S3C2410_DMAOP_FLUSH:
+               return s3c2410_dma_flush(chan);
+
+       case S3C2410_DMAOP_STARTED:
+               return s3c2410_dma_started(chan);
+
+       case S3C2410_DMAOP_TIMEOUT:
+               return 0;
+
+       }
+
+       return -ENOENT;      /* unknown, don't bother */
+}
+
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* DMA configuration for each channel
+ *
+ * DISRCC -> source of the DMA (AHB,APB)
+ * DISRC  -> source address of the DMA
+ * DIDSTC -> destination of the DMA (AHB,APD)
+ * DIDST  -> destination address of the DMA
+*/
+
+/* s3c2410_dma_config
+ *
+ * xfersize:     size of unit in bytes (1,2,4)
+ * dcon:         base value of the DCONx register
+*/
+
+int s3c2410_dma_config(dmach_t channel,
+                      int xferunit,
+                      int dcon)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
+                __FUNCTION__, channel, xferunit, dcon);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
+
+       dcon |= chan->dcon & dma_sel.dcon_mask;
+
+       pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
+
+       switch (xferunit) {
+       case 1:
+               dcon |= S3C2410_DCON_BYTE;
+               break;
+
+       case 2:
+               dcon |= S3C2410_DCON_HALFWORD;
+               break;
+
+       case 4:
+               dcon |= S3C2410_DCON_WORD;
+               break;
+
+       default:
+               pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
+               return -EINVAL;
+       }
+
+       dcon |= S3C2410_DCON_HWTRIG;
+       dcon |= S3C2410_DCON_INTREQ;
+
+       pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
+
+       chan->dcon = dcon;
+       chan->xfer_unit = xferunit;
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
+
+       chan->flags = flags;
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
+
+       chan->op_fn = rtn;
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
+
+       chan->callback_fn = rtn;
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the dma source/destination hardware type and address
+ *
+ * source:    S3C2410_DMASRC_HW: source is hardware
+ *            S3C2410_DMASRC_MEM: source is memory
+ *
+ * hwcfg:     the value for xxxSTCn register,
+ *            bit 0: 0=increment pointer, 1=leave pointer
+ *            bit 1: 0=soucre is AHB, 1=soucre is APB
+ *
+ * devaddr:   physical address of the source
+*/
+
+int s3c2410_dma_devconfig(int channel,
+                         enum s3c2410_dmasrc source,
+                         int hwcfg,
+                         unsigned long devaddr)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
+                __FUNCTION__, (int)source, hwcfg, devaddr);
+
+       chan->source = source;
+       chan->dev_addr = devaddr;
+
+       switch (source) {
+       case S3C2410_DMASRC_HW:
+               /* source is hardware */
+               pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
+                        __FUNCTION__, devaddr, hwcfg);
+               dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
+               dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
+               dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
+
+               chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
+               return 0;
+
+       case S3C2410_DMASRC_MEM:
+               /* source is memory */
+               pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
+                         __FUNCTION__, devaddr, hwcfg);
+               dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
+               dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
+               dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
+
+               chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
+               return 0;
+       }
+
+       printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
+       return -EINVAL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
+{
+       struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+
+       if (chan == NULL)
+               return -EINVAL;
+
+       if (src != NULL)
+               *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+       if (dst != NULL)
+               *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+
+/* system device class */
+
+#ifdef CONFIG_PM
+
+static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
+{
+       struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
+
+       printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
+
+       if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
+               /* the dma channel is still working, which is probably
+                * a bad thing to do over suspend/resume. We stop the
+                * channel and assume that the client is either going to
+                * retry after resume, or that it is broken.
+                */
+
+               printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
+                      cp->number);
+
+               s3c2410_dma_dostop(cp);
+       }
+
+       return 0;
+}
+
+static int s3c2410_dma_resume(struct sys_device *dev)
+{
+       return 0;
+}
+
+#else
+#define s3c2410_dma_suspend NULL
+#define s3c2410_dma_resume  NULL
+#endif /* CONFIG_PM */
+
+struct sysdev_class dma_sysclass = {
+       set_kset_name("s3c24xx-dma"),
+       .suspend        = s3c2410_dma_suspend,
+       .resume         = s3c2410_dma_resume,
+};
+
+/* kmem cache implementation */
+
+static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
+{
+       memset(p, 0, sizeof(struct s3c2410_dma_buf));
+}
+
+/* initialisation code */
+
+int __init s3c24xx_dma_sysclass_init(void)
+{
+       int ret = sysdev_class_register(&dma_sysclass);
+
+       if (ret != 0)
+               printk(KERN_ERR "dma sysclass registration failed\n");
+
+       return ret;
+}
+
+core_initcall(s3c24xx_dma_sysclass_init);
+
+int __init s3c24xx_dma_sysdev_register(void)
+{
+       struct s3c2410_dma_chan *cp = s3c2410_chans;
+       int channel, ret;
+
+       for (channel = 0; channel < dma_channels; cp++, channel++) {
+               cp->dev.cls = &dma_sysclass;
+               cp->dev.id  = channel;
+               ret = sysdev_register(&cp->dev);
+
+               if (ret) {
+                       printk(KERN_ERR "error registering dev for dma %d\n",
+                              channel);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+late_initcall(s3c24xx_dma_sysdev_register);
+
+int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+                           unsigned int stride)
+{
+       struct s3c2410_dma_chan *cp;
+       int channel;
+       int ret;
+
+       printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
+
+       dma_channels = channels;
+
+       dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
+       if (dma_base == NULL) {
+               printk(KERN_ERR "dma failed to remap register block\n");
+               return -ENOMEM;
+       }
+
+       dma_kmem = kmem_cache_create("dma_desc",
+                                    sizeof(struct s3c2410_dma_buf), 0,
+                                    SLAB_HWCACHE_ALIGN,
+                                    s3c2410_dma_cache_ctor, NULL);
+
+       if (dma_kmem == NULL) {
+               printk(KERN_ERR "dma failed to make kmem cache\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       for (channel = 0; channel < channels;  channel++) {
+               cp = &s3c2410_chans[channel];
+
+               memset(cp, 0, sizeof(struct s3c2410_dma_chan));
+
+               /* dma channel irqs are in order.. */
+               cp->number = channel;
+               cp->irq    = channel + irq;
+               cp->regs   = dma_base + (channel * stride);
+
+               /* point current stats somewhere */
+               cp->stats  = &cp->stats_store;
+               cp->stats_store.timeout_shortest = LONG_MAX;
+
+               /* basic channel configuration */
+
+               cp->load_timeout = 1<<18;
+
+               printk("DMA channel %d at %p, irq %d\n",
+                      cp->number, cp->regs, cp->irq);
+       }
+
+       return 0;
+
+ err:
+       kmem_cache_destroy(dma_kmem);
+       iounmap(dma_base);
+       dma_base = NULL;
+       return ret;
+}
+
+int s3c2410_dma_init(void)
+{
+       return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
+}
+
+static inline int is_channel_valid(unsigned int channel)
+{
+       return (channel & DMA_CH_VALID);
+}
+
+static struct s3c24xx_dma_order *dma_order;
+
+
+/* s3c2410_dma_map_channel()
+ *
+ * turn the virtual channel number into a real, and un-used hardware
+ * channel.
+ *
+ * first, try the dma ordering given to us by either the relevant
+ * dma code, or the board. Then just find the first usable free
+ * channel
+*/
+
+struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+{
+       struct s3c24xx_dma_order_ch *ord = NULL;
+       struct s3c24xx_dma_map *ch_map;
+       struct s3c2410_dma_chan *dmach;
+       int ch;
+
+       if (dma_sel.map == NULL || channel > dma_sel.map_size)
+               return NULL;
+
+       ch_map = dma_sel.map + channel;
+
+       /* first, try the board mapping */
+
+       if (dma_order) {
+               ord = &dma_order->channels[channel];
+
+               for (ch = 0; ch < dma_channels; ch++) {
+                       if (!is_channel_valid(ord->list[ch]))
+                               continue;
+
+                       if (s3c2410_chans[ord->list[ch]].in_use == 0) {
+                               ch = ord->list[ch] & ~DMA_CH_VALID;
+                               goto found;
+                       }
+               }
+
+               if (ord->flags & DMA_CH_NEVER)
+                       return NULL;
+       }
+
+       /* second, search the channel map for first free */
+
+       for (ch = 0; ch < dma_channels; ch++) {
+               if (!is_channel_valid(ch_map->channels[ch]))
+                       continue;
+
+               if (s3c2410_chans[ch].in_use == 0) {
+                       printk("mapped channel %d to %d\n", channel, ch);
+                       break;
+               }
+       }
+
+       if (ch >= dma_channels)
+               return NULL;
+
+       /* update our channel mapping */
+
+ found:
+       dmach = &s3c2410_chans[ch];
+       dma_chan_map[channel] = dmach;
+
+       /* select the channel */
+
+       (dma_sel.select)(dmach, ch_map);
+
+       return dmach;
+}
+
+static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
+{
+       return 0;
+}
+
+int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
+{
+       struct s3c24xx_dma_map *nmap;
+       size_t map_sz = sizeof(*nmap) * sel->map_size;
+       int ptr;
+
+       nmap = kmalloc(map_sz, GFP_KERNEL);
+       if (nmap == NULL)
+               return -ENOMEM;
+
+       memcpy(nmap, sel->map, map_sz);
+       memcpy(&dma_sel, sel, sizeof(*sel));
+
+       dma_sel.map = nmap;
+
+       for (ptr = 0; ptr < sel->map_size; ptr++)
+               s3c24xx_dma_check_entry(nmap+ptr, ptr);
+
+       return 0;
+}
+
+int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
+{
+       struct s3c24xx_dma_order *nord = dma_order;
+
+       if (nord == NULL)
+               nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
+
+       if (nord == NULL) {
+               printk(KERN_ERR "no memory to store dma channel order\n");
+               return -ENOMEM;
+       }
+
+       dma_order = nord;
+       memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
+       return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
new file mode 100644 (file)
index 0000000..ec3a09c
--- /dev/null
@@ -0,0 +1,188 @@
+/* linux/arch/arm/plat-s3c24xx/gpio.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX GPIO support
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-gpio.h>
+
+void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
+{
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
+       unsigned long mask;
+       unsigned long con;
+       unsigned long flags;
+
+       if (pin < S3C2410_GPIO_BANKB) {
+               mask = 1 << S3C2410_GPIO_OFFSET(pin);
+       } else {
+               mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
+       }
+
+       switch (function) {
+       case S3C2410_GPIO_LEAVE:
+               mask = 0;
+               function = 0;
+               break;
+
+       case S3C2410_GPIO_INPUT:
+       case S3C2410_GPIO_OUTPUT:
+       case S3C2410_GPIO_SFN2:
+       case S3C2410_GPIO_SFN3:
+               if (pin < S3C2410_GPIO_BANKB) {
+                       function -= 1;
+                       function &= 1;
+                       function <<= S3C2410_GPIO_OFFSET(pin);
+               } else {
+                       function &= 3;
+                       function <<= S3C2410_GPIO_OFFSET(pin)*2;
+               }
+       }
+
+       /* modify the specified register wwith IRQs off */
+
+       local_irq_save(flags);
+
+       con  = __raw_readl(base + 0x00);
+       con &= ~mask;
+       con |= function;
+
+       __raw_writel(con, base + 0x00);
+
+       local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
+
+unsigned int s3c2410_gpio_getcfg(unsigned int pin)
+{
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
+       unsigned long val = __raw_readl(base);
+
+       if (pin < S3C2410_GPIO_BANKB) {
+               val >>= S3C2410_GPIO_OFFSET(pin);
+               val &= 1;
+               val += 1;
+       } else {
+               val >>= S3C2410_GPIO_OFFSET(pin)*2;
+               val &= 3;
+       }
+
+       return val | S3C2410_GPIO_INPUT;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+
+void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
+{
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
+       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       unsigned long flags;
+       unsigned long up;
+
+       if (pin < S3C2410_GPIO_BANKB)
+               return;
+
+       local_irq_save(flags);
+
+       up = __raw_readl(base + 0x08);
+       up &= ~(1L << offs);
+       up |= to << offs;
+       __raw_writel(up, base + 0x08);
+
+       local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_pullup);
+
+void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
+{
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
+       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       unsigned long flags;
+       unsigned long dat;
+
+       local_irq_save(flags);
+
+       dat = __raw_readl(base + 0x04);
+       dat &= ~(1 << offs);
+       dat |= to << offs;
+       __raw_writel(dat, base + 0x04);
+
+       local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_setpin);
+
+unsigned int s3c2410_gpio_getpin(unsigned int pin)
+{
+       void __iomem *base = S3C24XX_GPIO_BASE(pin);
+       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+
+       return __raw_readl(base + 0x04) & (1<< offs);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getpin);
+
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+       unsigned long flags;
+       unsigned long misccr;
+
+       local_irq_save(flags);
+       misccr = __raw_readl(S3C24XX_MISCCR);
+       misccr &= ~clear;
+       misccr ^= change;
+       __raw_writel(misccr, S3C24XX_MISCCR);
+       local_irq_restore(flags);
+
+       return misccr;
+}
+
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+
+int s3c2410_gpio_getirq(unsigned int pin)
+{
+       if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
+               return -1;      /* not valid interrupts */
+
+       if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
+               return -1;      /* not valid pin */
+
+       if (pin < S3C2410_GPF4)
+               return (pin - S3C2410_GPF0) + IRQ_EINT0;
+
+       if (pin < S3C2410_GPG0)
+               return (pin - S3C2410_GPF4) + IRQ_EINT4;
+
+       return (pin - S3C2410_GPG0) + IRQ_EINT8;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
new file mode 100644 (file)
index 0000000..ce18639
--- /dev/null
@@ -0,0 +1,801 @@
+/* linux/arch/arm/plat-s3c24xx/irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ *
+ * Changelog:
+ *
+ *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
+ *                Fixed compile warnings
+ *
+ *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
+ *                Fixed s3c_extirq_type
+ *
+ *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
+ *                Addition of ADC/TC demux
+ *
+ *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
+ *               Fix for set_irq_type() on low EINT numbers
+ *
+ *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
+ *               Tidy up KF's patch and sort out new release
+ *
+ *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
+ *               Add support for power management controls
+ *
+ *   04-Nov-2004  Ben Dooks
+ *               Fix standard IRQ wake for EINT0..4 and RTC
+ *
+ *   22-Feb-2005  Ben Dooks
+ *               Fixed edge-triggering on ADC IRQ
+ *
+ *   28-Jun-2005  Ben Dooks
+ *               Mark IRQ_LCD valid
+ *
+ *   25-Jul-2005  Ben Dooks
+ *               Split the S3C2440 IRQ code to seperate file
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+/* wakeup irq control */
+
+#ifdef CONFIG_PM
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow     = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_intmask      = 0xffffffffL;
+unsigned long s3c_irqwake_eintallow    = 0x0000fff0L;
+unsigned long s3c_irqwake_eintmask     = 0xffffffffL;
+
+int
+s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+       unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+
+       if (!(s3c_irqwake_intallow & irqbit))
+               return -ENOENT;
+
+       printk(KERN_INFO "wake %s for irq %d\n",
+              state ? "enabled" : "disabled", irqno);
+
+       if (!state)
+               s3c_irqwake_intmask |= irqbit;
+       else
+               s3c_irqwake_intmask &= ~irqbit;
+
+       return 0;
+}
+
+static int
+s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+       unsigned long bit = 1L << (irqno - EXTINT_OFF);
+
+       if (!(s3c_irqwake_eintallow & bit))
+               return -ENOENT;
+
+       printk(KERN_INFO "wake %s for irq %d\n",
+              state ? "enabled" : "disabled", irqno);
+
+       if (!state)
+               s3c_irqwake_eintmask |= bit;
+       else
+               s3c_irqwake_eintmask &= ~bit;
+
+       return 0;
+}
+
+#else
+#define s3c_irqext_wake NULL
+#define s3c_irq_wake NULL
+#endif
+
+
+static void
+s3c_irq_mask(unsigned int irqno)
+{
+       unsigned long mask;
+
+       irqno -= IRQ_EINT0;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       mask |= 1UL << irqno;
+       __raw_writel(mask, S3C2410_INTMSK);
+}
+
+static inline void
+s3c_irq_ack(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c_irq_maskack(unsigned int irqno)
+{
+       unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+
+static void
+s3c_irq_unmask(unsigned int irqno)
+{
+       unsigned long mask;
+
+       if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
+               irqdbf2("s3c_irq_unmask %d\n", irqno);
+
+       irqno -= IRQ_EINT0;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       mask &= ~(1UL << irqno);
+       __raw_writel(mask, S3C2410_INTMSK);
+}
+
+struct irq_chip s3c_irq_level_chip = {
+       .name           = "s3c-level",
+       .ack            = s3c_irq_maskack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake
+};
+
+static struct irq_chip s3c_irq_chip = {
+       .name           = "s3c",
+       .ack            = s3c_irq_ack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake
+};
+
+static void
+s3c_irqext_mask(unsigned int irqno)
+{
+       unsigned long mask;
+
+       irqno -= EXTINT_OFF;
+
+       mask = __raw_readl(S3C24XX_EINTMASK);
+       mask |= ( 1UL << irqno);
+       __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+static void
+s3c_irqext_ack(unsigned int irqno)
+{
+       unsigned long req;
+       unsigned long bit;
+       unsigned long mask;
+
+       bit = 1UL << (irqno - EXTINT_OFF);
+
+       mask = __raw_readl(S3C24XX_EINTMASK);
+
+       __raw_writel(bit, S3C24XX_EINTPEND);
+
+       req = __raw_readl(S3C24XX_EINTPEND);
+       req &= ~mask;
+
+       /* not sure if we should be acking the parent irq... */
+
+       if (irqno <= IRQ_EINT7 ) {
+               if ((req & 0xf0) == 0)
+                       s3c_irq_ack(IRQ_EINT4t7);
+       } else {
+               if ((req >> 8) == 0)
+                       s3c_irq_ack(IRQ_EINT8t23);
+       }
+}
+
+static void
+s3c_irqext_unmask(unsigned int irqno)
+{
+       unsigned long mask;
+
+       irqno -= EXTINT_OFF;
+
+       mask = __raw_readl(S3C24XX_EINTMASK);
+       mask &= ~( 1UL << irqno);
+       __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+int
+s3c_irqext_type(unsigned int irq, unsigned int type)
+{
+       void __iomem *extint_reg;
+       void __iomem *gpcon_reg;
+       unsigned long gpcon_offset, extint_offset;
+       unsigned long newvalue = 0, value;
+
+       if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
+       {
+               gpcon_reg = S3C2410_GPFCON;
+               extint_reg = S3C24XX_EXTINT0;
+               gpcon_offset = (irq - IRQ_EINT0) * 2;
+               extint_offset = (irq - IRQ_EINT0) * 4;
+       }
+       else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
+       {
+               gpcon_reg = S3C2410_GPFCON;
+               extint_reg = S3C24XX_EXTINT0;
+               gpcon_offset = (irq - (EXTINT_OFF)) * 2;
+               extint_offset = (irq - (EXTINT_OFF)) * 4;
+       }
+       else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
+       {
+               gpcon_reg = S3C2410_GPGCON;
+               extint_reg = S3C24XX_EXTINT1;
+               gpcon_offset = (irq - IRQ_EINT8) * 2;
+               extint_offset = (irq - IRQ_EINT8) * 4;
+       }
+       else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
+       {
+               gpcon_reg = S3C2410_GPGCON;
+               extint_reg = S3C24XX_EXTINT2;
+               gpcon_offset = (irq - IRQ_EINT8) * 2;
+               extint_offset = (irq - IRQ_EINT16) * 4;
+       } else
+               return -1;
+
+       /* Set the GPIO to external interrupt mode */
+       value = __raw_readl(gpcon_reg);
+       value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
+       __raw_writel(value, gpcon_reg);
+
+       /* Set the external interrupt to pointed trigger type */
+       switch (type)
+       {
+               case IRQT_NOEDGE:
+                       printk(KERN_WARNING "No edge setting!\n");
+                       break;
+
+               case IRQT_RISING:
+                       newvalue = S3C2410_EXTINT_RISEEDGE;
+                       break;
+
+               case IRQT_FALLING:
+                       newvalue = S3C2410_EXTINT_FALLEDGE;
+                       break;
+
+               case IRQT_BOTHEDGE:
+                       newvalue = S3C2410_EXTINT_BOTHEDGE;
+                       break;
+
+               case IRQT_LOW:
+                       newvalue = S3C2410_EXTINT_LOWLEV;
+                       break;
+
+               case IRQT_HIGH:
+                       newvalue = S3C2410_EXTINT_HILEV;
+                       break;
+
+               default:
+                       printk(KERN_ERR "No such irq type %d", type);
+                       return -1;
+       }
+
+       value = __raw_readl(extint_reg);
+       value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
+       __raw_writel(value, extint_reg);
+
+       return 0;
+}
+
+static struct irq_chip s3c_irqext_chip = {
+       .name           = "s3c-ext",
+       .mask           = s3c_irqext_mask,
+       .unmask         = s3c_irqext_unmask,
+       .ack            = s3c_irqext_ack,
+       .set_type       = s3c_irqext_type,
+       .set_wake       = s3c_irqext_wake
+};
+
+static struct irq_chip s3c_irq_eint0t4 = {
+       .name           = "s3c-ext0",
+       .ack            = s3c_irq_ack,
+       .mask           = s3c_irq_mask,
+       .unmask         = s3c_irq_unmask,
+       .set_wake       = s3c_irq_wake,
+       .set_type       = s3c_irqext_type,
+};
+
+/* mask values for the parent registers for each of the interrupt types */
+
+#define INTMSK_UART0    (1UL << (IRQ_UART0 - IRQ_EINT0))
+#define INTMSK_UART1    (1UL << (IRQ_UART1 - IRQ_EINT0))
+#define INTMSK_UART2    (1UL << (IRQ_UART2 - IRQ_EINT0))
+#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
+
+
+/* UART0 */
+
+static void
+s3c_irq_uart0_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
+}
+
+static void
+s3c_irq_uart0_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_UART0);
+}
+
+static void
+s3c_irq_uart0_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
+}
+
+static struct irq_chip s3c_irq_uart0 = {
+       .name           = "s3c-uart0",
+       .mask           = s3c_irq_uart0_mask,
+       .unmask         = s3c_irq_uart0_unmask,
+       .ack            = s3c_irq_uart0_ack,
+};
+
+/* UART1 */
+
+static void
+s3c_irq_uart1_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static void
+s3c_irq_uart1_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_UART1);
+}
+
+static void
+s3c_irq_uart1_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
+}
+
+static struct irq_chip s3c_irq_uart1 = {
+       .name           = "s3c-uart1",
+       .mask           = s3c_irq_uart1_mask,
+       .unmask         = s3c_irq_uart1_unmask,
+       .ack            = s3c_irq_uart1_ack,
+};
+
+/* UART2 */
+
+static void
+s3c_irq_uart2_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static void
+s3c_irq_uart2_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_UART2);
+}
+
+static void
+s3c_irq_uart2_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
+}
+
+static struct irq_chip s3c_irq_uart2 = {
+       .name           = "s3c-uart2",
+       .mask           = s3c_irq_uart2_mask,
+       .unmask         = s3c_irq_uart2_unmask,
+       .ack            = s3c_irq_uart2_ack,
+};
+
+/* ADC and Touchscreen */
+
+static void
+s3c_irq_adc_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static void
+s3c_irq_adc_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
+}
+
+static void
+s3c_irq_adc_ack(unsigned int irqno)
+{
+       s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static struct irq_chip s3c_irq_adc = {
+       .name           = "s3c-adc",
+       .mask           = s3c_irq_adc_mask,
+       .unmask         = s3c_irq_adc_unmask,
+       .ack            = s3c_irq_adc_ack,
+};
+
+/* irq demux for adc */
+static void s3c_irq_demux_adc(unsigned int irq,
+                             struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+       unsigned int offset = 9;
+       struct irq_desc *mydesc;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc &= ~submsk;
+       subsrc >>= offset;
+       subsrc &= 3;
+
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       mydesc = irq_desc + IRQ_TC;
+                       desc_handle_irq(IRQ_TC, mydesc);
+               }
+               if (subsrc & 2) {
+                       mydesc = irq_desc + IRQ_ADC;
+                       desc_handle_irq(IRQ_ADC, mydesc);
+               }
+       }
+}
+
+static void s3c_irq_demux_uart(unsigned int start)
+{
+       unsigned int subsrc, submsk;
+       unsigned int offset = start - IRQ_S3CUART_RX0;
+       struct irq_desc *desc;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
+               start, offset, subsrc, submsk);
+
+       subsrc &= ~submsk;
+       subsrc >>= offset;
+       subsrc &= 7;
+
+       if (subsrc != 0) {
+               desc = irq_desc + start;
+
+               if (subsrc & 1)
+                       desc_handle_irq(start, desc);
+
+               desc++;
+
+               if (subsrc & 2)
+                       desc_handle_irq(start+1, desc);
+
+               desc++;
+
+               if (subsrc & 4)
+                       desc_handle_irq(start+2, desc);
+       }
+}
+
+/* uart demux entry points */
+
+static void
+s3c_irq_demux_uart0(unsigned int irq,
+                   struct irq_desc *desc)
+{
+       irq = irq;
+       s3c_irq_demux_uart(IRQ_S3CUART_RX0);
+}
+
+static void
+s3c_irq_demux_uart1(unsigned int irq,
+                   struct irq_desc *desc)
+{
+       irq = irq;
+       s3c_irq_demux_uart(IRQ_S3CUART_RX1);
+}
+
+static void
+s3c_irq_demux_uart2(unsigned int irq,
+                   struct irq_desc *desc)
+{
+       irq = irq;
+       s3c_irq_demux_uart(IRQ_S3CUART_RX2);
+}
+
+static void
+s3c_irq_demux_extint8(unsigned int irq,
+                     struct irq_desc *desc)
+{
+       unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+       unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+       eintpnd &= ~eintmsk;
+       eintpnd &= ~0xff;       /* ignore lower irqs */
+
+       /* we may as well handle all the pending IRQs here */
+
+       while (eintpnd) {
+               irq = __ffs(eintpnd);
+               eintpnd &= ~(1<<irq);
+
+               irq += (IRQ_EINT4 - 4);
+               desc_handle_irq(irq, irq_desc + irq);
+       }
+
+}
+
+static void
+s3c_irq_demux_extint4t7(unsigned int irq,
+                       struct irq_desc *desc)
+{
+       unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+       unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+       eintpnd &= ~eintmsk;
+       eintpnd &= 0xff;        /* only lower irqs */
+
+       /* we may as well handle all the pending IRQs here */
+
+       while (eintpnd) {
+               irq = __ffs(eintpnd);
+               eintpnd &= ~(1<<irq);
+
+               irq += (IRQ_EINT4 - 4);
+
+               desc_handle_irq(irq, irq_desc + irq);
+       }
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save irq_save[] = {
+       SAVE_ITEM(S3C2410_INTMSK),
+       SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+               save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+               save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+       s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+       save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+       return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+               __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+       for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+               __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+       s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+       __raw_writel(save_eintmask, S3C24XX_EINTMASK);
+
+       return 0;
+}
+
+#else
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
+
+/* s3c24xx_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
+
+void __init s3c24xx_init_irq(void)
+{
+       unsigned long pend;
+       unsigned long last;
+       int irqno;
+       int i;
+
+       irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
+
+       /* first, clear all interrupts pending... */
+
+       last = 0;
+       for (i = 0; i < 4; i++) {
+               pend = __raw_readl(S3C24XX_EINTPEND);
+
+               if (pend == 0 || pend == last)
+                       break;
+
+               __raw_writel(pend, S3C24XX_EINTPEND);
+               printk("irq: clearing pending ext status %08x\n", (int)pend);
+               last = pend;
+       }
+
+       last = 0;
+       for (i = 0; i < 4; i++) {
+               pend = __raw_readl(S3C2410_INTPND);
+
+               if (pend == 0 || pend == last)
+                       break;
+
+               __raw_writel(pend, S3C2410_SRCPND);
+               __raw_writel(pend, S3C2410_INTPND);
+               printk("irq: clearing pending status %08x\n", (int)pend);
+               last = pend;
+       }
+
+       last = 0;
+       for (i = 0; i < 4; i++) {
+               pend = __raw_readl(S3C2410_SUBSRCPND);
+
+               if (pend == 0 || pend == last)
+                       break;
+
+               printk("irq: clearing subpending status %08x\n", (int)pend);
+               __raw_writel(pend, S3C2410_SUBSRCPND);
+               last = pend;
+       }
+
+       /* register the main interrupts */
+
+       irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
+
+       for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
+               /* set all the s3c2410 internal irqs */
+
+               switch (irqno) {
+                       /* deal with the special IRQs (cascaded) */
+
+               case IRQ_EINT4t7:
+               case IRQ_EINT8t23:
+               case IRQ_UART0:
+               case IRQ_UART1:
+               case IRQ_UART2:
+               case IRQ_ADCPARENT:
+                       set_irq_chip(irqno, &s3c_irq_level_chip);
+                       set_irq_handler(irqno, handle_level_irq);
+                       break;
+
+               case IRQ_RESERVED6:
+               case IRQ_RESERVED24:
+                       /* no IRQ here */
+                       break;
+
+               default:
+                       //irqdbf("registering irq %d (s3c irq)\n", irqno);
+                       set_irq_chip(irqno, &s3c_irq_chip);
+                       set_irq_handler(irqno, handle_edge_irq);
+                       set_irq_flags(irqno, IRQF_VALID);
+               }
+       }
+
+       /* setup the cascade irq handlers */
+
+       set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+       set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
+
+       set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
+       set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
+       set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
+       set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
+
+       /* external interrupts */
+
+       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+               irqdbf("registering irq %d (ext int)\n", irqno);
+               set_irq_chip(irqno, &s3c_irq_eint0t4);
+               set_irq_handler(irqno, handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
+               irqdbf("registering irq %d (extended s3c irq)\n", irqno);
+               set_irq_chip(irqno, &s3c_irqext_chip);
+               set_irq_handler(irqno, handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       /* register the uart interrupts */
+
+       irqdbf("s3c2410: registering external interrupts\n");
+
+       for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
+               irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
+               set_irq_chip(irqno, &s3c_irq_uart0);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
+               irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
+               set_irq_chip(irqno, &s3c_irq_uart1);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
+               irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
+               set_irq_chip(irqno, &s3c_irq_uart2);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
+               irqdbf("registering irq %d (s3c adc irq)\n", irqno);
+               set_irq_chip(irqno, &s3c_irq_adc);
+               set_irq_handler(irqno, handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       irqdbf("s3c2410: registered interrupt handlers\n");
+}
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
new file mode 100644 (file)
index 0000000..bd965f2
--- /dev/null
@@ -0,0 +1,66 @@
+/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * Power Management helpers for Simtec S3C24XX implementations
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/map.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/plat-s3c24xx/pm.h>
+
+#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+
+/* pm_simtec_init
+ *
+ * enable the power management functions
+*/
+
+static __init int pm_simtec_init(void)
+{
+       unsigned long gstatus4;
+
+       /* check which machine we are running on */
+
+       if (!machine_is_bast() && !machine_is_vr1000() &&
+           !machine_is_anubis() && !machine_is_osiris() &&
+           !machine_is_aml_m5900())
+               return 0;
+
+       printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
+
+       gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+       gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+       gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+       __raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+       return s3c2410_pm_init();
+}
+
+arch_initcall(pm_simtec_init);
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
new file mode 100644 (file)
index 0000000..ecf68d6
--- /dev/null
@@ -0,0 +1,659 @@
+/* linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004,2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Power Manager (Suspend-To-RAM) support
+ *
+ * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+ *
+ * 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
+ *
+ * Parts based on arch/arm/mach-pxa/pm.c
+ *
+ * Thanks to Dimitry Andric for debugging
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-irq.h>
+
+#include <asm/mach/time.h>
+
+#include <asm/plat-s3c24xx/pm.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+#define PFX "s3c24xx-pm: "
+
+static struct sleep_save core_save[] = {
+       SAVE_ITEM(S3C2410_LOCKTIME),
+       SAVE_ITEM(S3C2410_CLKCON),
+
+       /* we restore the timings here, with the proviso that the board
+        * brings the system up in an slower, or equal frequency setting
+        * to the original system.
+        *
+        * if we cannot guarantee this, then things are going to go very
+        * wrong here, as we modify the refresh and both pll settings.
+        */
+
+       SAVE_ITEM(S3C2410_BWSCON),
+       SAVE_ITEM(S3C2410_BANKCON0),
+       SAVE_ITEM(S3C2410_BANKCON1),
+       SAVE_ITEM(S3C2410_BANKCON2),
+       SAVE_ITEM(S3C2410_BANKCON3),
+       SAVE_ITEM(S3C2410_BANKCON4),
+       SAVE_ITEM(S3C2410_BANKCON5),
+
+       SAVE_ITEM(S3C2410_CLKDIVN),
+       SAVE_ITEM(S3C2410_MPLLCON),
+       SAVE_ITEM(S3C2410_UPLLCON),
+       SAVE_ITEM(S3C2410_CLKSLOW),
+       SAVE_ITEM(S3C2410_REFRESH),
+};
+
+static struct sleep_save gpio_save[] = {
+       SAVE_ITEM(S3C2410_GPACON),
+       SAVE_ITEM(S3C2410_GPADAT),
+
+       SAVE_ITEM(S3C2410_GPBCON),
+       SAVE_ITEM(S3C2410_GPBDAT),
+       SAVE_ITEM(S3C2410_GPBUP),
+
+       SAVE_ITEM(S3C2410_GPCCON),
+       SAVE_ITEM(S3C2410_GPCDAT),
+       SAVE_ITEM(S3C2410_GPCUP),
+
+       SAVE_ITEM(S3C2410_GPDCON),
+       SAVE_ITEM(S3C2410_GPDDAT),
+       SAVE_ITEM(S3C2410_GPDUP),
+
+       SAVE_ITEM(S3C2410_GPECON),
+       SAVE_ITEM(S3C2410_GPEDAT),
+       SAVE_ITEM(S3C2410_GPEUP),
+
+       SAVE_ITEM(S3C2410_GPFCON),
+       SAVE_ITEM(S3C2410_GPFDAT),
+       SAVE_ITEM(S3C2410_GPFUP),
+
+       SAVE_ITEM(S3C2410_GPGCON),
+       SAVE_ITEM(S3C2410_GPGDAT),
+       SAVE_ITEM(S3C2410_GPGUP),
+
+       SAVE_ITEM(S3C2410_GPHCON),
+       SAVE_ITEM(S3C2410_GPHDAT),
+       SAVE_ITEM(S3C2410_GPHUP),
+
+       SAVE_ITEM(S3C2410_DCLKCON),
+};
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+
+#define SAVE_UART(va) \
+       SAVE_ITEM((va) + S3C2410_ULCON), \
+       SAVE_ITEM((va) + S3C2410_UCON), \
+       SAVE_ITEM((va) + S3C2410_UFCON), \
+       SAVE_ITEM((va) + S3C2410_UMCON), \
+       SAVE_ITEM((va) + S3C2410_UBRDIV)
+
+static struct sleep_save uart_save[] = {
+       SAVE_UART(S3C24XX_VA_UART0),
+       SAVE_UART(S3C24XX_VA_UART1),
+#ifndef CONFIG_CPU_S3C2400
+       SAVE_UART(S3C24XX_VA_UART2),
+#endif
+};
+
+/* debug
+ *
+ * we send the debug to printascii() to allow it to be seen if the
+ * system never wakes up from the sleep
+*/
+
+extern void printascii(const char *);
+
+void pm_dbg(const char *fmt, ...)
+{
+       va_list va;
+       char buff[256];
+
+       va_start(va, fmt);
+       vsprintf(buff, fmt, va);
+       va_end(va);
+
+       printascii(buff);
+}
+
+static void s3c2410_pm_debug_init(void)
+{
+       unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+       /* re-start uart clocks */
+       tmp |= S3C2410_CLKCON_UART0;
+       tmp |= S3C2410_CLKCON_UART1;
+       tmp |= S3C2410_CLKCON_UART2;
+
+       __raw_writel(tmp, S3C2410_CLKCON);
+       udelay(10);
+}
+
+#define DBG(fmt...) pm_dbg(fmt)
+#else
+#define DBG(fmt...) printk(KERN_DEBUG fmt)
+
+#define s3c2410_pm_debug_init() do { } while(0)
+
+static struct sleep_save uart_save[] = {};
+#endif
+
+#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size;   /* size needed for the crc block */
+static u32 *crcs;      /* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c2410_pm_run_res
+ *
+ * go thorugh the given resource list, and look for system ram
+*/
+
+static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+       while (ptr != NULL) {
+               if (ptr->child != NULL)
+                       s3c2410_pm_run_res(ptr->child, fn, arg);
+
+               if ((ptr->flags & IORESOURCE_MEM) &&
+                   strcmp(ptr->name, "System RAM") == 0) {
+                       DBG("Found system RAM at %08lx..%08lx\n",
+                           ptr->start, ptr->end);
+                       arg = (fn)(ptr, arg);
+               }
+
+               ptr = ptr->sibling;
+       }
+}
+
+static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+       s3c2410_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
+{
+       u32 size = (u32)(res->end - res->start)+1;
+
+       size += CHECK_CHUNKSIZE-1;
+       size /= CHECK_CHUNKSIZE;
+
+       DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
+
+       *val += size * sizeof(u32);
+       return val;
+}
+
+/* s3c2410_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+static void s3c2410_pm_check_prepare(void)
+{
+       crc_size = 0;
+
+       s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
+
+       DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
+
+       crcs = kmalloc(crc_size+4, GFP_KERNEL);
+       if (crcs == NULL)
+               printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
+{
+       unsigned long addr, left;
+
+       for (addr = res->start; addr < res->end;
+            addr += CHECK_CHUNKSIZE) {
+               left = res->end - addr;
+
+               if (left > CHECK_CHUNKSIZE)
+                       left = CHECK_CHUNKSIZE;
+
+               *val = crc32_le(~0, phys_to_virt(addr), left);
+               val++;
+       }
+
+       return val;
+}
+
+/* s3c2410_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+static void s3c2410_pm_check_store(void)
+{
+       if (crcs != NULL)
+               s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contatins the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+       if ((what+whatsz) < ptr)
+               return 0;
+
+       if (what > (ptr+size))
+               return 0;
+
+       return 1;
+}
+
+static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
+{
+       void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
+       unsigned long addr;
+       unsigned long left;
+       void *ptr;
+       u32 calc;
+
+       for (addr = res->start; addr < res->end;
+            addr += CHECK_CHUNKSIZE) {
+               left = res->end - addr;
+
+               if (left > CHECK_CHUNKSIZE)
+                       left = CHECK_CHUNKSIZE;
+
+               ptr = phys_to_virt(addr);
+
+               if (in_region(ptr, left, crcs, crc_size)) {
+                       DBG("skipping %08lx, has crc block in\n", addr);
+                       goto skip_check;
+               }
+
+               if (in_region(ptr, left, save_at, 32*4 )) {
+                       DBG("skipping %08lx, has save block in\n", addr);
+                       goto skip_check;
+               }
+
+               /* calculate and check the checksum */
+
+               calc = crc32_le(~0, ptr, left);
+               if (calc != *val) {
+                       printk(KERN_ERR PFX "Restore CRC error at "
+                              "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+                       DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+                           addr, calc, *val);
+               }
+
+       skip_check:
+               val++;
+       }
+
+       return val;
+}
+
+/* s3c2410_pm_check_restore
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+
+static void s3c2410_pm_check_restore(void)
+{
+       if (crcs != NULL) {
+               s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
+               kfree(crcs);
+               crcs = NULL;
+       }
+}
+
+#else
+
+#define s3c2410_pm_check_prepare() do { } while(0)
+#define s3c2410_pm_check_restore() do { } while(0)
+#define s3c2410_pm_check_store()   do { } while(0)
+#endif
+
+/* helper functions to save and restore register state */
+
+void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++) {
+               ptr->val = __raw_readl(ptr->reg);
+               DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+       }
+}
+
+/* s3c2410_pm_do_restore
+ *
+ * restore the system from the given list of saved registers
+ *
+ * Note, we do not use DBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++) {
+               printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+                      ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+               __raw_writel(ptr->val, ptr->reg);
+       }
+}
+
+/* s3c2410_pm_do_restore_core
+ *
+ * similar to s3c2410_pm_do_restore_core
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+       for (; count > 0; count--, ptr++) {
+               __raw_writel(ptr->val, ptr->reg);
+       }
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+
+static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
+                                       unsigned long mask)
+{
+       int i;
+
+       which &= ~mask;
+
+       for (i = 0; i <= 31; i++) {
+               if ((which) & (1L<<i)) {
+                       DBG("IRQ %d asserted at resume\n", start+i);
+               }
+       }
+}
+
+/* s3c2410_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+       unsigned long irqstate;
+       unsigned long pinstate;
+       int irq = s3c2410_gpio_getirq(pin);
+
+       if (irqoffs < 4)
+               irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
+       else
+               irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
+
+       pinstate = s3c2410_gpio_getcfg(pin);
+
+       if (!irqstate) {
+               if (pinstate == S3C2410_GPIO_IRQ)
+                       DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+       } else {
+               if (pinstate == S3C2410_GPIO_IRQ) {
+                       DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+                       s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+               }
+       }
+}
+
+/* s3c2410_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+static void s3c2410_pm_configure_extint(void)
+{
+       int pin;
+
+       /* for each of the external interrupts (EINT0..EINT15) we
+        * need to check wether it is an external interrupt source,
+        * and then configure it as an input if it is not
+       */
+
+       for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
+               s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
+       }
+
+       for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
+               s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
+       }
+}
+
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c2410_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c2410_pm_enter(suspend_state_t state)
+{
+       unsigned long regs_save[16];
+
+       /* ensure the debug is initialised (if enabled) */
+
+       s3c2410_pm_debug_init();
+
+       DBG("s3c2410_pm_enter(%d)\n", state);
+
+       if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+               printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
+               return -EINVAL;
+       }
+
+       if (state != PM_SUSPEND_MEM) {
+               printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
+               return -EINVAL;
+       }
+
+       /* check if we have anything to wake-up with... bad things seem
+        * to happen if you suspend with no wakeup (system will often
+        * require a full power-cycle)
+       */
+
+       if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+           !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+               printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
+               printk(KERN_ERR PFX "Aborting sleep\n");
+               return -EINVAL;
+       }
+
+       /* prepare check area if configured */
+
+       s3c2410_pm_check_prepare();
+
+       /* store the physical address of the register recovery block */
+
+       s3c2410_sleep_save_phys = virt_to_phys(regs_save);
+
+       DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
+
+       /* save all necessary core registers not covered by the drivers */
+
+       s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
+       s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
+       s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
+
+       /* set the irq configuration for wake */
+
+       s3c2410_pm_configure_extint();
+
+       DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+           s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+       __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+       __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+       /* ack any outstanding external interrupts before we go to sleep */
+
+       __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+       __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+       __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+       /* call cpu specific preperation */
+
+       pm_cpu_prep();
+
+       /* flush cache back to ram */
+
+       flush_cache_all();
+
+       s3c2410_pm_check_store();
+
+       /* send the cpu to sleep... */
+
+       __raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
+
+       /* s3c2410_cpu_save will also act as our return point from when
+        * we resume as it saves its own register state, so use the return
+        * code to differentiate return from save and return from sleep */
+
+       if (s3c2410_cpu_save(regs_save) == 0) {
+               flush_cache_all();
+               pm_cpu_sleep();
+       }
+
+       /* restore the cpu state */
+
+       cpu_init();
+
+       /* restore the system state */
+
+       s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+       s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
+       s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
+
+       s3c2410_pm_debug_init();
+
+       /* check what irq (if any) restored the system */
+
+       DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+           __raw_readl(S3C2410_SRCPND),
+           __raw_readl(S3C2410_EINTPEND));
+
+       s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+                                   s3c_irqwake_intmask);
+
+       s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+                                   s3c_irqwake_eintmask);
+
+       DBG("post sleep, preparing to return\n");
+
+       s3c2410_pm_check_restore();
+
+       /* ok, let's return from sleep */
+
+       DBG("S3C2410 PM Resume (post-restore)\n");
+       return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int s3c2410_pm_prepare(suspend_state_t state)
+{
+       return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int s3c2410_pm_finish(suspend_state_t state)
+{
+       return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops s3c2410_pm_ops = {
+       .pm_disk_mode   = PM_DISK_FIRMWARE,
+       .prepare        = s3c2410_pm_prepare,
+       .enter          = s3c2410_pm_enter,
+       .finish         = s3c2410_pm_finish,
+};
+
+/* s3c2410_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c2410_pm_init(void)
+{
+       printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
+
+       pm_set_ops(&s3c2410_pm_ops);
+       return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
new file mode 100644 (file)
index 0000000..a0e39d8
--- /dev/null
@@ -0,0 +1,146 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+#include <asm/plat-s3c24xx/irq.h>
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+                             struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+       struct irq_desc *mydesc;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc &= ~submsk;
+       subsrc >>= 11;
+       subsrc &= 3;
+
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       mydesc = irq_desc + IRQ_S3C2440_CAM_C;
+                       desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc);
+               }
+               if (subsrc & 2) {
+                       mydesc = irq_desc + IRQ_S3C2440_CAM_P;
+                       desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc);
+               }
+       }
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irq_chip s3c_irq_cam = {
+       .mask       = s3c_irq_cam_mask,
+       .unmask     = s3c_irq_cam_unmask,
+       .ack        = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct sys_device *sysdev)
+{
+       unsigned int irqno;
+
+       set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+       set_irq_handler(IRQ_NFCON, handle_level_irq);
+       set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+       /* add chained handler for camera */
+
+       set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+       set_irq_handler(IRQ_CAM, handle_level_irq);
+       set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+       for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+               set_irq_chip(irqno, &s3c_irq_cam);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+       .add            = s3c244x_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
+};
+
+static int s3c2440_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+static struct sysdev_driver s3c2442_irq_driver = {
+       .add            = s3c244x_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
+};
+
+
+static int s3c2442_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
+}
+
+arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
new file mode 100644 (file)
index 0000000..767f2e9
--- /dev/null
@@ -0,0 +1,184 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-gpioj.h>
+#include <asm/arch/regs-dsc.h>
+
+#include <asm/plat-s3c24xx/s3c2410.h>
+#include <asm/plat-s3c24xx/s3c2440.h>
+#include "s3c244x.h"
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/devs.h>
+#include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/pm.h>
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(WATCHDOG),
+       IODESC_ENT(LCD),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
+{
+       /* register our io-tables */
+
+       iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+       iotable_init(mach_desc, size);
+
+       /* rename any peripherals used differing from the s3c2410 */
+
+       s3c_device_i2c.name  = "s3c2440-i2c";
+       s3c_device_nand.name = "s3c2440-nand";
+       s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+       unsigned long clkdiv;
+       unsigned long camdiv;
+       unsigned long hclk, fclk, pclk;
+       int hdiv = 1;
+
+       /* now we've got our machine bits initialised, work out what
+        * clocks we've got */
+
+       fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+       clkdiv = __raw_readl(S3C2410_CLKDIVN);
+       camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+       /* work out clock scalings */
+
+       switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+       case S3C2440_CLKDIVN_HDIVN_1:
+               hdiv = 1;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_2:
+               hdiv = 2;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_4_8:
+               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_3_6:
+               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+               break;
+       }
+
+       hclk = fclk / hdiv;
+       pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
+
+       /* print brief summary of clocks, etc */
+
+       printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+       /* initialise the clocks here, to allow other things like the
+        * console to use them, and to add new ones after the initialisation
+        */
+
+       s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
+       s3c2410_baseclk_add();
+}
+
+#ifdef CONFIG_PM
+
+static struct sleep_save s3c244x_sleep[] = {
+       SAVE_ITEM(S3C2440_DSC0),
+       SAVE_ITEM(S3C2440_DSC1),
+       SAVE_ITEM(S3C2440_GPJDAT),
+       SAVE_ITEM(S3C2440_GPJCON),
+       SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
+{
+       s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+       return 0;
+}
+
+static int s3c244x_resume(struct sys_device *dev)
+{
+       s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+       return 0;
+}
+
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+/* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+       set_kset_name("s3c2440-core"),
+       .suspend        = s3c244x_suspend,
+       .resume         = s3c244x_resume
+};
+
+struct sysdev_class s3c2442_sysclass = {
+       set_kset_name("s3c2442-core"),
+       .suspend        = s3c244x_suspend,
+       .resume         = s3c244x_resume
+};
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+       return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+       return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
diff --git a/arch/arm/plat-s3c24xx/s3c244x.h b/arch/arm/plat-s3c24xx/s3c244x.h
new file mode 100644 (file)
index 0000000..f8ed176
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 cpu support
+ *
+ * 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.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#define s3c244x_map_io NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
new file mode 100644 (file)
index 0000000..435349d
--- /dev/null
@@ -0,0 +1,157 @@
+/* linux/arch/arm/mach-s3c2410/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *     Cliff Brake, (c) 2001
+ *
+ * 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+#include <asm/arch/map.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-serial.h>
+
+/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+*/
+//#define CONFIG_DEBUG_RESUME
+
+       .text
+
+       /* s3c2410_cpu_save
+        *
+        * save enough of the CPU state to allow us to re-start
+        * pm.c code. as we store items like the sp/lr, we will
+        * end up returning from this function when the cpu resumes
+        * so the return value is set to mark this.
+        *
+        * This arangement means we avoid having to flush the cache
+        * from this code.
+        *
+        * entry:
+        *      r0 = pointer to save block
+        *
+        * exit:
+        *      r0 = 0 => we stored everything
+        *           1 => resumed from sleep
+       */
+
+ENTRY(s3c2410_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 }
+
+       mov     r0, #0
+       ldmfd   sp, { r4 - r12, pc }
+
+       @@ return to the caller, after having the MMU
+       @@ turned on, this restores the last bits from the
+       @@ stack
+resume_with_mmu:
+       mov     r0, #1
+       ldmfd   sp!, { r4 - r12, pc }
+
+       .ltorg
+
+       @@ the next bits sit in the .data segment, even though they
+       @@ happen to be code... the s3c2410_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 s3c2410_sleep_save_phys
+s3c2410_sleep_save_phys:
+       .word   0
+
+       /* s3c2410_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(s3c2410_cpu_resume)
+       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+       msr     cpsr_c, r0
+
+       @@ load UART to allow us to print the two characters for
+       @@ resume debug
+
+       mov     r2, #S3C24XX_PA_UART & 0xff000000
+       orr     r2, r2, #S3C24XX_PA_UART & 0xff000
+
+#if 0
+       /* SMDK2440 LED set */
+       mov     r14, #S3C24XX_PA_GPIO
+       ldr     r12, [ r14, #0x54 ]
+       bic     r12, r12, #3<<4
+       orr     r12, r12, #1<<7
+       str     r12, [ r14, #0x54 ]
+#endif
+
+#ifdef CONFIG_DEBUG_RESUME
+       mov     r3, #'L'
+       strb    r3, [ r2, #S3C2410_UTXH ]
+1001:
+       ldrb    r14, [ r3, #S3C2410_UTRSTAT ]
+       tst     r14, #S3C2410_UTRSTAT_TXE
+       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, s3c2410_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
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
new file mode 100644 (file)
index 0000000..c523d1c
--- /dev/null
@@ -0,0 +1,262 @@
+/* linux/arch/arm/plat-s3c24xx/time.c
+ *
+ * Copyright (C) 2003-2005 Simtec Electronics
+ *     Ben Dooks, <ben@simtec.co.uk>
+ *
+ * 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/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/map.h>
+#include <asm/arch/regs-timer.h>
+#include <asm/arch/regs-irq.h>
+#include <asm/mach/time.h>
+
+#include <asm/plat-s3c24xx/clock.h>
+#include <asm/plat-s3c24xx/cpu.h>
+
+static unsigned long timer_startval;
+static unsigned long timer_usec_ticks;
+
+#define TIMER_USEC_SHIFT 16
+
+/* we use the shifted arithmetic to work out the ratio of timer ticks
+ * to usecs, as often the peripheral clock is not a nice even multiple
+ * of 1MHz.
+ *
+ * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
+ * for the current HZ value of 200 without producing overflows.
+ *
+ * Original patch by Dimitry Andric, updated by Ben Dooks
+*/
+
+
+/* timer_mask_usec_ticks
+ *
+ * given a clock and divisor, make the value to pass into timer_ticks_to_usec
+ * to scale the ticks into usecs
+*/
+
+static inline unsigned long
+timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
+{
+       unsigned long den = pclk / 1000;
+
+       return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
+}
+
+/* timer_ticks_to_usec
+ *
+ * convert timer ticks to usec.
+*/
+
+static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
+{
+       unsigned long res;
+
+       res = ticks * timer_usec_ticks;
+       res += 1 << (TIMER_USEC_SHIFT - 4);     /* round up slightly */
+
+       return res >> TIMER_USEC_SHIFT;
+}
+
+/***
+ * Returns microsecond  since last clock interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ * IRQs are disabled before entering here from do_gettimeofday()
+ */
+
+#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
+
+static unsigned long s3c2410_gettimeoffset (void)
+{
+       unsigned long tdone;
+       unsigned long irqpend;
+       unsigned long tval;
+
+       /* work out how many ticks have gone since last timer interrupt */
+
+        tval =  __raw_readl(S3C2410_TCNTO(4));
+       tdone = timer_startval - tval;
+
+       /* check to see if there is an interrupt pending */
+
+       irqpend = __raw_readl(S3C2410_SRCPND);
+       if (irqpend & SRCPND_TIMER4) {
+               /* re-read the timer, and try and fix up for the missed
+                * interrupt. Note, the interrupt may go off before the
+                * timer has re-loaded from wrapping.
+                */
+
+               tval =  __raw_readl(S3C2410_TCNTO(4));
+               tdone = timer_startval - tval;
+
+               if (tval != 0)
+                       tdone += timer_startval;
+       }
+
+       return timer_ticks_to_usec(tdone);
+}
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+s3c2410_timer_interrupt(int irq, void *dev_id)
+{
+       write_seqlock(&xtime_lock);
+       timer_tick();
+       write_sequnlock(&xtime_lock);
+       return IRQ_HANDLED;
+}
+
+static struct irqaction s3c2410_timer_irq = {
+       .name           = "S3C2410 Timer Tick",
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .handler        = s3c2410_timer_interrupt,
+};
+
+#define use_tclk1_12() ( \
+       machine_is_bast()       || \
+       machine_is_vr1000()     || \
+       machine_is_anubis()     || \
+       machine_is_osiris() )
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ *
+ * Currently we only use timer4, as it is the only timer which has no
+ * other function that can be exploited externally
+ */
+static void s3c2410_timer_setup (void)
+{
+       unsigned long tcon;
+       unsigned long tcnt;
+       unsigned long tcfg1;
+       unsigned long tcfg0;
+
+       tcnt = 0xffff;  /* default value for tcnt */
+
+       /* read the current timer configuration bits */
+
+       tcon = __raw_readl(S3C2410_TCON);
+       tcfg1 = __raw_readl(S3C2410_TCFG1);
+       tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+       /* configure the system for whichever machine is in use */
+
+       if (use_tclk1_12()) {
+               /* timer is at 12MHz, scaler is 1 */
+               timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
+               tcnt = 12000000 / HZ;
+
+               tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
+               tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
+       } else {
+               unsigned long pclk;
+               struct clk *clk;
+
+               /* for the h1940 (and others), we use the pclk from the core
+                * to generate the timer values. since values around 50 to
+                * 70MHz are not values we can directly generate the timer
+                * value from, we need to pre-scale and divide before using it.
+                *
+                * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
+                * (8.45 ticks per usec)
+                */
+
+               /* this is used as default if no other timer can be found */
+
+               clk = clk_get(NULL, "timers");
+               if (IS_ERR(clk))
+                       panic("failed to get clock for system timer");
+
+               clk_enable(clk);
+
+               pclk = clk_get_rate(clk);
+
+               /* configure clock tick */
+
+               timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
+
+               tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
+               tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
+
+               tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
+               tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
+
+               tcnt = (pclk / 6) / HZ;
+       }
+
+       /* timers reload after counting zero, so reduce the count by 1 */
+
+       tcnt--;
+
+       printk("timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
+              tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
+
+       /* check to see if timer is within 16bit range... */
+       if (tcnt > 0xffff) {
+               panic("setup_timer: HZ is too small, cannot configure timer!");
+               return;
+       }
+
+       __raw_writel(tcfg1, S3C2410_TCFG1);
+       __raw_writel(tcfg0, S3C2410_TCFG0);
+
+       timer_startval = tcnt;
+       __raw_writel(tcnt, S3C2410_TCNTB(4));
+
+       /* ensure timer is stopped... */
+
+       tcon &= ~(7<<20);
+       tcon |= S3C2410_TCON_T4RELOAD;
+       tcon |= S3C2410_TCON_T4MANUALUPD;
+
+       __raw_writel(tcon, S3C2410_TCON);
+       __raw_writel(tcnt, S3C2410_TCNTB(4));
+       __raw_writel(tcnt, S3C2410_TCMPB(4));
+
+       /* start the timer running */
+       tcon |= S3C2410_TCON_T4START;
+       tcon &= ~S3C2410_TCON_T4MANUALUPD;
+       __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void __init s3c2410_timer_init (void)
+{
+       s3c2410_timer_setup();
+       setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
+}
+
+struct sys_timer s3c24xx_timer = {
+       .init           = s3c2410_timer_init,
+       .offset         = s3c2410_gettimeoffset,
+       .resume         = s3c2410_timer_setup
+};
index c3b1567c852a711595c1dbd4ac2575afe7d83044..14e83d0aac8c8fcc94372710f53067bd5a4ddad9 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
+#include <asm/io.h>
 #include <asm/arch/i2c.h>
 #include <asm/arch/pxa-regs.h>
 
@@ -54,8 +55,21 @@ struct pxa_i2c {
        unsigned int            irqlogidx;
        u32                     isrlog[32];
        u32                     icrlog[32];
+
+       void __iomem            *reg_base;
+
+       unsigned long           iobase;
+       unsigned long           iosize;
+
+       int                     irq;
 };
 
+#define _IBMR(i2c)     ((i2c)->reg_base + 0)
+#define _IDBR(i2c)     ((i2c)->reg_base + 8)
+#define _ICR(i2c)      ((i2c)->reg_base + 0x10)
+#define _ISR(i2c)      ((i2c)->reg_base + 0x18)
+#define _ISAR(i2c)     ((i2c)->reg_base + 0x20)
+
 /*
  * I2C Slave mode address
  */
@@ -130,7 +144,8 @@ static unsigned int i2c_debug = DEBUG;
 
 static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
 {
-       dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR);
+       dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno,
+               readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 }
 
 #define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
@@ -153,7 +168,7 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
        printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
                i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
        printk("i2c: ICR: %08x ISR: %08x\n"
-              "i2c: log: ", ICR, ISR);
+              "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
        for (i = 0; i < i2c->irqlogidx; i++)
                printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
        printk("\n");
@@ -161,7 +176,7 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
 
 static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
 {
-       return !(ICR & ICR_SCLE);
+       return !(readl(_ICR(i2c)) & ICR_SCLE);
 }
 
 static void i2c_pxa_abort(struct pxa_i2c *i2c)
@@ -173,28 +188,29 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c)
                return;
        }
 
-       while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) {
-               unsigned long icr = ICR;
+       while (time_before(jiffies, timeout) && (readl(_IBMR(i2c)) & 0x1) == 0) {
+               unsigned long icr = readl(_ICR(i2c));
 
                icr &= ~ICR_START;
                icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
 
-               ICR = icr;
+               writel(icr, _ICR(i2c));
 
                show_state(i2c);
 
                msleep(1);
        }
 
-       ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
+       writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP),
+              _ICR(i2c));
 }
 
 static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
 {
        int timeout = DEF_TIMEOUT;
 
-       while (timeout-- && ISR & (ISR_IBB | ISR_UB)) {
-               if ((ISR & ISR_SAD) != 0)
+       while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
+               if ((readl(_ISR(i2c)) & ISR_SAD) != 0)
                        timeout += 4;
 
                msleep(2);
@@ -214,9 +230,9 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
        while (time_before(jiffies, timeout)) {
                if (i2c_debug > 1)
                        dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-                               __func__, (long)jiffies, ISR, ICR, IBMR);
+                               __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 
-               if (ISR & ISR_SAD) {
+               if (readl(_ISR(i2c)) & ISR_SAD) {
                        if (i2c_debug > 0)
                                dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
                        goto out;
@@ -226,7 +242,7 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
                 * quick check of the i2c lines themselves to ensure they've
                 * gone high...
                 */
-               if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) {
+               if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && readl(_IBMR(i2c)) == 3) {
                        if (i2c_debug > 0)
                                dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
                        return 1;
@@ -246,7 +262,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
        if (i2c_debug)
                dev_dbg(&i2c->adap.dev, "setting to bus master\n");
 
-       if ((ISR & (ISR_UB | ISR_IBB)) != 0) {
+       if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
                dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
                if (!i2c_pxa_wait_master(i2c)) {
                        dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
@@ -254,7 +270,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
                }
        }
 
-       ICR |= ICR_SCLE;
+       writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
        return 0;
 }
 
@@ -270,11 +286,11 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
        while (time_before(jiffies, timeout)) {
                if (i2c_debug > 1)
                        dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-                               __func__, (long)jiffies, ISR, ICR, IBMR);
+                               __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 
-               if ((ISR & (ISR_UB|ISR_IBB)) == 0 ||
-                   (ISR & ISR_SAD) != 0 ||
-                   (ICR & ICR_SCLE) == 0) {
+               if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
+                   (readl(_ISR(i2c)) & ISR_SAD) != 0 ||
+                   (readl(_ICR(i2c)) & ICR_SCLE) == 0) {
                        if (i2c_debug > 1)
                                dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
                        return 1;
@@ -302,9 +318,9 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
                /* we need to wait for the stop condition to end */
 
                /* if we where in stop, then clear... */
-               if (ICR & ICR_STOP) {
+               if (readl(_ICR(i2c)) & ICR_STOP) {
                        udelay(100);
-                       ICR &= ~ICR_STOP;
+                       writel(readl(_ICR(i2c)) & ~ICR_STOP, _ICR(i2c));
                }
 
                if (!i2c_pxa_wait_slave(i2c)) {
@@ -314,12 +330,12 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
                }
        }
 
-       ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA);
-       ICR &= ~ICR_SCLE;
+       writel(readl(_ICR(i2c)) & ~(ICR_STOP|ICR_ACKNAK|ICR_MA), _ICR(i2c));
+       writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 
        if (i2c_debug) {
-               dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR);
-               decode_ICR(ICR);
+               dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", readl(_ICR(i2c)), readl(_ISR(i2c)));
+               decode_ICR(readl(_ICR(i2c)));
        }
 }
 #else
@@ -334,24 +350,24 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
        i2c_pxa_abort(i2c);
 
        /* reset according to 9.8 */
-       ICR = ICR_UR;
-       ISR = I2C_ISR_INIT;
-       ICR &= ~ICR_UR;
+       writel(ICR_UR, _ICR(i2c));
+       writel(I2C_ISR_INIT, _ISR(i2c));
+       writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
 
-       ISAR = i2c->slave_addr;
+       writel(i2c->slave_addr, _ISAR(i2c));
 
        /* set control register values */
-       ICR = I2C_ICR_INIT;
+       writel(I2C_ICR_INIT, _ICR(i2c));
 
 #ifdef CONFIG_I2C_PXA_SLAVE
        dev_info(&i2c->adap.dev, "Enabling slave mode\n");
-       ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE;
+       writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
 #endif
 
        i2c_pxa_set_slave(i2c, 0);
 
        /* enable unit */
-       ICR |= ICR_IUE;
+       writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
        udelay(100);
 }
 
@@ -371,19 +387,19 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
                if (i2c->slave != NULL)
                        ret = i2c->slave->read(i2c->slave->data);
 
-               IDBR = ret;
-               ICR |= ICR_TB;   /* allow next byte */
+               writel(ret, _IDBR(i2c));
+               writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));   /* allow next byte */
        }
 }
 
 static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-       unsigned int byte = IDBR;
+       unsigned int byte = readl(_IDBR(i2c));
 
        if (i2c->slave != NULL)
                i2c->slave->write(i2c->slave->data, byte);
 
-       ICR |= ICR_TB;
+       writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -403,13 +419,13 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
         * start condition... if this happens, we'd better back off
         * and stop holding the poor thing up
         */
-       ICR &= ~(ICR_START|ICR_STOP);
-       ICR |= ICR_TB;
+       writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
+       writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
 
        timeout = 0x10000;
 
        while (1) {
-               if ((IBMR & 2) == 2)
+               if ((readl(_IBMR(i2c)) & 2) == 2)
                        break;
 
                timeout--;
@@ -420,7 +436,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
                }
        }
 
-       ICR &= ~ICR_SCLE;
+       writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -447,14 +463,14 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
        if (isr & ISR_BED) {
                /* what should we do here? */
        } else {
-               IDBR = 0;
-               ICR |= ICR_TB;
+               writel(0, _IDBR(i2c));
+               writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
        }
 }
 
 static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-       ICR |= ICR_TB | ICR_ACKNAK;
+       writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -466,13 +482,13 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
         * start condition... if this happens, we'd better back off
         * and stop holding the poor thing up
         */
-       ICR &= ~(ICR_START|ICR_STOP);
-       ICR |= ICR_TB | ICR_ACKNAK;
+       writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
+       writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
 
        timeout = 0x10000;
 
        while (1) {
-               if ((IBMR & 2) == 2)
+               if ((readl(_IBMR(i2c)) & 2) == 2)
                        break;
 
                timeout--;
@@ -483,7 +499,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
                }
        }
 
-       ICR &= ~ICR_SCLE;
+       writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
 }
 
 static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -514,13 +530,13 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
        /*
         * Step 1: target slave address into IDBR
         */
-       IDBR = i2c_pxa_addr_byte(i2c->msg);
+       writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
 
        /*
         * Step 2: initiate the write.
         */
-       icr = ICR & ~(ICR_STOP | ICR_ALDIE);
-       ICR = icr | ICR_START | ICR_TB;
+       icr = readl(_ICR(i2c)) & ~(ICR_STOP | ICR_ALDIE);
+       writel(icr | ICR_START | ICR_TB, _ICR(i2c));
 }
 
 /*
@@ -594,7 +610,7 @@ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
 
 static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
 {
-       u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+       u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
 
  again:
        /*
@@ -645,7 +661,7 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
                /*
                 * Write mode.  Write the next data byte.
                 */
-               IDBR = i2c->msg->buf[i2c->msg_ptr++];
+               writel(i2c->msg->buf[i2c->msg_ptr++], _IDBR(i2c));
 
                icr |= ICR_ALDIE | ICR_TB;
 
@@ -675,7 +691,7 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
                /*
                 * Write the next address.
                 */
-               IDBR = i2c_pxa_addr_byte(i2c->msg);
+               writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
 
                /*
                 * And trigger a repeated start, and send the byte.
@@ -696,18 +712,18 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
 
        i2c->icrlog[i2c->irqlogidx-1] = icr;
 
-       ICR = icr;
+       writel(icr, _ICR(i2c));
        show_state(i2c);
 }
 
 static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
 {
-       u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
+       u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
 
        /*
         * Read the byte.
         */
-       i2c->msg->buf[i2c->msg_ptr++] = IDBR;
+       i2c->msg->buf[i2c->msg_ptr++] = readl(_IDBR(i2c));
 
        if (i2c->msg_ptr < i2c->msg->len) {
                /*
@@ -724,17 +740,17 @@ static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
 
        i2c->icrlog[i2c->irqlogidx-1] = icr;
 
-       ICR = icr;
+       writel(icr, _ICR(i2c));
 }
 
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 {
        struct pxa_i2c *i2c = dev_id;
-       u32 isr = ISR;
+       u32 isr = readl(_ISR(i2c));
 
        if (i2c_debug > 2 && 0) {
                dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
-                       __func__, isr, ICR, IBMR);
+                       __func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
                decode_ISR(isr);
        }
 
@@ -746,7 +762,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
        /*
         * Always clear all pending IRQs.
         */
-       ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED);
+       writel(isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED), _ISR(i2c));
 
        if (isr & ISR_SAD)
                i2c_pxa_slave_start(i2c, isr);
@@ -779,7 +795,7 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
        /* If the I2C controller is disabled we need to reset it (probably due
           to a suspend/resume destroying state). We do this here as we can then
           avoid worrying about resuming the controller before its users. */
-       if (!(ICR & ICR_IUE))
+       if (!(readl(_ICR(i2c)) & ICR_IUE))
                i2c_pxa_reset(i2c);
 
        for (i = adap->retries; i >= 0; i--) {
@@ -810,28 +826,53 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
 
 static struct pxa_i2c i2c_pxa = {
        .lock   = SPIN_LOCK_UNLOCKED,
-       .wait   = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
        .adap   = {
                .owner          = THIS_MODULE,
                .algo           = &i2c_pxa_algorithm,
-               .name           = "pxa2xx-i2c",
+               .name           = "pxa2xx-i2c.0",
                .retries        = 5,
        },
 };
 
+#define res_len(r)             ((r)->end - (r)->start + 1)
 static int i2c_pxa_probe(struct platform_device *dev)
 {
        struct pxa_i2c *i2c = &i2c_pxa;
+       struct resource *res;
 #ifdef CONFIG_I2C_PXA_SLAVE
        struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 #endif
        int ret;
+       int irq;
 
-#ifdef CONFIG_PXA27x
-       pxa_gpio_mode(GPIO117_I2CSCL_MD);
-       pxa_gpio_mode(GPIO118_I2CSDA_MD);
-       udelay(100);
-#endif
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       irq = platform_get_irq(dev, 0);
+       if (res == NULL || irq < 0)
+               return -ENODEV;
+
+       if (!request_mem_region(res->start, res_len(res), res->name))
+               return -ENOMEM;
+
+       i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
+       if (!i2c) {
+               ret = -ENOMEM;
+               goto emalloc;
+       }
+
+       memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
+       init_waitqueue_head(&i2c->wait);
+       i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
+
+       i2c->reg_base = ioremap(res->start, res_len(res));
+       if (!i2c->reg_base) {
+               ret = -EIO;
+               goto eremap;
+       }
+
+       i2c->iobase = res->start;
+       i2c->iosize = res_len(res);
+
+       i2c->irq = irq;
 
        i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
 
@@ -842,11 +883,28 @@ static int i2c_pxa_probe(struct platform_device *dev)
        }
 #endif
 
-       pxa_set_cken(CKEN14_I2C, 1);
-       ret = request_irq(IRQ_I2C, i2c_pxa_handler, IRQF_DISABLED,
-                         "pxa2xx-i2c", i2c);
+       switch (dev->id) {
+       case 0:
+#ifdef CONFIG_PXA27x
+               pxa_gpio_mode(GPIO117_I2CSCL_MD);
+               pxa_gpio_mode(GPIO118_I2CSDA_MD);
+#endif
+               pxa_set_cken(CKEN14_I2C, 1);
+               break;
+#ifdef CONFIG_PXA27x
+       case 1:
+               local_irq_disable();
+               PCFR |= PCFR_PI2CEN;
+               local_irq_enable();
+               pxa_set_cken(CKEN15_PWRI2C, 1);
+#endif
+       }
+
+       ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
+                         i2c->adap.name, i2c);
        if (ret)
-               goto out;
+               goto ereqirq;
+
 
        i2c_pxa_reset(i2c);
 
@@ -856,7 +914,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
        ret = i2c_add_adapter(&i2c->adap);
        if (ret < 0) {
                printk(KERN_INFO "I2C: Failed to add bus\n");
-               goto err_irq;
+               goto eadapt;
        }
 
        platform_set_drvdata(dev, i2c);
@@ -870,9 +928,25 @@ static int i2c_pxa_probe(struct platform_device *dev)
 #endif
        return 0;
 
- err_irq:
-       free_irq(IRQ_I2C, i2c);
- out:
+eadapt:
+       free_irq(irq, i2c);
+ereqirq:
+       switch (dev->id) {
+       case 0:
+               pxa_set_cken(CKEN14_I2C, 0);
+               break;
+#ifdef CONFIG_PXA27x
+       case 1:
+               pxa_set_cken(CKEN15_PWRI2C, 0);
+               local_irq_disable();
+               PCFR &= ~PCFR_PI2CEN;
+               local_irq_enable();
+#endif
+       }
+eremap:
+       kfree(i2c);
+emalloc:
+       release_mem_region(res->start, res_len(res));
        return ret;
 }
 
@@ -883,8 +957,21 @@ static int i2c_pxa_remove(struct platform_device *dev)
        platform_set_drvdata(dev, NULL);
 
        i2c_del_adapter(&i2c->adap);
-       free_irq(IRQ_I2C, i2c);
-       pxa_set_cken(CKEN14_I2C, 0);
+       free_irq(i2c->irq, i2c);
+       switch (dev->id) {
+       case 0:
+               pxa_set_cken(CKEN14_I2C, 0);
+               break;
+#ifdef CONFIG_PXA27x
+       case 1:
+               pxa_set_cken(CKEN15_PWRI2C, 0);
+               local_irq_disable();
+               PCFR &= ~PCFR_PI2CEN;
+               local_irq_enable();
+#endif
+       }
+       release_mem_region(i2c->iobase, i2c->iosize);
+       kfree(i2c);
 
        return 0;
 }
index 2978c09860eeff81cbedebf0c52ca8e142bf946c..09f8bff1fbd1cf5acf1b42bb1ceb6bd56b19340f 100644 (file)
@@ -262,7 +262,8 @@ config SERIAL_AMBA_PL010
        select SERIAL_CORE
        help
          This selects the ARM(R) AMBA(R) PrimeCell PL010 UART.  If you have
-         an Integrator/AP or Integrator/PP2 platform, say Y or M here.
+         an Integrator/AP or Integrator/PP2 platform, or if you have a
+         Cirrus Logic EP93xx CPU, say Y or M here.
 
          If unsure, say N.
 
index e216dcf29376582776418cf2ccfb825885a91124..04cc88cc528cec7eb742eee9e5e952e3662be502 100644 (file)
@@ -154,7 +154,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
 {
        struct circ_buf *xmit = &sport->port.info->xmit;
 
-       do {
+       while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
                /* send xmit->buf[xmit->tail]
                 * out the port here */
                URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
@@ -163,7 +163,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
                sport->port.icount.tx++;
                if (uart_circ_empty(xmit))
                        break;
-       } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL));
+       }
 
        if (uart_circ_empty(xmit))
                imx_stop_tx(&sport->port);
@@ -178,8 +178,7 @@ static void imx_start_tx(struct uart_port *port)
 
        UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
 
-       if(UTS((u32)sport->port.membase) & UTS_TXEMPTY)
-               imx_transmit_buffer(sport);
+       imx_transmit_buffer(sport);
 }
 
 static irqreturn_t imx_rtsint(int irq, void *dev_id)
@@ -404,7 +403,8 @@ static int imx_startup(struct uart_port *port)
        if (retval) goto error_out2;
 
        retval = request_irq(sport->rtsirq, imx_rtsint,
-                            IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+                            (sport->rtsirq < IMX_IRQS) ? 0 :
+                              IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                             DRIVER_NAME, sport);
        if (retval) goto error_out3;
 
@@ -678,7 +678,7 @@ static struct imx_port imx_ports[] = {
                .mapbase        = IMX_UART1_BASE, /* FIXME */
                .irq            = UART1_MINT_RX,
                .uartclk        = 16000000,
-               .fifosize       = 8,
+               .fifosize       = 32,
                .flags          = UPF_BOOT_AUTOCONF,
                .ops            = &imx_pops,
                .line           = 0,
@@ -694,7 +694,7 @@ static struct imx_port imx_ports[] = {
                .mapbase        = IMX_UART2_BASE, /* FIXME */
                .irq            = UART2_MINT_RX,
                .uartclk        = 16000000,
-               .fifosize       = 8,
+               .fifosize       = 32,
                .flags          = UPF_BOOT_AUTOCONF,
                .ops            = &imx_pops,
                .line           = 1,
index b78de96946652128f326aae340bcdb991cd39d82..3547f049237e02c4ca621036fa4000ec72ffb9db 100644 (file)
@@ -156,7 +156,7 @@ static int is_vbus_present(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_vbus)
-               return pxa_gpio_get(mach->gpio_vbus);
+               return udc_gpio_get(mach->gpio_vbus);
        if (mach->udc_is_connected)
                return mach->udc_is_connected();
        return 1;
@@ -168,7 +168,7 @@ static void pullup_off(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               pxa_gpio_set(mach->gpio_pullup, 0);
+               udc_gpio_set(mach->gpio_pullup, 0);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
@@ -178,7 +178,7 @@ static void pullup_on(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
        if (mach->gpio_pullup)
-               pxa_gpio_set(mach->gpio_pullup, 1);
+               udc_gpio_set(mach->gpio_pullup, 1);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
@@ -1756,7 +1756,7 @@ lubbock_vbus_irq(int irq, void *_dev)
 static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
-       int                     vbus = pxa_gpio_get(dev->mach->gpio_vbus);
+       int                     vbus = udc_gpio_get(dev->mach->gpio_vbus);
 
        pxa2xx_udc_vbus_session(&dev->gadget, vbus);
        return IRQ_HANDLED;
@@ -2546,15 +2546,13 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
        if (dev->mach->gpio_vbus) {
-               vbus_irq = IRQ_GPIO(dev->mach->gpio_vbus & GPIO_MD_MASK_NR);
-               pxa_gpio_mode((dev->mach->gpio_vbus & GPIO_MD_MASK_NR)
-                               | GPIO_IN);
+               udc_gpio_init_vbus(dev->mach->gpio_vbus);
+               vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus);
                set_irq_type(vbus_irq, IRQT_BOTHEDGE);
        } else
                vbus_irq = 0;
        if (dev->mach->gpio_pullup)
-               pxa_gpio_mode((dev->mach->gpio_pullup & GPIO_MD_MASK_NR)
-                               | GPIO_OUT | GPIO_DFLT_LOW);
+               udc_gpio_init_pullup(dev->mach->gpio_pullup);
 
        init_timer(&dev->timer);
        dev->timer.function = udc_watchdog;
index 8e598c8bf4e388da20c6672b3a0f54a95e296e6e..773e549aff3f721eb1f7b0ace82b45ff51b4c470 100644 (file)
@@ -177,21 +177,6 @@ struct pxa2xx_udc {
 
 static struct pxa2xx_udc *the_controller;
 
-static inline int pxa_gpio_get(unsigned gpio)
-{
-       return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
-}
-
-static inline void pxa_gpio_set(unsigned gpio, int is_on)
-{
-       int mask = GPIO_bit(gpio);
-
-       if (is_on)
-               GPSR(gpio) = mask;
-       else
-               GPCR(gpio) = mask;
-}
-
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/include/asm-arm/.gitignore b/include/asm-arm/.gitignore
new file mode 100644 (file)
index 0000000..e02c15d
--- /dev/null
@@ -0,0 +1,2 @@
+arch
+mach-types.h
index 593f562f85c35ab08cede727f564f51f3622b813..625c6f0abc030c50b5fab0f1014dae6deaeebd3b 100644 (file)
 
 #define EP93XX_GPIO_BASE               (EP93XX_APB_VIRT_BASE + 0x00040000)
 #define EP93XX_GPIO_REG(x)             (EP93XX_GPIO_BASE + (x))
+#define EP93XX_GPIO_F_INT_TYPE1                EP93XX_GPIO_REG(0x4c)
+#define EP93XX_GPIO_F_INT_TYPE2                EP93XX_GPIO_REG(0x50)
+#define EP93XX_GPIO_F_INT_ACK          EP93XX_GPIO_REG(0x54)
+#define EP93XX_GPIO_F_INT_ENABLE       EP93XX_GPIO_REG(0x58)
+#define EP93XX_GPIO_F_INT_STATUS       EP93XX_GPIO_REG(0x5c)
 #define EP93XX_GPIO_A_INT_TYPE1                EP93XX_GPIO_REG(0x90)
 #define EP93XX_GPIO_A_INT_TYPE2                EP93XX_GPIO_REG(0x94)
 #define EP93XX_GPIO_A_INT_ACK          EP93XX_GPIO_REG(0x98)
index ae532e304bf1f2b182e1e1430c350c57c7089e2d..2a8c63638c5e824cd30aa2a612d185263ba28f05 100644 (file)
 #define IRQ_EP93XX_SAI                 60
 #define EP93XX_VIC2_VALID_IRQ_MASK     0x1fffffff
 
-#define IRQ_EP93XX_GPIO(x)             (64 + (x))
+/*
+ * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
+ * F0..F7 to 80..87.
+ */
+#define IRQ_EP93XX_GPIO(x)             (64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
 
-#define NR_EP93XX_IRQS                 IRQ_EP93XX_GPIO(16)
+#define NR_EP93XX_IRQS                 (64 + 24)
 
 #define EP93XX_BOARD_IRQ(x)            (NR_EP93XX_IRQS + (x))
 #define EP93XX_BOARD_IRQS              32
index b4a8deb8bdef8c4aae9c08c50ca29702d2ea15eb..44eccec2cba45d36f69a6ac11e097feb250ca307 100644 (file)
@@ -8,7 +8,6 @@ void ep93xx_map_io(void);
 void ep93xx_init_irq(void);
 void ep93xx_init_time(unsigned long);
 void ep93xx_init_devices(void);
-void ep93xx_clock_init(void);
 extern struct sys_timer ep93xx_timer;
 
 struct ep93xx_eth_data
index 3b9ef69146275a68929602e67f773b238f676348..61bb0bdc1b1651744c0b888a5ffd73a8461dd50c 100644 (file)
                .endm
 #define AITC_NIVECSR   0x40
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \irqstat, =IO_ADDRESS(IMX_AITC_BASE)
+               ldr     \base, =IO_ADDRESS(IMX_AITC_BASE)
                @ Load offset & priority of the highest priority
                @ interrupt pending.
-               ldr     \irqnr, [\irqstat, #AITC_NIVECSR]
+               ldr     \irqstat, [\base, #AITC_NIVECSR]
                @ Shift off the priority leaving the offset or
-               @ "interrupt number"
-               mov     \irqnr, \irqnr, lsr #16
-               ldr     \irqstat, =1    @ dummy compare
-               ldr     \base, =0xFFFF          // invalid interrupt
-               cmp     \irqnr, \base
-               bne     1001f
-               ldr     \irqstat, =0
-1001:
-               tst     \irqstat, #1    @ to make the condition code = TRUE
+               @ "interrupt number", use arithmetic shift to
+               @ transform illegal source (0xffff) as -1
+               mov     \irqnr, \irqstat, asr #16
+               adds    \tmp, \irqnr, #1
                .endm
-
index dbdec36ff0d1bc7642dd64c662ea17262a52a13a..79b850a3be475cdb96422c85be26d3170d8e8307 100644 (file)
@@ -6,3 +6,25 @@
 
 extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
+static inline int udc_gpio_to_irq(unsigned gpio)
+{
+       return 0;
+}
+
+static inline void udc_gpio_init_vbus(unsigned gpio)
+{
+}
+
+static inline void udc_gpio_init_pullup(unsigned gpio)
+{
+}
+
+static inline int udc_gpio_get(unsigned gpio)
+{
+       return 0;
+}
+
+static inline void udc_gpio_set(unsigned gpio, int is_on)
+{
+}
+
index e24f6b6c79ae763f97bd9806d01e55628357c531..aec835b6f057e52bc1edd16cafeb8494dbb7d37f 100644 (file)
  * Serial Audio Controller
  */
 
-/* FIXME: This clash with SA1111 defines */
-#ifndef _ASM_ARCH_SA1111
-
 #define SACR0          __REG(0x40400000)  /* Global Control Register */
 #define SACR1          __REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
 #define SASR0          __REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
 #define SADIV          __REG(0x40400060)  /* Audio Clock Divider Register. */
 #define SADR           __REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
 
-#define SACR0_RFTH(x)  (x << 12)       /* Rx FIFO Interrupt or DMA Trigger Threshold */
-#define SACR0_TFTH(x)  (x << 8)        /* Tx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_RFTH(x)  ((x) << 12)     /* Rx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_TFTH(x)  ((x) << 8)      /* Tx FIFO Interrupt or DMA Trigger Threshold */
 #define SACR0_STRF     (1 << 5)        /* FIFO Select for EFWR Special Function */
 #define SACR0_EFWR     (1 << 4)        /* Enable EFWR Function  */
 #define SACR0_RST      (1 << 3)        /* FIFO, i2s Register Reset */
 #define SAIMR_RFS      (1 << 4)        /* Enable Rx FIFO Service Interrupt */
 #define SAIMR_TFS      (1 << 3)        /* Enable Tx FIFO Service Interrupt */
 
-#endif
-
 /*
  * AC97 Controller registers
  */
 #define SSSR_PINT              (1 << 18)       /* Peripheral Trailing Byte Interrupt */
 
 #define SSPSP_FSRT             (1 << 25)       /* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x)       (x << 23)       /* Dummy Stop */
-#define SSPSP_SFRMWDTH(x)      (x << 16)       /* Serial Frame Width */
-#define SSPSP_SFRMDLY(x)       (x << 9)        /* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x)       (x << 7)        /* Dummy Start */
-#define SSPSP_STRTDLY(x)       (x << 4)        /* Start Delay */
+#define SSPSP_DMYSTOP(x)       ((x) << 23)     /* Dummy Stop */
+#define SSPSP_SFRMWDTH(x)      ((x) << 16)     /* Serial Frame Width */
+#define SSPSP_SFRMDLY(x)       ((x) << 9)      /* Serial Frame Delay */
+#define SSPSP_DMYSTRT(x)       ((x) << 7)      /* Dummy Start */
+#define SSPSP_STRTDLY(x)       ((x) << 4)      /* Start Delay */
 #define SSPSP_ETDS                     (1 << 3)        /* End of Transfer data State */
 #define SSPSP_SFRMP                    (1 << 2)        /* Serial Frame Polarity */
-#define SSPSP_SCMODE(x)                (x << 0)        /* Serial Bit Rate Clock Mode */
+#define SSPSP_SCMODE(x)                ((x) << 0)      /* Serial Bit Rate Clock Mode */
 
+#define SSACD_SCDB             (1 << 3)        /* SSPSYSCLK Divider Bypass */
+#define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
+#define SSACD_ACDS(x)          ((x) << 0)      /* Audio clock divider select */
 
 #define SSCR0_P1       __REG(0x41000000)  /* SSP Port 1 Control Register 0 */
 #define SSCR1_P1       __REG(0x41000004)  /* SSP Port 1 Control Register 1 */
index 646480d37256a067146db1a6202c734f06ad60d7..8bc6f9c3e3ea2c130b271b46359e7b0a34f7d3bc 100644 (file)
@@ -9,3 +9,33 @@
 
 extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
 
+static inline int udc_gpio_to_irq(unsigned gpio)
+{
+       return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
+}
+
+static inline void udc_gpio_init_vbus(unsigned gpio)
+{
+       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
+}
+
+static inline void udc_gpio_init_pullup(unsigned gpio)
+{
+       pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
+}
+
+static inline int udc_gpio_get(unsigned gpio)
+{
+       return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
+}
+
+static inline void udc_gpio_set(unsigned gpio, int is_on)
+{
+       int mask = GPIO_bit(gpio);
+
+       if (is_on)
+               GPSR(gpio) = mask;
+       else
+               GPCR(gpio) = mask;
+}
+
index 9ca76dc3a7af8ef39fbb6af750a3882ada9e5231..aa78fe087ab2a39cf9ed841aac5e97f42e318ab1 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/arch/platform.h>
 
 /* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+#define IO_ADDRESS(x)          ((((x) & 0x0effffff) | (((x) >> 4) & 0x0f000000)) + 0xf0000000)
 #define __io_address(n)                __io(IO_ADDRESS(n))
 
 #endif
index 76b498eb20a60a2f348f93118df9e53691a3f3f8..5a5db56f86b8cd9a712dc31fc8b630c4cf075e4f 100644 (file)
@@ -78,6 +78,9 @@
 #define IRQ_PMU_SCU6           (IRQ_GIC_START + INT_PMU_SCU6)
 #define IRQ_PMU_SCU7           (IRQ_GIC_START + INT_PMU_SCU7)
 
+#define IRQ_EB_IRQ1            (IRQ_GIC_START + INT_EB_IRQ1)
+#define IRQ_EB_IRQ2            (IRQ_GIC_START + INT_EB_IRQ2)
+
 #define IRQMASK_WDOGINT                INTMASK_WDOGINT
 #define IRQMASK_SOFTINT                INTMASK_SOFTINT
 #define IRQMASK_COMMRx                 INTMASK_COMMRx
 #define IRQMASK_ETH            INTMASK_ETH
 #define IRQMASK_USB            INTMASK_USB
 
-#define NR_IRQS                        (IRQ_GIC_START + 64)
+#define NR_IRQS                        (IRQ_GIC_START + 96)
index 18d7c18b738c7941501063283de1061c31a33959..6e0eab95a3a2ed3b8de1a0ae9044e5bc78c193c9 100644 (file)
 #define REALVIEW_GIC_CPU_BASE         0x10040000       /* Generic interrupt controller CPU interface */
 #define REALVIEW_GIC_DIST_BASE        0x10041000       /* Generic interrupt controller distributor */
 #else
+#ifdef CONFIG_REALVIEW_MPCORE_REVB
 #define REALVIEW_MPCORE_SCU_BASE       0x10100000      /*  SCU registers */
 #define REALVIEW_GIC_CPU_BASE          0x10100100      /* Generic interrupt controller CPU interface */
 #define REALVIEW_TWD_BASE              0x10100700
 #define REALVIEW_TWD_SIZE              0x00000100
 #define REALVIEW_GIC_DIST_BASE         0x10101000      /* Generic interrupt controller distributor */
+#define REALVIEW_MPCORE_L220_BASE      0x10102000      /* L220 registers */
+#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0xD8             /*  Register offset for MPCore sysctl */
+#else
+#define REALVIEW_MPCORE_SCU_BASE      0x1F000000       /*  SCU registers */
+#define REALVIEW_GIC_CPU_BASE         0x1F000100       /* Generic interrupt controller CPU interface */
+#define REALVIEW_TWD_BASE             0x1F000700
+#define REALVIEW_TWD_SIZE             0x00000100
+#define REALVIEW_GIC_DIST_BASE        0x1F001000       /* Generic interrupt controller distributor */
+#define REALVIEW_MPCORE_L220_BASE     0x1F002000       /* L220 registers */
+#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0x74             /*  Register offset for MPCore sysctl */
+#endif
+#define REALVIEW_GIC1_CPU_BASE        0x10040000       /* Generic interrupt controller CPU interface */
+#define REALVIEW_GIC1_DIST_BASE       0x10041000       /* Generic interrupt controller distributor */
 #endif
 #define REALVIEW_SMC_BASE             0x10080000       /* SMC */
        /* Reserved 0x10090000 - 0x100EFFFF */
 #define INT_USB                                29      /* USB controller */
 #define INT_TSPENINT                   30      /* Touchscreen pen */
 #define INT_TSKPADINT                  31      /* Touchscreen keypad */
+
 #else
+
+#define MAX_GIC_NR                     2
+
 #define INT_AACI                       0
 #define INT_TIMERINT0_1                        1
 #define INT_TIMERINT2_3                        2
diff --git a/include/asm-arm/arch-realview/scu.h b/include/asm-arm/arch-realview/scu.h
new file mode 100644 (file)
index 0000000..cc29364
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __ASMARM_ARCH_SCU_H
+#define __ASMARM_ARCH_SCU_H
+
+#include <asm/arch/platform.h>
+
+#define SCU_BASE       REALVIEW_MPCORE_SCU_BASE
+
+#endif
index 58ffa7ba3c88dc68728794225220f14f297cd7e7..c6e8d8f64938e4e3aa0af3fb6119ec47ae8202ee 100644 (file)
@@ -51,13 +51,19 @@ enum dma_ch {
        DMACH_UART0_SRC2,       /* s3c2412 second uart sources */
        DMACH_UART1_SRC2,
        DMACH_UART2_SRC2,
+       DMACH_UART3,            /* s3c2443 has extra uart */
+       DMACH_UART3_SRC2,
        DMACH_MAX,              /* the end entry */
 };
 
 #define DMACH_LOW_LEVEL        (1<<28) /* use this to specifiy hardware ch no */
 
 /* we have 4 dma channels */
-#define S3C2410_DMA_CHANNELS        (4)
+#ifndef CONFIG_CPU_S3C2443
+#define S3C2410_DMA_CHANNELS           (4)
+#else
+#define S3C2410_DMA_CHANNELS           (6)
+#endif
 
 /* types */
 
@@ -321,6 +327,7 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 #define S3C2410_DMA_DCDST       (0x1C)
 #define S3C2410_DMA_DMASKTRIG   (0x20)
 #define S3C2412_DMA_DMAREQSEL  (0x24)
+#define S3C2443_DMA_DMAREQSEL  (0x24)
 
 #define S3C2410_DISRCC_INC     (1<<0)
 #define S3C2410_DISRCC_APB     (1<<1)
@@ -415,4 +422,31 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 #define S3C2412_DMAREQSEL_UART2_1      S3C2412_DMAREQSEL_SRC(24)
 
 #endif
+
+#define S3C2443_DMAREQSEL_SRC(x)       ((x)<<1)
+
+#define S3C2443_DMAREQSEL_HW           (1)
+
+#define S3C2443_DMAREQSEL_SPI0TX       S3C2443_DMAREQSEL_SRC(0)
+#define S3C2443_DMAREQSEL_SPI0RX       S3C2443_DMAREQSEL_SRC(1)
+#define S3C2443_DMAREQSEL_SPI1TX       S3C2443_DMAREQSEL_SRC(2)
+#define S3C2443_DMAREQSEL_SPI1RX       S3C2443_DMAREQSEL_SRC(3)
+#define S3C2443_DMAREQSEL_I2STX                S3C2443_DMAREQSEL_SRC(4)
+#define S3C2443_DMAREQSEL_I2SRX                S3C2443_DMAREQSEL_SRC(5)
+#define S3C2443_DMAREQSEL_TIMER                S3C2443_DMAREQSEL_SRC(9)
+#define S3C2443_DMAREQSEL_SDI          S3C2443_DMAREQSEL_SRC(10)
+#define S3C2443_DMAREQSEL_XDREQ0       S3C2443_DMAREQSEL_SRC(17)
+#define S3C2443_DMAREQSEL_XDREQ1       S3C2443_DMAREQSEL_SRC(18)
+#define S3C2443_DMAREQSEL_UART0_0      S3C2443_DMAREQSEL_SRC(19)
+#define S3C2443_DMAREQSEL_UART0_1      S3C2443_DMAREQSEL_SRC(20)
+#define S3C2443_DMAREQSEL_UART1_0      S3C2443_DMAREQSEL_SRC(21)
+#define S3C2443_DMAREQSEL_UART1_1      S3C2443_DMAREQSEL_SRC(22)
+#define S3C2443_DMAREQSEL_UART2_0      S3C2443_DMAREQSEL_SRC(23)
+#define S3C2443_DMAREQSEL_UART2_1      S3C2443_DMAREQSEL_SRC(24)
+#define S3C2443_DMAREQSEL_UART3_0      S3C2443_DMAREQSEL_SRC(25)
+#define S3C2443_DMAREQSEL_UART3_1      S3C2443_DMAREQSEL_SRC(26)
+#define S3C2443_DMAREQSEL_PCMOUT       S3C2443_DMAREQSEL_SRC(27)
+#define S3C2443_DMAREQSEL_PCMIN        S3C2443_DMAREQSEL_SRC(28)
+#define S3C2443_DMAREQSEL_MICIN                S3C2443_DMAREQSEL_SRC(29)
+
 #endif /* __ASM_ARCH_DMA_H */
index 4b7cff456c4e04f935acfb3b07f87554101d62b1..c79cb18199138e18f20f33b86041e06c4a1390ff 100644 (file)
 #define IRQ_EINT4t7    S3C2410_IRQ(4)      /* 20 */
 #define IRQ_EINT8t23   S3C2410_IRQ(5)
 #define IRQ_RESERVED6  S3C2410_IRQ(6)      /* for s3c2410 */
-#define IRQ_CAM        S3C2410_IRQ(6)      /* for s3c2440 */
+#define IRQ_CAM        S3C2410_IRQ(6)      /* for s3c2440,s3c2443 */
 #define IRQ_BATT_FLT   S3C2410_IRQ(7)
 #define IRQ_TICK       S3C2410_IRQ(8)      /* 24 */
-#define IRQ_WDT               S3C2410_IRQ(9)
+#define IRQ_WDT               S3C2410_IRQ(9)       /* WDT/AC97 for s3c2443 */
 #define IRQ_TIMER0     S3C2410_IRQ(10)
 #define IRQ_TIMER1     S3C2410_IRQ(11)
 #define IRQ_TIMER2     S3C2410_IRQ(12)
@@ -45,7 +45,7 @@
 #define IRQ_TIMER4     S3C2410_IRQ(14)
 #define IRQ_UART2      S3C2410_IRQ(15)
 #define IRQ_LCD               S3C2410_IRQ(16)      /* 32 */
-#define IRQ_DMA0       S3C2410_IRQ(17)
+#define IRQ_DMA0       S3C2410_IRQ(17)     /* IRQ_DMA for s3c2443 */
 #define IRQ_DMA1       S3C2410_IRQ(18)
 #define IRQ_DMA2       S3C2410_IRQ(19)
 #define IRQ_DMA3       S3C2410_IRQ(20)
  * these need to be ordered in number of appearance in the
  * SUBSRC mask register
 */
-#define IRQ_S3CUART_RX0  S3C2410_IRQ(54)   /* 70 */
-#define IRQ_S3CUART_TX0  S3C2410_IRQ(55)   /* 71 */
-#define IRQ_S3CUART_ERR0 S3C2410_IRQ(56)
 
-#define IRQ_S3CUART_RX1  S3C2410_IRQ(57)
-#define IRQ_S3CUART_TX1  S3C2410_IRQ(58)
-#define IRQ_S3CUART_ERR1 S3C2410_IRQ(59)
+#define S3C2410_IRQSUB(x)      S3C2410_IRQ((x)+54)
 
-#define IRQ_S3CUART_RX2  S3C2410_IRQ(60)
-#define IRQ_S3CUART_TX2  S3C2410_IRQ(61)
-#define IRQ_S3CUART_ERR2 S3C2410_IRQ(62)
+#define IRQ_S3CUART_RX0                S3C2410_IRQSUB(0)       /* 70 */
+#define IRQ_S3CUART_TX0                S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0       S3C2410_IRQSUB(2)
 
-#define IRQ_TC          S3C2410_IRQ(63)
-#define IRQ_ADC                 S3C2410_IRQ(64)
+#define IRQ_S3CUART_RX1                S3C2410_IRQSUB(3)       /* 73 */
+#define IRQ_S3CUART_TX1                S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1       S3C2410_IRQSUB(5)
 
-/* extra irqs for s3c2440 */
+#define IRQ_S3CUART_RX2                S3C2410_IRQSUB(6)       /* 76 */
+#define IRQ_S3CUART_TX2                S3C2410_IRQSUB(7)
+#define IRQ_S3CUART_ERR2       S3C2410_IRQSUB(8)
 
-#define IRQ_S3C2440_CAM_C      S3C2410_IRQ(65)
-#define IRQ_S3C2440_CAM_P      S3C2410_IRQ(66)
-#define IRQ_S3C2440_WDT                S3C2410_IRQ(67)
-#define IRQ_S3C2440_AC97       S3C2410_IRQ(68)
+#define IRQ_TC                 S3C2410_IRQSUB(9)
+#define IRQ_ADC                        S3C2410_IRQSUB(10)
 
-#define NR_IRQS (IRQ_S3C2440_AC97+1)
+/* extra irqs for s3c2440 */
 
+#define IRQ_S3C2440_CAM_C      S3C2410_IRQSUB(11)      /* S3C2443 too */
+#define IRQ_S3C2440_CAM_P      S3C2410_IRQSUB(12)      /* S3C2443 too */
+#define IRQ_S3C2440_WDT                S3C2410_IRQSUB(13)
+#define IRQ_S3C2440_AC97       S3C2410_IRQSUB(14)
+
+/* irqs for s3c2443 */
+
+#define IRQ_S3C2443_DMA                S3C2410_IRQ(17)         /* IRQ_DMA1 */
+#define IRQ_S3C2443_UART3      S3C2410_IRQ(18)         /* IRQ_DMA2 */
+#define IRQ_S3C2443_CFCON      S3C2410_IRQ(19)         /* IRQ_DMA3 */
+#define IRQ_S3C2443_SDI1       S3C2410_IRQ(20)         /* IRQ_SDI */
+#define IRQ_S3C2443_NAND       S3C2410_IRQ(24)         /* reserved */
+
+#define IRQ_S3C2443_LCD1       S3C2410_IRQSUB(14)
+#define IRQ_S3C2443_LCD2       S3C2410_IRQSUB(15)
+#define IRQ_S3C2443_LCD3       S3C2410_IRQSUB(16)
+#define IRQ_S3C2443_LCD4       S3C2410_IRQSUB(17)
+
+#define IRQ_S3C2443_DMA0       S3C2410_IRQSUB(18)
+#define IRQ_S3C2443_DMA1       S3C2410_IRQSUB(19)
+#define IRQ_S3C2443_DMA2       S3C2410_IRQSUB(20)
+#define IRQ_S3C2443_DMA3       S3C2410_IRQSUB(21)
+#define IRQ_S3C2443_DMA4       S3C2410_IRQSUB(22)
+#define IRQ_S3C2443_DMA5       S3C2410_IRQSUB(23)
+
+/* UART3 */
+#define IRQ_S3C2443_RX3                S3C2410_IRQSUB(24)
+#define IRQ_S3C2443_TX3                S3C2410_IRQSUB(25)
+#define IRQ_S3C2443_ERR3       S3C2410_IRQSUB(26)
+
+#define IRQ_S3C2443_WDT                S3C2410_IRQSUB(27)
+#define IRQ_S3C2443_AC97       S3C2410_IRQSUB(28)
+
+#ifdef CONFIG_CPU_S3C2443
+#define NR_IRQS (IRQ_S3C2443_AC97+1)
+#else
+#define NR_IRQS (IRQ_S3C2440_AC97+1)
+#endif
 
 #endif /* __ASM_ARCH_IRQ_H */
index 3196a2849e8ae508061339b45ff4e2426d84698a..c7f231963e7607b30a108bb5526d1d7885ef5ccf 100644 (file)
@@ -41,7 +41,7 @@
 #define S3C2410_ADCTSC_XP_SEN          (1<<4)
 #define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
 #define S3C2410_ADCTSC_AUTO_PST                (1<<2)
-#define S3C2410_ADCTSC_XY_PST          (0x3<<0)
+#define S3C2410_ADCTSC_XY_PST(x)       (((x)&0x3)<<0)
 
 /* ADCDAT0 Bits */
 #define S3C2410_ADCDAT0_UPDOWN         (1<<15)
index eae91694edcdf61939eacbdd99225d440572e7bd..dea578b8f7f66e1b035bc07b03baa3764e8c2d7e 100644 (file)
 #define S3C2400_GPBDAT    S3C2410_GPIOREG(0x0C)
 #define S3C2400_GPBUP     S3C2410_GPIOREG(0x10)
 
-/* no i/o pin in port b can have value 3! */
+/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
 
 #define S3C2410_GPB0         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0)
 #define S3C2410_GPB0_INP     (0x00 << 0)
 #define S3C2410_GPB5_INP     (0x00 << 10)
 #define S3C2410_GPB5_OUTP    (0x01 << 10)
 #define S3C2410_GPB5_nXBACK  (0x02 << 10)
+#define S3C2443_GPB5_XBACK   (0x03 << 10)
 #define S3C2400_GPB5_DATA21  (0x02 << 10)
 #define S3C2400_GPB5_nCTS1   (0x03 << 10)
 
 #define S3C2410_GPB6_INP     (0x00 << 12)
 #define S3C2410_GPB6_OUTP    (0x01 << 12)
 #define S3C2410_GPB6_nXBREQ  (0x02 << 12)
+#define S3C2443_GPB6_XBREQ   (0x03 << 12)
 #define S3C2400_GPB6_DATA22  (0x02 << 12)
 #define S3C2400_GPB6_nRTS1   (0x03 << 12)
 
 #define S3C2410_GPB7_INP     (0x00 << 14)
 #define S3C2410_GPB7_OUTP    (0x01 << 14)
 #define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2443_GPB7_XDACK1  (0x03 << 14)
 #define S3C2400_GPB7_DATA23  (0x02 << 14)
 
 #define S3C2410_GPB8         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8)
 #define S3C2410_GPB9_INP     (0x00 << 18)
 #define S3C2410_GPB9_OUTP    (0x01 << 18)
 #define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2443_GPB9_XDACK0  (0x03 << 18)
 #define S3C2400_GPB9_DATA25  (0x02 << 18)
 #define S3C2400_GPB9_I2SSDI  (0x03 << 18)
 
 #define S3C2410_GPB10_INP    (0x00 << 20)
 #define S3C2410_GPB10_OUTP   (0x01 << 20)
 #define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
 #define S3C2400_GPB10_DATA26 (0x02 << 20)
 #define S3C2400_GPB10_nSS    (0x03 << 20)
 
 #define S3C2410_GPE0_INP       (0x00 << 0)
 #define S3C2410_GPE0_OUTP      (0x01 << 0)
 #define S3C2410_GPE0_I2SLRCK   (0x02 << 0)
+#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
 #define S3C2400_GPE0_EINT0     (0x02 << 0)
 #define S3C2410_GPE0_MASK      (0x03 << 0)
 
 #define S3C2410_GPE1_INP       (0x00 << 2)
 #define S3C2410_GPE1_OUTP      (0x01 << 2)
 #define S3C2410_GPE1_I2SSCLK   (0x02 << 2)
+#define S3C2443_GPE1_AC_SYNC   (0x03 << 2)
 #define S3C2400_GPE1_EINT1     (0x02 << 2)
 #define S3C2400_GPE1_nSS       (0x03 << 2)
 #define S3C2410_GPE1_MASK      (0x03 << 2)
 #define S3C2410_GPE2_INP       (0x00 << 4)
 #define S3C2410_GPE2_OUTP      (0x01 << 4)
 #define S3C2410_GPE2_CDCLK     (0x02 << 4)
+#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
 #define S3C2400_GPE2_EINT2     (0x02 << 4)
 #define S3C2400_GPE2_I2SSDI    (0x03 << 4)
 
 #define S3C2410_GPE3_INP       (0x00 << 6)
 #define S3C2410_GPE3_OUTP      (0x01 << 6)
 #define S3C2410_GPE3_I2SSDI    (0x02 << 6)
+#define S3C2443_GPE3_AC_SDI    (0x03 << 6)
 #define S3C2400_GPE3_EINT3     (0x02 << 6)
 #define S3C2400_GPE3_nCTS1     (0x03 << 6)
 #define S3C2410_GPE3_nSS0      (0x03 << 6)
 #define S3C2410_GPE4_INP       (0x00 << 8)
 #define S3C2410_GPE4_OUTP      (0x01 << 8)
 #define S3C2410_GPE4_I2SSDO    (0x02 << 8)
+#define S3C2443_GPE4_AC_SDO    (0x03 << 8)
 #define S3C2400_GPE4_EINT4     (0x02 << 8)
 #define S3C2400_GPE4_nRTS1     (0x03 << 8)
 #define S3C2410_GPE4_I2SSDI    (0x03 << 8)
 #define S3C2410_GPE5_INP       (0x00 << 10)
 #define S3C2410_GPE5_OUTP      (0x01 << 10)
 #define S3C2410_GPE5_SDCLK     (0x02 << 10)
+#define S3C2443_GPE5_SD1_CLK   (0x02 << 10)
 #define S3C2400_GPE5_EINT5     (0x02 << 10)
 #define S3C2400_GPE5_TCLK1     (0x03 << 10)
 
 #define S3C2410_GPE6_INP       (0x00 << 12)
 #define S3C2410_GPE6_OUTP      (0x01 << 12)
 #define S3C2410_GPE6_SDCMD     (0x02 << 12)
+#define S3C2443_GPE6_SD1_CMD   (0x02 << 12)
+#define S3C2443_GPE6_AC_BITCLK (0x03 << 12)
 #define S3C2400_GPE6_EINT6     (0x02 << 12)
 
 #define S3C2410_GPE7           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7)
 #define S3C2410_GPE7_INP       (0x00 << 14)
 #define S3C2410_GPE7_OUTP      (0x01 << 14)
 #define S3C2410_GPE7_SDDAT0    (0x02 << 14)
+#define S3C2443_GPE5_SD1_DAT0  (0x02 << 14)
+#define S3C2443_GPE7_AC_SDI    (0x03 << 14)
 #define S3C2400_GPE7_EINT7     (0x02 << 14)
 
 #define S3C2410_GPE8           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8)
 #define S3C2410_GPE8_INP       (0x00 << 16)
 #define S3C2410_GPE8_OUTP      (0x01 << 16)
 #define S3C2410_GPE8_SDDAT1    (0x02 << 16)
+#define S3C2443_GPE8_SD1_DAT1  (0x02 << 16)
+#define S3C2443_GPE8_AC_SDO    (0x03 << 16)
 #define S3C2400_GPE8_nXDACK0   (0x02 << 16)
 
 #define S3C2410_GPE9           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9)
 #define S3C2410_GPE9_INP       (0x00 << 18)
 #define S3C2410_GPE9_OUTP      (0x01 << 18)
 #define S3C2410_GPE9_SDDAT2    (0x02 << 18)
+#define S3C2443_GPE9_SD1_DAT2  (0x02 << 18)
+#define S3C2443_GPE9_AC_SYNC   (0x03 << 18)
 #define S3C2400_GPE9_nXDACK1   (0x02 << 18)
 #define S3C2400_GPE9_nXBACK    (0x03 << 18)
 
 #define S3C2410_GPE10_INP      (0x00 << 20)
 #define S3C2410_GPE10_OUTP     (0x01 << 20)
 #define S3C2410_GPE10_SDDAT3   (0x02 << 20)
+#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
+#define S3C2443_GPE10_AC_nRESET (0x03 << 20)
 #define S3C2400_GPE10_nXDREQ0  (0x02 << 20)
 
 #define S3C2410_GPE11          S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11)
 #define S3C2400_GPG4_MMCCLK   (0x02 << 8)
 #define S3C2400_GPG4_I2SSDI   (0x03 << 8)
 #define S3C2410_GPG4_LCDPWREN (0x03 << 8)
+#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
 
 #define S3C2410_GPG5          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5)
 #define S3C2410_GPG5_INP      (0x00 << 10)
 #define S3C2410_GPG5_EINT13   (0x02 << 10)
 #define S3C2400_GPG5_MMCCMD   (0x02 << 10)
 #define S3C2400_GPG5_IICSDA   (0x03 << 10)
-#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)
+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)     /* not s3c2443 */
 
 #define S3C2410_GPG6          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6)
 #define S3C2410_GPG6_INP      (0x00 << 12)
 #define S3C2410_GPG11_OUTP    (0x01 << 22)
 #define S3C2410_GPG11_EINT19  (0x02 << 22)
 #define S3C2410_GPG11_TCLK1   (0x03 << 22)
+#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
 
 #define S3C2410_GPG12         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 12)
 #define S3C2410_GPG12_INP     (0x00 << 24)
 #define S3C2410_GPG12_EINT20  (0x02 << 24)
 #define S3C2410_GPG12_XMON    (0x03 << 24)
 #define S3C2442_GPG12_nSPICS0 (0x03 << 24)
+#define S3C2443_GPG12_nINPACK (0x03 << 24)
 
 #define S3C2410_GPG13         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13)
 #define S3C2410_GPG13_INP     (0x00 << 26)
 #define S3C2410_GPG13_OUTP    (0x01 << 26)
 #define S3C2410_GPG13_EINT21  (0x02 << 26)
 #define S3C2410_GPG13_nXPON   (0x03 << 26)
+#define S3C2443_GPG13_CF_nREG (0x03 << 26)
 
 #define S3C2410_GPG14         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 14)
 #define S3C2410_GPG14_INP     (0x00 << 28)
 #define S3C2410_GPG14_OUTP    (0x01 << 28)
 #define S3C2410_GPG14_EINT22  (0x02 << 28)
 #define S3C2410_GPG14_YMON    (0x03 << 28)
+#define S3C2443_GPG14_CF_RESET (0x03 << 28)
 
 #define S3C2410_GPG15         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 15)
 #define S3C2410_GPG15_INP     (0x00 << 30)
 #define S3C2410_GPG15_OUTP    (0x01 << 30)
 #define S3C2410_GPG15_EINT23  (0x02 << 30)
 #define S3C2410_GPG15_nYPON   (0x03 << 30)
-
+#define S3C2443_GPG15_CF_PWR  (0x03 << 30)
 
 #define S3C2410_GPG_PUPDIS(x)  (1<<(x))
 
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h b/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h
new file mode 100644 (file)
index 0000000..ff0536d
--- /dev/null
@@ -0,0 +1,194 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-clock.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * 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.
+ *
+ * S3C2443 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
+#define __ASM_ARM_REGS_S3C2443_CLOCK
+
+#define S3C2443_CLKREG(x)              ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2443_PLLCON_MDIVSHIFT       16
+#define S3C2443_PLLCON_PDIVSHIFT       8
+#define S3C2443_PLLCON_SDIVSHIFT       0
+#define S3C2443_PLLCON_MDIVMASK                ((1<<(1+(23-16)))-1)
+#define S3C2443_PLLCON_PDIVMASK                ((1<<(1+(9-8)))-1)
+#define S3C2443_PLLCON_SDIVMASK                (3)
+
+#define S3C2443_MPLLCON                        S3C2443_CLKREG(0x10)
+#define S3C2443_EPLLCON                        S3C2443_CLKREG(0x18)
+#define S3C2443_CLKSRC                 S3C2443_CLKREG(0x20)
+#define S3C2443_CLKDIV0                        S3C2443_CLKREG(0x24)
+#define S3C2443_CLKDIV1                        S3C2443_CLKREG(0x28)
+#define S3C2443_HCLKCON                        S3C2443_CLKREG(0x30)
+#define S3C2443_PCLKCON                        S3C2443_CLKREG(0x34)
+#define S3C2443_SCLKCON                        S3C2443_CLKREG(0x38)
+#define S3C2443_PWRMODE                        S3C2443_CLKREG(0x40)
+#define S3C2443_SWRST                  S3C2443_CLKREG(0x44)
+#define S3C2443_BUSPRI0                        S3C2443_CLKREG(0x50)
+#define S3C2443_SYSID                  S3C2443_CLKREG(0x5C)
+#define S3C2443_PWRCFG                 S3C2443_CLKREG(0x60)
+#define S3C2443_RSTCON                 S3C2443_CLKREG(0x64)
+
+#define S3C2443_SWRST_RESET            (0x533c2443)
+
+#define S3C2443_PLLCON_OFF             (1<<24)
+
+#define S3C2443_CLKSRC_I2S_EXT         (1<<14)
+#define S3C2443_CLKSRC_I2S_EPLLDIV     (0<<14)
+#define S3C2443_CLKSRC_I2S_EPLLREF     (2<<14)
+#define S3C2443_CLKSRC_I2S_EPLLREF3    (3<<14)
+#define S3C2443_CLKSRC_I2S_MASK                (3<<14)
+
+#define S3C2443_CLKSRC_EPLLREF_XTAL    (2<<8)
+#define S3C2443_CLKSRC_EPLLREF_EXTCLK  (3<<8)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<8)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF2        (1<<8)
+#define S3C2443_CLKSRC_EPLLREF_MASK    (3<<8)
+
+#define S3C2443_CLKSRC_ESYSCLK_EPLL    (1<<6)
+#define S3C2443_CLKSRC_MSYSCLK_MPLL    (1<<4)
+#define S3C2443_CLKSRC_EXTCLK_DIV      (1<<3)
+
+#define S3C2443_CLKDIV0_DVS            (1<<13)
+#define S3C2443_CLKDIV0_HALF_HCLK      (1<<3)
+#define S3C2443_CLKDIV0_HALF_PCLK      (1<<2)
+
+#define S3C2443_CLKDIV0_HCLKDIV_MASK   (3<<0)
+
+#define S3C2443_CLKDIV0_EXTDIV_MASK    (3<<6)
+#define S3C2443_CLKDIV0_EXTDIV_SHIFT   (6)
+
+#define S3C2443_CLKDIV0_PREDIV_MASK    (3<<4)
+#define S3C2443_CLKDIV0_PREDIV_SHIFT   (4)
+
+#define S3C2443_CLKDIV0_ARMDIV_MASK    (15<<9)
+#define S3C2443_CLKDIV0_ARMDIV_SHIFT   (9)
+#define S3C2443_CLKDIV0_ARMDIV_1       (0<<9)
+#define S3C2443_CLKDIV0_ARMDIV_2       (8<<9)
+#define S3C2443_CLKDIV0_ARMDIV_3       (2<<9)
+#define S3C2443_CLKDIV0_ARMDIV_4       (9<<9)
+#define S3C2443_CLKDIV0_ARMDIV_6       (10<<9)
+#define S3C2443_CLKDIV0_ARMDIV_8       (11<<9)
+#define S3C2443_CLKDIV0_ARMDIV_12      (13<<9)
+#define S3C2443_CLKDIV0_ARMDIV_16      (15<<9)
+
+/* S3C2443_CLKDIV1 */
+
+#define S3C2443_CLKDIV1_CAMDIV_MASK    (15<<26)
+#define S3C2443_CLKDIV1_CAMDIV_SHIFT   (26)
+
+#define S3C2443_CLKDIV1_HSSPIDIV_MASK  (3<<24)
+#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT (24)
+
+#define S3C2443_CLKDIV1_DISPDIV_MASK   (0xff<<16)
+#define S3C2443_CLKDIV1_DISPDIV_SHIFT  (16)
+
+#define S3C2443_CLKDIV1_I2SDIV_MASK    (15<<12)
+#define S3C2443_CLKDIV1_I2SDIV_SHIFT   (12)
+
+#define S3C2443_CLKDIV1_UARTDIV_MASK   (15<<8)
+#define S3C2443_CLKDIV1_UARTDIV_SHIFT  (8)
+
+#define S3C2443_CLKDIV1_HSMMCDIV_MASK  (3<<6)
+#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT (6)
+
+#define S3C2443_CLKDIV1_USBHOSTDIV_MASK        (3<<4)
+#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4)
+
+#define S3C2443_CLKCON_NAND
+
+#define S3C2443_HCLKCON_DMA0           (1<<0)
+#define S3C2443_HCLKCON_DMA1           (1<<1)
+#define S3C2443_HCLKCON_DMA2           (1<<2)
+#define S3C2443_HCLKCON_DMA3           (1<<3)
+#define S3C2443_HCLKCON_DMA4           (1<<4)
+#define S3C2443_HCLKCON_DMA5           (1<<5)
+#define S3C2443_HCLKCON_CAMIF          (1<<8)
+#define S3C2443_HCLKCON_DISP           (1<<9)
+#define S3C2443_HCLKCON_LCDC           (1<<10)
+#define S3C2443_HCLKCON_USBH           (1<<11)
+#define S3C2443_HCLKCON_USBD           (1<<12)
+#define S3C2443_HCLKCON_HSMMC          (1<<16)
+#define S3C2443_HCLKCON_CFC            (1<<17)
+#define S3C2443_HCLKCON_SSMC           (1<<18)
+#define S3C2443_HCLKCON_DRAMC          (1<<19)
+
+#define S3C2443_PCLKCON_UART0          (1<<0)
+#define S3C2443_PCLKCON_UART1          (1<<1)
+#define S3C2443_PCLKCON_UART2          (1<<2)
+#define S3C2443_PCLKCON_UART3          (1<<3)
+#define S3C2443_PCLKCON_IIC            (1<<4)
+#define S3C2443_PCLKCON_SDI            (1<<5)
+#define S3C2443_PCLKCON_ADC            (1<<7)
+#define S3C2443_PCLKCON_IIS            (1<<9)
+#define S3C2443_PCLKCON_PWMT           (1<<10)
+#define S3C2443_PCLKCON_WDT            (1<<11)
+#define S3C2443_PCLKCON_RTC            (1<<12)
+#define S3C2443_PCLKCON_GPIO           (1<<13)
+#define S3C2443_PCLKCON_SPI0           (1<<14)
+#define S3C2443_PCLKCON_SPI1           (1<<15)
+
+#define S3C2443_SCLKCON_DDRCLK         (1<<16)
+#define S3C2443_SCLKCON_SSMCCLK                (1<<15)
+#define S3C2443_SCLKCON_HSSPICLK       (1<<14)
+#define S3C2443_SCLKCON_HSMMCCLK_EXT   (1<<13)
+#define S3C2443_SCLKCON_HSMMCCLK_EPLL  (1<<12)
+#define S3C2443_SCLKCON_CAMCLK         (1<<11)
+#define S3C2443_SCLKCON_DISPCLK                (1<<10)
+#define S3C2443_SCLKCON_I2SCLK         (1<<9)
+#define S3C2443_SCLKCON_UARTCLK                (1<<8)
+#define S3C2443_SCLKCON_USBHOST                (1<<1)
+
+#include <asm/div64.h>
+
+static inline unsigned int
+s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+       mdiv &= S3C2443_PLLCON_MDIVMASK;
+       pdiv &= S3C2443_PLLCON_PDIVMASK;
+       sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+       fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
+       do_div(fvco, pdiv << sdiv);
+
+       return (unsigned int)fvco;
+}
+
+static inline unsigned int
+s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+       mdiv &= S3C2443_PLLCON_MDIVMASK;
+       pdiv &= S3C2443_PLLCON_PDIVMASK;
+       sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+       fvco = (uint64_t)baseclk * (mdiv + 8);
+       do_div(fvco, (pdiv + 2) << sdiv);
+
+       return (unsigned int)fvco;
+}
+
+#endif /*  __ASM_ARM_REGS_S3C2443_CLOCK */
+
index 46f52401d132f9e2baacd635d12bd475e4a51701..8946702a87f506f7f3c7066fa18b049a69e991c9 100644 (file)
 #define S3C24XX_VA_UART0      (S3C24XX_VA_UART)
 #define S3C24XX_VA_UART1      (S3C24XX_VA_UART + 0x4000 )
 #define S3C24XX_VA_UART2      (S3C24XX_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3      (S3C24XX_VA_UART + 0xC000 )
 
 #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
 #define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
 #define S3C2410_PA_UART2      (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3      (S3C24XX_PA_UART + 0xC000 )
 
 #define S3C2410_URXH     (0x24)
 #define S3C2410_UTXH     (0x20)
@@ -73,6 +75,8 @@
 #define S3C2440_UCON_UCLK        (1<<10)
 #define S3C2440_UCON_PCLK2       (2<<10)
 #define S3C2440_UCON_FCLK        (3<<10)
+#define S3C2443_UCON_EPLL        (3<<10)
+
 #define S3C2440_UCON2_FCLK_EN    (1<<15)
 #define S3C2440_UCON0_DIVMASK    (15 << 12)
 #define S3C2440_UCON1_DIVMASK    (15 << 12)
@@ -93,6 +97,8 @@
 #define S3C2410_UCON_TXIRQMODE   (1<<2)
 #define S3C2410_UCON_RXIRQMODE   (1<<0)
 #define S3C2410_UCON_RXFIFO_TOI          (1<<7)
+#define S3C2443_UCON_RXERR_IRQEN  (1<<6)
+#define S3C2443_UCON_LOOPBACK    (1<<5)
 
 #define S3C2410_UCON_DEFAULT     (S3C2410_UCON_TXILEVEL  | \
                                   S3C2410_UCON_RXILEVEL  | \
 #define        S3C2410_UMCOM_AFC         (1<<4)
 #define        S3C2410_UMCOM_RTS_LOW     (1<<0)
 
-#define S3C2412_UMCON_AFC_63   (0<<5)
+#define S3C2412_UMCON_AFC_63   (0<<5)          /* same as s3c2443 */
 #define S3C2412_UMCON_AFC_56   (1<<5)
 #define S3C2412_UMCON_AFC_48   (2<<5)
 #define S3C2412_UMCON_AFC_40   (3<<5)
 #define S3C2410_UFSTAT_RXMASK    (15<<0)
 #define S3C2410_UFSTAT_RXSHIFT   (0)
 
+/* UFSTAT S3C2443 same as S3C2440 */
 #define S3C2440_UFSTAT_TXFULL    (1<<14)
 #define S3C2440_UFSTAT_RXFULL    (1<<6)
 #define S3C2440_UFSTAT_TXSHIFT   (8)
 #define S3C2410_UERSTAT_OVERRUN          (1<<0)
 #define S3C2410_UERSTAT_FRAME    (1<<2)
 #define S3C2410_UERSTAT_BREAK    (1<<3)
+#define S3C2443_UERSTAT_PARITY   (1<<1)
+
 #define S3C2410_UERSTAT_ANY      (S3C2410_UERSTAT_OVERRUN | \
                                   S3C2410_UERSTAT_FRAME | \
                                   S3C2410_UERSTAT_BREAK)
 #define S3C2410_UMSTAT_CTS       (1<<0)
 #define S3C2410_UMSTAT_DeltaCTS          (1<<2)
 
+#define S3C2443_DIVSLOT                  (0x2C)
+
 #ifndef __ASSEMBLY__
 
 /* struct s3c24xx_uart_clksrc
diff --git a/include/asm-arm/arch-s3c2410/reset.h b/include/asm-arm/arch-s3c2410/reset.h
new file mode 100644 (file)
index 0000000..4f866cd
--- /dev/null
@@ -0,0 +1,22 @@
+/* linux/include/asm-arm/arch-s3c2410/reset.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * 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.
+ *
+ * S3C2410 CPU reset controls
+*/
+
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H __FILE__
+
+/* This allows the over-ride of the default reset code
+*/
+
+extern void (*s3c24xx_reset_hook)(void);
+
+#endif /* __ASM_ARCH_RESET_H */
index ecf250db45fbc613dd892f1595e39850a2c898e0..1c74ef17da3363eda55e8dcf8fee51c84d502148 100644 (file)
 
 #include <asm/arch/map.h>
 #include <asm/arch/idle.h>
+#include <asm/arch/reset.h>
 
 #include <asm/arch/regs-watchdog.h>
 #include <asm/arch/regs-clock.h>
 
 void (*s3c24xx_idle)(void);
+void (*s3c24xx_reset_hook)(void);
 
 void s3c24xx_default_idle(void)
 {
-       void __iomem *reg = S3C2410_CLKCON;
        unsigned long tmp;
        int i;
 
@@ -33,16 +34,18 @@ void s3c24xx_default_idle(void)
 
        /* Warning: going into idle state upsets jtag scanning */
 
-       __raw_writel(__raw_readl(reg) | (1<<2), reg);
+       __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+                    S3C2410_CLKCON);
 
        /* the samsung port seems to do a loop and then unset idle.. */
        for (i = 0; i < 50; i++) {
-               tmp += __raw_readl(reg); /* ensure loop not optimised out */
+               tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
        }
 
        /* this bit is not cleared on re-start... */
 
-       __raw_writel(__raw_readl(reg) & ~(1<<2), reg);
+       __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+                    S3C2410_CLKCON);
 }
 
 static void arch_idle(void)
@@ -53,7 +56,6 @@ static void arch_idle(void)
                s3c24xx_default_idle();
 }
 
-
 static void
 arch_reset(char mode)
 {
@@ -61,6 +63,9 @@ arch_reset(char mode)
                cpu_reset(0);
        }
 
+       if (s3c24xx_reset_hook)
+               s3c24xx_reset_hook();
+
        printk("arch_reset: attempting watchdog reset\n");
 
        __raw_writel(0, S3C2410_WTCON);   /* disable watchdog, to be safe  */
diff --git a/include/asm-arm/arch-s3c2410/udc.h b/include/asm-arm/arch-s3c2410/udc.h
new file mode 100644 (file)
index 0000000..e59ec33
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/include/asm/arch-s3c2410/udc.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * 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.
+ *
+ *
+ *  Changelog:
+ *     14-Mar-2005     RTP     Created file
+ *     02-Aug-2005     RTP     File rename
+ *     07-Sep-2005     BJD     Minor cleanups, changed cmd to enum
+ *     18-Jan-2007     HMW     Add per-platform vbus_draw function
+*/
+
+#ifndef __ASM_ARM_ARCH_UDC_H
+#define __ASM_ARM_ARCH_UDC_H
+
+enum s3c2410_udc_cmd_e {
+       S3C2410_UDC_P_ENABLE    = 1,    /* Pull-up enable        */
+       S3C2410_UDC_P_DISABLE   = 2,    /* Pull-up disable       */
+       S3C2410_UDC_P_RESET     = 3,    /* UDC reset, in case of */
+};
+
+struct s3c2410_udc_mach_info {
+       void    (*udc_command)(enum s3c2410_udc_cmd_e);
+       void    (*vbus_draw)(unsigned int ma);
+       unsigned int vbus_pin;
+       unsigned char vbus_pin_inverted;
+};
+
+extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
+
+#endif /* __ASM_ARM_ARCH_UDC_H */
index 5f531ea03059d003bab3e86643ed2580a36133cf..afad32c76e6c964df908c6493441139ccb328977 100644 (file)
@@ -185,9 +185,15 @@ struct cpu_cache_fns {
        void (*coherent_user_range)(unsigned long, unsigned long);
        void (*flush_kern_dcache_page)(void *);
 
-       void (*dma_inv_range)(unsigned long, unsigned long);
-       void (*dma_clean_range)(unsigned long, unsigned long);
-       void (*dma_flush_range)(unsigned long, unsigned long);
+       void (*dma_inv_range)(const void *, const void *);
+       void (*dma_clean_range)(const void *, const void *);
+       void (*dma_flush_range)(const void *, const void *);
+};
+
+struct outer_cache_fns {
+       void (*inv_range)(unsigned long, unsigned long);
+       void (*clean_range)(unsigned long, unsigned long);
+       void (*flush_range)(unsigned long, unsigned long);
 };
 
 /*
@@ -240,9 +246,40 @@ extern void __cpuc_flush_dcache_page(void *);
 #define dmac_clean_range               __glue(_CACHE,_dma_clean_range)
 #define dmac_flush_range               __glue(_CACHE,_dma_flush_range)
 
-extern void dmac_inv_range(unsigned long, unsigned long);
-extern void dmac_clean_range(unsigned long, unsigned long);
-extern void dmac_flush_range(unsigned long, unsigned long);
+extern void dmac_inv_range(const void *, const void *);
+extern void dmac_clean_range(const void *, const void *);
+extern void dmac_flush_range(const void *, const void *);
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.inv_range)
+               outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.clean_range)
+               outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{
+       if (outer_cache.flush_range)
+               outer_cache.flush_range(start, end);
+}
+
+#else
+
+static inline void outer_inv_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_clean_range(unsigned long start, unsigned long end)
+{ }
+static inline void outer_flush_range(unsigned long start, unsigned long end)
+{ }
 
 #endif
 
index d8f9872b0e2dc3587a9e658adc957f093b7906fb..c61642b406033659db06494a75fcb4c8d8914477 100644 (file)
@@ -3,5 +3,13 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+#ifndef ASMARM_DEVICE_H
+#define ASMARM_DEVICE_H
 
+struct dev_archdata {
+#ifdef CONFIG_DMABOUNCE
+       struct dmabounce_device_info *dmabounce;
+#endif
+};
+
+#endif
index 9bc46b486afba7a5970e93b5c938a3be33c4684e..abfb75b654c7df7f8795b1f0db4ea4aa173fd0e8 100644 (file)
@@ -17,7 +17,7 @@
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-extern void consistent_sync(void *kaddr, size_t size, int rw);
+extern void consistent_sync(const void *kaddr, size_t size, int rw);
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -61,6 +61,22 @@ static inline int dma_mapping_error(dma_addr_t dma_addr)
        return dma_addr == ~0;
 }
 
+/*
+ * Dummy noncoherent implementation.  We don't provide a dma_cache_sync
+ * function so drivers using this API are highlighted with build warnings.
+ */
+static inline void *
+dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+       return NULL;
+}
+
+static inline void
+dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
+                    dma_addr_t handle)
+{
+}
+
 /**
  * dma_alloc_coherent - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
index 4c2885abbe6c950f04d06c6345bb6358f591421b..3c12a7625304d24d19bcb9e469c5b5bbcca8faef 100644 (file)
@@ -57,6 +57,7 @@
        __asm__ __volatile__(                           \
        "mcr    p15, 0, %0, c3, c0      @ set domain"   \
          : : "r" (x));                                 \
+       isb();                                          \
        } while (0)
 
 #define modify_domain(dom,type)                                        \
index 9903f60c84b713fdde431f61e33c87ba8f683be4..7d28eb5a17587ed0b4dbc3219d75e50fd52c5a4f 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef ASMARM_HARDWARE_ARM_SCU_H
 #define ASMARM_HARDWARE_ARM_SCU_H
 
+#include <asm/arch/scu.h>
+
 /*
  * SCU registers
  */
diff --git a/include/asm-arm/hardware/cache-l2x0.h b/include/asm-arm/hardware/cache-l2x0.h
new file mode 100644 (file)
index 0000000..54029a7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * include/asm-arm/hardware/cache-l2x0.h
+ *
+ * Copyright (C) 2007 ARM 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
+ */
+
+#ifndef __ASM_ARM_HARDWARE_L2X0_H
+#define __ASM_ARM_HARDWARE_L2X0_H
+
+#define L2X0_CACHE_ID                  0x000
+#define L2X0_CACHE_TYPE                        0x004
+#define L2X0_CTRL                      0x100
+#define L2X0_AUX_CTRL                  0x104
+#define L2X0_EVENT_CNT_CTRL            0x200
+#define L2X0_EVENT_CNT1_CFG            0x204
+#define L2X0_EVENT_CNT0_CFG            0x208
+#define L2X0_EVENT_CNT1_VAL            0x20C
+#define L2X0_EVENT_CNT0_VAL            0x210
+#define L2X0_INTR_MASK                 0x214
+#define L2X0_MASKED_INTR_STAT          0x218
+#define L2X0_RAW_INTR_STAT             0x21C
+#define L2X0_INTR_CLEAR                        0x220
+#define L2X0_CACHE_SYNC                        0x730
+#define L2X0_INV_LINE_PA               0x770
+#define L2X0_INV_WAY                   0x77C
+#define L2X0_CLEAN_LINE_PA             0x7B0
+#define L2X0_CLEAN_LINE_IDX            0x7B8
+#define L2X0_CLEAN_WAY                 0x7BC
+#define L2X0_CLEAN_INV_LINE_PA         0x7F0
+#define L2X0_CLEAN_INV_LINE_IDX                0x7F8
+#define L2X0_CLEAN_INV_WAY             0x7FC
+#define L2X0_LOCKDOWN_WAY_D            0x900
+#define L2X0_LOCKDOWN_WAY_I            0x904
+#define L2X0_TEST_OPERATION            0xF00
+#define L2X0_LINE_DATA                 0xF10
+#define L2X0_LINE_TAG                  0xF30
+#define L2X0_DEBUG_CTRL                        0xF40
+
+#ifndef __ASSEMBLY__
+extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+#endif
+
+#endif
index 3fa5eb70f64ed7926f0a41584a338e9279045289..966e428ad32c858aec9870a9cb72491effa7b3f3 100644 (file)
@@ -33,8 +33,9 @@
 #define GIC_DIST_SOFTINT               0xf00
 
 #ifndef __ASSEMBLY__
-void gic_dist_init(void __iomem *base);
-void gic_cpu_init(void __iomem *base);
+void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
+void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
+void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(cpumask_t cpumask, unsigned int irq);
 #endif
 
index 6aa0a5b75b69dc9bc5f72266f8df5763f9c561eb..61b1d05c7df74772f95cd581cd06c05ee81cbdf8 100644 (file)
@@ -29,6 +29,9 @@
 #define _SA1111(x)     ((x) + sa1111->resource.start)
 #endif
 
+#define sa1111_writel(val,addr)        __raw_writel(val, addr)
+#define sa1111_readl(addr)     __raw_readl(addr)
+
 /*
  * 26 bits of the SA-1110 address bus are available to the SA-1111.
  * Use these when feeding target addresses to the DMA engines.
 
 #define SA1111_SAC_DMA_MIN_XFER        (0x800)
 
-/*
- * SA1111 register definitions.
- */
-#define __CCREG(x)     __REGP(SA1111_VBASE + (x))
-
-#define sa1111_writel(val,addr)        __raw_writel(val, addr)
-#define sa1111_readl(addr)     __raw_readl(addr)
-
 /*
  * System Bus Interface (SBI)
  *
  *    SADR              Serial Audio Data Register (16 x 32-bit)
  */
 
-#define _SACR0          _SA1111( 0x0600 )
-#define _SACR1          _SA1111( 0x0604 )
-#define _SACR2          _SA1111( 0x0608 )
-#define _SASR0          _SA1111( 0x060c )
-#define _SASR1          _SA1111( 0x0610 )
-#define _SASCR          _SA1111( 0x0618 )
-#define _L3_CAR         _SA1111( 0x061c )
-#define _L3_CDR         _SA1111( 0x0620 )
-#define _ACCAR          _SA1111( 0x0624 )
-#define _ACCDR          _SA1111( 0x0628 )
-#define _ACSAR          _SA1111( 0x062c )
-#define _ACSDR          _SA1111( 0x0630 )
-#define _SADTCS         _SA1111( 0x0634 )
-#define _SADTSA         _SA1111( 0x0638 )
-#define _SADTCA         _SA1111( 0x063c )
-#define _SADTSB         _SA1111( 0x0640 )
-#define _SADTCB         _SA1111( 0x0644 )
-#define _SADRCS         _SA1111( 0x0648 )
-#define _SADRSA         _SA1111( 0x064c )
-#define _SADRCA         _SA1111( 0x0650 )
-#define _SADRSB         _SA1111( 0x0654 )
-#define _SADRCB         _SA1111( 0x0658 )
-#define _SAITR          _SA1111( 0x065c )
-#define _SADR           _SA1111( 0x0680 )
-
-#define SACR0          __CCREG(0x0600)
-#define SACR1          __CCREG(0x0604)
-#define SACR2          __CCREG(0x0608)
-#define SASR0          __CCREG(0x060c)
-#define SASR1          __CCREG(0x0610)
-#define SASCR          __CCREG(0x0618)
-#define L3_CAR         __CCREG(0x061c)
-#define L3_CDR         __CCREG(0x0620)
-#define ACCAR          __CCREG(0x0624)
-#define ACCDR          __CCREG(0x0628)
-#define ACSAR          __CCREG(0x062c)
-#define ACSDR          __CCREG(0x0630)
-#define SADTCS         __CCREG(0x0634)
-#define SADTSA         __CCREG(0x0638)
-#define SADTCA         __CCREG(0x063c)
-#define SADTSB         __CCREG(0x0640)
-#define SADTCB         __CCREG(0x0644)
-#define SADRCS         __CCREG(0x0648)
-#define SADRSA         __CCREG(0x064c)
-#define SADRCA         __CCREG(0x0650)
-#define SADRSB         __CCREG(0x0654)
-#define SADRCB         __CCREG(0x0658)
-#define SAITR          __CCREG(0x065c)
-#define SADR           __CCREG(0x0680)
+#define SA1111_SERAUDIO                0x0600
+
+/*
+ * These are offsets from the above base.
+ */
+#define SA1111_SACR0           0x00
+#define SA1111_SACR1           0x04
+#define SA1111_SACR2           0x08
+#define SA1111_SASR0           0x0c
+#define SA1111_SASR1           0x10
+#define SA1111_SASCR           0x18
+#define SA1111_L3_CAR          0x1c
+#define SA1111_L3_CDR          0x20
+#define SA1111_ACCAR           0x24
+#define SA1111_ACCDR           0x28
+#define SA1111_ACSAR           0x2c
+#define SA1111_ACSDR           0x30
+#define SA1111_SADTCS          0x34
+#define SA1111_SADTSA          0x38
+#define SA1111_SADTCA          0x3c
+#define SA1111_SADTSB          0x40
+#define SA1111_SADTCB          0x44
+#define SA1111_SADRCS          0x48
+#define SA1111_SADRSA          0x4c
+#define SA1111_SADRCA          0x50
+#define SA1111_SADRSB          0x54
+#define SA1111_SADRCB          0x58
+#define SA1111_SAITR           0x5c
+#define SA1111_SADR            0x80
+
+#ifndef CONFIG_ARCH_PXA
 
 #define SACR0_ENB      (1<<0)
 #define SACR0_BCKD     (1<<2)
 #define SAITR_RDBDA    (1<<10)
 #define SAITR_RDBDB    (1<<11)
 
+#endif  /* !CONFIG_ARCH_PXA */
+
 /*
  * General-Purpose I/O Interface
  *
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
new file mode 100644 (file)
index 0000000..8c1c616
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _ARM_KEXEC_H
+#define _ARM_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE        4096
+
+#define KEXEC_ARCH KEXEC_ARCH_ARM
+
+#ifndef __ASSEMBLY__
+
+#define MAX_NOTE_BYTES 1024
+
+struct kimage;
+/* Provide a dummy definition to avoid build failures. */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                        struct pt_regs *oldregs) { }
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ARM_KEXEC_H */
index b8cf2d5ec3041c7e3c5ff32a46078bca6b10e4aa..7b2bafce21a254924cdedcd17dfaf4e0e721e7f9 100644 (file)
@@ -175,19 +175,29 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #ifndef __ASSEMBLY__
 
 /*
- * The following macros handle the cache and bufferable bits...
+ * The pgprot_* and protection_map entries will be fixed up in runtime
+ * to include the cachable and bufferable bits based on memory policy,
+ * as well as any architecture dependent bits like global/ASID and SMP
+ * shared mapping bits.
  */
 #define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
 #define _L_PTE_READ    L_PTE_USER | L_PTE_EXEC
 
+extern pgprot_t                pgprot_user;
 extern pgprot_t                pgprot_kernel;
 
-#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)
-#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
-#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_NONE      pgprot_user
+#define PAGE_COPY      __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
+#define PAGE_SHARED    __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
+                                L_PTE_WRITE)
+#define PAGE_READONLY  __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
 #define PAGE_KERNEL    pgprot_kernel
 
+#define __PAGE_NONE    __pgprot(_L_PTE_DEFAULT)
+#define __PAGE_COPY    __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define __PAGE_SHARED  __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
+#define __PAGE_READONLY        __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -198,23 +208,23 @@ extern pgprot_t           pgprot_kernel;
  *  2) If we could do execute protection, then read is implied
  *  3) write implies read permissions
  */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
+#define __P000  __PAGE_NONE
+#define __P001  __PAGE_READONLY
+#define __P010  __PAGE_COPY
+#define __P011  __PAGE_COPY
+#define __P100  __PAGE_READONLY
+#define __P101  __PAGE_READONLY
+#define __P110  __PAGE_COPY
+#define __P111  __PAGE_COPY
+
+#define __S000  __PAGE_NONE
+#define __S001  __PAGE_READONLY
+#define __S010  __PAGE_SHARED
+#define __S011  __PAGE_SHARED
+#define __S100  __PAGE_READONLY
+#define __S101  __PAGE_READONLY
+#define __S110  __PAGE_SHARED
+#define __S111  __PAGE_SHARED
 
 #ifndef __ASSEMBLY__
 /*
diff --git a/include/asm-arm/plat-s3c24xx/clock.h b/include/asm-arm/plat-s3c24xx/clock.h
new file mode 100644 (file)
index 0000000..f6135db
--- /dev/null
@@ -0,0 +1,63 @@
+/* linux/include/asm-arm/plat-s3c24xx/clock.h
+ * linux/arch/arm/mach-s3c2410/clock.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/SWLINUX/
+ *     Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * 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.
+*/
+
+struct clk {
+       struct list_head      list;
+       struct module        *owner;
+       struct clk           *parent;
+       const char           *name;
+       int                   id;
+       int                   usage;
+       unsigned long         rate;
+       unsigned long         ctrlbit;
+
+       int                 (*enable)(struct clk *, int enable);
+       int                 (*set_rate)(struct clk *c, unsigned long rate);
+       unsigned long       (*get_rate)(struct clk *c);
+       unsigned long       (*round_rate)(struct clk *c, unsigned long rate);
+       int                 (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+/* other clocks which may be registered by board support */
+
+extern struct clk s3c24xx_dclk0;
+extern struct clk s3c24xx_dclk1;
+extern struct clk s3c24xx_clkout0;
+extern struct clk s3c24xx_clkout1;
+extern struct clk s3c24xx_uclk;
+
+extern struct clk clk_usb_bus;
+
+/* core clock support */
+
+extern struct clk clk_f;
+extern struct clk clk_h;
+extern struct clk clk_p;
+extern struct clk clk_mpll;
+extern struct clk clk_upll;
+extern struct clk clk_xtal;
+
+/* exports for arch/arm/mach-s3c2410
+ *
+ * Please DO NOT use these outside of arch/arm/mach-s3c2410
+*/
+
+extern struct mutex clocks_mutex;
+
+extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
+
+extern int s3c24xx_register_clock(struct clk *clk);
+
+extern int s3c24xx_setup_clocks(unsigned long xtal,
+                               unsigned long fclk,
+                               unsigned long hclk,
+                               unsigned long pclk);
diff --git a/include/asm-arm/plat-s3c24xx/common-smdk.h b/include/asm-arm/plat-s3c24xx/common-smdk.h
new file mode 100644 (file)
index 0000000..58d9094
--- /dev/null
@@ -0,0 +1,15 @@
+/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * 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.
+*/
+
+extern void smdk_machine_init(void);
diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h
new file mode 100644 (file)
index 0000000..15dd188
--- /dev/null
@@ -0,0 +1,70 @@
+/* linux/include/asm-arm/plat-s3c24xx/cpu.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU support
+ *
+ * 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.
+*/
+
+/* todo - fix when rmk changes iodescs to use `void __iomem *` */
+
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
+
+/* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
+struct s3c2410_uartcfg;
+struct map_desc;
+
+/* core initialisation functions */
+
+extern void s3c24xx_init_irq(void);
+
+extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
+
+extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c24xx_init_clocks(int xtal);
+
+extern void s3c24xx_init_uartdevs(char *name,
+                                 struct s3c24xx_uart_resources *res,
+                                 struct s3c2410_uartcfg *cfg, int no);
+
+/* the board structure is used at first initialsation time
+ * to get info such as the devices to register for this
+ * board. This is done because platfrom_add_devices() cannot
+ * be called from the map_io entry.
+*/
+
+struct s3c24xx_board {
+       struct platform_device  **devices;
+       unsigned int              devices_count;
+
+       struct clk              **clocks;
+       unsigned int              clocks_count;
+};
+
+extern void s3c24xx_set_board(struct s3c24xx_board *board);
+
+/* timer for 2410/2440 */
+
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
+
+/* system device classes */
+
+extern struct sysdev_class s3c2410_sysclass;
+extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2440_sysclass;
+extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
diff --git a/include/asm-arm/plat-s3c24xx/devs.h b/include/asm-arm/plat-s3c24xx/devs.h
new file mode 100644 (file)
index 0000000..dddf485
--- /dev/null
@@ -0,0 +1,51 @@
+/* linux/include/asm-arm/plat-s3c24xx/devs.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 standard platform devices
+ *
+ * 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 <linux/platform_device.h>
+
+struct s3c24xx_uart_resources {
+       struct resource         *resources;
+       unsigned long            nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+
+extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
+
+extern struct platform_device s3c_device_usb;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_i2c;
+extern struct platform_device s3c_device_iis;
+extern struct platform_device s3c_device_rtc;
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_sdi;
+
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+
+extern struct platform_device s3c_device_nand;
+
+extern struct platform_device s3c_device_timer0;
+extern struct platform_device s3c_device_timer1;
+extern struct platform_device s3c_device_timer2;
+extern struct platform_device s3c_device_timer3;
+
+extern struct platform_device s3c_device_usbgadget;
+
+/* s3c2440 specific devices */
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern struct platform_device s3c_device_camif;
+
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h
new file mode 100644 (file)
index 0000000..2c59406
--- /dev/null
@@ -0,0 +1,77 @@
+/* linux/include/asm-arm/plat-s3c24xx/dma.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ *
+ * 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.
+*/
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+#define DMA_CH_VALID           (1<<31)
+#define DMA_CH_NEVER           (1<<30)
+
+struct s3c24xx_dma_addr {
+       unsigned long           from;
+       unsigned long           to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+       const char              *name;
+       struct s3c24xx_dma_addr  hw_addr;
+
+       unsigned long            channels[S3C2410_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+       struct s3c24xx_dma_map  *map;
+       unsigned long            map_size;
+       unsigned long            dcon_mask;
+
+       void    (*select)(struct s3c2410_dma_chan *chan,
+                         struct s3c24xx_dma_map *map);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+
+/* struct s3c24xx_dma_order_ch
+ *
+ * channel map for one of the `enum dma_ch` dma channels. the list
+ * entry contains a set of low-level channel numbers, orred with
+ * DMA_CH_VALID, which are checked in the order in the array.
+*/
+
+struct s3c24xx_dma_order_ch {
+       unsigned int    list[S3C2410_DMA_CHANNELS];     /* list of channels */
+       unsigned int    flags;                          /* flags */
+};
+
+/* struct s3c24xx_dma_order
+ *
+ * information provided by either the core or the board to give the
+ * dma system a hint on how to allocate channels
+*/
+
+struct s3c24xx_dma_order {
+       struct s3c24xx_dma_order_ch     channels[DMACH_MAX];
+};
+
+extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+                           unsigned int stride);
diff --git a/include/asm-arm/plat-s3c24xx/irq.h b/include/asm-arm/plat-s3c24xx/irq.h
new file mode 100644 (file)
index 0000000..8af6d95
--- /dev/null
@@ -0,0 +1,107 @@
+/* linux/include/asm-arm/plat-s3c24xx/irq.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU IRQ support
+ *
+ * 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.
+*/
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+#define EXTINT_OFF (IRQ_EINT4 - 4)
+
+extern struct irq_chip s3c_irq_level_chip;
+
+static inline void
+s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
+               int subcheck)
+{
+       unsigned long mask;
+       unsigned long submask;
+
+       submask = __raw_readl(S3C2410_INTSUBMSK);
+       mask = __raw_readl(S3C2410_INTMSK);
+
+       submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
+
+       /* check to see if we need to mask the parent IRQ */
+
+       if ((submask  & subcheck) == subcheck) {
+               __raw_writel(mask | parentbit, S3C2410_INTMSK);
+       }
+
+       /* write back masks */
+       __raw_writel(submask, S3C2410_INTSUBMSK);
+
+}
+
+static inline void
+s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
+{
+       unsigned long mask;
+       unsigned long submask;
+
+       submask = __raw_readl(S3C2410_INTSUBMSK);
+       mask = __raw_readl(S3C2410_INTMSK);
+
+       submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
+       mask &= ~parentbit;
+
+       /* write back masks */
+       __raw_writel(submask, S3C2410_INTSUBMSK);
+       __raw_writel(mask, S3C2410_INTMSK);
+}
+
+
+static inline void
+s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+       s3c_irqsub_mask(irqno, parentmask, group);
+
+       __raw_writel(bit, S3C2410_SUBSRCPND);
+
+       /* only ack parent if we've got all the irqs (seems we must
+        * ack, all and hope that the irq system retriggers ok when
+        * the interrupt goes off again)
+        */
+
+       if (1) {
+               __raw_writel(parentmask, S3C2410_SRCPND);
+               __raw_writel(parentmask, S3C2410_INTPND);
+       }
+}
+
+static inline void
+s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+       __raw_writel(bit, S3C2410_SUBSRCPND);
+
+       /* only ack parent if we've got all the irqs (seems we must
+        * ack, all and hope that the irq system retriggers ok when
+        * the interrupt goes off again)
+        */
+
+       if (1) {
+               __raw_writel(parentmask, S3C2410_SRCPND);
+               __raw_writel(parentmask, S3C2410_INTPND);
+       }
+}
+
+/* exported for use in arch/arm/mach-s3c2410 */
+
+#ifdef CONFIG_PM
+extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
+#else
+#define s3c_irq_wake NULL
+#endif
+
+extern int s3c_irqext_type(unsigned int irq, unsigned int type);
diff --git a/include/asm-arm/plat-s3c24xx/pm.h b/include/asm-arm/plat-s3c24xx/pm.h
new file mode 100644 (file)
index 0000000..cc62366
--- /dev/null
@@ -0,0 +1,73 @@
+/* linux/include/asm-arm/plat-s3c24xx/pm.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * 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.
+*/
+
+/* s3c2410_pm_init
+ *
+ * called from board at initialisation time to setup the power
+ * management
+*/
+
+#ifdef CONFIG_PM
+
+extern __init int s3c2410_pm_init(void);
+
+#else
+
+static inline int s3c2410_pm_init(void)
+{
+       return 0;
+}
+#endif
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+/* from sleep.S */
+
+extern int  s3c2410_cpu_save(unsigned long *saveblk);
+extern void s3c2410_cpu_suspend(void);
+extern void s3c2410_cpu_resume(void);
+
+extern unsigned long s3c2410_sleep_save_phys;
+
+/* sleep save info */
+
+struct sleep_save {
+       void __iomem    *reg;
+       unsigned long   val;
+};
+
+#define SAVE_ITEM(x) \
+       { .reg = (x) }
+
+extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume  NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2400.h b/include/asm-arm/plat-s3c24xx/s3c2400.h
new file mode 100644 (file)
index 0000000..3a5a168
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2400 cpu support
+ *
+ * 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.
+ *
+ * Modifications:
+ *     09-Fev-2006 LCVR  First version, based on s3c2410.h
+*/
+
+#ifdef CONFIG_CPU_S3C2400
+
+extern  int s3c2400_init(void);
+
+extern void s3c2400_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2400_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2400_init_clocks(int xtal);
+
+#else
+#define s3c2400_init_clocks NULL
+#define s3c2400_init_uarts NULL
+#define s3c2400_map_io NULL
+#define s3c2400_init NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2410.h b/include/asm-arm/plat-s3c24xx/s3c2410.h
new file mode 100644 (file)
index 0000000..36de0b8
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 machine directory
+ *
+ * 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.
+ *
+*/
+
+#ifdef CONFIG_CPU_S3C2410
+
+extern  int s3c2410_init(void);
+
+extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2410_init_clocks(int xtal);
+
+extern  int s3c2410_baseclk_add(void);
+
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2412.h b/include/asm-arm/plat-s3c24xx/s3c2412.h
new file mode 100644 (file)
index 0000000..3ec9768
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2412 cpu support
+ *
+ * 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2412
+
+extern  int s3c2412_init(void);
+
+extern void s3c2412_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2412_init_clocks(int xtal);
+
+extern  int s3c2412_baseclk_add(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2440.h b/include/asm-arm/plat-s3c24xx/s3c2440.h
new file mode 100644 (file)
index 0000000..107853b
--- /dev/null
@@ -0,0 +1,17 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2440 cpu support
+ *
+ * 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2440
+extern  int s3c2440_init(void);
+#else
+#define s3c2440_init NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2442.h b/include/asm-arm/plat-s3c24xx/s3c2442.h
new file mode 100644 (file)
index 0000000..451a23a
--- /dev/null
@@ -0,0 +1,17 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2442 cpu support
+ *
+ * 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2442
+extern  int s3c2442_init(void);
+#else
+#define s3c2442_init NULL
+#endif
diff --git a/include/asm-arm/plat-s3c24xx/s3c2443.h b/include/asm-arm/plat-s3c24xx/s3c2443.h
new file mode 100644 (file)
index 0000000..11d83b5
--- /dev/null
@@ -0,0 +1,32 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2443 cpu support
+ *
+ * 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2443
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2443_init(void);
+
+extern void s3c2443_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2443_init_clocks(int xtal);
+
+extern  int s3c2443_baseclk_add(void);
+
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
index aa223fc546afdee10d5b0d74bae41014122a07fe..f4386906b200002d6d6a3612f4037382a9ba9cef 100644 (file)
@@ -140,6 +140,40 @@ static inline int cpu_is_xsc3(void)
 #define        cpu_is_xscale() 1
 #endif
 
+#define UDBG_UNDEFINED (1 << 0)
+#define UDBG_SYSCALL   (1 << 1)
+#define UDBG_BADABORT  (1 << 2)
+#define UDBG_SEGV      (1 << 3)
+#define UDBG_BUS       (1 << 4)
+
+extern unsigned int user_debug;
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_high() (cr_alignment & CR_V)
+#else
+#define vectors_high() (0)
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 6
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+                                   : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+                                   : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+                                   : : "r" (0) : "memory")
+#else
+#define isb() __asm__ __volatile__ ("" : : : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+                                   : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+#endif
+#define mb() dmb()
+#define rmb() mb()
+#define wmb() mb()
+#define read_barrier_depends() do { } while(0)
+#define set_mb(var, value)  do { var = value; mb(); } while (0)
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
 extern unsigned long cr_no_alignment;  /* defined in entry-armv.S */
 extern unsigned long cr_alignment;     /* defined in entry-armv.S */
 
@@ -154,6 +188,7 @@ static inline void set_cr(unsigned int val)
 {
        asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
          : : "r" (val) : "cc");
+       isb();
 }
 
 #ifndef CONFIG_SMP
@@ -176,34 +211,9 @@ static inline void set_copro_access(unsigned int val)
 {
        asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
          : : "r" (val) : "cc");
+       isb();
 }
 
-#define UDBG_UNDEFINED (1 << 0)
-#define UDBG_SYSCALL   (1 << 1)
-#define UDBG_BADABORT  (1 << 2)
-#define UDBG_SEGV      (1 << 3)
-#define UDBG_BUS       (1 << 4)
-
-extern unsigned int user_debug;
-
-#if __LINUX_ARM_ARCH__ >= 4
-#define vectors_high() (cr_alignment & CR_V)
-#else
-#define vectors_high() (0)
-#endif
-
-#if __LINUX_ARM_ARCH__ >= 6
-#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
-                                   : : "r" (0) : "memory")
-#else
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#endif
-#define rmb() mb()
-#define wmb() mb()
-#define read_barrier_depends() do { } while(0)
-#define set_mb(var, value)  do { var = value; mb(); } while (0)
-#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
-
 /*
  * switch_mm() may do a full cache flush over the context switch,
  * so enable interrupts over the context switch to avoid high
index cd10a0b5f8ae77510234c15c9295f80944f59f4a..08c6991dc9c9925a36e5057047fdf3956639078f 100644 (file)
@@ -247,7 +247,7 @@ static inline void local_flush_tlb_all(void)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+               dsb();
 
        if (tlb_flag(TLB_V3_FULL))
                asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
@@ -257,6 +257,15 @@ static inline void local_flush_tlb_all(void)
                asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
        if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
                asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+
+       if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+                    TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+                    TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -266,7 +275,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+               dsb();
 
        if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_FULL))
@@ -285,6 +294,14 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
                asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
        if (tlb_flag(TLB_V6_I_ASID))
                asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
+
+       if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+                    TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+                    TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+       }
 }
 
 static inline void
@@ -296,7 +313,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
        uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
 
        if (tlb_flag(TLB_WB))
-               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero));
+               dsb();
 
        if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
                if (tlb_flag(TLB_V3_PAGE))
@@ -317,6 +334,14 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
                asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
        if (tlb_flag(TLB_V6_I_PAGE))
                asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
+
+       if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+                    TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+                    TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+       }
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -327,7 +352,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        kaddr &= PAGE_MASK;
 
        if (tlb_flag(TLB_WB))
-               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+               dsb();
 
        if (tlb_flag(TLB_V3_PAGE))
                asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
@@ -347,11 +372,14 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        if (tlb_flag(TLB_V6_I_PAGE))
                asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
 
-       /* The ARM ARM states that the completion of a TLB maintenance
-        * operation is only guaranteed by a DSB instruction
-        */
-       if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE))
-               asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc");
+       if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+                    TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+                    TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 /*
@@ -369,15 +397,13 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
  */
 static inline void flush_pmd_entry(pmd_t *pmd)
 {
-       const unsigned int zero = 0;
        const unsigned int __tlb_flag = __cpu_tlb_flags;
 
        if (tlb_flag(TLB_DCLEAN))
                asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
                        : : "r" (pmd) : "cc");
        if (tlb_flag(TLB_WB))
-               asm("mcr        p15, 0, %0, c7, c10, 4  @ flush_pmd"
-                       : : "r" (zero) : "cc");
+               dsb();
 }
 
 static inline void clean_pmd_entry(pmd_t *pmd)
index 97e7060000cf9170fe376bf689681ef2c1f303f7..0991b7bc3f78dc0acac510de92668d818e6cc897 100644 (file)
 #define __NR_move_pages                        (__NR_SYSCALL_BASE+344)
 #define __NR_getcpu                    (__NR_SYSCALL_BASE+345)
                                        /* 346 for epoll_pwait */
+#define __NR_sys_kexec_load            (__NR_SYSCALL_BASE+347)
 
 /*
  * The following SWIs are ARM private.
index d02425cdd801c28d94cef85666bdc564ae6c867e..696e5ec63f77b83fdb81cf35299783633637736a 100644 (file)
@@ -125,6 +125,7 @@ extern struct kimage *kexec_crash_image;
 #define KEXEC_ARCH_PPC     (20 << 16)
 #define KEXEC_ARCH_PPC64   (21 << 16)
 #define KEXEC_ARCH_IA_64   (50 << 16)
+#define KEXEC_ARCH_ARM     (40 << 16)
 #define KEXEC_ARCH_S390    (22 << 16)
 #define KEXEC_ARCH_SH      (42 << 16)
 #define KEXEC_ARCH_MIPS_LE (10 << 16)