aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig17
-rw-r--r--arch/arm/Kconfig-nommu2
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/common/dmabounce.c4
-rw-r--r--arch/arm/kernel/bios32.c4
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/arm/kernel/relocate_kernel.S29
-rw-r--r--arch/arm/kernel/setup.c51
-rw-r--r--arch/arm/mach-at91/Kconfig25
-rw-r--r--arch/arm/mach-at91/Makefile5
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c195
-rw-r--r--arch/arm/mach-at91/at91x40.c67
-rw-r--r--arch/arm/mach-at91/at91x40_time.c80
-rw-r--r--arch/arm/mach-at91/board-eb01.c44
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-clps7500/core.c6
-rw-r--r--arch/arm/mach-ep93xx/Kconfig6
-rw-r--r--arch/arm/mach-ep93xx/Makefile1
-rw-r--r--arch/arm/mach-ep93xx/core.c2
-rw-r--r--arch/arm/mach-ep93xx/edb9307.c91
-rw-r--r--arch/arm/mach-footbridge/isa.c45
-rw-r--r--arch/arm/mach-imx/mx1ads.c2
-rw-r--r--arch/arm/mach-ns9xxx/Makefile2
-rw-r--r--arch/arm/mach-ns9xxx/board-a9m9750dev.c70
-rw-r--r--arch/arm/mach-ns9xxx/gpio.c190
-rw-r--r--arch/arm/mach-ns9xxx/irq.c50
-rw-r--r--arch/arm/mach-ns9xxx/time.c172
-rw-r--r--arch/arm/mach-omap1/leds-innovator.c3
-rw-r--r--arch/arm/mach-omap2/Kconfig11
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c218
-rw-r--r--arch/arm/mach-omap2/board-apollon.c99
-rw-r--r--arch/arm/mach-omap2/board-h4.c46
-rw-r--r--arch/arm/mach-omap2/devices.c6
-rw-r--r--arch/arm/mach-omap2/gpmc.c47
-rw-r--r--arch/arm/mach-omap2/id.c6
-rw-r--r--arch/arm/mach-omap2/io.c22
-rw-r--r--arch/arm/mach-omap2/irq.c19
-rw-r--r--arch/arm/mach-omap2/memory.c18
-rw-r--r--arch/arm/mach-omap2/mux.c38
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c349
-rw-r--r--arch/arm/mach-pxa/corgi.c18
-rw-r--r--arch/arm/mach-pxa/spitz.c18
-rw-r--r--arch/arm/mach-s3c2410/dma.c2
-rw-r--r--arch/arm/mach-s3c2412/dma.c2
-rw-r--r--arch/arm/mach-s3c2412/irq.c58
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c5
-rw-r--r--arch/arm/mach-s3c2440/dma.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c18
-rw-r--r--arch/arm/mach-s3c2443/dma.c2
-rw-r--r--arch/arm/mach-s3c2443/irq.c4
-rw-r--r--arch/arm/mm/cache-l2x0.c12
-rw-r--r--arch/arm/mm/consistent.c4
-rw-r--r--arch/arm/nwfpe/ARM-gcc.h2
-rw-r--r--arch/arm/nwfpe/entry.S25
-rw-r--r--arch/arm/nwfpe/fpa11.inl8
-rw-r--r--arch/arm/plat-omap/Kconfig9
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/debug-devices.c86
-rw-r--r--arch/arm/plat-s3c24xx/dma.c2
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S8
61 files changed, 2018 insertions, 317 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 691aae309c8..fcd1d8f95a2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -318,6 +318,9 @@ config ARCH_KS8695
318 318
319config ARCH_NS9XXX 319config ARCH_NS9XXX
320 bool "NetSilicon NS9xxx" 320 bool "NetSilicon NS9xxx"
321 select GENERIC_GPIO
322 select GENERIC_TIME
323 select GENERIC_CLOCKEVENTS
321 help 324 help
322 Say Y here if you intend to run this kernel on a NetSilicon NS9xxx 325 Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
323 System. 326 System.
@@ -994,6 +997,10 @@ source "drivers/pnp/Kconfig"
994 997
995source "drivers/block/Kconfig" 998source "drivers/block/Kconfig"
996 999
1000# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
1001
1002source "drivers/misc/Kconfig"
1003
997if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ 1004if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
998 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ 1005 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
999 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ 1006 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
@@ -1029,16 +1036,16 @@ source "drivers/spi/Kconfig"
1029 1036
1030source "drivers/w1/Kconfig" 1037source "drivers/w1/Kconfig"
1031 1038
1039source "drivers/power/Kconfig"
1040
1032source "drivers/hwmon/Kconfig" 1041source "drivers/hwmon/Kconfig"
1033 1042
1034#source "drivers/l3/Kconfig" 1043source "drivers/ssb/Kconfig"
1035 1044
1036source "drivers/misc/Kconfig" 1045#source "drivers/l3/Kconfig"
1037 1046
1038source "drivers/mfd/Kconfig" 1047source "drivers/mfd/Kconfig"
1039 1048
1040source "drivers/leds/Kconfig"
1041
1042source "drivers/media/Kconfig" 1049source "drivers/media/Kconfig"
1043 1050
1044source "drivers/video/Kconfig" 1051source "drivers/video/Kconfig"
@@ -1051,6 +1058,8 @@ source "drivers/usb/Kconfig"
1051 1058
1052source "drivers/mmc/Kconfig" 1059source "drivers/mmc/Kconfig"
1053 1060
1061source "drivers/leds/Kconfig"
1062
1054source "drivers/rtc/Kconfig" 1063source "drivers/rtc/Kconfig"
1055 1064
1056source "drivers/dma/Kconfig" 1065source "drivers/dma/Kconfig"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index f087376748d..901e6dff843 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -26,7 +26,7 @@ config FLASH_SIZE
26 default 0x00400000 26 default 0x00400000
27 27
28config PROCESSOR_ID 28config PROCESSOR_ID
29 hex 29 hex 'Hard wire the processor ID'
30 default 0x00007700 30 default 0x00007700
31 depends on !CPU_CP15 31 depends on !CPU_CP15
32 help 32 help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index fa4ea9ff079..6c2d539cd22 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -12,7 +12,7 @@
12 12
13LDFLAGS_vmlinux :=-p --no-undefined -X 13LDFLAGS_vmlinux :=-p --no-undefined -X
14CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) 14CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
15OBJCOPYFLAGS :=-O binary -R .note -R .comment -S 15OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
16GZFLAGS :=-9 16GZFLAGS :=-9
17#CFLAGS +=-pipe 17#CFLAGS +=-pipe
18# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: 18# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index b36b1e8a105..44ab0dad403 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -263,7 +263,7 @@ map_single(struct device *dev, void *ptr, size_t size,
263 * We don't need to sync the DMA buffer since 263 * We don't need to sync the DMA buffer since
264 * it was allocated via the coherent allocators. 264 * it was allocated via the coherent allocators.
265 */ 265 */
266 consistent_sync(ptr, size, dir); 266 dma_cache_maint(ptr, size, dir);
267 } 267 }
268 268
269 return dma_addr; 269 return dma_addr;
@@ -383,7 +383,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
383 * via the coherent allocators. 383 * via the coherent allocators.
384 */ 384 */
385 } else { 385 } else {
386 consistent_sync(dma_to_virt(dev, dma_addr), size, dir); 386 dma_cache_maint(dma_to_virt(dev, dma_addr), size, dir);
387 } 387 }
388} 388}
389 389
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 240c448ec31..a2dd930d11e 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -338,7 +338,7 @@ pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
338 * pcibios_fixup_bus - Called after each bus is probed, 338 * pcibios_fixup_bus - Called after each bus is probed,
339 * but before its children are examined. 339 * but before its children are examined.
340 */ 340 */
341void __devinit pcibios_fixup_bus(struct pci_bus *bus) 341void pcibios_fixup_bus(struct pci_bus *bus)
342{ 342{
343 struct pci_sys_data *root = bus->sysdata; 343 struct pci_sys_data *root = bus->sysdata;
344 struct pci_dev *dev; 344 struct pci_dev *dev;
@@ -419,7 +419,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
419/* 419/*
420 * Convert from Linux-centric to bus-centric addresses for bridge devices. 420 * Convert from Linux-centric to bus-centric addresses for bridge devices.
421 */ 421 */
422void __devinit 422void
423pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 423pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
424 struct resource *res) 424 struct resource *res)
425{ 425{
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index a98d0c933db..cecf658e362 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -361,6 +361,7 @@
361 CALL(sys_signalfd) 361 CALL(sys_signalfd)
362/* 350 */ CALL(sys_timerfd) 362/* 350 */ CALL(sys_timerfd)
363 CALL(sys_eventfd) 363 CALL(sys_eventfd)
364 CALL(sys_fallocate)
364#ifndef syscalls_counted 365#ifndef syscalls_counted
365.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 366.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
366#define syscalls_counted 367#define syscalls_counted
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 7baadae7cb2..062c111c572 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,6 +7,23 @@
7 .globl relocate_new_kernel 7 .globl relocate_new_kernel
8relocate_new_kernel: 8relocate_new_kernel:
9 9
10 /* Move boot params back to where the kernel expects them */
11
12 ldr r0,kexec_boot_params_address
13 teq r0,#0
14 beq 8f
15
16 ldr r1,kexec_boot_params_copy
17 mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
187:
19 ldr r5,[r1],#4
20 str r5,[r0],#4
21 subs r6,r6,#1
22 bne 7b
23
248:
25 /* Boot params moved, now go on with the kernel */
26
10 ldr r0,kexec_indirection_page 27 ldr r0,kexec_indirection_page
11 ldr r1,kexec_start_address 28 ldr r1,kexec_start_address
12 29
@@ -50,7 +67,7 @@ relocate_new_kernel:
50 mov lr,r1 67 mov lr,r1
51 mov r0,#0 68 mov r0,#0
52 ldr r1,kexec_mach_type 69 ldr r1,kexec_mach_type
53 mov r2,#0 70 ldr r2,kexec_boot_params_address
54 mov pc,lr 71 mov pc,lr
55 72
56 .globl kexec_start_address 73 .globl kexec_start_address
@@ -65,6 +82,16 @@ kexec_indirection_page:
65kexec_mach_type: 82kexec_mach_type:
66 .long 0x0 83 .long 0x0
67 84
85 /* phy addr where new kernel will expect to find boot params */
86 .globl kexec_boot_params_address
87kexec_boot_params_address:
88 .long 0x0
89
90 /* phy addr where old kernel put a copy of orig boot params */
91 .globl kexec_boot_params_copy
92kexec_boot_params_copy:
93 .long 0x0
94
68relocate_new_kernel_end: 95relocate_new_kernel_end:
69 96
70 .globl relocate_new_kernel_size 97 .globl relocate_new_kernel_size
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 4de432ec903..bf56eb337df 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/kexec.h>
27 28
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/elf.h> 30#include <asm/elf.h>
@@ -304,10 +305,23 @@ int cpu_architecture(void)
304 cpu_arch = (processor_id >> 16) & 7; 305 cpu_arch = (processor_id >> 16) & 7;
305 if (cpu_arch) 306 if (cpu_arch)
306 cpu_arch += CPU_ARCH_ARMv3; 307 cpu_arch += CPU_ARCH_ARMv3;
307 } else { 308 } else if ((processor_id & 0x000f0000) == 0x000f0000) {
308 /* the revised CPUID */ 309 unsigned int mmfr0;
309 cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6; 310
310 } 311 /* Revised CPUID format. Read the Memory Model Feature
312 * Register 0 and check for VMSAv7 or PMSAv7 */
313 asm("mrc p15, 0, %0, c0, c1, 4"
314 : "=r" (mmfr0));
315 if ((mmfr0 & 0x0000000f) == 0x00000003 ||
316 (mmfr0 & 0x000000f0) == 0x00000030)
317 cpu_arch = CPU_ARCH_ARMv7;
318 else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
319 (mmfr0 & 0x000000f0) == 0x00000020)
320 cpu_arch = CPU_ARCH_ARMv6;
321 else
322 cpu_arch = CPU_ARCH_UNKNOWN;
323 } else
324 cpu_arch = CPU_ARCH_UNKNOWN;
311 325
312 return cpu_arch; 326 return cpu_arch;
313} 327}
@@ -770,6 +784,23 @@ static int __init customize_machine(void)
770} 784}
771arch_initcall(customize_machine); 785arch_initcall(customize_machine);
772 786
787#ifdef CONFIG_KEXEC
788
789/* Physical addr of where the boot params should be for this machine */
790extern unsigned long kexec_boot_params_address;
791
792/* Physical addr of the buffer into which the boot params are copied */
793extern unsigned long kexec_boot_params_copy;
794
795/* Pointer to the boot params buffer, for manipulation and display */
796unsigned long kexec_boot_params;
797EXPORT_SYMBOL(kexec_boot_params);
798
799/* The buffer itself - make sure it is sized correctly */
800static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
801
802#endif
803
773void __init setup_arch(char **cmdline_p) 804void __init setup_arch(char **cmdline_p)
774{ 805{
775 struct tag *tags = (struct tag *)&init_tags; 806 struct tag *tags = (struct tag *)&init_tags;
@@ -788,6 +819,18 @@ void __init setup_arch(char **cmdline_p)
788 else if (mdesc->boot_params) 819 else if (mdesc->boot_params)
789 tags = phys_to_virt(mdesc->boot_params); 820 tags = phys_to_virt(mdesc->boot_params);
790 821
822#ifdef CONFIG_KEXEC
823 kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
824 kexec_boot_params = (unsigned long)kexec_boot_params_buf;
825 if (__atags_pointer) {
826 kexec_boot_params_address = __atags_pointer;
827 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
828 } else if (mdesc->boot_params) {
829 kexec_boot_params_address = mdesc->boot_params;
830 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
831 }
832#endif
833
791 /* 834 /*
792 * If we have the old style parameters, convert them to 835 * If we have the old style parameters, convert them to
793 * a tag list. 836 * a tag list.
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index a31157f1655..05a9f8a1b45 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -7,6 +7,8 @@ choice
7 7
8config ARCH_AT91RM9200 8config ARCH_AT91RM9200
9 bool "AT91RM9200" 9 bool "AT91RM9200"
10 select GENERIC_TIME
11 select GENERIC_CLOCKEVENTS
10 12
11config ARCH_AT91SAM9260 13config ARCH_AT91SAM9260
12 bool "AT91SAM9260 or AT91SAM9XE" 14 bool "AT91SAM9260 or AT91SAM9XE"
@@ -20,8 +22,15 @@ config ARCH_AT91SAM9263
20config ARCH_AT91SAM9RL 22config ARCH_AT91SAM9RL
21 bool "AT91SAM9RL" 23 bool "AT91SAM9RL"
22 24
25config ARCH_AT91X40
26 bool "AT91x40"
27
23endchoice 28endchoice
24 29
30config AT91_PMC_UNIT
31 bool
32 default !ARCH_AT91X40
33
25# ---------------------------------------------------------- 34# ----------------------------------------------------------
26 35
27if ARCH_AT91RM9200 36if ARCH_AT91RM9200
@@ -169,6 +178,22 @@ endif
169 178
170# ---------------------------------------------------------- 179# ----------------------------------------------------------
171 180
181if ARCH_AT91X40
182
183comment "AT91X40 Board Type"
184
185config MACH_AT91EB01
186 bool "Atmel AT91EB01 Evaluation Kit"
187 help
188 Select this if you are using Atmel's AT91EB01 Evaluation Kit.
189 It is also a popular target for simulators such as GDB's
190 ARM simulator (commonly known as the ARMulator) and the
191 Skyeye simulator.
192
193endif
194
195# ----------------------------------------------------------
196
172comment "AT91 Board Options" 197comment "AT91 Board Options"
173 198
174config MTD_AT91_DATAFLASH_CARD 199config MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index a4d80eb056e..a21f08c64ea 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,11 +2,12 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := clock.o irq.o gpio.o 5obj-y := irq.o gpio.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
9 9
10obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
10obj-$(CONFIG_PM) += pm.o 11obj-$(CONFIG_PM) += pm.o
11 12
12# CPU-specific support 13# CPU-specific support
@@ -15,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d
15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o 16obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
16obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o 17obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
17obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o 18obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
19obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
18 20
19# AT91RM9200 board-specific support 21# AT91RM9200 board-specific support
20obj-$(CONFIG_MACH_ONEARM) += board-1arm.o 22obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
@@ -27,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
27obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o 29obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
28obj-$(CONFIG_MACH_KAFA) += board-kafa.o 30obj-$(CONFIG_MACH_KAFA) += board-kafa.o
29obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o 31obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
32obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
30 33
31# AT91SAM9260 board-specific support 34# AT91SAM9260 board-specific support
32obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o 35obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index a6340357585..50392ff7151 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -19,70 +19,64 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/init.h> 22#include <linux/kernel.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/kernel.h> 25#include <linux/clockchips.h>
26#include <linux/sched.h>
27#include <linux/time.h>
28 26
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/mach/time.h> 27#include <asm/mach/time.h>
32 28
33#include <asm/arch/at91_st.h> 29#include <asm/arch/at91_st.h>
34 30
35static unsigned long last_crtr; 31static unsigned long last_crtr;
32static u32 irqmask;
33static struct clock_event_device clkevt;
36 34
37/* 35/*
38 * The ST_CRTR is updated asynchronously to the master clock. It is therefore 36 * The ST_CRTR is updated asynchronously to the master clock ... but
39 * necessary to read it twice (with the same value) to ensure accuracy. 37 * the updates as seen by the CPU don't seem to be strictly monotonic.
38 * Waiting until we read the same value twice avoids glitching.
40 */ 39 */
41static inline unsigned long read_CRTR(void) { 40static inline unsigned long read_CRTR(void)
41{
42 unsigned long x1, x2; 42 unsigned long x1, x2;
43 43
44 x1 = at91_sys_read(AT91_ST_CRTR);
44 do { 45 do {
45 x1 = at91_sys_read(AT91_ST_CRTR);
46 x2 = at91_sys_read(AT91_ST_CRTR); 46 x2 = at91_sys_read(AT91_ST_CRTR);
47 } while (x1 != x2); 47 if (x1 == x2)
48 48 break;
49 x1 = x2;
50 } while (1);
49 return x1; 51 return x1;
50} 52}
51 53
52/* 54/*
53 * Returns number of microseconds since last timer interrupt. Note that interrupts
54 * will have been disabled by do_gettimeofday()
55 * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
56 * 'tick' is usecs per jiffy (linux/timex.h).
57 */
58static unsigned long at91rm9200_gettimeoffset(void)
59{
60 unsigned long elapsed;
61
62 elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
63
64 return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
65}
66
67/*
68 * IRQ handler for the timer. 55 * IRQ handler for the timer.
69 */ 56 */
70static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) 57static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
71{ 58{
72 if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ 59 u32 sr = at91_sys_read(AT91_ST_SR) & irqmask;
73 write_seqlock(&xtime_lock);
74 60
75 while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) { 61 /* simulate "oneshot" timer with alarm */
76 timer_tick(); 62 if (sr & AT91_ST_ALMS) {
77 last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV; 63 clkevt.event_handler(&clkevt);
78 } 64 return IRQ_HANDLED;
65 }
79 66
80 write_sequnlock(&xtime_lock); 67 /* periodic mode should handle delayed ticks */
68 if (sr & AT91_ST_PITS) {
69 u32 crtr = read_CRTR();
81 70
71 while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) {
72 last_crtr += LATCH;
73 clkevt.event_handler(&clkevt);
74 }
82 return IRQ_HANDLED; 75 return IRQ_HANDLED;
83 } 76 }
84 else 77
85 return IRQ_NONE; /* not handled */ 78 /* this irq is shared ... */
79 return IRQ_NONE;
86} 80}
87 81
88static struct irqaction at91rm9200_timer_irq = { 82static struct irqaction at91rm9200_timer_irq = {
@@ -91,56 +85,127 @@ static struct irqaction at91rm9200_timer_irq = {
91 .handler = at91rm9200_timer_interrupt 85 .handler = at91rm9200_timer_interrupt
92}; 86};
93 87
94void at91rm9200_timer_reset(void) 88static cycle_t read_clk32k(void)
95{ 89{
96 last_crtr = 0; 90 return read_CRTR();
91}
97 92
98 /* Real time counter incremented every 30.51758 microseconds */ 93static struct clocksource clk32k = {
99 at91_sys_write(AT91_ST_RTMR, 1); 94 .name = "32k_counter",
95 .rating = 150,
96 .read = read_clk32k,
97 .mask = CLOCKSOURCE_MASK(20),
98 .shift = 10,
99 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
100};
101
102static void
103clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
104{
105 /* Disable and flush pending timer interrupts */
106 at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
107 (void) at91_sys_read(AT91_ST_SR);
100 108
101 /* Set Period Interval timer */ 109 last_crtr = read_CRTR();
102 at91_sys_write(AT91_ST_PIMR, LATCH); 110 switch (mode) {
111 case CLOCK_EVT_MODE_PERIODIC:
112 /* PIT for periodic irqs; fixed rate of 1/HZ */
113 irqmask = AT91_ST_PITS;
114 at91_sys_write(AT91_ST_PIMR, LATCH);
115 break;
116 case CLOCK_EVT_MODE_ONESHOT:
117 /* ALM for oneshot irqs, set by next_event()
118 * before 32 seconds have passed
119 */
120 irqmask = AT91_ST_ALMS;
121 at91_sys_write(AT91_ST_RTAR, last_crtr);
122 break;
123 case CLOCK_EVT_MODE_SHUTDOWN:
124 case CLOCK_EVT_MODE_UNUSED:
125 case CLOCK_EVT_MODE_RESUME:
126 irqmask = 0;
127 break;
128 }
129 at91_sys_write(AT91_ST_IER, irqmask);
130}
103 131
104 /* Clear any pending interrupts */ 132static int
133clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
134{
135 unsigned long flags;
136 u32 alm;
137 int status = 0;
138
139 BUG_ON(delta < 2);
140
141 /* Use "raw" primitives so we behave correctly on RT kernels. */
142 raw_local_irq_save(flags);
143
144 /* The alarm IRQ uses absolute time (now+delta), not the relative
145 * time (delta) in our calling convention. Like all clockevents
146 * using such "match" hardware, we have a race to defend against.
147 *
148 * Our defense here is to have set up the clockevent device so the
149 * delta is at least two. That way we never end up writing RTAR
150 * with the value then held in CRTR ... which would mean the match
151 * wouldn't trigger until 32 seconds later, after CRTR wraps.
152 */
153 alm = read_CRTR();
154
155 /* Cancel any pending alarm; flush any pending IRQ */
156 at91_sys_write(AT91_ST_RTAR, alm);
105 (void) at91_sys_read(AT91_ST_SR); 157 (void) at91_sys_read(AT91_ST_SR);
106 158
107 /* Enable Period Interval Timer interrupt */ 159 /* Schedule alarm by writing RTAR. */
108 at91_sys_write(AT91_ST_IER, AT91_ST_PITS); 160 alm += delta;
161 at91_sys_write(AT91_ST_RTAR, alm);
162
163 raw_local_irq_restore(flags);
164 return status;
109} 165}
110 166
167static struct clock_event_device clkevt = {
168 .name = "at91_tick",
169 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
170 .shift = 32,
171 .rating = 150,
172 .cpumask = CPU_MASK_CPU0,
173 .set_next_event = clkevt32k_next_event,
174 .set_mode = clkevt32k_mode,
175};
176
111/* 177/*
112 * Set up timer interrupt. 178 * ST (system timer) module supports both clockevents and clocksource.
113 */ 179 */
114void __init at91rm9200_timer_init(void) 180void __init at91rm9200_timer_init(void)
115{ 181{
116 /* Disable all timer interrupts */ 182 /* Disable all timer interrupts, and clear any pending ones */
117 at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); 183 at91_sys_write(AT91_ST_IDR,
118 (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ 184 AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
185 (void) at91_sys_read(AT91_ST_SR);
119 186
120 /* Make IRQs happen for the system timer */ 187 /* Make IRQs happen for the system timer */
121 setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); 188 setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
122 189
123 /* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */ 190 /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
124 tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE; 191 * directly for the clocksource and all clockevents, after adjusting
192 * its prescaler from the 1 Hz default.
193 */
194 at91_sys_write(AT91_ST_RTMR, 1);
125 195
126 /* Initialize and enable the timer interrupt */ 196 /* Setup timer clockevent, with minimum of two ticks (important!!) */
127 at91rm9200_timer_reset(); 197 clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
128} 198 clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
199 clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
200 clkevt.cpumask = cpumask_of_cpu(0);
201 clockevents_register_device(&clkevt);
129 202
130#ifdef CONFIG_PM 203 /* register clocksource */
131static void at91rm9200_timer_suspend(void) 204 clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift);
132{ 205 clocksource_register(&clk32k);
133 /* disable Period Interval Timer interrupt */
134 at91_sys_write(AT91_ST_IDR, AT91_ST_PITS);
135} 206}
136#else
137#define at91rm9200_timer_suspend NULL
138#endif
139 207
140struct sys_timer at91rm9200_timer = { 208struct sys_timer at91rm9200_timer = {
141 .init = at91rm9200_timer_init, 209 .init = at91rm9200_timer_init,
142 .offset = at91rm9200_gettimeoffset,
143 .suspend = at91rm9200_timer_suspend,
144 .resume = at91rm9200_timer_reset,
145}; 210};
146 211
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
new file mode 100644
index 00000000000..1de121fc55f
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40.c
@@ -0,0 +1,67 @@
1/*
2 * arch/arm/mach-at91/at91x40.c
3 *
4 * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
5 * Copyright (C) 2005 SAN People
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/mach/arch.h>
17#include <asm/arch/at91x40.h>
18#include <asm/arch/at91_st.h>
19#include "generic.h"
20
21/*
22 * This is used in the gpio code, stub locally.
23 */
24int clk_enable(struct clk *clk)
25{
26 return 0;
27}
28
29void __init at91x40_initialize(unsigned long main_clock)
30{
31 at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
32 | (1 << AT91X40_ID_IRQ2);
33}
34
35/*
36 * The default interrupt priority levels (0 = lowest, 7 = highest).
37 */
38static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = {
39 7, /* Advanced Interrupt Controller (FIQ) */
40 0, /* System Peripherals */
41 0, /* USART 0 */
42 0, /* USART 1 */
43 2, /* Timer Counter 0 */
44 2, /* Timer Counter 1 */
45 2, /* Timer Counter 2 */
46 0, /* Watchdog timer */
47 0, /* Parallel IO Controller A */
48 0, /* Reserved */
49 0, /* Reserved */
50 0, /* Reserved */
51 0, /* Reserved */
52 0, /* Reserved */
53 0, /* Reserved */
54 0, /* Reserved */
55 0, /* External IRQ0 */
56 0, /* External IRQ1 */
57 0, /* External IRQ2 */
58};
59
60void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS])
61{
62 if (!priority)
63 priority = at91x40_default_irq_priority;
64
65 at91_aic_init(priority);
66}
67
diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c
new file mode 100644
index 00000000000..eddc882f1b4
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40_time.c
@@ -0,0 +1,80 @@
1/*
2 * arch/arm/mach-at91/at91x40_time.c
3 *
4 * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/time.h>
26#include <asm/hardware.h>
27#include <asm/io.h>
28#include <asm/mach/time.h>
29#include <asm/arch/at91_tc.h>
30
31/*
32 * 3 counter/timer units present.
33 */
34#define AT91_TC_CLK0BASE 0
35#define AT91_TC_CLK1BASE 0x40
36#define AT91_TC_CLK2BASE 0x80
37
38static unsigned long at91x40_gettimeoffset(void)
39{
40 return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
41}
42
43static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id)
44{
45 at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR);
46 timer_tick();
47 return IRQ_HANDLED;
48}
49
50static struct irqaction at91x40_timer_irq = {
51 .name = "at91_tick",
52 .flags = IRQF_DISABLED | IRQF_TIMER,
53 .handler = at91x40_timer_interrupt
54};
55
56void __init at91x40_timer_init(void)
57{
58 unsigned int v;
59
60 at91_sys_write(AT91_TC + AT91_TC_BCR, 0);
61 v = at91_sys_read(AT91_TC + AT91_TC_BMR);
62 v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
63 at91_sys_write(AT91_TC + AT91_TC_BMR, v);
64
65 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
66 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
67 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
68 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
69 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
70
71 setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);
72
73 at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
74}
75
76struct sys_timer at91x40_timer = {
77 .init = at91x40_timer_init,
78 .offset = at91x40_gettimeoffset,
79};
80
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c
new file mode 100644
index 00000000000..0c1e3858e7d
--- /dev/null
+++ b/arch/arm/mach-at91/board-eb01.c
@@ -0,0 +1,44 @@
1/*
2 * arch/arm/mach-at91/board-eb01.c
3 *
4 * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/irq.h>
26#include <asm/mach-types.h>
27#include <asm/hardware.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/arch/board.h>
31#include "generic.h"
32
33static void __init at91eb01_map_io(void)
34{
35 at91x40_initialize(40000000);
36}
37
38MACHINE_START(AT91EB01, "Atmel AT91 EB01")
39 /* Maintainer: Greg Ungerer <gerg@snapgear.com> */
40 .timer = &at91x40_timer,
41 .init_irq = at91x40_init_interrupts,
42 .map_io = at91eb01_map_io,
43MACHINE_END
44
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 68ed71a3e6c..77d4c0a3784 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
14extern void __init at91sam9261_initialize(unsigned long main_clock); 14extern void __init at91sam9261_initialize(unsigned long main_clock);
15extern void __init at91sam9263_initialize(unsigned long main_clock); 15extern void __init at91sam9263_initialize(unsigned long main_clock);
16extern void __init at91sam9rl_initialize(unsigned long main_clock); 16extern void __init at91sam9rl_initialize(unsigned long main_clock);
17extern void __init at91x40_initialize(unsigned long main_clock);
17 18
18 /* Interrupts */ 19 /* Interrupts */
19extern void __init at91rm9200_init_interrupts(unsigned int priority[]); 20extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -21,12 +22,14 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
21extern void __init at91sam9261_init_interrupts(unsigned int priority[]); 22extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
22extern void __init at91sam9263_init_interrupts(unsigned int priority[]); 23extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
23extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); 24extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
25extern void __init at91x40_init_interrupts(unsigned int priority[]);
24extern void __init at91_aic_init(unsigned int priority[]); 26extern void __init at91_aic_init(unsigned int priority[]);
25 27
26 /* Timer */ 28 /* Timer */
27struct sys_timer; 29struct sys_timer;
28extern struct sys_timer at91rm9200_timer; 30extern struct sys_timer at91rm9200_timer;
29extern struct sys_timer at91sam926x_timer; 31extern struct sys_timer at91sam926x_timer;
32extern struct sys_timer at91x40_timer;
30 33
31 /* Clocks */ 34 /* Clocks */
32extern int __init at91_clock_init(unsigned long main_clock); 35extern int __init at91_clock_init(unsigned long main_clock);
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 4dde34f25e6..986205ec926 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -193,7 +193,11 @@ static struct irq_chip clps7500_no_chip = {
193 .unmask = cl7500_no_action, 193 .unmask = cl7500_no_action,
194}; 194};
195 195
196static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; 196static struct irqaction irq_isa = {
197 .handler = no_action,
198 .mask = CPU_MASK_NONE,
199 .name = "isa",
200};
197 201
198static void __init clps7500_init_irq(void) 202static void __init clps7500_init_irq(void)
199{ 203{
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 575a21dabd2..ea8549bfbef 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -27,6 +27,12 @@ config MACH_EDB9302A
27 Say 'Y' here if you want your kernel to support the Cirrus 27 Say 'Y' here if you want your kernel to support the Cirrus
28 Logic EDB9302A Evaluation Board. 28 Logic EDB9302A Evaluation Board.
29 29
30config MACH_EDB9307
31 bool "Support Cirrus Logic EDB9307"
32 help
33 Say 'Y' here if you want your kernel to support the Cirrus
34 Logic EDB9307 Evaluation Board.
35
30config MACH_EDB9312 36config MACH_EDB9312
31 bool "Support Cirrus Logic EDB9312" 37 bool "Support Cirrus Logic EDB9312"
32 help 38 help
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 0d3bf932654..0ecf99761fe 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -9,6 +9,7 @@ obj- :=
9obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o 9obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
10obj-$(CONFIG_MACH_EDB9302) += edb9302.o 10obj-$(CONFIG_MACH_EDB9302) += edb9302.o
11obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o 11obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o
12obj-$(CONFIG_MACH_EDB9307) += edb9307.o
12obj-$(CONFIG_MACH_EDB9312) += edb9312.o 13obj-$(CONFIG_MACH_EDB9312) += edb9312.o
13obj-$(CONFIG_MACH_EDB9315) += edb9315.o 14obj-$(CONFIG_MACH_EDB9315) += edb9315.o
14obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o 15obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 851cc7158ca..70b2c780111 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -336,7 +336,7 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
336 if (line >= 0 && line < 16) { 336 if (line >= 0 && line < 16) {
337 gpio_line_config(line, GPIO_IN); 337 gpio_line_config(line, GPIO_IN);
338 } else { 338 } else {
339 gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN); 339 gpio_line_config(EP93XX_GPIO_LINE_F(line-16), GPIO_IN);
340 } 340 }
341 341
342 port = line >> 3; 342 port = line >> 3;
diff --git a/arch/arm/mach-ep93xx/edb9307.c b/arch/arm/mach-ep93xx/edb9307.c
new file mode 100644
index 00000000000..d6a5698da91
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb9307.c
@@ -0,0 +1,91 @@
1/*
2 * arch/arm/mach-ep93xx/edb9307.c
3 * Cirrus Logic EDB9307 support.
4 *
5 * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mm.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/mtd/physmap.h>
20#include <linux/platform_device.h>
21#include <asm/io.h>
22#include <asm/hardware.h>
23#include <asm/mach-types.h>
24#include <asm/mach/arch.h>
25
26static struct physmap_flash_data edb9307_flash_data = {
27 .width = 4,
28};
29
30static struct resource edb9307_flash_resource = {
31 .start = 0x60000000,
32 .end = 0x61ffffff,
33 .flags = IORESOURCE_MEM,
34};
35
36static struct platform_device edb9307_flash = {
37 .name = "physmap-flash",
38 .id = 0,
39 .dev = {
40 .platform_data = &edb9307_flash_data,
41 },
42 .num_resources = 1,
43 .resource = &edb9307_flash_resource,
44};
45
46static struct ep93xx_eth_data edb9307_eth_data = {
47 .phy_id = 1,
48};
49
50static struct resource edb9307_eth_resource[] = {
51 {
52 .start = EP93XX_ETHERNET_PHYS_BASE,
53 .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
54 .flags = IORESOURCE_MEM,
55 }, {
56 .start = IRQ_EP93XX_ETHERNET,
57 .end = IRQ_EP93XX_ETHERNET,
58 .flags = IORESOURCE_IRQ,
59 }
60};
61
62static struct platform_device edb9307_eth_device = {
63 .name = "ep93xx-eth",
64 .id = -1,
65 .dev = {
66 .platform_data = &edb9307_eth_data,
67 },
68 .num_resources = 2,
69 .resource = edb9307_eth_resource,
70};
71
72static void __init edb9307_init_machine(void)
73{
74 ep93xx_init_devices();
75 platform_device_register(&edb9307_flash);
76
77 memcpy(edb9307_eth_data.dev_addr,
78 (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
79 platform_device_register(&edb9307_eth_device);
80}
81
82MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
83 /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
84 .phys_io = EP93XX_APB_PHYS_BASE,
85 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
86 .boot_params = 0x00000100,
87 .map_io = ep93xx_map_io,
88 .init_irq = ep93xx_init_irq,
89 .timer = &ep93xx_timer,
90 .init_machine = edb9307_init_machine,
91MACHINE_END
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
index 28846c7edaa..725a219d0ed 100644
--- a/arch/arm/mach-footbridge/isa.c
+++ b/arch/arm/mach-footbridge/isa.c
@@ -12,6 +12,39 @@
12 12
13#include <asm/irq.h> 13#include <asm/irq.h>
14 14
15static struct resource rtc_resources[] = {
16 [0] = {
17 .start = 0x70,
18 .end = 0x73,
19 .flags = IORESOURCE_IO,
20 },
21 [1] = {
22 .start = IRQ_ISA_RTC_ALARM,
23 .end = IRQ_ISA_RTC_ALARM,
24 .flags = IORESOURCE_IRQ,
25 }
26};
27
28static struct platform_device rtc_device = {
29 .name = "rtc_cmos",
30 .id = -1,
31 .resource = rtc_resources,
32 .num_resources = ARRAY_SIZE(rtc_resources),
33};
34
35static struct resource serial_resources[] = {
36 [0] = {
37 .start = 0x3f8,
38 .end = 0x3ff,
39 .flags = IORESOURCE_IO,
40 },
41 [1] = {
42 .start = 0x2f8,
43 .end = 0x2ff,
44 .flags = IORESOURCE_IO,
45 },
46};
47
15static struct plat_serial8250_port serial_platform_data[] = { 48static struct plat_serial8250_port serial_platform_data[] = {
16 { 49 {
17 .iobase = 0x3f8, 50 .iobase = 0x3f8,
@@ -38,11 +71,21 @@ static struct platform_device serial_device = {
38 .dev = { 71 .dev = {
39 .platform_data = serial_platform_data, 72 .platform_data = serial_platform_data,
40 }, 73 },
74 .resource = serial_resources,
75 .num_resources = ARRAY_SIZE(serial_resources),
41}; 76};
42 77
43static int __init footbridge_isa_init(void) 78static int __init footbridge_isa_init(void)
44{ 79{
45 return platform_device_register(&serial_device); 80 int err;
81
82 err = platform_device_register(&rtc_device);
83 if (err)
84 printk(KERN_ERR "Unable to register RTC device: %d\n", err);
85 err = platform_device_register(&serial_device);
86 if (err)
87 printk(KERN_ERR "Unable to register serial device: %d\n", err);
88 return 0;
46} 89}
47 90
48arch_initcall(footbridge_isa_init); 91arch_initcall(footbridge_isa_init);
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index da893c80d47..a9778c1587a 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -116,7 +116,7 @@ static struct platform_device *devices[] __initdata = {
116}; 116};
117 117
118#ifdef CONFIG_MMC_IMX 118#ifdef CONFIG_MMC_IMX
119static int mx1ads_mmc_card_present(void) 119static int mx1ads_mmc_card_present(struct device *dev)
120{ 120{
121 /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */ 121 /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
122 return (SSR(1) & (1 << 20) ? 0 : 1); 122 return (SSR(1) & (1 << 20) ? 0 : 1);
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
index 4476411b814..6fb82b855a5 100644
--- a/arch/arm/mach-ns9xxx/Makefile
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -1,4 +1,4 @@
1obj-y := irq.o time.o generic.o 1obj-y := irq.o time.o generic.o gpio.o
2 2
3obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o 3obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
4obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o 4obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index 925048e7adf..0f65177f9e5 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -13,6 +13,7 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14 14
15#include <asm/mach/map.h> 15#include <asm/mach/map.h>
16#include <asm/gpio.h>
16 17
17#include <asm/arch-ns9xxx/board.h> 18#include <asm/arch-ns9xxx/board.h>
18#include <asm/arch-ns9xxx/regs-sys.h> 19#include <asm/arch-ns9xxx/regs-sys.h>
@@ -44,7 +45,13 @@ static void a9m9750dev_fpga_ack_irq(unsigned int irq)
44 45
45static void a9m9750dev_fpga_mask_irq(unsigned int irq) 46static void a9m9750dev_fpga_mask_irq(unsigned int irq)
46{ 47{
47 FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0))); 48 u8 ier;
49
50 ier = __raw_readb(FPGA_IER);
51
52 ier &= ~(1 << (irq - FPGA_IRQ(0)));
53
54 __raw_writeb(ier, FPGA_IER);
48} 55}
49 56
50static void a9m9750dev_fpga_maskack_irq(unsigned int irq) 57static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
@@ -55,7 +62,13 @@ static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
55 62
56static void a9m9750dev_fpga_unmask_irq(unsigned int irq) 63static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
57{ 64{
58 FPGA_IER |= 1 << (irq - FPGA_IRQ(0)); 65 u8 ier;
66
67 ier = __raw_readb(FPGA_IER);
68
69 ier |= 1 << (irq - FPGA_IRQ(0));
70
71 __raw_writeb(ier, FPGA_IER);
59} 72}
60 73
61static struct irq_chip a9m9750dev_fpga_chip = { 74static struct irq_chip a9m9750dev_fpga_chip = {
@@ -68,30 +81,34 @@ static struct irq_chip a9m9750dev_fpga_chip = {
68static void a9m9750dev_fpga_demux_handler(unsigned int irq, 81static void a9m9750dev_fpga_demux_handler(unsigned int irq,
69 struct irq_desc *desc) 82 struct irq_desc *desc)
70{ 83{
71 int stat = FPGA_ISR; 84 u8 stat = __raw_readb(FPGA_ISR);
85
86 desc->chip->mask_ack(irq);
72 87
73 while (stat != 0) { 88 while (stat != 0) {
74 int irqno = fls(stat) - 1; 89 int irqno = fls(stat) - 1;
90 struct irq_desc *fpgadesc;
75 91
76 stat &= ~(1 << irqno); 92 stat &= ~(1 << irqno);
77 93
78 desc = irq_desc + FPGA_IRQ(irqno); 94 fpgadesc = irq_desc + FPGA_IRQ(irqno);
79 95
80 desc_handle_irq(FPGA_IRQ(irqno), desc); 96 desc_handle_irq(FPGA_IRQ(irqno), fpgadesc);
81 } 97 }
98
99 desc->chip->unmask(irq);
82} 100}
83 101
84void __init board_a9m9750dev_init_irq(void) 102void __init board_a9m9750dev_init_irq(void)
85{ 103{
86 u32 reg; 104 u32 eic;
87 int i; 105 int i;
88 106
89 /* 107 if (gpio_request(11, "board a9m9750dev extirq2") == 0)
90 * configure gpio for IRQ_EXT2 108 ns9xxx_gpio_configure(11, 0, 1);
91 * use GPIO 11, because GPIO 32 is used for the LCD 109 else
92 */ 110 printk(KERN_ERR "%s: cannot get gpio 11 for IRQ_EXT2\n",
93 /* XXX: proper GPIO handling */ 111 __func__);
94 BBU_GCONFb1(1) &= ~0x2000;
95 112
96 for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { 113 for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
97 set_irq_chip(i, &a9m9750dev_fpga_chip); 114 set_irq_chip(i, &a9m9750dev_fpga_chip);
@@ -100,10 +117,10 @@ void __init board_a9m9750dev_init_irq(void)
100 } 117 }
101 118
102 /* IRQ_EXT2: level sensitive + active low */ 119 /* IRQ_EXT2: level sensitive + active low */
103 reg = SYS_EIC(2); 120 eic = __raw_readl(SYS_EIC(2));
104 REGSET(reg, SYS_EIC, PLTY, AL); 121 REGSET(eic, SYS_EIC, PLTY, AL);
105 REGSET(reg, SYS_EIC, LVEDG, LEVEL); 122 REGSET(eic, SYS_EIC, LVEDG, LEVEL);
106 SYS_EIC(2) = reg; 123 __raw_writel(eic, SYS_EIC(2));
107 124
108 set_irq_chained_handler(IRQ_EXT2, 125 set_irq_chained_handler(IRQ_EXT2,
109 a9m9750dev_fpga_demux_handler); 126 a9m9750dev_fpga_demux_handler);
@@ -167,17 +184,18 @@ void __init board_a9m9750dev_init_machine(void)
167 u32 reg; 184 u32 reg;
168 185
169 /* setup static CS0: memory base ... */ 186 /* setup static CS0: memory base ... */
170 REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB, 187 reg = __raw_readl(SYS_SMCSSMB(0));
171 NS9XXX_CSxSTAT_PHYS(0) >> 12); 188 REGSETIM(reg, SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12);
189 __raw_writel(reg, SYS_SMCSSMB(0));
172 190
173 /* ... and mask */ 191 /* ... and mask */
174 reg = SYS_SMCSSMM(0); 192 reg = __raw_readl(SYS_SMCSSMM(0));
175 REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff); 193 REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
176 REGSET(reg, SYS_SMCSSMM, CSEx, EN); 194 REGSET(reg, SYS_SMCSSMM, CSEx, EN);
177 SYS_SMCSSMM(0) = reg; 195 __raw_writel(reg, SYS_SMCSSMM(0));
178 196
179 /* setup static CS0: memory configuration */ 197 /* setup static CS0: memory configuration */
180 reg = MEM_SMC(0); 198 reg = __raw_readl(MEM_SMC(0));
181 REGSET(reg, MEM_SMC, PSMC, OFF); 199 REGSET(reg, MEM_SMC, PSMC, OFF);
182 REGSET(reg, MEM_SMC, BSMC, OFF); 200 REGSET(reg, MEM_SMC, BSMC, OFF);
183 REGSET(reg, MEM_SMC, EW, OFF); 201 REGSET(reg, MEM_SMC, EW, OFF);
@@ -185,13 +203,13 @@ void __init board_a9m9750dev_init_machine(void)
185 REGSET(reg, MEM_SMC, PC, AL); 203 REGSET(reg, MEM_SMC, PC, AL);
186 REGSET(reg, MEM_SMC, PM, DIS); 204 REGSET(reg, MEM_SMC, PM, DIS);
187 REGSET(reg, MEM_SMC, MW, 8); 205 REGSET(reg, MEM_SMC, MW, 8);
188 MEM_SMC(0) = reg; 206 __raw_writel(reg, MEM_SMC(0));
189 207
190 /* setup static CS0: timing */ 208 /* setup static CS0: timing */
191 MEM_SMWED(0) = 0x2; 209 __raw_writel(0x2, MEM_SMWED(0));
192 MEM_SMOED(0) = 0x2; 210 __raw_writel(0x2, MEM_SMOED(0));
193 MEM_SMRD(0) = 0x6; 211 __raw_writel(0x6, MEM_SMRD(0));
194 MEM_SMWD(0) = 0x6; 212 __raw_writel(0x6, MEM_SMWD(0));
195 213
196 platform_add_devices(board_a9m9750dev_devices, 214 platform_add_devices(board_a9m9750dev_devices,
197 ARRAY_SIZE(board_a9m9750dev_devices)); 215 ARRAY_SIZE(board_a9m9750dev_devices));
diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c
new file mode 100644
index 00000000000..b2230213b98
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/gpio.c
@@ -0,0 +1,190 @@
1/*
2 * arch/arm/mach-ns9xxx/gpio.c
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/compiler.h>
12#include <linux/init.h>
13#include <linux/spinlock.h>
14#include <linux/module.h>
15
16#include <asm/arch-ns9xxx/gpio.h>
17#include <asm/arch-ns9xxx/processor.h>
18#include <asm/arch-ns9xxx/regs-bbu.h>
19#include <asm/io.h>
20#include <asm/bug.h>
21#include <asm/types.h>
22#include <asm/bitops.h>
23
24#if defined(CONFIG_PROCESSOR_NS9360)
25#define GPIO_MAX 72
26#elif defined(CONFIG_PROCESSOR_NS9750)
27#define GPIO_MAX 49
28#endif
29
30/* protects BBU_GCONFx and BBU_GCTRLx */
31static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock);
32
33/* only access gpiores with atomic ops */
34static DECLARE_BITMAP(gpiores, GPIO_MAX);
35
36static inline int ns9xxx_valid_gpio(unsigned gpio)
37{
38#if defined(CONFIG_PROCESSOR_NS9360)
39 if (processor_is_ns9360())
40 return gpio <= 72;
41 else
42#endif
43#if defined(CONFIG_PROCESSOR_NS9750)
44 if (processor_is_ns9750())
45 return gpio <= 49;
46 else
47#endif
48 BUG();
49}
50
51static inline void __iomem *ns9xxx_gpio_get_gconfaddr(unsigned gpio)
52{
53 if (gpio < 56)
54 return BBU_GCONFb1(gpio / 8);
55 else
56 /*
57 * this could be optimised away on
58 * ns9750 only builds, but it isn't ...
59 */
60 return BBU_GCONFb2((gpio - 56) / 8);
61}
62
63static inline void __iomem *ns9xxx_gpio_get_gctrladdr(unsigned gpio)
64{
65 if (gpio < 32)
66 return BBU_GCTRL1;
67 else if (gpio < 64)
68 return BBU_GCTRL2;
69 else
70 /* this could be optimised away on ns9750 only builds */
71 return BBU_GCTRL3;
72}
73
74static inline void __iomem *ns9xxx_gpio_get_gstataddr(unsigned gpio)
75{
76 if (gpio < 32)
77 return BBU_GSTAT1;
78 else if (gpio < 64)
79 return BBU_GSTAT2;
80 else
81 /* this could be optimised away on ns9750 only builds */
82 return BBU_GSTAT3;
83}
84
85int gpio_request(unsigned gpio, const char *label)
86{
87 if (likely(ns9xxx_valid_gpio(gpio)))
88 return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0;
89 else
90 return -EINVAL;
91}
92EXPORT_SYMBOL(gpio_request);
93
94void gpio_free(unsigned gpio)
95{
96 clear_bit(gpio, gpiores);
97 return;
98}
99EXPORT_SYMBOL(gpio_free);
100
101/*
102 * each gpio can serve for 4 different purposes [0..3]. These are called
103 * "functions" and passed in the parameter func. Functions 0-2 are always some
104 * special things, function 3 is GPIO. If func == 3 dir specifies input or
105 * output, and with inv you can enable an inverter (independent of func).
106 */
107static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func)
108{
109 void __iomem *conf = ns9xxx_gpio_get_gconfaddr(gpio);
110 u32 confval;
111 unsigned long flags;
112
113 spin_lock_irqsave(&gpio_lock, flags);
114
115 confval = __raw_readl(conf);
116 REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir);
117 REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv);
118 REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func);
119 __raw_writel(confval, conf);
120
121 spin_unlock_irqrestore(&gpio_lock, flags);
122
123 return 0;
124}
125
126int ns9xxx_gpio_configure(unsigned gpio, int inv, int func)
127{
128 if (likely(ns9xxx_valid_gpio(gpio))) {
129 if (func == 3) {
130 printk(KERN_WARNING "use gpio_direction_input "
131 "or gpio_direction_output\n");
132 return -EINVAL;
133 } else
134 return __ns9xxx_gpio_configure(gpio, 0, inv, func);
135 } else
136 return -EINVAL;
137}
138EXPORT_SYMBOL(ns9xxx_gpio_configure);
139
140int gpio_direction_input(unsigned gpio)
141{
142 if (likely(ns9xxx_valid_gpio(gpio))) {
143 return __ns9xxx_gpio_configure(gpio, 0, 0, 3);
144 } else
145 return -EINVAL;
146}
147EXPORT_SYMBOL(gpio_direction_input);
148
149int gpio_direction_output(unsigned gpio, int value)
150{
151 if (likely(ns9xxx_valid_gpio(gpio))) {
152 gpio_set_value(gpio, value);
153
154 return __ns9xxx_gpio_configure(gpio, 1, 0, 3);
155 } else
156 return -EINVAL;
157}
158EXPORT_SYMBOL(gpio_direction_output);
159
160int gpio_get_value(unsigned gpio)
161{
162 void __iomem *stat = ns9xxx_gpio_get_gstataddr(gpio);
163 int ret;
164
165 ret = 1 & (__raw_readl(stat) >> (gpio & 31));
166
167 return ret;
168}
169EXPORT_SYMBOL(gpio_get_value);
170
171void gpio_set_value(unsigned gpio, int value)
172{
173 void __iomem *ctrl = ns9xxx_gpio_get_gctrladdr(gpio);
174 u32 ctrlval;
175 unsigned long flags;
176
177 spin_lock_irqsave(&gpio_lock, flags);
178
179 ctrlval = __raw_readl(ctrl);
180
181 if (value)
182 ctrlval |= 1 << (gpio & 31);
183 else
184 ctrlval &= ~(1 << (gpio & 31));
185
186 __raw_writel(ctrlval, ctrl);
187
188 spin_unlock_irqrestore(&gpio_lock, flags);
189}
190EXPORT_SYMBOL(gpio_set_value);
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index b8c7b00522e..00001b874e9 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -9,6 +9,7 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 */ 10 */
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <asm/io.h>
12#include <asm/mach/irq.h> 13#include <asm/mach/irq.h>
13#include <asm/mach-types.h> 14#include <asm/mach-types.h>
14#include <asm/arch-ns9xxx/regs-sys.h> 15#include <asm/arch-ns9xxx/regs-sys.h>
@@ -17,48 +18,17 @@
17 18
18#include "generic.h" 19#include "generic.h"
19 20
20static void ns9xxx_ack_irq_timer(unsigned int irq)
21{
22 u32 tc = SYS_TC(irq - IRQ_TIMER0);
23
24 /*
25 * If the timer is programmed to halt on terminal count, the
26 * timer must be disabled before clearing the interrupt.
27 */
28 if (REGGET(tc, SYS_TCx, REN) == 0) {
29 REGSET(tc, SYS_TCx, TEN, DIS);
30 SYS_TC(irq - IRQ_TIMER0) = tc;
31 }
32
33 REGSET(tc, SYS_TCx, INTC, SET);
34 SYS_TC(irq - IRQ_TIMER0) = tc;
35
36 REGSET(tc, SYS_TCx, INTC, UNSET);
37 SYS_TC(irq - IRQ_TIMER0) = tc;
38}
39
40static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
41 [IRQ_TIMER0] = ns9xxx_ack_irq_timer,
42 [IRQ_TIMER1] = ns9xxx_ack_irq_timer,
43 [IRQ_TIMER2] = ns9xxx_ack_irq_timer,
44 [IRQ_TIMER3] = ns9xxx_ack_irq_timer,
45};
46
47static void ns9xxx_mask_irq(unsigned int irq) 21static void ns9xxx_mask_irq(unsigned int irq)
48{ 22{
49 /* XXX: better use cpp symbols */ 23 /* XXX: better use cpp symbols */
50 SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3)))); 24 u32 ic = __raw_readl(SYS_IC(irq / 4));
25 ic &= ~(1 << (7 + 8 * (3 - (irq & 3))));
26 __raw_writel(ic, SYS_IC(irq / 4));
51} 27}
52 28
53static void ns9xxx_ack_irq(unsigned int irq) 29static void ns9xxx_ack_irq(unsigned int irq)
54{ 30{
55 if (!ns9xxx_ack_irq_functions[irq]) { 31 __raw_writel(0, SYS_ISRADDR);
56 printk(KERN_ERR "no ack function for irq %u\n", irq);
57 BUG();
58 }
59
60 ns9xxx_ack_irq_functions[irq](irq);
61 SYS_ISRADDR = 0;
62} 32}
63 33
64static void ns9xxx_maskack_irq(unsigned int irq) 34static void ns9xxx_maskack_irq(unsigned int irq)
@@ -70,7 +40,9 @@ static void ns9xxx_maskack_irq(unsigned int irq)
70static void ns9xxx_unmask_irq(unsigned int irq) 40static void ns9xxx_unmask_irq(unsigned int irq)
71{ 41{
72 /* XXX: better use cpp symbols */ 42 /* XXX: better use cpp symbols */
73 SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3))); 43 u32 ic = __raw_readl(SYS_IC(irq / 4));
44 ic |= 1 << (7 + 8 * (3 - (irq & 3)));
45 __raw_writel(ic, SYS_IC(irq / 4));
74} 46}
75 47
76static struct irq_chip ns9xxx_chip = { 48static struct irq_chip ns9xxx_chip = {
@@ -86,14 +58,14 @@ void __init ns9xxx_init_irq(void)
86 58
87 /* disable all IRQs */ 59 /* disable all IRQs */
88 for (i = 0; i < 8; ++i) 60 for (i = 0; i < 8; ++i)
89 SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 | 61 __raw_writel((4 * i) << 24 | (4 * i + 1) << 16 |
90 (4 * i + 2) << 8 | (4 * i + 3); 62 (4 * i + 2) << 8 | (4 * i + 3), SYS_IC(i));
91 63
92 /* simple interrupt prio table: 64 /* simple interrupt prio table:
93 * prio(x) < prio(y) <=> x < y 65 * prio(x) < prio(y) <=> x < y
94 */ 66 */
95 for (i = 0; i < 32; ++i) 67 for (i = 0; i < 32; ++i)
96 SYS_IVA(i) = i; 68 __raw_writel(i, SYS_IVA(i));
97 69
98 for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) { 70 for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
99 set_irq_chip(i, &ns9xxx_chip); 71 set_irq_chip(i, &ns9xxx_chip);
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
index b97d0c54a38..c3dd1f4acb9 100644
--- a/arch/arm/mach-ns9xxx/time.c
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -11,78 +11,174 @@
11#include <linux/jiffies.h> 11#include <linux/jiffies.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/stringify.h>
15#include <linux/clocksource.h>
16#include <linux/clockchips.h>
17
14#include <asm/arch-ns9xxx/regs-sys.h> 18#include <asm/arch-ns9xxx/regs-sys.h>
15#include <asm/arch-ns9xxx/clock.h> 19#include <asm/arch-ns9xxx/clock.h>
16#include <asm/arch-ns9xxx/irqs.h> 20#include <asm/arch-ns9xxx/irqs.h>
17#include <asm/arch/system.h> 21#include <asm/arch/system.h>
18#include "generic.h" 22#include "generic.h"
19 23
20#define TIMERCLOCKSELECT 64 24#define TIMER_CLOCKSOURCE 0
25#define TIMER_CLOCKEVENT 1
26static u32 latch;
27
28static cycle_t ns9xxx_clocksource_read(void)
29{
30 return __raw_readl(SYS_TR(TIMER_CLOCKSOURCE));
31}
21 32
22static u32 usecs_per_tick; 33static struct clocksource ns9xxx_clocksource = {
34 .name = "ns9xxx-timer" __stringify(TIMER_CLOCKSOURCE),
35 .rating = 300,
36 .read = ns9xxx_clocksource_read,
37 .mask = CLOCKSOURCE_MASK(32),
38 .shift = 20,
39 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
40};
23 41
24static irqreturn_t 42static void ns9xxx_clockevent_setmode(enum clock_event_mode mode,
25ns9xxx_timer_interrupt(int irq, void *dev_id) 43 struct clock_event_device *clk)
26{ 44{
27 write_seqlock(&xtime_lock); 45 u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
28 timer_tick(); 46
29 write_sequnlock(&xtime_lock); 47 switch(mode) {
48 case CLOCK_EVT_MODE_PERIODIC:
49 __raw_writel(latch, SYS_TRC(TIMER_CLOCKEVENT));
50 REGSET(tc, SYS_TCx, REN, EN);
51 REGSET(tc, SYS_TCx, INTS, EN);
52 REGSET(tc, SYS_TCx, TEN, EN);
53 break;
54
55 case CLOCK_EVT_MODE_ONESHOT:
56 REGSET(tc, SYS_TCx, REN, DIS);
57 REGSET(tc, SYS_TCx, INTS, EN);
58
59 /* fall through */
60
61 case CLOCK_EVT_MODE_UNUSED:
62 case CLOCK_EVT_MODE_SHUTDOWN:
63 case CLOCK_EVT_MODE_RESUME:
64 default:
65 REGSET(tc, SYS_TCx, TEN, DIS);
66 break;
67 }
68
69 __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
70}
30 71
31 return IRQ_HANDLED; 72static int ns9xxx_clockevent_setnextevent(unsigned long evt,
73 struct clock_event_device *clk)
74{
75 u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
76
77 if (REGGET(tc, SYS_TCx, TEN)) {
78 REGSET(tc, SYS_TCx, TEN, DIS);
79 __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
80 }
81
82 REGSET(tc, SYS_TCx, TEN, EN);
83
84 __raw_writel(evt, SYS_TRC(TIMER_CLOCKEVENT));
85
86 __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
87
88 return 0;
32} 89}
33 90
34static unsigned long ns9xxx_timer_gettimeoffset(void) 91static struct clock_event_device ns9xxx_clockevent_device = {
92 .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT),
93 .shift = 20,
94 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
95 .set_mode = ns9xxx_clockevent_setmode,
96 .set_next_event = ns9xxx_clockevent_setnextevent,
97};
98
99static irqreturn_t ns9xxx_clockevent_handler(int irq, void *dev_id)
35{ 100{
36 /* return the microseconds which have passed since the last interrupt 101 int timerno = irq - IRQ_TIMER0;
37 * was _serviced_. That is, if an interrupt is pending or the counter 102 u32 tc;
38 * reloads, return one period more. */
39 103
40 u32 counter1 = SYS_TR(0); 104 struct clock_event_device *evt = &ns9xxx_clockevent_device;
41 int pending = SYS_ISR & (1 << IRQ_TIMER0);
42 u32 counter2 = SYS_TR(0);
43 u32 elapsed;
44 105
45 if (pending || counter2 > counter1) 106 /* clear irq */
46 elapsed = 2 * SYS_TRC(0) - counter2; 107 tc = __raw_readl(SYS_TC(timerno));
47 else 108 if (REGGET(tc, SYS_TCx, REN) == SYS_TCx_REN_DIS) {
48 elapsed = SYS_TRC(0) - counter1; 109 REGSET(tc, SYS_TCx, TEN, DIS);
110 __raw_writel(tc, SYS_TC(timerno));
111 }
112 REGSET(tc, SYS_TCx, INTC, SET);
113 __raw_writel(tc, SYS_TC(timerno));
114 REGSET(tc, SYS_TCx, INTC, UNSET);
115 __raw_writel(tc, SYS_TC(timerno));
49 116
50 return (elapsed * usecs_per_tick) >> 16; 117 evt->event_handler(evt);
51 118
119 return IRQ_HANDLED;
52} 120}
53 121
54static struct irqaction ns9xxx_timer_irq = { 122static struct irqaction ns9xxx_clockevent_action = {
55 .name = "NS9xxx Timer Tick", 123 .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT),
56 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 124 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
57 .handler = ns9xxx_timer_interrupt, 125 .handler = ns9xxx_clockevent_handler,
58}; 126};
59 127
60static void __init ns9xxx_timer_init(void) 128static void __init ns9xxx_timer_init(void)
61{ 129{
62 int tc; 130 int tc;
63 131
64 usecs_per_tick = 132 tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE));
65 SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16); 133 if (REGGET(tc, SYS_TCx, TEN)) {
134 REGSET(tc, SYS_TCx, TEN, DIS);
135 __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
136 }
66 137
67 /* disable timer */ 138 __raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE));
68 if ((tc = SYS_TC(0)) & SYS_TCx_TEN)
69 SYS_TC(0) = tc & ~SYS_TCx_TEN;
70
71 SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0);
72 139
73 REGSET(tc, SYS_TCx, TEN, EN); 140 REGSET(tc, SYS_TCx, TEN, EN);
74 REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */
75 REGSET(tc, SYS_TCx, INTS, EN);
76 REGSET(tc, SYS_TCx, UDS, DOWN);
77 REGSET(tc, SYS_TCx, TDBG, STOP); 141 REGSET(tc, SYS_TCx, TDBG, STOP);
142 REGSET(tc, SYS_TCx, TLCS, CPU);
143 REGSET(tc, SYS_TCx, TM, IEE);
144 REGSET(tc, SYS_TCx, INTS, DIS);
145 REGSET(tc, SYS_TCx, UDS, UP);
78 REGSET(tc, SYS_TCx, TSZ, 32); 146 REGSET(tc, SYS_TCx, TSZ, 32);
79 REGSET(tc, SYS_TCx, REN, EN); 147 REGSET(tc, SYS_TCx, REN, EN);
80 SYS_TC(0) = tc;
81 148
82 setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq); 149 __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
150
151 ns9xxx_clocksource.mult = clocksource_hz2mult(ns9xxx_cpuclock(),
152 ns9xxx_clocksource.shift);
153
154 clocksource_register(&ns9xxx_clocksource);
155
156 latch = SH_DIV(ns9xxx_cpuclock(), HZ, 0);
157
158 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
159 REGSET(tc, SYS_TCx, TEN, DIS);
160 REGSET(tc, SYS_TCx, TDBG, STOP);
161 REGSET(tc, SYS_TCx, TLCS, CPU);
162 REGSET(tc, SYS_TCx, TM, IEE);
163 REGSET(tc, SYS_TCx, INTS, DIS);
164 REGSET(tc, SYS_TCx, UDS, DOWN);
165 REGSET(tc, SYS_TCx, TSZ, 32);
166 REGSET(tc, SYS_TCx, REN, EN);
167 __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
168
169 ns9xxx_clockevent_device.mult = div_sc(ns9xxx_cpuclock(),
170 NSEC_PER_SEC, ns9xxx_clockevent_device.shift);
171 ns9xxx_clockevent_device.max_delta_ns =
172 clockevent_delta2ns(-1, &ns9xxx_clockevent_device);
173 ns9xxx_clockevent_device.min_delta_ns =
174 clockevent_delta2ns(1, &ns9xxx_clockevent_device);
175
176 ns9xxx_clockevent_device.cpumask = cpumask_of_cpu(0);
177 clockevents_register_device(&ns9xxx_clockevent_device);
178
179 setup_irq(IRQ_TIMER0 + TIMER_CLOCKEVENT, &ns9xxx_clockevent_action);
83} 180}
84 181
85struct sys_timer ns9xxx_timer = { 182struct sys_timer ns9xxx_timer = {
86 .init = ns9xxx_timer_init, 183 .init = ns9xxx_timer_init,
87 .offset = ns9xxx_timer_gettimeoffset,
88}; 184};
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
index a0cd001ac39..e7835d6f53a 100644
--- a/arch/arm/mach-omap1/leds-innovator.c
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -95,8 +95,5 @@ void innovator_leds_event(led_event_t evt)
95 break; 95 break;
96 } 96 }
97 97
98 if (led_state & LED_STATE_ENABLED)
99 ;
100
101 local_irq_restore(flags); 98 local_irq_restore(flags);
102} 99}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 7393109f5c3..7069c9d536f 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -11,6 +11,10 @@ config ARCH_OMAP2420
11 select OMAP_DM_TIMER 11 select OMAP_DM_TIMER
12 select ARCH_OMAP_OTG 12 select ARCH_OMAP_OTG
13 13
14config ARCH_OMAP2430
15 bool "OMAP2430 support"
16 depends on ARCH_OMAP24XX
17
14comment "OMAP Board Type" 18comment "OMAP Board Type"
15 depends on ARCH_OMAP2 19 depends on ARCH_OMAP2
16 20
@@ -21,8 +25,13 @@ config MACH_OMAP_GENERIC
21config MACH_OMAP_H4 25config MACH_OMAP_H4
22 bool "OMAP 2420 H4 board" 26 bool "OMAP 2420 H4 board"
23 depends on ARCH_OMAP2 && ARCH_OMAP24XX 27 depends on ARCH_OMAP2 && ARCH_OMAP24XX
24 select OMAP_DEBUG_LEDS if LEDS || LEDS_OMAP_DEBUG 28 select OMAP_DEBUG_DEVICES
25 29
26config MACH_OMAP_APOLLON 30config MACH_OMAP_APOLLON
27 bool "OMAP 2420 Apollon board" 31 bool "OMAP 2420 Apollon board"
28 depends on ARCH_OMAP2 && ARCH_OMAP24XX 32 depends on ARCH_OMAP2 && ARCH_OMAP24XX
33
34config MACH_OMAP_2430SDP
35 bool "OMAP 2430 SDP board"
36 depends on ARCH_OMAP2 && ARCH_OMAP24XX
37
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 266d88e77bd..b05b738d31e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
14# Specific board support 14# Specific board support
15obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o 15obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
16obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o 16obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
17obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
17obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o 18obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
18 19
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
new file mode 100644
index 00000000000..7e76fbf19b5
--- /dev/null
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -0,0 +1,218 @@
1/*
2 * linux/arch/arm/mach-omap2/board-2430sdp.c
3 *
4 * Copyright (C) 2006 Texas Instruments
5 *
6 * Modified from mach-omap2/board-generic.c
7 *
8 * Initial Code : Based on a patch from Komal Shah and Richard Woodruff
9 * Updated the Code for 2430 SDP : Syed Mohammed Khasim
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/partitions.h>
21#include <linux/delay.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24
25#include <asm/hardware.h>
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/flash.h>
30
31#include <asm/arch/gpio.h>
32#include <asm/arch/mux.h>
33#include <asm/arch/board.h>
34#include <asm/arch/common.h>
35#include <asm/arch/gpmc.h>
36#include "prcm-regs.h"
37
38#include <asm/io.h>
39
40
41#define SDP2430_FLASH_CS 0
42#define SDP2430_SMC91X_CS 5
43
44static struct mtd_partition sdp2430_partitions[] = {
45 /* bootloader (U-Boot, etc) in first sector */
46 {
47 .name = "bootloader",
48 .offset = 0,
49 .size = SZ_256K,
50 .mask_flags = MTD_WRITEABLE, /* force read-only */
51 },
52 /* bootloader params in the next sector */
53 {
54 .name = "params",
55 .offset = MTDPART_OFS_APPEND,
56 .size = SZ_128K,
57 .mask_flags = 0,
58 },
59 /* kernel */
60 {
61 .name = "kernel",
62 .offset = MTDPART_OFS_APPEND,
63 .size = SZ_2M,
64 .mask_flags = 0
65 },
66 /* file system */
67 {
68 .name = "filesystem",
69 .offset = MTDPART_OFS_APPEND,
70 .size = MTDPART_SIZ_FULL,
71 .mask_flags = 0
72 }
73};
74
75static struct flash_platform_data sdp2430_flash_data = {
76 .map_name = "cfi_probe",
77 .width = 2,
78 .parts = sdp2430_partitions,
79 .nr_parts = ARRAY_SIZE(sdp2430_partitions),
80};
81
82static struct resource sdp2430_flash_resource = {
83 .start = SDP2430_CS0_BASE,
84 .end = SDP2430_CS0_BASE + SZ_64M - 1,
85 .flags = IORESOURCE_MEM,
86};
87
88static struct platform_device sdp2430_flash_device = {
89 .name = "omapflash",
90 .id = 0,
91 .dev = {
92 .platform_data = &sdp2430_flash_data,
93 },
94 .num_resources = 1,
95 .resource = &sdp2430_flash_resource,
96};
97
98static struct resource sdp2430_smc91x_resources[] = {
99 [0] = {
100 .start = SDP2430_CS0_BASE,
101 .end = SDP2430_CS0_BASE + SZ_64M - 1,
102 .flags = IORESOURCE_MEM,
103 },
104 [1] = {
105 .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
106 .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
107 .flags = IORESOURCE_IRQ,
108 },
109};
110
111static struct platform_device sdp2430_smc91x_device = {
112 .name = "smc91x",
113 .id = -1,
114 .num_resources = ARRAY_SIZE(sdp2430_smc91x_resources),
115 .resource = sdp2430_smc91x_resources,
116};
117
118static struct platform_device *sdp2430_devices[] __initdata = {
119 &sdp2430_smc91x_device,
120 &sdp2430_flash_device,
121};
122
123static inline void __init sdp2430_init_smc91x(void)
124{
125 int eth_cs;
126 unsigned long cs_mem_base;
127 unsigned int rate;
128 struct clk *l3ck;
129
130 eth_cs = SDP2430_SMC91X_CS;
131
132 l3ck = clk_get(NULL, "core_l3_ck");
133 if (IS_ERR(l3ck))
134 rate = 100000000;
135 else
136 rate = clk_get_rate(l3ck);
137
138 /* Make sure CS1 timings are correct, for 2430 always muxed */
139 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
140
141 if (rate >= 160000000) {
142 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
143 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
144 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
145 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
146 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
147 } else if (rate >= 130000000) {
148 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
149 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
150 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
151 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
152 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
153 } else { /* rate = 100000000 */
154 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
155 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
156 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
157 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
158 gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
159 }
160
161 if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
162 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
163 return;
164 }
165
166 sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300;
167 sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f;
168 udelay(100);
169
170 if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
171 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
172 OMAP24XX_ETHR_GPIO_IRQ);
173 gpmc_cs_free(eth_cs);
174 return;
175 }
176 omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
177
178}
179
180static void __init omap_2430sdp_init_irq(void)
181{
182 omap2_init_common_hw();
183 omap_init_irq();
184 omap_gpio_init();
185 sdp2430_init_smc91x();
186}
187
188static struct omap_uart_config sdp2430_uart_config __initdata = {
189 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
190};
191
192static struct omap_board_config_kernel sdp2430_config[] = {
193 {OMAP_TAG_UART, &sdp2430_uart_config},
194};
195
196static void __init omap_2430sdp_init(void)
197{
198 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
199 omap_board_config = sdp2430_config;
200 omap_board_config_size = ARRAY_SIZE(sdp2430_config);
201 omap_serial_init();
202}
203
204static void __init omap_2430sdp_map_io(void)
205{
206 omap2_map_common_io();
207}
208
209MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
210 /* Maintainer: Syed Khasim - Texas Instruments Inc */
211 .phys_io = 0x48000000,
212 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
213 .boot_params = 0x80000100,
214 .map_io = omap_2430sdp_map_io,
215 .init_irq = omap_2430sdp_init_irq,
216 .init_machine = omap_2430sdp_init,
217 .timer = &omap_timer,
218MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 878ff9181d0..3bb49c17c85 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -25,6 +25,8 @@
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/leds.h>
29#include <linux/irq.h>
28 30
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -32,10 +34,12 @@
32#include <asm/mach/flash.h> 34#include <asm/mach/flash.h>
33 35
34#include <asm/arch/gpio.h> 36#include <asm/arch/gpio.h>
37#include <asm/arch/led.h>
35#include <asm/arch/mux.h> 38#include <asm/arch/mux.h>
36#include <asm/arch/usb.h> 39#include <asm/arch/usb.h>
37#include <asm/arch/board.h> 40#include <asm/arch/board.h>
38#include <asm/arch/common.h> 41#include <asm/arch/common.h>
42#include <asm/arch/gpmc.h>
39#include "prcm-regs.h" 43#include "prcm-regs.h"
40 44
41/* LED & Switch macros */ 45/* LED & Switch macros */
@@ -46,6 +50,9 @@
46#define SW_UP_GPIO17 17 50#define SW_UP_GPIO17 17
47#define SW_DOWN_GPIO58 58 51#define SW_DOWN_GPIO58 58
48 52
53#define APOLLON_FLASH_CS 0
54#define APOLLON_ETH_CS 1
55
49static struct mtd_partition apollon_partitions[] = { 56static struct mtd_partition apollon_partitions[] = {
50 { 57 {
51 .name = "X-Loader + U-Boot", 58 .name = "X-Loader + U-Boot",
@@ -85,10 +92,10 @@ static struct flash_platform_data apollon_flash_data = {
85 .nr_parts = ARRAY_SIZE(apollon_partitions), 92 .nr_parts = ARRAY_SIZE(apollon_partitions),
86}; 93};
87 94
88static struct resource apollon_flash_resource = { 95static struct resource apollon_flash_resource[] = {
89 .start = APOLLON_CS0_BASE, 96 [0] = {
90 .end = APOLLON_CS0_BASE + SZ_128K, 97 .flags = IORESOURCE_MEM,
91 .flags = IORESOURCE_MEM, 98 },
92}; 99};
93 100
94static struct platform_device apollon_onenand_device = { 101static struct platform_device apollon_onenand_device = {
@@ -97,14 +104,24 @@ static struct platform_device apollon_onenand_device = {
97 .dev = { 104 .dev = {
98 .platform_data = &apollon_flash_data, 105 .platform_data = &apollon_flash_data,
99 }, 106 },
100 .num_resources = ARRAY_SIZE(&apollon_flash_resource), 107 .num_resources = ARRAY_SIZE(apollon_flash_resource),
101 .resource = &apollon_flash_resource, 108 .resource = apollon_flash_resource,
102}; 109};
103 110
111static void __init apollon_flash_init(void)
112{
113 unsigned long base;
114
115 if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
116 printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
117 return;
118 }
119 apollon_flash_resource[0].start = base;
120 apollon_flash_resource[0].end = base + SZ_128K - 1;
121}
122
104static struct resource apollon_smc91x_resources[] = { 123static struct resource apollon_smc91x_resources[] = {
105 [0] = { 124 [0] = {
106 .start = APOLLON_ETHR_START, /* Physical */
107 .end = APOLLON_ETHR_START + 0xf,
108 .flags = IORESOURCE_MEM, 125 .flags = IORESOURCE_MEM,
109 }, 126 },
110 [1] = { 127 [1] = {
@@ -126,14 +143,51 @@ static struct platform_device apollon_lcd_device = {
126 .id = -1, 143 .id = -1,
127}; 144};
128 145
146static struct omap_led_config apollon_led_config[] = {
147 {
148 .cdev = {
149 .name = "apollon:led0",
150 },
151 .gpio = LED0_GPIO13,
152 },
153 {
154 .cdev = {
155 .name = "apollon:led1",
156 },
157 .gpio = LED1_GPIO14,
158 },
159 {
160 .cdev = {
161 .name = "apollon:led2",
162 },
163 .gpio = LED2_GPIO15,
164 },
165};
166
167static struct omap_led_platform_data apollon_led_data = {
168 .nr_leds = ARRAY_SIZE(apollon_led_config),
169 .leds = apollon_led_config,
170};
171
172static struct platform_device apollon_led_device = {
173 .name = "omap-led",
174 .id = -1,
175 .dev = {
176 .platform_data = &apollon_led_data,
177 },
178};
179
129static struct platform_device *apollon_devices[] __initdata = { 180static struct platform_device *apollon_devices[] __initdata = {
130 &apollon_onenand_device, 181 &apollon_onenand_device,
131 &apollon_smc91x_device, 182 &apollon_smc91x_device,
132 &apollon_lcd_device, 183 &apollon_lcd_device,
184 &apollon_led_device,
133}; 185};
134 186
135static inline void __init apollon_init_smc91x(void) 187static inline void __init apollon_init_smc91x(void)
136{ 188{
189 unsigned long base;
190
137 /* Make sure CS1 timings are correct */ 191 /* Make sure CS1 timings are correct */
138 GPMC_CONFIG1_1 = 0x00011203; 192 GPMC_CONFIG1_1 = 0x00011203;
139 GPMC_CONFIG2_1 = 0x001f1f01; 193 GPMC_CONFIG2_1 = 0x001f1f01;
@@ -141,13 +195,20 @@ static inline void __init apollon_init_smc91x(void)
141 GPMC_CONFIG4_1 = 0x1c091c09; 195 GPMC_CONFIG4_1 = 0x1c091c09;
142 GPMC_CONFIG5_1 = 0x041f1f1f; 196 GPMC_CONFIG5_1 = 0x041f1f1f;
143 GPMC_CONFIG6_1 = 0x000004c4; 197 GPMC_CONFIG6_1 = 0x000004c4;
144 GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); 198
199 if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
200 printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
201 return;
202 }
203 apollon_smc91x_resources[0].start = base + 0x300;
204 apollon_smc91x_resources[0].end = base + 0x30f;
145 udelay(100); 205 udelay(100);
146 206
147 omap_cfg_reg(W4__24XX_GPIO74); 207 omap_cfg_reg(W4__24XX_GPIO74);
148 if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { 208 if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
149 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", 209 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
150 APOLLON_ETHR_GPIO_IRQ); 210 APOLLON_ETHR_GPIO_IRQ);
211 gpmc_cs_free(APOLLON_ETH_CS);
151 return; 212 return;
152 } 213 }
153 omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); 214 omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
@@ -175,6 +236,13 @@ static struct omap_mmc_config apollon_mmc_config __initdata = {
175 }, 236 },
176}; 237};
177 238
239static struct omap_usb_config apollon_usb_config __initdata = {
240 .register_dev = 1,
241 .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
242
243 .pins[0] = 6,
244};
245
178static struct omap_lcd_config apollon_lcd_config __initdata = { 246static struct omap_lcd_config apollon_lcd_config __initdata = {
179 .ctrl_name = "internal", 247 .ctrl_name = "internal",
180}; 248};
@@ -182,6 +250,7 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
182static struct omap_board_config_kernel apollon_config[] = { 250static struct omap_board_config_kernel apollon_config[] = {
183 { OMAP_TAG_UART, &apollon_uart_config }, 251 { OMAP_TAG_UART, &apollon_uart_config },
184 { OMAP_TAG_MMC, &apollon_mmc_config }, 252 { OMAP_TAG_MMC, &apollon_mmc_config },
253 { OMAP_TAG_USB, &apollon_usb_config },
185 { OMAP_TAG_LCD, &apollon_lcd_config }, 254 { OMAP_TAG_LCD, &apollon_lcd_config },
186}; 255};
187 256
@@ -250,10 +319,22 @@ static void __init apollon_sw_init(void)
250 return; 319 return;
251} 320}
252 321
322static void __init apollon_usb_init(void)
323{
324 /* USB device */
325 /* DEVICE_SUSPEND */
326 omap_cfg_reg(P21_242X_GPIO12);
327 omap_request_gpio(12);
328 omap_set_gpio_direction(12, 0); /* OUT */
329 omap_set_gpio_dataout(12, 0);
330}
331
253static void __init omap_apollon_init(void) 332static void __init omap_apollon_init(void)
254{ 333{
255 apollon_led_init(); 334 apollon_led_init();
256 apollon_sw_init(); 335 apollon_sw_init();
336 apollon_flash_init();
337 apollon_usb_init();
257 338
258 /* REVISIT: where's the correct place */ 339 /* REVISIT: where's the correct place */
259 omap_cfg_reg(W19_24XX_SYS_NIRQ); 340 omap_cfg_reg(W19_24XX_SYS_NIRQ);
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 452193f0153..f125f432cc3 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -131,26 +131,6 @@ static struct platform_device h4_flash_device = {
131 .resource = &h4_flash_resource, 131 .resource = &h4_flash_resource,
132}; 132};
133 133
134static struct resource h4_smc91x_resources[] = {
135 [0] = {
136 .start = OMAP24XX_ETHR_START, /* Physical */
137 .end = OMAP24XX_ETHR_START + 0xf,
138 .flags = IORESOURCE_MEM,
139 },
140 [1] = {
141 .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
142 .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
143 .flags = IORESOURCE_IRQ,
144 },
145};
146
147static struct platform_device h4_smc91x_device = {
148 .name = "smc91x",
149 .id = -1,
150 .num_resources = ARRAY_SIZE(h4_smc91x_resources),
151 .resource = h4_smc91x_resources,
152};
153
154/* Select between the IrDA and aGPS module 134/* Select between the IrDA and aGPS module
155 */ 135 */
156static int h4_select_irda(struct device *dev, int state) 136static int h4_select_irda(struct device *dev, int state)
@@ -266,29 +246,14 @@ static struct platform_device h4_lcd_device = {
266 .id = -1, 246 .id = -1,
267}; 247};
268 248
269static struct resource h4_led_resources[] = {
270 [0] = {
271 .flags = IORESOURCE_MEM,
272 },
273};
274
275static struct platform_device h4_led_device = {
276 .name = "omap_dbg_led",
277 .id = -1,
278 .num_resources = ARRAY_SIZE(h4_led_resources),
279 .resource = h4_led_resources,
280};
281
282static struct platform_device *h4_devices[] __initdata = { 249static struct platform_device *h4_devices[] __initdata = {
283 &h4_smc91x_device,
284 &h4_flash_device, 250 &h4_flash_device,
285 &h4_irda_device, 251 &h4_irda_device,
286 &h4_kp_device, 252 &h4_kp_device,
287 &h4_lcd_device, 253 &h4_lcd_device,
288 &h4_led_device,
289}; 254};
290 255
291static inline void __init h4_init_smc91x(void) 256static inline void __init h4_init_debug(void)
292{ 257{
293 /* Make sure CS1 timings are correct */ 258 /* Make sure CS1 timings are correct */
294 GPMC_CONFIG1_1 = 0x00011200; 259 GPMC_CONFIG1_1 = 0x00011200;
@@ -301,12 +266,8 @@ static inline void __init h4_init_smc91x(void)
301 udelay(100); 266 udelay(100);
302 267
303 omap_cfg_reg(M15_24XX_GPIO92); 268 omap_cfg_reg(M15_24XX_GPIO92);
304 if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) { 269 if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0)
305 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", 270 gpmc_cs_free(eth_cs);
306 OMAP24XX_ETHR_GPIO_IRQ);
307 return;
308 }
309 omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
310} 271}
311 272
312static void __init omap_h4_init_irq(void) 273static void __init omap_h4_init_irq(void)
@@ -314,7 +275,6 @@ static void __init omap_h4_init_irq(void)
314 omap2_init_common_hw(); 275 omap2_init_common_hw();
315 omap_init_irq(); 276 omap_init_irq();
316 omap_gpio_init(); 277 omap_gpio_init();
317 h4_init_smc91x();
318} 278}
319 279
320static struct omap_uart_config h4_uart_config __initdata = { 280static struct omap_uart_config h4_uart_config __initdata = {
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 52ec2f2d636..b603bc5f8e5 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -55,8 +55,10 @@ static void omap_init_i2c(void)
55 if (machine_is_omap_h4()) 55 if (machine_is_omap_h4())
56 return; 56 return;
57 57
58 omap_cfg_reg(J15_24XX_I2C2_SCL); 58 if (!cpu_is_omap2430()) {
59 omap_cfg_reg(H19_24XX_I2C2_SDA); 59 omap_cfg_reg(J15_24XX_I2C2_SCL);
60 omap_cfg_reg(H19_24XX_I2C2_SDA);
61 }
60 (void) platform_device_register(&omap_i2c_device2); 62 (void) platform_device_register(&omap_i2c_device2);
61} 63}
62 64
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e290b989aa9..5a4cc2076a7 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -22,7 +22,14 @@
22 22
23#undef DEBUG 23#undef DEBUG
24 24
25#ifdef CONFIG_ARCH_OMAP2420
25#define GPMC_BASE 0x6800a000 26#define GPMC_BASE 0x6800a000
27#endif
28
29#ifdef CONFIG_ARCH_OMAP2430
30#define GPMC_BASE 0x6E000000
31#endif
32
26#define GPMC_REVISION 0x00 33#define GPMC_REVISION 0x00
27#define GPMC_SYSCONFIG 0x10 34#define GPMC_SYSCONFIG 0x10
28#define GPMC_SYSSTATUS 0x14 35#define GPMC_SYSSTATUS 0x14
@@ -88,7 +95,7 @@ u32 gpmc_cs_read_reg(int cs, int idx)
88} 95}
89 96
90/* TODO: Add support for gpmc_fck to clock framework and use it */ 97/* TODO: Add support for gpmc_fck to clock framework and use it */
91static unsigned long gpmc_get_fclk_period(void) 98unsigned long gpmc_get_fclk_period(void)
92{ 99{
93 /* In picoseconds */ 100 /* In picoseconds */
94 return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000); 101 return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000);
@@ -104,6 +111,13 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
104 return (time_ns * 1000 + tick_ps - 1) / tick_ps; 111 return (time_ns * 1000 + tick_ps - 1) / tick_ps;
105} 112}
106 113
114unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
115{
116 unsigned long ticks = gpmc_ns_to_ticks(time_ns);
117
118 return ticks * gpmc_get_fclk_period() / 1000;
119}
120
107#ifdef DEBUG 121#ifdef DEBUG
108static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 122static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
109 int time, const char *name) 123 int time, const char *name)
@@ -120,15 +134,21 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
120 else 134 else
121 ticks = gpmc_ns_to_ticks(time); 135 ticks = gpmc_ns_to_ticks(time);
122 nr_bits = end_bit - st_bit + 1; 136 nr_bits = end_bit - st_bit + 1;
123 if (ticks >= 1 << nr_bits) 137 if (ticks >= 1 << nr_bits) {
138#ifdef DEBUG
139 printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
140 cs, name, time, ticks, 1 << nr_bits);
141#endif
124 return -1; 142 return -1;
143 }
125 144
126 mask = (1 << nr_bits) - 1; 145 mask = (1 << nr_bits) - 1;
127 l = gpmc_cs_read_reg(cs, reg); 146 l = gpmc_cs_read_reg(cs, reg);
128#ifdef DEBUG 147#ifdef DEBUG
129 printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n", 148 printk(KERN_INFO
149 "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
130 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, 150 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
131 (l >> st_bit) & mask); 151 (l >> st_bit) & mask, time);
132#endif 152#endif
133 l &= ~(mask << st_bit); 153 l &= ~(mask << st_bit);
134 l |= ticks << st_bit; 154 l |= ticks << st_bit;
@@ -157,7 +177,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
157 div = l / gpmc_get_fclk_period(); 177 div = l / gpmc_get_fclk_period();
158 if (div > 4) 178 if (div > 4)
159 return -1; 179 return -1;
160 if (div < 0) 180 if (div <= 0)
161 div = 1; 181 div = 1;
162 182
163 return div; 183 return div;
@@ -191,14 +211,19 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
191 211
192 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); 212 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
193 213
214 /* caller is expected to have initialized CONFIG1 to cover
215 * at least sync vs async
216 */
217 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
218 if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
194#ifdef DEBUG 219#ifdef DEBUG
195 printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n", 220 printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
196 cs, gpmc_get_fclk_period(), div); 221 cs, (div * gpmc_get_fclk_period()) / 1000, div);
197#endif 222#endif
198 223 l &= ~0x03;
199 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 224 l |= (div - 1);
200 l &= ~0x03; 225 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
201 l |= (div - 1); 226 }
202 227
203 return 0; 228 return 0;
204} 229}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 871ace4fccb..4dfd878d796 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -17,7 +17,13 @@
17 17
18#include <asm/io.h> 18#include <asm/io.h>
19 19
20#if defined(CONFIG_ARCH_OMAP2420)
20#define OMAP24XX_TAP_BASE io_p2v(0x48014000) 21#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
22#endif
23
24#if defined(CONFIG_ARCH_OMAP2430)
25#define OMAP24XX_TAP_BASE io_p2v(0x4900A000)
26#endif
21 27
22#define OMAP_TAP_IDCODE 0x0204 28#define OMAP_TAP_IDCODE 0x0204
23#define OMAP_TAP_PROD_ID 0x0208 29#define OMAP_TAP_PROD_ID 0x0208
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 82dc70f6b77..5a4091f582e 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -5,6 +5,7 @@
5 * 5 *
6 * Copyright (C) 2005 Nokia Corporation 6 * Copyright (C) 2005 Nokia Corporation
7 * Author: Juha Yrjölä <juha.yrjola@nokia.com> 7 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
8 * Updated map desc to add 2430 support : <x0khasim@ti.com>
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -26,6 +27,7 @@
26extern void omap_sram_init(void); 27extern void omap_sram_init(void);
27extern int omap2_clk_init(void); 28extern int omap2_clk_init(void);
28extern void omap2_check_revision(void); 29extern void omap2_check_revision(void);
30extern void omap2_init_memory(void);
29extern void gpmc_init(void); 31extern void gpmc_init(void);
30extern void omapfb_reserve_sdram(void); 32extern void omapfb_reserve_sdram(void);
31 33
@@ -40,6 +42,20 @@ static struct map_desc omap2_io_desc[] __initdata = {
40 .length = L3_24XX_SIZE, 42 .length = L3_24XX_SIZE,
41 .type = MT_DEVICE 43 .type = MT_DEVICE
42 }, 44 },
45#ifdef CONFIG_ARCH_OMAP2430
46 {
47 .virtual = L4_WK_243X_VIRT,
48 .pfn = __phys_to_pfn(L4_WK_243X_PHYS),
49 .length = L4_WK_243X_SIZE,
50 .type = MT_DEVICE
51 },
52 {
53 .virtual = OMAP243X_GPMC_VIRT,
54 .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS),
55 .length = OMAP243X_GPMC_SIZE,
56 .type = MT_DEVICE
57 },
58#endif
43 { 59 {
44 .virtual = DSP_MEM_24XX_VIRT, 60 .virtual = DSP_MEM_24XX_VIRT,
45 .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), 61 .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
@@ -80,5 +96,11 @@ void __init omap2_init_common_hw(void)
80{ 96{
81 omap2_mux_init(); 97 omap2_mux_init();
82 omap2_clk_init(); 98 omap2_clk_init();
99/*
100 * Need to Fix this for 2430
101 */
102#ifndef CONFIG_ARCH_OMAP2430
103 omap2_init_memory();
104#endif
83 gpmc_init(); 105 gpmc_init();
84} 106}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index a39d3068030..f064f725e72 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -37,7 +37,7 @@ static struct omap_irq_bank {
37} __attribute__ ((aligned(4))) irq_banks[] = { 37} __attribute__ ((aligned(4))) irq_banks[] = {
38 { 38 {
39 /* MPU INTC */ 39 /* MPU INTC */
40 .base_reg = OMAP24XX_IC_BASE, 40 .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE),
41 .nr_irqs = 96, 41 .nr_irqs = 96,
42 }, { 42 }, {
43 /* XXX: DSP INTC */ 43 /* XXX: DSP INTC */
@@ -47,7 +47,7 @@ static struct omap_irq_bank {
47/* XXX: FIQ and additional INTC support (only MPU at the moment) */ 47/* XXX: FIQ and additional INTC support (only MPU at the moment) */
48static void omap_ack_irq(unsigned int irq) 48static void omap_ack_irq(unsigned int irq)
49{ 49{
50 omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); 50 __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
51} 51}
52 52
53static void omap_mask_irq(unsigned int irq) 53static void omap_mask_irq(unsigned int irq)
@@ -60,7 +60,7 @@ static void omap_mask_irq(unsigned int irq)
60 irq %= 32; 60 irq %= 32;
61 } 61 }
62 62
63 omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); 63 __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
64} 64}
65 65
66static void omap_unmask_irq(unsigned int irq) 66static void omap_unmask_irq(unsigned int irq)
@@ -73,7 +73,7 @@ static void omap_unmask_irq(unsigned int irq)
73 irq %= 32; 73 irq %= 32;
74 } 74 }
75 75
76 omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); 76 __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
77} 77}
78 78
79static void omap_mask_ack_irq(unsigned int irq) 79static void omap_mask_ack_irq(unsigned int irq)
@@ -93,17 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
93{ 93{
94 unsigned long tmp; 94 unsigned long tmp;
95 95
96 tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff; 96 tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff;
97 printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx " 97 printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
98 "(revision %ld.%ld) with %d interrupts\n", 98 "(revision %ld.%ld) with %d interrupts\n",
99 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); 99 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
100 100
101 tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG); 101 tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG);
102 tmp |= 1 << 1; /* soft reset */ 102 tmp |= 1 << 1; /* soft reset */
103 omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG); 103 __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
104 104
105 while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) 105 while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
106 /* Wait for reset to complete */; 106 /* Wait for reset to complete */;
107
108 /* Enable autoidle */
109 __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG);
107} 110}
108 111
109void __init omap_init_irq(void) 112void __init omap_init_irq(void)
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
index 85cbc2a2e66..3e5d8cd4ea4 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/memory.c
@@ -30,6 +30,7 @@
30#include "prcm-regs.h" 30#include "prcm-regs.h"
31#include "memory.h" 31#include "memory.h"
32 32
33
33static struct memory_timings mem_timings; 34static struct memory_timings mem_timings;
34 35
35u32 omap2_memory_get_slow_dll_ctrl(void) 36u32 omap2_memory_get_slow_dll_ctrl(void)
@@ -99,3 +100,20 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
99 /* 90 degree phase for anything below 133Mhz + disable DLL filter */ 100 /* 90 degree phase for anything below 133Mhz + disable DLL filter */
100 mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); 101 mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
101} 102}
103
104/* turn on smart idle modes for SDRAM scheduler and controller */
105void __init omap2_init_memory(void)
106{
107 u32 l;
108
109 l = SMS_SYSCONFIG;
110 l &= ~(0x3 << 3);
111 l |= (0x2 << 3);
112 SMS_SYSCONFIG = l;
113
114 l = SDRC_SYSCONFIG;
115 l &= ~(0x3 << 3);
116 l |= (0x2 << 3);
117 SDRC_SYSCONFIG = l;
118
119}
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 0439906d5da..05750975d74 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -53,8 +53,8 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
53MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1) 53MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
54 54
55/* 24xx GPMC chipselects, wait pin monitoring */ 55/* 24xx GPMC chipselects, wait pin monitoring */
56MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1) 56MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1)
57MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1) 57MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1)
58MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1) 58MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1)
59MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1) 59MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1)
60MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1) 60MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1)
@@ -67,18 +67,18 @@ MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
67MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1) 67MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
68 68
69/* 24xx GPIO */ 69/* 24xx GPIO */
70MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1) 70MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
71MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1) 71MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1)
72MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1) 72MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
73MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1) 73MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
74MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1) 74MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
75MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1) 75MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
76MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1) 76MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
77MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1) 77MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
78MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) 78MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
79MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1) 79MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
80MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) 80MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
81MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1) 81MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1)
82MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1) 82MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
83MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1) 83MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1)
84 84
@@ -95,17 +95,17 @@ MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1)
95MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1) 95MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1)
96 96
97/* 24xx external DMA requests */ 97/* 24xx external DMA requests */
98MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1) 98MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1)
99MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1) 99MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1)
100MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1) 100MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1)
101MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1) 101MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1)
102MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1) 102MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1)
103MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1) 103MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1)
104 104
105/* TSC IRQ */ 105/* TSC IRQ */
106MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) 106MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
107 107
108/* UART3 */ 108/* UART3 */
109MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) 109MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
110MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) 110MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
111 111
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
new file mode 100644
index 00000000000..80bb42eb508
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -0,0 +1,349 @@
1/*
2 * linux/arch/arm/mach-omap2/usb-tusb6010.c
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/types.h>
12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/platform_device.h>
15
16#include <linux/usb/musb.h>
17
18#include <asm/arch/gpmc.h>
19#include <asm/arch/gpio.h>
20#include <asm/arch/mux.h>
21
22
23static u8 async_cs, sync_cs;
24static unsigned refclk_psec;
25
26
27/* t2_ps, when quantized to fclk units, must happen no earlier than
28 * the clock after after t1_NS.
29 *
30 * Return a possibly updated value of t2_ps, converted to nsec.
31 */
32static unsigned
33next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
34{
35 unsigned t1_ps = t1_NS * 1000;
36 unsigned t1_f, t2_f;
37
38 if ((t1_ps + fclk_ps) < t2_ps)
39 return t2_ps / 1000;
40
41 t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
42 t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
43
44 if (t1_f >= t2_f)
45 t2_f = t1_f + 1;
46
47 return (t2_f * fclk_ps) / 1000;
48}
49
50/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
51
52static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
53{
54 struct gpmc_timings t;
55 unsigned t_acsnh_advnh = sysclk_ps + 3000;
56 unsigned tmp;
57
58 memset(&t, 0, sizeof(t));
59
60 /* CS_ON = t_acsnh_acsnl */
61 t.cs_on = 8;
62 /* ADV_ON = t_acsnh_advnh - t_advn */
63 t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
64
65 /*
66 * READ ... from omap2420 TRM fig 12-13
67 */
68
69 /* ADV_RD_OFF = t_acsnh_advnh */
70 t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
71
72 /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
73 t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
74
75 /* ACCESS = counters continue only after nRDY */
76 tmp = t.oe_on * 1000 + 300;
77 t.access = next_clk(t.oe_on, tmp, fclk_ps);
78
79 /* OE_OFF = after data gets sampled */
80 tmp = t.access * 1000;
81 t.oe_off = next_clk(t.access, tmp, fclk_ps);
82
83 t.cs_rd_off = t.oe_off;
84
85 tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
86 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
87
88 /*
89 * WRITE ... from omap2420 TRM fig 12-15
90 */
91
92 /* ADV_WR_OFF = t_acsnh_advnh */
93 t.adv_wr_off = t.adv_rd_off;
94
95 /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
96 t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
97
98 /* WE_OFF = after data gets sampled */
99 tmp = t.we_on * 1000 + 300;
100 t.we_off = next_clk(t.we_on, tmp, fclk_ps);
101
102 t.cs_wr_off = t.we_off;
103
104 tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
105 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
106
107 return gpmc_cs_set_timings(async_cs, &t);
108}
109
110static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
111{
112 struct gpmc_timings t;
113 unsigned t_scsnh_advnh = sysclk_ps + 3000;
114 unsigned tmp;
115
116 memset(&t, 0, sizeof(t));
117 t.cs_on = 8;
118
119 /* ADV_ON = t_acsnh_advnh - t_advn */
120 t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
121
122 /* GPMC_CLK rate = fclk rate / div */
123 t.sync_clk = 12 /* 11.1 nsec */;
124 tmp = (t.sync_clk * 1000 + fclk_ps - 1) / fclk_ps;
125 if (tmp > 4)
126 return -ERANGE;
127 if (tmp <= 0)
128 tmp = 1;
129 t.page_burst_access = (fclk_ps * tmp) / 1000;
130
131 /*
132 * READ ... based on omap2420 TRM fig 12-19, 12-20
133 */
134
135 /* ADV_RD_OFF = t_scsnh_advnh */
136 t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
137
138 /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
139 tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
140 t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
141
142 /* ACCESS = number of clock cycles after t_adv_eon */
143 tmp = (t.oe_on * 1000) + (5 * fclk_ps);
144 t.access = next_clk(t.oe_on, tmp, fclk_ps);
145
146 /* OE_OFF = after data gets sampled */
147 tmp = (t.access * 1000) + (1 * fclk_ps);
148 t.oe_off = next_clk(t.access, tmp, fclk_ps);
149
150 t.cs_rd_off = t.oe_off;
151
152 tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
153 t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
154
155 /*
156 * WRITE ... based on omap2420 TRM fig 12-21
157 */
158
159 /* ADV_WR_OFF = t_scsnh_advnh */
160 t.adv_wr_off = t.adv_rd_off;
161
162 /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
163 tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
164 t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
165
166 /* WE_OFF = number of clock cycles after t_adv_wen */
167 tmp = (t.we_on * 1000) + (6 * fclk_ps);
168 t.we_off = next_clk(t.we_on, tmp, fclk_ps);
169
170 t.cs_wr_off = t.we_off;
171
172 tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
173 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
174
175 return gpmc_cs_set_timings(sync_cs, &t);
176}
177
178extern unsigned long gpmc_get_fclk_period(void);
179
180/* tusb driver calls this when it changes the chip's clocking */
181int tusb6010_platform_retime(unsigned is_refclk)
182{
183 static const char error[] =
184 KERN_ERR "tusb6010 %s retime error %d\n";
185
186 unsigned fclk_ps = gpmc_get_fclk_period();
187 unsigned sysclk_ps;
188 int status;
189
190 if (!refclk_psec)
191 return -ENODEV;
192
193 sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
194
195 status = tusb_set_async_mode(sysclk_ps, fclk_ps);
196 if (status < 0) {
197 printk(error, "async", status);
198 goto done;
199 }
200 status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
201 if (status < 0)
202 printk(error, "sync", status);
203done:
204 return status;
205}
206EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
207
208static struct resource tusb_resources[] = {
209 /* Order is significant! The start/end fields
210 * are updated during setup..
211 */
212 { /* Asynchronous access */
213 .flags = IORESOURCE_MEM,
214 },
215 { /* Synchronous access */
216 .flags = IORESOURCE_MEM,
217 },
218 { /* IRQ */
219 .flags = IORESOURCE_IRQ,
220 },
221};
222
223static u64 tusb_dmamask = ~(u32)0;
224
225static struct platform_device tusb_device = {
226 .name = "musb_hdrc",
227 .id = -1,
228 .dev = {
229 .dma_mask = &tusb_dmamask,
230 .coherent_dma_mask = 0xffffffff,
231 },
232 .num_resources = ARRAY_SIZE(tusb_resources),
233 .resource = tusb_resources,
234};
235
236
237/* this may be called only from board-*.c setup code */
238int __init
239tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
240 unsigned ps_refclk, unsigned waitpin,
241 unsigned async, unsigned sync,
242 unsigned irq, unsigned dmachan)
243{
244 int status;
245 static char error[] __initdata =
246 KERN_ERR "tusb6010 init error %d, %d\n";
247
248 /* ASYNC region, primarily for PIO */
249 status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
250 &tusb_resources[0].start);
251 if (status < 0) {
252 printk(error, 1, status);
253 return status;
254 }
255 tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
256 async_cs = async;
257 gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
258 GPMC_CONFIG1_PAGE_LEN(2)
259 | GPMC_CONFIG1_WAIT_READ_MON
260 | GPMC_CONFIG1_WAIT_WRITE_MON
261 | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
262 | GPMC_CONFIG1_READTYPE_ASYNC
263 | GPMC_CONFIG1_WRITETYPE_ASYNC
264 | GPMC_CONFIG1_DEVICESIZE_16
265 | GPMC_CONFIG1_DEVICETYPE_NOR
266 | GPMC_CONFIG1_MUXADDDATA);
267
268
269 /* SYNC region, primarily for DMA */
270 status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
271 &tusb_resources[1].start);
272 if (status < 0) {
273 printk(error, 2, status);
274 return status;
275 }
276 tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
277 sync_cs = sync;
278 gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
279 GPMC_CONFIG1_READMULTIPLE_SUPP
280 | GPMC_CONFIG1_READTYPE_SYNC
281 | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
282 | GPMC_CONFIG1_WRITETYPE_SYNC
283 | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
284 | GPMC_CONFIG1_PAGE_LEN(2)
285 | GPMC_CONFIG1_WAIT_READ_MON
286 | GPMC_CONFIG1_WAIT_WRITE_MON
287 | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
288 | GPMC_CONFIG1_DEVICESIZE_16
289 | GPMC_CONFIG1_DEVICETYPE_NOR
290 | GPMC_CONFIG1_MUXADDDATA
291 /* fclk divider gets set later */
292 );
293
294 /* IRQ */
295 status = omap_request_gpio(irq);
296 if (status < 0) {
297 printk(error, 3, status);
298 return status;
299 }
300 omap_set_gpio_direction(irq, 1);
301 tusb_resources[2].start = irq + IH_GPIO_BASE;
302
303 /* set up memory timings ... can speed them up later */
304 if (!ps_refclk) {
305 printk(error, 4, status);
306 return -ENODEV;
307 }
308 refclk_psec = ps_refclk;
309 status = tusb6010_platform_retime(1);
310 if (status < 0) {
311 printk(error, 5, status);
312 return status;
313 }
314
315 /* finish device setup ... */
316 if (!data) {
317 printk(error, 6, status);
318 return -ENODEV;
319 }
320 data->multipoint = 1;
321 tusb_device.dev.platform_data = data;
322
323 /* REVISIT let the driver know what DMA channels work */
324 if (!dmachan)
325 tusb_device.dev.dma_mask = NULL;
326 else {
327 /* assume OMAP 2420 ES2.0 and later */
328 if (dmachan & (1 << 0))
329 omap_cfg_reg(AA10_242X_DMAREQ0);
330 if (dmachan & (1 << 1))
331 omap_cfg_reg(AA6_242X_DMAREQ1);
332 if (dmachan & (1 << 2))
333 omap_cfg_reg(E4_242X_DMAREQ2);
334 if (dmachan & (1 << 3))
335 omap_cfg_reg(G4_242X_DMAREQ3);
336 if (dmachan & (1 << 4))
337 omap_cfg_reg(D3_242X_DMAREQ4);
338 if (dmachan & (1 << 5))
339 omap_cfg_reg(E3_242X_DMAREQ5);
340 }
341
342 /* so far so good ... register the device */
343 status = platform_device_register(&tusb_device);
344 if (status < 0) {
345 printk(error, 7, status);
346 return status;
347 }
348 return 0;
349}
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index aab27297b3c..2363cc64fe0 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -20,6 +20,7 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
22#include <linux/pm.h> 22#include <linux/pm.h>
23#include <linux/backlight.h>
23 24
24#include <asm/setup.h> 25#include <asm/setup.h>
25#include <asm/memory.h> 26#include <asm/memory.h>
@@ -142,15 +143,28 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
142/* 143/*
143 * Corgi Backlight Device 144 * Corgi Backlight Device
144 */ 145 */
145static struct corgibl_machinfo corgi_bl_machinfo = { 146static void corgi_bl_kick_battery(void)
147{
148 void (*kick_batt)(void);
149
150 kick_batt = symbol_get(sharpsl_battery_kick);
151 if (kick_batt) {
152 kick_batt();
153 symbol_put(sharpsl_battery_kick);
154 }
155}
156
157static struct generic_bl_info corgi_bl_machinfo = {
158 .name = "corgi-bl",
146 .max_intensity = 0x2f, 159 .max_intensity = 0x2f,
147 .default_intensity = 0x1f, 160 .default_intensity = 0x1f,
148 .limit_mask = 0x0b, 161 .limit_mask = 0x0b,
149 .set_bl_intensity = corgi_bl_set_intensity, 162 .set_bl_intensity = corgi_bl_set_intensity,
163 .kick_battery = corgi_bl_kick_battery,
150}; 164};
151 165
152static struct platform_device corgibl_device = { 166static struct platform_device corgibl_device = {
153 .name = "corgi-bl", 167 .name = "generic-bl",
154 .dev = { 168 .dev = {
155 .parent = &corgifb_device.dev, 169 .parent = &corgifb_device.dev,
156 .platform_data = &corgi_bl_machinfo, 170 .platform_data = &corgi_bl_machinfo,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index bae47e145de..2d78199d24a 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/mmc/host.h> 22#include <linux/mmc/host.h>
23#include <linux/pm.h> 23#include <linux/pm.h>
24#include <linux/backlight.h>
24 25
25#include <asm/setup.h> 26#include <asm/setup.h>
26#include <asm/memory.h> 27#include <asm/memory.h>
@@ -222,14 +223,27 @@ struct corgissp_machinfo spitz_ssp_machinfo = {
222/* 223/*
223 * Spitz Backlight Device 224 * Spitz Backlight Device
224 */ 225 */
225static struct corgibl_machinfo spitz_bl_machinfo = { 226static void spitz_bl_kick_battery(void)
227{
228 void (*kick_batt)(void);
229
230 kick_batt = symbol_get(sharpsl_battery_kick);
231 if (kick_batt) {
232 kick_batt();
233 symbol_put(sharpsl_battery_kick);
234 }
235}
236
237static struct generic_bl_info spitz_bl_machinfo = {
238 .name = "corgi-bl",
226 .default_intensity = 0x1f, 239 .default_intensity = 0x1f,
227 .limit_mask = 0x0b, 240 .limit_mask = 0x0b,
228 .max_intensity = 0x2f, 241 .max_intensity = 0x2f,
242 .kick_battery = spitz_bl_kick_battery,
229}; 243};
230 244
231static struct platform_device spitzbl_device = { 245static struct platform_device spitzbl_device = {
232 .name = "corgi-bl", 246 .name = "generic-bl",
233 .dev = { 247 .dev = {
234 .platform_data = &spitz_bl_machinfo, 248 .platform_data = &spitz_bl_machinfo,
235 }, 249 },
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 80d83739ab9..8f12e855ef5 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -145,7 +145,7 @@ static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
145 }, 145 },
146}; 146};
147 147
148static int s3c2410_dma_add(struct sys_device *sysdev) 148static int __init s3c2410_dma_add(struct sys_device *sysdev)
149{ 149{
150 s3c2410_dma_init(); 150 s3c2410_dma_init();
151 s3c24xx_dma_order_set(&s3c2410_dma_order); 151 s3c24xx_dma_order_set(&s3c2410_dma_order);
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 4b9425c1bf7..53c1d5bbce1 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -144,7 +144,7 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
144 .map_size = ARRAY_SIZE(s3c2412_dma_mappings), 144 .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
145}; 145};
146 146
147static int s3c2412_dma_add(struct sys_device *sysdev) 147static int __init s3c2412_dma_add(struct sys_device *sysdev)
148{ 148{
149 s3c2410_dma_init(); 149 s3c2410_dma_init();
150 return s3c24xx_dma_init_map(&s3c2412_dma_sel); 150 return s3c24xx_dma_init_map(&s3c2412_dma_sel);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index f0d66828f96..e9d0c769f5d 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -38,6 +38,9 @@
38#include <asm/plat-s3c24xx/irq.h> 38#include <asm/plat-s3c24xx/irq.h>
39#include <asm/plat-s3c24xx/pm.h> 39#include <asm/plat-s3c24xx/pm.h>
40 40
41#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
42#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
43
41/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by 44/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
42 * having them turn up in both the INT* and the EINT* registers. Whilst 45 * having them turn up in both the INT* and the EINT* registers. Whilst
43 * both show the status, they both now need to be acked when the IRQs 46 * both show the status, they both now need to be acked when the IRQs
@@ -105,6 +108,51 @@ static struct irq_chip s3c2412_irq_eint0t4 = {
105 .set_type = s3c_irqext_type, 108 .set_type = s3c_irqext_type,
106}; 109};
107 110
111#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
112
113/* CF and SDI sub interrupts */
114
115static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
116{
117 unsigned int subsrc, submsk;
118
119 subsrc = __raw_readl(S3C2410_SUBSRCPND);
120 submsk = __raw_readl(S3C2410_INTSUBMSK);
121
122 subsrc &= ~submsk;
123
124 if (subsrc & INTBIT(IRQ_S3C2412_SDI))
125 desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);
126
127 if (subsrc & INTBIT(IRQ_S3C2412_CF))
128 desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
129}
130
131#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
132#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
133
134static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
135{
136 s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
137}
138
139static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
140{
141 s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
142}
143
144static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
145{
146 s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
147}
148
149static struct irq_chip s3c2412_irq_cfsdi = {
150 .name = "s3c2412-cfsdi",
151 .ack = s3c2412_irq_cfsdi_ack,
152 .mask = s3c2412_irq_cfsdi_mask,
153 .unmask = s3c2412_irq_cfsdi_unmask,
154};
155
108static int s3c2412_irq_add(struct sys_device *sysdev) 156static int s3c2412_irq_add(struct sys_device *sysdev)
109{ 157{
110 unsigned int irqno; 158 unsigned int irqno;
@@ -115,6 +163,16 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
115 set_irq_flags(irqno, IRQF_VALID); 163 set_irq_flags(irqno, IRQF_VALID);
116 } 164 }
117 165
166 /* add demux support for CF/SDI */
167
168 set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
169
170 for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
171 set_irq_chip(irqno, &s3c2412_irq_cfsdi);
172 set_irq_handler(irqno, handle_level_irq);
173 set_irq_flags(irqno, IRQF_VALID);
174 }
175
118 return 0; 176 return 0;
119} 177}
120 178
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index e0ccb404623..4f92a1562d7 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -78,6 +78,11 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
78 s3c_device_lcd.name = "s3c2412-lcd"; 78 s3c_device_lcd.name = "s3c2412-lcd";
79 s3c_device_nand.name = "s3c2412-nand"; 79 s3c_device_nand.name = "s3c2412-nand";
80 80
81 /* alter IRQ of SDI controller */
82
83 s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
84 s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI;
85
81 /* spi channel related changes, s3c2412/13 specific */ 86 /* spi channel related changes, s3c2412/13 specific */
82 s3c_device_spi0.name = "s3c2412-spi"; 87 s3c_device_spi0.name = "s3c2412-spi";
83 s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; 88 s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index f509f062e74..0b1260827ac 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -190,7 +190,7 @@ static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
190 }, 190 },
191}; 191};
192 192
193static int s3c2440_dma_add(struct sys_device *sysdev) 193static int __init s3c2440_dma_add(struct sys_device *sysdev)
194{ 194{
195 s3c2410_dma_init(); 195 s3c2410_dma_init();
196 s3c24xx_dma_order_set(&s3c2440_dma_order); 196 s3c24xx_dma_order_set(&s3c2440_dma_order);
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 0ba7e9060c7..c326983f4a8 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -276,7 +276,21 @@ static unsigned char pm_osiris_ctrl0;
276 276
277static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state) 277static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
278{ 278{
279 unsigned int tmp;
280
279 pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0); 281 pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0);
282 tmp = pm_osiris_ctrl0 & ~OSIRIS_CTRL0_NANDSEL;
283
284 /* ensure correct NAND slot is selected on resume */
285 if ((pm_osiris_ctrl0 & OSIRIS_CTRL0_BOOT_INT) == 0)
286 tmp |= 2;
287
288 __raw_writeb(tmp, OSIRIS_VA_CTRL0);
289
290 /* ensure that an nRESET is not generated on resume. */
291 s3c2410_gpio_setpin(S3C2410_GPA21, 1);
292 s3c2410_gpio_cfgpin(S3C2410_GPA21, S3C2410_GPA21_OUT);
293
280 return 0; 294 return 0;
281} 295}
282 296
@@ -285,6 +299,10 @@ static int osiris_pm_resume(struct sys_device *sd)
285 if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8) 299 if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
286 __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1); 300 __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
287 301
302 __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
303
304 s3c2410_gpio_cfgpin(S3C2410_GPA21, S3C2410_GPA21_nRSTOUT);
305
288 return 0; 306 return 0;
289} 307}
290 308
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index fc3ede82af8..f6c006d4297 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -162,7 +162,7 @@ static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
162 .map_size = ARRAY_SIZE(s3c2443_dma_mappings), 162 .map_size = ARRAY_SIZE(s3c2443_dma_mappings),
163}; 163};
164 164
165static int s3c2443_dma_add(struct sys_device *sysdev) 165static int __init s3c2443_dma_add(struct sys_device *sysdev)
166{ 166{
167 s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); 167 s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
168 return s3c24xx_dma_init_map(&s3c2443_dma_sel); 168 return s3c24xx_dma_init_map(&s3c2443_dma_sel);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 6cd4818f3f0..f9ad498a6fc 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -252,7 +252,7 @@ static int __init s3c2443_add_sub(unsigned int base,
252 return 0; 252 return 0;
253} 253}
254 254
255static int s3c2443_irq_add(struct sys_device *sysdev) 255static int __init s3c2443_irq_add(struct sys_device *sysdev)
256{ 256{
257 printk("S3C2443: IRQ Support\n"); 257 printk("S3C2443: IRQ Support\n");
258 258
@@ -280,7 +280,7 @@ static struct sysdev_driver s3c2443_irq_driver = {
280 .add = s3c2443_irq_add, 280 .add = s3c2443_irq_add,
281}; 281};
282 282
283static int s3c2443_irq_init(void) 283static int __init s3c2443_irq_init(void)
284{ 284{
285 return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver); 285 return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
286} 286}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b4e9b734e0b..76b800a9519 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -57,7 +57,17 @@ static void l2x0_inv_range(unsigned long start, unsigned long end)
57{ 57{
58 unsigned long addr; 58 unsigned long addr;
59 59
60 start &= ~(CACHE_LINE_SIZE - 1); 60 if (start & (CACHE_LINE_SIZE - 1)) {
61 start &= ~(CACHE_LINE_SIZE - 1);
62 sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1);
63 start += CACHE_LINE_SIZE;
64 }
65
66 if (end & (CACHE_LINE_SIZE - 1)) {
67 end &= ~(CACHE_LINE_SIZE - 1);
68 sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1);
69 }
70
61 for (addr = start; addr < end; addr += CACHE_LINE_SIZE) 71 for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
62 sync_writel(addr, L2X0_INV_LINE_PA, 1); 72 sync_writel(addr, L2X0_INV_LINE_PA, 1);
63 cache_sync(); 73 cache_sync();
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 1f9f94f9af4..cefdf2f9f26 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -481,7 +481,7 @@ core_initcall(consistent_init);
481 * platforms with CONFIG_DMABOUNCE. 481 * platforms with CONFIG_DMABOUNCE.
482 * Use the driver DMA support - see dma-mapping.h (dma_sync_*) 482 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
483 */ 483 */
484void consistent_sync(const void *start, size_t size, int direction) 484void dma_cache_maint(const void *start, size_t size, int direction)
485{ 485{
486 const void *end = start + size; 486 const void *end = start + size;
487 487
@@ -504,4 +504,4 @@ void consistent_sync(const void *start, size_t size, int direction)
504 BUG(); 504 BUG();
505 } 505 }
506} 506}
507EXPORT_SYMBOL(consistent_sync); 507EXPORT_SYMBOL(dma_cache_maint);
diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h
index e6598470b07..436e54aa02e 100644
--- a/arch/arm/nwfpe/ARM-gcc.h
+++ b/arch/arm/nwfpe/ARM-gcc.h
@@ -68,7 +68,7 @@ a compiler does not support explicit inlining, this macro should be defined
68to be `static'. 68to be `static'.
69------------------------------------------------------------------------------- 69-------------------------------------------------------------------------------
70*/ 70*/
71#define INLINE extern __inline__ 71#define INLINE static inline
72 72
73 73
74/* For use as a GCC soft-float library we need some special function names. */ 74/* For use as a GCC soft-float library we need some special function names. */
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 1dc13bc6d81..48bca0db460 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -70,13 +70,24 @@ floating point instructions. GCC attempts to group floating point
70instructions to allow the emulator to spread the cost of the trap over 70instructions to allow the emulator to spread the cost of the trap over
71several floating point instructions. */ 71several floating point instructions. */
72 72
73#include <asm/asm-offsets.h>
74
73 .globl nwfpe_enter 75 .globl nwfpe_enter
74nwfpe_enter: 76nwfpe_enter:
75 mov r4, lr @ save the failure-return addresses 77 mov r4, lr @ save the failure-return addresses
76 mov sl, sp @ we access the registers via 'sl' 78 mov sl, sp @ we access the registers via 'sl'
77 79
78 ldr r5, [sp, #60] @ get contents of PC; 80 ldr r5, [sp, #S_PC] @ get contents of PC;
81 mov r6, r0 @ save the opcode
79emulate: 82emulate:
83 ldr r1, [sp, #S_PSR] @ fetch the PSR
84 bl checkCondition @ check the condition
85 cmp r0, #0 @ r0 = 0 ==> condition failed
86
87 @ if condition code failed to match, next insn
88 beq next @ get the next instruction;
89
90 mov r0, r6 @ prepare for EmulateAll()
80 bl EmulateAll @ emulate the instruction 91 bl EmulateAll @ emulate the instruction
81 cmp r0, #0 @ was emulation successful 92 cmp r0, #0 @ was emulation successful
82 moveq pc, r4 @ no, return failure 93 moveq pc, r4 @ no, return failure
@@ -91,18 +102,10 @@ next:
91 teqne r2, #0x0E000000 102 teqne r2, #0x0E000000
92 movne pc, r9 @ return ok if not a fp insn 103 movne pc, r9 @ return ok if not a fp insn
93 104
94 str r5, [sp, #60] @ update PC copy in regs 105 str r5, [sp, #S_PC] @ update PC copy in regs
95 106
96 mov r0, r6 @ save a copy 107 mov r0, r6 @ save a copy
97 ldr r1, [sp, #64] @ fetch the condition codes 108 b emulate @ check condition and emulate
98 bl checkCondition @ check the condition
99 cmp r0, #0 @ r0 = 0 ==> condition failed
100
101 @ if condition code failed to match, next insn
102 beq next @ get the next instruction;
103
104 mov r0, r6 @ prepare for EmulateAll()
105 b emulate @ if r0 != 0, goto EmulateAll
106 109
107 @ We need to be prepared for the instructions at .Lx1 and .Lx2 110 @ We need to be prepared for the instructions at .Lx1 and .Lx2
108 @ to fault. Emit the appropriate exception gunk to fix things up. 111 @ to fault. Emit the appropriate exception gunk to fix things up.
diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl
index 10c3caf2868..ab8d6826245 100644
--- a/arch/arm/nwfpe/fpa11.inl
+++ b/arch/arm/nwfpe/fpa11.inl
@@ -22,13 +22,13 @@
22#include "fpa11.h" 22#include "fpa11.h"
23 23
24/* Read and write floating point status register */ 24/* Read and write floating point status register */
25extern __inline__ unsigned int readFPSR(void) 25static inline unsigned int readFPSR(void)
26{ 26{
27 FPA11 *fpa11 = GET_FPA11(); 27 FPA11 *fpa11 = GET_FPA11();
28 return (fpa11->fpsr); 28 return (fpa11->fpsr);
29} 29}
30 30
31extern __inline__ void writeFPSR(FPSR reg) 31static inline void writeFPSR(FPSR reg)
32{ 32{
33 FPA11 *fpa11 = GET_FPA11(); 33 FPA11 *fpa11 = GET_FPA11();
34 /* the sysid byte in the status register is readonly */ 34 /* the sysid byte in the status register is readonly */
@@ -36,14 +36,14 @@ extern __inline__ void writeFPSR(FPSR reg)
36} 36}
37 37
38/* Read and write floating point control register */ 38/* Read and write floating point control register */
39extern __inline__ FPCR readFPCR(void) 39static inline FPCR readFPCR(void)
40{ 40{
41 FPA11 *fpa11 = GET_FPA11(); 41 FPA11 *fpa11 = GET_FPA11();
42 /* clear SB, AB and DA bits before returning FPCR */ 42 /* clear SB, AB and DA bits before returning FPCR */
43 return (fpa11->fpcr & ~MASK_RFC); 43 return (fpa11->fpcr & ~MASK_RFC);
44} 44}
45 45
46extern __inline__ void writeFPCR(FPCR reg) 46static inline void writeFPCR(FPCR reg)
47{ 47{
48 FPA11 *fpa11 = GET_FPA11(); 48 FPA11 *fpa11 = GET_FPA11();
49 fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ 49 fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index cfc69f3842f..c1f7e5a819a 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -20,10 +20,15 @@ endchoice
20 20
21comment "OMAP Feature Selections" 21comment "OMAP Feature Selections"
22 22
23config OMAP_DEBUG_LEDS 23config OMAP_DEBUG_DEVICES
24 bool 24 bool
25 help 25 help
26 For debug card leds on TI reference boards. 26 For debug cards on TI reference boards.
27
28config OMAP_DEBUG_LEDS
29 bool
30 depends on OMAP_DEBUG_DEVICES
31 default y if LEDS || LEDS_OMAP_DEBUG
27 32
28config OMAP_RESET_CLOCKS 33config OMAP_RESET_CLOCKS
29 bool "Reset unused clocks during boot" 34 bool "Reset unused clocks during boot"
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 41a3c1cf3bd..2549129aabc 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
17 17
18obj-$(CONFIG_CPU_FREQ) += cpu-omap.o 18obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
19obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 19obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
20obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
20obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o 21obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
new file mode 100644
index 00000000000..83a5f8b9185
--- /dev/null
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -0,0 +1,86 @@
1/*
2 * linux/arch/arm/plat-omap/debug-devices.c
3 *
4 * Copyright (C) 2005 Nokia Corporation
5 * Modified from mach-omap2/board-h4.c
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15
16#include <asm/hardware.h>
17#include <asm/io.h>
18
19#include <asm/arch/board.h>
20#include <asm/arch/gpio.h>
21
22
23/* Many OMAP development platforms reuse the same "debug board"; these
24 * platforms include H2, H3, H4, and Perseus2.
25 */
26
27static struct resource smc91x_resources[] = {
28 [0] = {
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .flags = IORESOURCE_IRQ,
33 },
34};
35
36static struct platform_device smc91x_device = {
37 .name = "smc91x",
38 .id = -1,
39 .num_resources = ARRAY_SIZE(smc91x_resources),
40 .resource = smc91x_resources,
41};
42
43static struct resource led_resources[] = {
44 [0] = {
45 .flags = IORESOURCE_MEM,
46 },
47};
48
49static struct platform_device led_device = {
50 .name = "omap_dbg_led",
51 .id = -1,
52 .num_resources = ARRAY_SIZE(led_resources),
53 .resource = led_resources,
54};
55
56static struct platform_device *debug_devices[] __initdata = {
57 &smc91x_device,
58 &led_device,
59 /* ps2 kbd + mouse ports */
60 /* 4 extra uarts */
61 /* 6 input dip switches */
62 /* 8 output pins */
63};
64
65int __init debug_card_init(u32 addr, unsigned gpio)
66{
67 int status;
68
69 smc91x_resources[0].start = addr + 0x300;
70 smc91x_resources[0].end = addr + 0x30f;
71
72 smc91x_resources[1].start = OMAP_GPIO_IRQ(gpio);
73 smc91x_resources[1].end = OMAP_GPIO_IRQ(gpio);
74
75 status = omap_request_gpio(gpio);
76 if (status < 0) {
77 printk(KERN_ERR "GPIO%d unavailable for smc91x IRQ\n", gpio);
78 return status;
79 }
80 omap_set_gpio_direction(gpio, 1);
81
82 led_resources[0].start = addr;
83 led_resources[0].end = addr + SZ_4K - 1;
84
85 return platform_add_devices(debug_devices, ARRAY_SIZE(debug_devices));
86}
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 6d048490c55..992ca435a92 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1372,7 +1372,7 @@ int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
1372 return ret; 1372 return ret;
1373} 1373}
1374 1374
1375int s3c2410_dma_init(void) 1375int __init s3c2410_dma_init(void)
1376{ 1376{
1377 return s3c24xx_dma_init(4, IRQ_DMA0, 0x40); 1377 return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
1378} 1378}
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index d47113bbc34..a646cbe8244 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -96,6 +96,14 @@ resume_with_mmu:
96s3c2410_sleep_save_phys: 96s3c2410_sleep_save_phys:
97 .word 0 97 .word 0
98 98
99
100 /* sleep magic, to allow the bootloader to check for an valid
101 * image to resume to. Must be the first word before the
102 * s3c2410_cpu_resume entry.
103 */
104
105 .word 0x2bedf00d
106
99 /* s3c2410_cpu_resume 107 /* s3c2410_cpu_resume
100 * 108 *
101 * resume code entry for bootloader to call 109 * resume code entry for bootloader to call