aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/boot/compressed/.gitignore1
-rw-r--r--arch/arm/boot/compressed/Makefile13
-rw-r--r--arch/arm/boot/compressed/head-xscale.S5
-rw-r--r--arch/arm/boot/compressed/head.S93
-rw-r--r--arch/arm/common/sharpsl_pm.c2
-rw-r--r--arch/arm/kernel/head-common.S40
-rw-r--r--arch/arm/kernel/head.S7
-rw-r--r--arch/arm/kernel/process.c8
-rw-r--r--arch/arm/kernel/setup.c6
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c130
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c64
-rw-r--r--arch/arm/mach-davinci/Makefile3
-rw-r--r--arch/arm/mach-davinci/board-evm.c2
-rw-r--r--arch/arm/mach-davinci/clock.c323
-rw-r--r--arch/arm/mach-davinci/clock.h33
-rw-r--r--arch/arm/mach-davinci/gpio.c286
-rw-r--r--arch/arm/mach-davinci/io.c6
-rw-r--r--arch/arm/mach-davinci/mux.c41
-rw-r--r--arch/arm/mach-davinci/psc.c87
-rw-r--r--arch/arm/mach-imx/generic.c118
-rw-r--r--arch/arm/mach-imx/time.c121
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig16
-rw-r--r--arch/arm/mach-ixp4xx/Makefile4
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c108
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c8
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c96
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c109
-rw-r--r--arch/arm/mach-ks8695/Makefile2
-rw-r--r--arch/arm/mach-ks8695/gpio.c218
-rw-r--r--arch/arm/mach-pxa/clock.c15
-rw-r--r--arch/arm/mach-pxa/corgi.c7
-rw-r--r--arch/arm/mach-pxa/devices.h11
-rw-r--r--arch/arm/mach-pxa/dma.c44
-rw-r--r--arch/arm/mach-pxa/generic.c93
-rw-r--r--arch/arm/mach-pxa/generic.h6
-rw-r--r--arch/arm/mach-pxa/idp.c3
-rw-r--r--arch/arm/mach-pxa/irq.c106
-rw-r--r--arch/arm/mach-pxa/lpd270.c3
-rw-r--r--arch/arm/mach-pxa/lubbock.c3
-rw-r--r--arch/arm/mach-pxa/mainstone.c3
-rw-r--r--arch/arm/mach-pxa/pm.c47
-rw-r--r--arch/arm/mach-pxa/poodle.c3
-rw-r--r--arch/arm/mach-pxa/pxa25x.c62
-rw-r--r--arch/arm/mach-pxa/pxa27x.c78
-rw-r--r--arch/arm/mach-pxa/spitz.c7
-rw-r--r--arch/arm/mach-pxa/time.c9
-rw-r--r--arch/arm/mach-pxa/tosa.c4
-rw-r--r--arch/arm/mach-pxa/trizeps4.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c59
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c141
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c38
-rw-r--r--arch/arm/mach-sa1100/pm.c9
-rw-r--r--arch/arm/mach-sa1100/time.c24
-rw-r--r--arch/arm/mm/ioremap.c10
57 files changed, 2503 insertions, 366 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50d9f3e4e0f1..a0fa1ce9ad6c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -241,6 +241,9 @@ config ARCH_H720X
241 241
242config ARCH_IMX 242config ARCH_IMX
243 bool "IMX" 243 bool "IMX"
244 select GENERIC_GPIO
245 select GENERIC_TIME
246 select GENERIC_CLOCKEVENTS
244 help 247 help
245 Support for Motorola's i.MX family of processors (MX1, MXL). 248 Support for Motorola's i.MX family of processors (MX1, MXL).
246 249
@@ -308,6 +311,7 @@ config ARCH_L7200
308 311
309config ARCH_KS8695 312config ARCH_KS8695
310 bool "Micrel/Kendin KS8695" 313 bool "Micrel/Kendin KS8695"
314 select GENERIC_GPIO
311 help 315 help
312 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based 316 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
313 System-on-Chip devices. 317 System-on-Chip devices.
@@ -384,6 +388,7 @@ config ARCH_DAVINCI
384 bool "TI DaVinci" 388 bool "TI DaVinci"
385 select GENERIC_TIME 389 select GENERIC_TIME
386 select GENERIC_CLOCKEVENTS 390 select GENERIC_CLOCKEVENTS
391 select GENERIC_GPIO
387 help 392 help
388 Support for TI's DaVinci platform. 393 Support for TI's DaVinci platform.
389 394
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index aefee20cbf98..b15f927a5926 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1 +1,2 @@
1piggy.gz 1piggy.gz
2font.c
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index adddc7131685..a1f1691b67fe 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -6,15 +6,13 @@
6 6
7HEAD = head.o 7HEAD = head.o
8OBJS = misc.o 8OBJS = misc.o
9FONTC = drivers/video/console/font_acorn_8x8.c 9FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
10
11FONT = $(addprefix ../../../../drivers/video/console/, font_acorn_8x8.o)
12 10
13# 11#
14# Architecture dependencies 12# Architecture dependencies
15# 13#
16ifeq ($(CONFIG_ARCH_ACORN),y) 14ifeq ($(CONFIG_ARCH_ACORN),y)
17OBJS += ll_char_wr.o $(FONT) 15OBJS += ll_char_wr.o font.o
18endif 16endif
19 17
20ifeq ($(CONFIG_ARCH_SHARK),y) 18ifeq ($(CONFIG_ARCH_SHARK),y)
@@ -73,7 +71,7 @@ endif
73 71
74SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ 72SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
75 73
76targets := vmlinux vmlinux.lds piggy.gz piggy.o $(FONT) \ 74targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
77 head.o misc.o $(OBJS) 75 head.o misc.o $(OBJS)
78EXTRA_CFLAGS := -fpic 76EXTRA_CFLAGS := -fpic
79EXTRA_AFLAGS := 77EXTRA_AFLAGS :=
@@ -105,7 +103,10 @@ $(obj)/piggy.gz: $(obj)/../Image FORCE
105 103
106$(obj)/piggy.o: $(obj)/piggy.gz FORCE 104$(obj)/piggy.o: $(obj)/piggy.gz FORCE
107 105
108CFLAGS_font_acorn_8x8.o := -Dstatic= 106CFLAGS_font.o := -Dstatic=
107
108$(obj)/font.c: $(FONTC)
109 $(call cmd,shipped)
109 110
110$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config 111$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
111 @sed "$(SEDFLAGS)" < $< > $@ 112 @sed "$(SEDFLAGS)" < $< > $@
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 73c5d9e0201c..236bbe578312 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -41,11 +41,6 @@ __XScale_start:
41 mov r7, #MACH_TYPE_COTULLA_IDP 41 mov r7, #MACH_TYPE_COTULLA_IDP
42#endif 42#endif
43 43
44#ifdef CONFIG_MACH_GTWX5715
45 mov r7, #(MACH_TYPE_GTWX5715 & 0xff)
46 orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
47#endif
48
49#ifdef CONFIG_ARCH_IXP2000 44#ifdef CONFIG_ARCH_IXP2000
50 mov r1, #-1 45 mov r1, #-1
51 mov r0, #0xd6000000 46 mov r0, #0xd6000000
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 680ea6ed77b8..d7fb5ee1637e 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -436,6 +436,28 @@ __armv4_mmu_cache_on:
436 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 436 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
437 mov pc, r12 437 mov pc, r12
438 438
439__armv7_mmu_cache_on:
440 mov r12, lr
441 mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
442 tst r11, #0xf @ VMSA
443 blne __setup_mmu
444 mov r0, #0
445 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
446 tst r11, #0xf @ VMSA
447 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
448 mrc p15, 0, r0, c1, c0, 0 @ read control reg
449 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
450 orr r0, r0, #0x003c @ write buffer
451 orrne r0, r0, #1 @ MMU enabled
452 movne r1, #-1
453 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
454 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
455 mcr p15, 0, r0, c1, c0, 0 @ load control register
456 mrc p15, 0, r0, c1, c0, 0 @ and read it back
457 mov r0, #0
458 mcr p15, 0, r0, c7, c5, 4 @ ISB
459 mov pc, r12
460
439__arm6_mmu_cache_on: 461__arm6_mmu_cache_on:
440 mov r12, lr 462 mov r12, lr
441 bl __setup_mmu 463 bl __setup_mmu
@@ -622,11 +644,17 @@ proc_types:
622 b __armv4_mmu_cache_flush 644 b __armv4_mmu_cache_flush
623 645
624 .word 0x0007b000 @ ARMv6 646 .word 0x0007b000 @ ARMv6
625 .word 0x0007f000 647 .word 0x000ff000
626 b __armv4_mmu_cache_on 648 b __armv4_mmu_cache_on
627 b __armv4_mmu_cache_off 649 b __armv4_mmu_cache_off
628 b __armv6_mmu_cache_flush 650 b __armv6_mmu_cache_flush
629 651
652 .word 0x000f0000 @ new CPU Id
653 .word 0x000f0000
654 b __armv7_mmu_cache_on
655 b __armv7_mmu_cache_off
656 b __armv7_mmu_cache_flush
657
630 .word 0 @ unrecognised type 658 .word 0 @ unrecognised type
631 .word 0 659 .word 0
632 mov pc, lr 660 mov pc, lr
@@ -674,6 +702,16 @@ __armv4_mmu_cache_off:
674 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 702 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
675 mov pc, lr 703 mov pc, lr
676 704
705__armv7_mmu_cache_off:
706 mrc p15, 0, r0, c1, c0
707 bic r0, r0, #0x000d
708 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
709 mov r12, lr
710 bl __armv7_mmu_cache_flush
711 mov r0, #0
712 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
713 mov pc, r12
714
677__arm6_mmu_cache_off: 715__arm6_mmu_cache_off:
678 mov r0, #0x00000030 @ ARM6 control reg. 716 mov r0, #0x00000030 @ ARM6 control reg.
679 b __armv3_mmu_cache_off 717 b __armv3_mmu_cache_off
@@ -730,6 +768,59 @@ __armv6_mmu_cache_flush:
730 mcr p15, 0, r1, c7, c10, 4 @ drain WB 768 mcr p15, 0, r1, c7, c10, 4 @ drain WB
731 mov pc, lr 769 mov pc, lr
732 770
771__armv7_mmu_cache_flush:
772 mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
773 tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
774 beq hierarchical
775 mov r10, #0
776 mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D
777 b iflush
778hierarchical:
779 stmfd sp!, {r0-r5, r7, r9-r11}
780 mrc p15, 1, r0, c0, c0, 1 @ read clidr
781 ands r3, r0, #0x7000000 @ extract loc from clidr
782 mov r3, r3, lsr #23 @ left align loc bit field
783 beq finished @ if loc is 0, then no need to clean
784 mov r10, #0 @ start clean at cache level 0
785loop1:
786 add r2, r10, r10, lsr #1 @ work out 3x current cache level
787 mov r1, r0, lsr r2 @ extract cache type bits from clidr
788 and r1, r1, #7 @ mask of the bits for current cache only
789 cmp r1, #2 @ see what cache we have at this level
790 blt skip @ skip if no cache, or just i-cache
791 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
792 mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr
793 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
794 and r2, r1, #7 @ extract the length of the cache lines
795 add r2, r2, #4 @ add 4 (line length offset)
796 ldr r4, =0x3ff
797 ands r4, r4, r1, lsr #3 @ find maximum number on the way size
798 .word 0xe16f5f14 @ clz r5, r4 - find bit position of way size increment
799 ldr r7, =0x7fff
800 ands r7, r7, r1, lsr #13 @ extract max number of the index size
801loop2:
802 mov r9, r4 @ create working copy of max way size
803loop3:
804 orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
805 orr r11, r11, r7, lsl r2 @ factor index number into r11
806 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
807 subs r9, r9, #1 @ decrement the way
808 bge loop3
809 subs r7, r7, #1 @ decrement the index
810 bge loop2
811skip:
812 add r10, r10, #2 @ increment cache number
813 cmp r3, r10
814 bgt loop1
815finished:
816 mov r10, #0 @ swith back to cache level 0
817 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
818 ldmfd sp!, {r0-r5, r7, r9-r11}
819iflush:
820 mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB
821 mcr p15, 0, r10, c7, c10, 4 @ drain WB
822 mov pc, lr
823
733__armv4_mmu_cache_flush: 824__armv4_mmu_cache_flush:
734 mov r2, #64*1024 @ default: 32K dcache size (*2) 825 mov r2, #64*1024 @ default: 32K dcache size (*2)
735 mov r11, #32 @ default: 32 byte line size 826 mov r11, #32 @ default: 32 byte line size
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 3bf3a927ae22..111a7fa5debe 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -766,9 +766,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
766} 766}
767 767
768static struct pm_ops sharpsl_pm_ops = { 768static struct pm_ops sharpsl_pm_ops = {
769 .prepare = pxa_pm_prepare,
770 .enter = corgi_pxa_pm_enter, 769 .enter = corgi_pxa_pm_enter,
771 .finish = pxa_pm_finish,
772 .valid = pm_valid_only_mem, 770 .valid = pm_valid_only_mem,
773}; 771};
774 772
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index a52da0ddb43d..024a9cf469b4 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -20,7 +20,8 @@ __switch_data:
20 .long _end @ r7 20 .long _end @ r7
21 .long processor_id @ r4 21 .long processor_id @ r4
22 .long __machine_arch_type @ r5 22 .long __machine_arch_type @ r5
23 .long cr_alignment @ r6 23 .long __atags_pointer @ r6
24 .long cr_alignment @ r7
24 .long init_thread_union + THREAD_START_SP @ sp 25 .long init_thread_union + THREAD_START_SP @ sp
25 26
26/* 27/*
@@ -29,6 +30,7 @@ __switch_data:
29 * 30 *
30 * r0 = cp#15 control register 31 * r0 = cp#15 control register
31 * r1 = machine ID 32 * r1 = machine ID
33 * r2 = atags pointer
32 * r9 = processor ID 34 * r9 = processor ID
33 */ 35 */
34 .type __mmap_switched, %function 36 .type __mmap_switched, %function
@@ -47,11 +49,12 @@ __mmap_switched:
47 strcc fp, [r6],#4 49 strcc fp, [r6],#4
48 bcc 1b 50 bcc 1b
49 51
50 ldmia r3, {r4, r5, r6, sp} 52 ldmia r3, {r4, r5, r6, r7, sp}
51 str r9, [r4] @ Save processor ID 53 str r9, [r4] @ Save processor ID
52 str r1, [r5] @ Save machine type 54 str r1, [r5] @ Save machine type
55 str r2, [r6] @ Save atags pointer
53 bic r4, r0, #CR_A @ Clear 'A' bit 56 bic r4, r0, #CR_A @ Clear 'A' bit
54 stmia r6, {r0, r4} @ Save control register values 57 stmia r7, {r0, r4} @ Save control register values
55 b start_kernel 58 b start_kernel
56 59
57/* 60/*
@@ -215,3 +218,34 @@ ENTRY(lookup_machine_type)
215 bl __lookup_machine_type 218 bl __lookup_machine_type
216 mov r0, r5 219 mov r0, r5
217 ldmfd sp!, {r4 - r6, pc} 220 ldmfd sp!, {r4 - r6, pc}
221
222/* Determine validity of the r2 atags pointer. The heuristic requires
223 * that the pointer be aligned, in the first 16k of physical RAM and
224 * that the ATAG_CORE marker is first and present. Future revisions
225 * of this function may be more lenient with the physical address and
226 * may also be able to move the ATAGS block if necessary.
227 *
228 * r8 = machinfo
229 *
230 * Returns:
231 * r2 either valid atags pointer, or zero
232 * r5, r6 corrupted
233 */
234
235 .type __vet_atags, %function
236__vet_atags:
237 tst r2, #0x3 @ aligned?
238 bne 1f
239
240 ldr r5, [r2, #0] @ is first tag ATAG_CORE?
241 subs r5, r5, #ATAG_CORE_SIZE
242 bne 1f
243 ldr r5, [r2, #4]
244 ldr r6, =ATAG_CORE
245 cmp r5, r6
246 bne 1f
247
248 mov pc, lr @ atag pointer is ok
249
2501: mov r2, #0
251 mov pc, lr
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 41f98b4ba2ee..7898cbc9861a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -29,6 +29,10 @@
29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) 29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
30#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) 30#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
31 31
32#define ATAG_CORE 0x54410001
33#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
34
35
32/* 36/*
33 * swapper_pg_dir is the virtual address of the initial page table. 37 * swapper_pg_dir is the virtual address of the initial page table.
34 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must 38 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
@@ -61,7 +65,7 @@
61 * 65 *
62 * This is normally called from the decompressor code. The requirements 66 * This is normally called from the decompressor code. The requirements
63 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 67 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
64 * r1 = machine nr. 68 * r1 = machine nr, r2 = atags pointer.
65 * 69 *
66 * This code is mostly position independent, so if you link the kernel at 70 * This code is mostly position independent, so if you link the kernel at
67 * 0xc0008000, you call this at __pa(0xc0008000). 71 * 0xc0008000, you call this at __pa(0xc0008000).
@@ -85,6 +89,7 @@ ENTRY(stext)
85 bl __lookup_machine_type @ r5=machinfo 89 bl __lookup_machine_type @ r5=machinfo
86 movs r8, r5 @ invalid machine (r5=0)? 90 movs r8, r5 @ invalid machine (r5=0)?
87 beq __error_a @ yes, error 'a' 91 beq __error_a @ yes, error 'a'
92 bl __vet_atags
88 bl __create_page_tables 93 bl __create_page_tables
89 94
90 /* 95 /*
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 842361777d4e..93b7f8e22dcc 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -44,6 +44,10 @@ static const char *processor_modes[] = {
44 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" 44 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
45}; 45};
46 46
47static const char *isa_modes[] = {
48 "ARM" , "Thumb" , "Jazelle", "ThumbEE"
49};
50
47extern void setup_mm_for_reboot(char mode); 51extern void setup_mm_for_reboot(char mode);
48 52
49static volatile int hlt_counter; 53static volatile int hlt_counter;
@@ -230,11 +234,11 @@ void __show_regs(struct pt_regs *regs)
230 buf[3] = flags & PSR_V_BIT ? 'V' : 'v'; 234 buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
231 buf[4] = '\0'; 235 buf[4] = '\0';
232 236
233 printk("Flags: %s IRQs o%s FIQs o%s Mode %s%s Segment %s\n", 237 printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n",
234 buf, interrupts_enabled(regs) ? "n" : "ff", 238 buf, interrupts_enabled(regs) ? "n" : "ff",
235 fast_interrupts_enabled(regs) ? "n" : "ff", 239 fast_interrupts_enabled(regs) ? "n" : "ff",
236 processor_modes[processor_mode(regs)], 240 processor_modes[processor_mode(regs)],
237 thumb_mode(regs) ? " (T)" : "", 241 isa_modes[isa_mode(regs)],
238 get_fs() == get_ds() ? "kernel" : "user"); 242 get_fs() == get_ds() ? "kernel" : "user");
239#ifdef CONFIG_CPU_CP15 243#ifdef CONFIG_CPU_CP15
240 { 244 {
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 650eac1bc0a6..5be2e987b843 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -63,6 +63,8 @@ unsigned int processor_id;
63unsigned int __machine_arch_type; 63unsigned int __machine_arch_type;
64EXPORT_SYMBOL(__machine_arch_type); 64EXPORT_SYMBOL(__machine_arch_type);
65 65
66unsigned int __atags_pointer __initdata;
67
66unsigned int system_rev; 68unsigned int system_rev;
67EXPORT_SYMBOL(system_rev); 69EXPORT_SYMBOL(system_rev);
68 70
@@ -780,7 +782,9 @@ void __init setup_arch(char **cmdline_p)
780 if (mdesc->soft_reboot) 782 if (mdesc->soft_reboot)
781 reboot_setup("s"); 783 reboot_setup("s");
782 784
783 if (mdesc->boot_params) 785 if (__atags_pointer)
786 tags = phys_to_virt(__atags_pointer);
787 else if (mdesc->boot_params)
784 tags = phys_to_virt(mdesc->boot_params); 788 tags = phys_to_virt(mdesc->boot_params);
785 789
786 /* 790 /*
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 26ca8ab3f62a..42e172cb0f49 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -27,6 +27,11 @@
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <linux/dm9000.h> 29#include <linux/dm9000.h>
30#include <linux/fb.h>
31#include <linux/gpio_keys.h>
32#include <linux/input.h>
33
34#include <video/atmel_lcdc.h>
30 35
31#include <asm/hardware.h> 36#include <asm/hardware.h>
32#include <asm/setup.h> 37#include <asm/setup.h>
@@ -271,6 +276,127 @@ static struct spi_board_info ek_spi_devices[] = {
271}; 276};
272 277
273 278
279/*
280 * LCD Controller
281 */
282#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
283static struct fb_videomode at91_tft_vga_modes[] = {
284 {
285 .name = "TX09D50VM1CCA @ 60",
286 .refresh = 60,
287 .xres = 240, .yres = 320,
288 .pixclock = KHZ2PICOS(4965),
289
290 .left_margin = 1, .right_margin = 33,
291 .upper_margin = 1, .lower_margin = 0,
292 .hsync_len = 5, .vsync_len = 1,
293
294 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
295 .vmode = FB_VMODE_NONINTERLACED,
296 },
297};
298
299static struct fb_monspecs at91fb_default_monspecs = {
300 .manufacturer = "HIT",
301 .monitor = "TX09D50VM1CCA",
302
303 .modedb = at91_tft_vga_modes,
304 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
305 .hfmin = 15000,
306 .hfmax = 64000,
307 .vfmin = 50,
308 .vfmax = 150,
309};
310
311#define AT91SAM9261_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
312 | ATMEL_LCDC_DISTYPE_TFT \
313 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
314
315static void at91_lcdc_power_control(int on)
316{
317 if (on)
318 at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */
319 else
320 at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */
321}
322
323/* Driver datas */
324static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
325 .default_bpp = 16,
326 .default_dmacon = ATMEL_LCDC_DMAEN,
327 .default_lcdcon2 = AT91SAM9261_DEFAULT_LCDCON2,
328 .default_monspecs = &at91fb_default_monspecs,
329 .atmel_lcdfb_power_control = at91_lcdc_power_control,
330 .guard_time = 1,
331};
332
333#else
334static struct atmel_lcdfb_info __initdata ek_lcdc_data;
335#endif
336
337
338/*
339 * GPIO Buttons
340 */
341#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
342static struct gpio_keys_button ek_buttons[] = {
343 {
344 .gpio = AT91_PIN_PA27,
345 .keycode = BTN_0,
346 .desc = "Button 0",
347 .active_low = 1,
348 },
349 {
350 .gpio = AT91_PIN_PA26,
351 .keycode = BTN_1,
352 .desc = "Button 1",
353 .active_low = 1,
354 },
355 {
356 .gpio = AT91_PIN_PA25,
357 .keycode = BTN_2,
358 .desc = "Button 2",
359 .active_low = 1,
360 },
361 {
362 .gpio = AT91_PIN_PA24,
363 .keycode = BTN_3,
364 .desc = "Button 3",
365 .active_low = 1,
366 }
367};
368
369static struct gpio_keys_platform_data ek_button_data = {
370 .buttons = ek_buttons,
371 .nbuttons = ARRAY_SIZE(ek_buttons),
372};
373
374static struct platform_device ek_button_device = {
375 .name = "gpio-keys",
376 .id = -1,
377 .num_resources = 0,
378 .dev = {
379 .platform_data = &ek_button_data,
380 }
381};
382
383static void __init ek_add_device_buttons(void)
384{
385 at91_set_gpio_input(AT91_PIN_PB27, 0); /* btn0 */
386 at91_set_deglitch(AT91_PIN_PB27, 1);
387 at91_set_gpio_input(AT91_PIN_PB26, 0); /* btn1 */
388 at91_set_deglitch(AT91_PIN_PB26, 1);
389 at91_set_gpio_input(AT91_PIN_PB25, 0); /* btn2 */
390 at91_set_deglitch(AT91_PIN_PB25, 1);
391 at91_set_gpio_input(AT91_PIN_PB24, 0); /* btn3 */
392 at91_set_deglitch(AT91_PIN_PB24, 1);
393
394 platform_device_register(&ek_button_device);
395}
396#else
397static void __init ek_add_device_buttons(void) {}
398#endif
399
274static void __init ek_board_init(void) 400static void __init ek_board_init(void)
275{ 401{
276 /* Serial */ 402 /* Serial */
@@ -296,6 +422,10 @@ static void __init ek_board_init(void)
296 /* MMC */ 422 /* MMC */
297 at91_add_device_mmc(0, &ek_mmc_data); 423 at91_add_device_mmc(0, &ek_mmc_data);
298#endif 424#endif
425 /* LCD Controller */
426 at91_add_device_lcdc(&ek_lcdc_data);
427 /* Push Buttons */
428 ek_add_device_buttons();
299} 429}
300 430
301MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") 431MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index c164c8e58ae6..2a1cc73390b7 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -26,6 +26,9 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <linux/fb.h>
30
31#include <video/atmel_lcdc.h>
29 32
30#include <asm/hardware.h> 33#include <asm/hardware.h>
31#include <asm/setup.h> 34#include <asm/setup.h>
@@ -202,6 +205,65 @@ static struct at91_nand_data __initdata ek_nand_data = {
202 205
203 206
204/* 207/*
208 * LCD Controller
209 */
210#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
211static struct fb_videomode at91_tft_vga_modes[] = {
212 {
213 .name = "TX09D50VM1CCA @ 60",
214 .refresh = 60,
215 .xres = 240, .yres = 320,
216 .pixclock = KHZ2PICOS(4965),
217
218 .left_margin = 1, .right_margin = 33,
219 .upper_margin = 1, .lower_margin = 0,
220 .hsync_len = 5, .vsync_len = 1,
221
222 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
223 .vmode = FB_VMODE_NONINTERLACED,
224 },
225};
226
227static struct fb_monspecs at91fb_default_monspecs = {
228 .manufacturer = "HIT",
229 .monitor = "TX09D70VM1CCA",
230
231 .modedb = at91_tft_vga_modes,
232 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
233 .hfmin = 15000,
234 .hfmax = 64000,
235 .vfmin = 50,
236 .vfmax = 150,
237};
238
239#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
240 | ATMEL_LCDC_DISTYPE_TFT \
241 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
242
243static void at91_lcdc_power_control(int on)
244{
245 if (on)
246 at91_set_gpio_value(AT91_PIN_PD12, 0); /* power up */
247 else
248 at91_set_gpio_value(AT91_PIN_PD12, 1); /* power down */
249}
250
251/* Driver datas */
252static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
253 .default_bpp = 16,
254 .default_dmacon = ATMEL_LCDC_DMAEN,
255 .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
256 .default_monspecs = &at91fb_default_monspecs,
257 .atmel_lcdfb_power_control = at91_lcdc_power_control,
258 .guard_time = 1,
259};
260
261#else
262static struct atmel_lcdfb_info __initdata ek_lcdc_data;
263#endif
264
265
266/*
205 * AC97 267 * AC97
206 */ 268 */
207static struct atmel_ac97_data ek_ac97_data = { 269static struct atmel_ac97_data ek_ac97_data = {
@@ -230,6 +292,8 @@ static void __init ek_board_init(void)
230 at91_add_device_nand(&ek_nand_data); 292 at91_add_device_nand(&ek_nand_data);
231 /* I2C */ 293 /* I2C */
232 at91_add_device_i2c(); 294 at91_add_device_i2c();
295 /* LCD Controller */
296 at91_add_device_lcdc(&ek_lcdc_data);
233 /* AC97 */ 297 /* AC97 */
234 at91_add_device_ac97(&ek_ac97_data); 298 at91_add_device_ac97(&ek_ac97_data);
235} 299}
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index a8f88cd29905..99ac2e55774d 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,7 +4,8 @@
4# 4#
5 5
6# Common objects 6# Common objects
7obj-y := time.o irq.o serial.o io.o id.o psc.o 7obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
8 gpio.o mux.o
8 9
9# Board specific 10# Board specific
10obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o 11obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c
index 633c12e43044..9e4024c4965f 100644
--- a/arch/arm/mach-davinci/board-evm.c
+++ b/arch/arm/mach-davinci/board-evm.c
@@ -32,6 +32,7 @@
32void __init davinci_psc_init(void); 32void __init davinci_psc_init(void);
33void __init davinci_irq_init(void); 33void __init davinci_irq_init(void);
34void __init davinci_map_common_io(void); 34void __init davinci_map_common_io(void);
35void __init davinci_init_common_hw(void);
35 36
36/* NOR Flash base address set to CS0 by default */ 37/* NOR Flash base address set to CS0 by default */
37#define NOR_FLASH_PHYS 0x02000000 38#define NOR_FLASH_PHYS 0x02000000
@@ -116,6 +117,7 @@ static __init void davinci_evm_init(void)
116 117
117static __init void davinci_evm_irq_init(void) 118static __init void davinci_evm_irq_init(void)
118{ 119{
120 davinci_init_common_hw();
119 davinci_irq_init(); 121 davinci_irq_init();
120} 122}
121 123
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644
index 000000000000..139ceaa35e24
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,323 @@
1/*
2 * TI DaVinci clock config file
3 *
4 * Copyright (C) 2006 Texas Instruments.
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
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/mutex.h>
18#include <linux/platform_device.h>
19
20#include <asm/hardware.h>
21#include <asm/io.h>
22
23#include <asm/arch/psc.h>
24#include "clock.h"
25
26/* PLL/Reset register offsets */
27#define PLLM 0x110
28
29static LIST_HEAD(clocks);
30static DEFINE_MUTEX(clocks_mutex);
31static DEFINE_SPINLOCK(clockfw_lock);
32
33static unsigned int commonrate;
34static unsigned int armrate;
35static unsigned int fixedrate = 27000000; /* 27 MHZ */
36
37extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
38
39/*
40 * Returns a clock. Note that we first try to use device id on the bus
41 * and clock name. If this fails, we try to use clock name only.
42 */
43struct clk *clk_get(struct device *dev, const char *id)
44{
45 struct clk *p, *clk = ERR_PTR(-ENOENT);
46 int idno;
47
48 if (dev == NULL || dev->bus != &platform_bus_type)
49 idno = -1;
50 else
51 idno = to_platform_device(dev)->id;
52
53 mutex_lock(&clocks_mutex);
54
55 list_for_each_entry(p, &clocks, node) {
56 if (p->id == idno &&
57 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
58 clk = p;
59 goto found;
60 }
61 }
62
63 list_for_each_entry(p, &clocks, node) {
64 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
65 clk = p;
66 break;
67 }
68 }
69
70found:
71 mutex_unlock(&clocks_mutex);
72
73 return clk;
74}
75EXPORT_SYMBOL(clk_get);
76
77void clk_put(struct clk *clk)
78{
79 if (clk && !IS_ERR(clk))
80 module_put(clk->owner);
81}
82EXPORT_SYMBOL(clk_put);
83
84static int __clk_enable(struct clk *clk)
85{
86 if (clk->flags & ALWAYS_ENABLED)
87 return 0;
88
89 davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
90 return 0;
91}
92
93static void __clk_disable(struct clk *clk)
94{
95 if (clk->usecount)
96 return;
97
98 davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
99}
100
101int clk_enable(struct clk *clk)
102{
103 unsigned long flags;
104 int ret = 0;
105
106 if (clk == NULL || IS_ERR(clk))
107 return -EINVAL;
108
109 if (clk->usecount++ == 0) {
110 spin_lock_irqsave(&clockfw_lock, flags);
111 ret = __clk_enable(clk);
112 spin_unlock_irqrestore(&clockfw_lock, flags);
113 }
114
115 return ret;
116}
117EXPORT_SYMBOL(clk_enable);
118
119void clk_disable(struct clk *clk)
120{
121 unsigned long flags;
122
123 if (clk == NULL || IS_ERR(clk))
124 return;
125
126 if (clk->usecount > 0 && !(--clk->usecount)) {
127 spin_lock_irqsave(&clockfw_lock, flags);
128 __clk_disable(clk);
129 spin_unlock_irqrestore(&clockfw_lock, flags);
130 }
131}
132EXPORT_SYMBOL(clk_disable);
133
134unsigned long clk_get_rate(struct clk *clk)
135{
136 if (clk == NULL || IS_ERR(clk))
137 return -EINVAL;
138
139 return *(clk->rate);
140}
141EXPORT_SYMBOL(clk_get_rate);
142
143long clk_round_rate(struct clk *clk, unsigned long rate)
144{
145 if (clk == NULL || IS_ERR(clk))
146 return -EINVAL;
147
148 return *(clk->rate);
149}
150EXPORT_SYMBOL(clk_round_rate);
151
152int clk_set_rate(struct clk *clk, unsigned long rate)
153{
154 if (clk == NULL || IS_ERR(clk))
155 return -EINVAL;
156
157 /* changing the clk rate is not supported */
158 return -EINVAL;
159}
160EXPORT_SYMBOL(clk_set_rate);
161
162int clk_register(struct clk *clk)
163{
164 if (clk == NULL || IS_ERR(clk))
165 return -EINVAL;
166
167 mutex_lock(&clocks_mutex);
168 list_add(&clk->node, &clocks);
169 mutex_unlock(&clocks_mutex);
170
171 return 0;
172}
173EXPORT_SYMBOL(clk_register);
174
175void clk_unregister(struct clk *clk)
176{
177 if (clk == NULL || IS_ERR(clk))
178 return;
179
180 mutex_lock(&clocks_mutex);
181 list_del(&clk->node);
182 mutex_unlock(&clocks_mutex);
183}
184EXPORT_SYMBOL(clk_unregister);
185
186static struct clk davinci_clks[] = {
187 {
188 .name = "ARMCLK",
189 .rate = &armrate,
190 .lpsc = -1,
191 .flags = ALWAYS_ENABLED,
192 },
193 {
194 .name = "UART",
195 .rate = &fixedrate,
196 .lpsc = DAVINCI_LPSC_UART0,
197 },
198 {
199 .name = "EMACCLK",
200 .rate = &commonrate,
201 .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
202 },
203 {
204 .name = "I2CCLK",
205 .rate = &fixedrate,
206 .lpsc = DAVINCI_LPSC_I2C,
207 },
208 {
209 .name = "IDECLK",
210 .rate = &commonrate,
211 .lpsc = DAVINCI_LPSC_ATA,
212 },
213 {
214 .name = "McBSPCLK",
215 .rate = &commonrate,
216 .lpsc = DAVINCI_LPSC_McBSP,
217 },
218 {
219 .name = "MMCSDCLK",
220 .rate = &commonrate,
221 .lpsc = DAVINCI_LPSC_MMC_SD,
222 },
223 {
224 .name = "SPICLK",
225 .rate = &commonrate,
226 .lpsc = DAVINCI_LPSC_SPI,
227 },
228 {
229 .name = "gpio",
230 .rate = &commonrate,
231 .lpsc = DAVINCI_LPSC_GPIO,
232 },
233 {
234 .name = "AEMIFCLK",
235 .rate = &commonrate,
236 .lpsc = DAVINCI_LPSC_AEMIF,
237 .usecount = 1,
238 }
239};
240
241int __init davinci_clk_init(void)
242{
243 struct clk *clkp;
244 int count = 0;
245 u32 pll_mult;
246
247 pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
248 commonrate = ((pll_mult + 1) * 27000000) / 6;
249 armrate = ((pll_mult + 1) * 27000000) / 2;
250
251 for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
252 count++, clkp++) {
253 clk_register(clkp);
254
255 /* Turn on clocks that have been enabled in the
256 * table above */
257 if (clkp->usecount)
258 clk_enable(clkp);
259 }
260
261 return 0;
262}
263
264#ifdef CONFIG_PROC_FS
265#include <linux/proc_fs.h>
266#include <linux/seq_file.h>
267
268static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
269{
270 return *pos < 1 ? (void *)1 : NULL;
271}
272
273static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
274{
275 ++*pos;
276 return NULL;
277}
278
279static void davinci_ck_stop(struct seq_file *m, void *v)
280{
281}
282
283static int davinci_ck_show(struct seq_file *m, void *v)
284{
285 struct clk *cp;
286
287 list_for_each_entry(cp, &clocks, node)
288 seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
289
290 return 0;
291}
292
293static struct seq_operations davinci_ck_op = {
294 .start = davinci_ck_start,
295 .next = davinci_ck_next,
296 .stop = davinci_ck_stop,
297 .show = davinci_ck_show
298};
299
300static int davinci_ck_open(struct inode *inode, struct file *file)
301{
302 return seq_open(file, &davinci_ck_op);
303}
304
305static struct file_operations proc_davinci_ck_operations = {
306 .open = davinci_ck_open,
307 .read = seq_read,
308 .llseek = seq_lseek,
309 .release = seq_release,
310};
311
312static int __init davinci_ck_proc_init(void)
313{
314 struct proc_dir_entry *entry;
315
316 entry = create_proc_entry("davinci_clocks", 0, NULL);
317 if (entry)
318 entry->proc_fops = &proc_davinci_ck_operations;
319 return 0;
320
321}
322__initcall(davinci_ck_proc_init);
323#endif /* CONFIG_DEBUG_PROC_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
new file mode 100644
index 000000000000..ed47079a52e4
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,33 @@
1/*
2 * TI DaVinci clock definitions
3 *
4 * Copyright (C) 2006 Texas Instruments.
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#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
12#define __ARCH_ARM_DAVINCI_CLOCK_H
13
14struct clk {
15 struct list_head node;
16 struct module *owner;
17 const char *name;
18 unsigned int *rate;
19 int id;
20 __s8 usecount;
21 __u8 flags;
22 __u8 lpsc;
23};
24
25/* Clock flags */
26#define RATE_CKCTL 1
27#define RATE_FIXED 2
28#define RATE_PROPAGATES 4
29#define VIRTUAL_CLOCK 8
30#define ALWAYS_ENABLED 16
31#define ENABLE_REG_32BIT 32
32
33#endif
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
new file mode 100644
index 000000000000..9c67886e7189
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio.c
@@ -0,0 +1,286 @@
1/*
2 * TI DaVinci GPIO Support
3 *
4 * Copyright (c) 2006 David Brownell
5 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
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/errno.h>
14#include <linux/kernel.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/clk.h>
18#include <linux/err.h>
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/bitops.h>
22
23#include <asm/arch/irqs.h>
24#include <asm/arch/hardware.h>
25#include <asm/arch/gpio.h>
26
27#include <asm/mach/irq.h>
28
29static DEFINE_SPINLOCK(gpio_lock);
30static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
31
32int gpio_request(unsigned gpio, const char *tag)
33{
34 if (gpio >= DAVINCI_N_GPIO)
35 return -EINVAL;
36
37 if (test_and_set_bit(gpio, gpio_in_use))
38 return -EBUSY;
39
40 return 0;
41}
42EXPORT_SYMBOL(gpio_request);
43
44void gpio_free(unsigned gpio)
45{
46 if (gpio >= DAVINCI_N_GPIO)
47 return;
48
49 clear_bit(gpio, gpio_in_use);
50}
51EXPORT_SYMBOL(gpio_free);
52
53/* create a non-inlined version */
54static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
55{
56 return __gpio_to_controller(gpio);
57}
58
59/*
60 * Assuming the pin is muxed as a gpio output, set its output value.
61 */
62void __gpio_set(unsigned gpio, int value)
63{
64 struct gpio_controller *__iomem g = gpio2controller(gpio);
65
66 __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
67}
68EXPORT_SYMBOL(__gpio_set);
69
70
71/*
72 * Read the pin's value (works even if it's set up as output);
73 * returns zero/nonzero.
74 *
75 * Note that changes are synched to the GPIO clock, so reading values back
76 * right after you've set them may give old values.
77 */
78int __gpio_get(unsigned gpio)
79{
80 struct gpio_controller *__iomem g = gpio2controller(gpio);
81
82 return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
83}
84EXPORT_SYMBOL(__gpio_get);
85
86
87/*--------------------------------------------------------------------------*/
88
89/*
90 * board setup code *MUST* set PINMUX0 and PINMUX1 as
91 * needed, and enable the GPIO clock.
92 */
93
94int gpio_direction_input(unsigned gpio)
95{
96 struct gpio_controller *__iomem g = gpio2controller(gpio);
97 u32 temp;
98 u32 mask;
99
100 if (!g)
101 return -EINVAL;
102
103 spin_lock(&gpio_lock);
104 mask = __gpio_mask(gpio);
105 temp = __raw_readl(&g->dir);
106 temp |= mask;
107 __raw_writel(temp, &g->dir);
108 spin_unlock(&gpio_lock);
109 return 0;
110}
111EXPORT_SYMBOL(gpio_direction_input);
112
113int gpio_direction_output(unsigned gpio, int value)
114{
115 struct gpio_controller *__iomem g = gpio2controller(gpio);
116 u32 temp;
117 u32 mask;
118
119 if (!g)
120 return -EINVAL;
121
122 spin_lock(&gpio_lock);
123 mask = __gpio_mask(gpio);
124 temp = __raw_readl(&g->dir);
125 temp &= ~mask;
126 __raw_writel(mask, value ? &g->set_data : &g->clr_data);
127 __raw_writel(temp, &g->dir);
128 spin_unlock(&gpio_lock);
129 return 0;
130}
131EXPORT_SYMBOL(gpio_direction_output);
132
133/*
134 * We expect irqs will normally be set up as input pins, but they can also be
135 * used as output pins ... which is convenient for testing.
136 *
137 * NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
138 * to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
139 * a good way to hook those up ...
140 *
141 * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
142 * serve as EDMA event triggers.
143 */
144
145static void gpio_irq_disable(unsigned irq)
146{
147 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
148 u32 mask = __gpio_mask(irq_to_gpio(irq));
149
150 __raw_writel(mask, &g->clr_falling);
151 __raw_writel(mask, &g->clr_rising);
152}
153
154static void gpio_irq_enable(unsigned irq)
155{
156 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
157 u32 mask = __gpio_mask(irq_to_gpio(irq));
158
159 if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
160 __raw_writel(mask, &g->set_falling);
161 if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
162 __raw_writel(mask, &g->set_rising);
163}
164
165static int gpio_irq_type(unsigned irq, unsigned trigger)
166{
167 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
168 u32 mask = __gpio_mask(irq_to_gpio(irq));
169
170 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
171 return -EINVAL;
172
173 irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
174 irq_desc[irq].status |= trigger;
175
176 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
177 ? &g->set_falling : &g->clr_falling);
178 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
179 ? &g->set_rising : &g->clr_rising);
180 return 0;
181}
182
183static struct irq_chip gpio_irqchip = {
184 .name = "GPIO",
185 .enable = gpio_irq_enable,
186 .disable = gpio_irq_disable,
187 .set_type = gpio_irq_type,
188};
189
190static void
191gpio_irq_handler(unsigned irq, struct irq_desc *desc)
192{
193 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
194 u32 mask = 0xffff;
195
196 /* we only care about one bank */
197 if (irq & 1)
198 mask <<= 16;
199
200 /* temporarily mask (level sensitive) parent IRQ */
201 desc->chip->ack(irq);
202 while (1) {
203 u32 status;
204 struct irq_desc *gpio;
205 int n;
206 int res;
207
208 /* ack any irqs */
209 status = __raw_readl(&g->intstat) & mask;
210 if (!status)
211 break;
212 __raw_writel(status, &g->intstat);
213 if (irq & 1)
214 status >>= 16;
215
216 /* now demux them to the right lowlevel handler */
217 n = (int)get_irq_data(irq);
218 gpio = &irq_desc[n];
219 while (status) {
220 res = ffs(status);
221 n += res;
222 gpio += res;
223 desc_handle_irq(n - 1, gpio - 1);
224 status >>= res;
225 }
226 }
227 desc->chip->unmask(irq);
228 /* now it may re-trigger */
229}
230
231/*
232 * NOTE: for suspend/resume, probably best to make a sysdev (and class)
233 * with its suspend/resume calls hooking into the results of the set_wake()
234 * calls ... so if no gpios are wakeup events the clock can be disabled,
235 * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
236 * can be set appropriately for GPIOV33 pins.
237 */
238
239static int __init davinci_gpio_irq_setup(void)
240{
241 unsigned gpio, irq, bank;
242 struct clk *clk;
243
244 clk = clk_get(NULL, "gpio");
245 if (IS_ERR(clk)) {
246 printk(KERN_ERR "Error %ld getting gpio clock?\n",
247 PTR_ERR(clk));
248 return 0;
249 }
250
251 clk_enable(clk);
252
253 for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
254 gpio < DAVINCI_N_GPIO; bank++) {
255 struct gpio_controller *__iomem g = gpio2controller(gpio);
256 unsigned i;
257
258 __raw_writel(~0, &g->clr_falling);
259 __raw_writel(~0, &g->clr_rising);
260
261 /* set up all irqs in this bank */
262 set_irq_chained_handler(bank, gpio_irq_handler);
263 set_irq_chip_data(bank, g);
264 set_irq_data(bank, (void *)irq);
265
266 for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
267 i++, irq++, gpio++) {
268 set_irq_chip(irq, &gpio_irqchip);
269 set_irq_chip_data(irq, g);
270 set_irq_handler(irq, handle_simple_irq);
271 set_irq_flags(irq, IRQF_VALID);
272 }
273 }
274
275 /* BINTEN -- per-bank interrupt enable. genirq would also let these
276 * bits be set/cleared dynamically.
277 */
278 __raw_writel(0x1f, (void *__iomem)
279 IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
280
281 printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
282
283 return 0;
284}
285
286arch_initcall(davinci_gpio_irq_setup);
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index 87fae6fb6ecf..47787ff84a6a 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -17,6 +17,7 @@
17#include <asm/memory.h> 17#include <asm/memory.h>
18 18
19#include <asm/mach/map.h> 19#include <asm/mach/map.h>
20#include <asm/arch/clock.h>
20 21
21extern void davinci_check_revision(void); 22extern void davinci_check_revision(void);
22 23
@@ -49,3 +50,8 @@ void __init davinci_map_common_io(void)
49 */ 50 */
50 davinci_check_revision(); 51 davinci_check_revision();
51} 52}
53
54void __init davinci_init_common_hw(void)
55{
56 davinci_clk_init();
57}
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644
index 000000000000..92d26bd305b7
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,41 @@
1/*
2 * DaVinci pin multiplexing configurations
3 *
4 * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
5 *
6 * 2007 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11#include <linux/io.h>
12#include <linux/spinlock.h>
13
14#include <asm/hardware.h>
15
16#include <asm/arch/mux.h>
17
18/* System control register offsets */
19#define PINMUX0 0x00
20#define PINMUX1 0x04
21
22static DEFINE_SPINLOCK(mux_lock);
23
24void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
25{
26 u32 pinmux, muxreg = PINMUX0;
27
28 if (mux >= DAVINCI_MUX_LEVEL2) {
29 muxreg = PINMUX1;
30 mux -= DAVINCI_MUX_LEVEL2;
31 }
32
33 spin_lock(&mux_lock);
34 pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
35 if (enable)
36 pinmux |= (1 << mux);
37 else
38 pinmux &= ~(1 << mux);
39 davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
40 spin_unlock(&mux_lock);
41}
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index e1b0050283a6..1334416559ad 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -25,39 +25,40 @@
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/hardware.h> 26#include <asm/hardware.h>
27#include <asm/arch/psc.h> 27#include <asm/arch/psc.h>
28#include <asm/arch/mux.h>
28 29
29#define PTCMD __REG(0x01C41120) 30/* PSC register offsets */
30#define PDSTAT __REG(0x01C41200) 31#define EPCPR 0x070
31#define PDCTL1 __REG(0x01C41304) 32#define PTCMD 0x120
32#define EPCPR __REG(0x01C41070) 33#define PTSTAT 0x128
33#define PTSTAT __REG(0x01C41128) 34#define PDSTAT 0x200
35#define PDCTL1 0x304
36#define MDSTAT 0x800
37#define MDCTL 0xA00
34 38
35#define MDSTAT IO_ADDRESS(0x01C41800) 39/* System control register offsets */
36#define MDCTL IO_ADDRESS(0x01C41A00) 40#define VDD3P3V_PWDN 0x48
37
38#define PINMUX0 __REG(0x01c40000)
39#define PINMUX1 __REG(0x01c40004)
40#define VDD3P3V_PWDN __REG(0x01C40048)
41 41
42static void davinci_psc_mux(unsigned int id) 42static void davinci_psc_mux(unsigned int id)
43{ 43{
44 switch (id) { 44 switch (id) {
45 case DAVINCI_LPSC_ATA: 45 case DAVINCI_LPSC_ATA:
46 PINMUX0 |= (1 << 17) | (1 << 16); 46 davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
47 davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
47 break; 48 break;
48 case DAVINCI_LPSC_MMC_SD: 49 case DAVINCI_LPSC_MMC_SD:
49 /* VDD power manupulations are done in U-Boot for CPMAC 50 /* VDD power manupulations are done in U-Boot for CPMAC
50 * so applies to MMC as well 51 * so applies to MMC as well
51 */ 52 */
52 /*Set up the pull regiter for MMC */ 53 /*Set up the pull regiter for MMC */
53 VDD3P3V_PWDN = 0x0; 54 davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
54 PINMUX1 &= (~(1 << 9)); 55 davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
55 break; 56 break;
56 case DAVINCI_LPSC_I2C: 57 case DAVINCI_LPSC_I2C:
57 PINMUX1 |= (1 << 7); 58 davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
58 break; 59 break;
59 case DAVINCI_LPSC_McBSP: 60 case DAVINCI_LPSC_McBSP:
60 PINMUX1 |= (1 << 10); 61 davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
61 break; 62 break;
62 default: 63 default:
63 break; 64 break;
@@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id)
67/* Enable or disable a PSC domain */ 68/* Enable or disable a PSC domain */
68void davinci_psc_config(unsigned int domain, unsigned int id, char enable) 69void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
69{ 70{
70 volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id); 71 u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
71 volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
72 72
73 if (id < 0) 73 if (id < 0)
74 return; 74 return;
75 75
76 mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
76 if (enable) 77 if (enable)
77 *mdctl |= 0x00000003; /* Enable Module */ 78 mdctl |= 0x00000003; /* Enable Module */
78 else 79 else
79 *mdctl &= 0xFFFFFFF2; /* Disable Module */ 80 mdctl &= 0xFFFFFFF2; /* Disable Module */
81 davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
82
83 pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
84 if ((pdstat & 0x00000001) == 0) {
85 pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
86 pdctl1 |= 0x1;
87 davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
88
89 ptcmd = 1 << domain;
90 davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
80 91
81 if ((PDSTAT & 0x00000001) == 0) { 92 do {
82 PDCTL1 |= 0x1; 93 epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
83 PTCMD = (1 << domain); 94 EPCPR);
84 while ((((EPCPR >> domain) & 1) == 0)); 95 } while ((((epcpr >> domain) & 1) == 0));
85 96
86 PDCTL1 |= 0x100; 97 pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
87 while (!(((PTSTAT >> domain) & 1) == 0)); 98 pdctl1 |= 0x100;
99 davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
100
101 do {
102 ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
103 PTSTAT);
104 } while (!(((ptstat >> domain) & 1) == 0));
88 } else { 105 } else {
89 PTCMD = (1 << domain); 106 ptcmd = 1 << domain;
90 while (!(((PTSTAT >> domain) & 1) == 0)); 107 davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
108
109 do {
110 ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
111 PTSTAT);
112 } while (!(((ptstat >> domain) & 1) == 0));
91 } 113 }
92 114
93 if (enable) 115 if (enable)
94 while (!((*mdstat & 0x0000001F) == 0x3)); 116 mdstat_mask = 0x3;
95 else 117 else
96 while (!((*mdstat & 0x0000001F) == 0x2)); 118 mdstat_mask = 0x2;
119
120 do {
121 mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
122 MDSTAT + 4 * id);
123 } while (!((mdstat & 0x0000001F) == mdstat_mask));
97 124
98 if (enable) 125 if (enable)
99 davinci_psc_mux(id); 126 davinci_psc_mux(id);
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 1c474cf709ca..a58b678006df 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -28,12 +28,16 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/string.h> 29#include <linux/string.h>
30 30
31#include <asm/errno.h>
31#include <asm/arch/imxfb.h> 32#include <asm/arch/imxfb.h>
32#include <asm/hardware.h> 33#include <asm/hardware.h>
33#include <asm/arch/imx-regs.h> 34#include <asm/arch/imx-regs.h>
34 35
35#include <asm/mach/map.h> 36#include <asm/mach/map.h>
36#include <asm/arch/mmc.h> 37#include <asm/arch/mmc.h>
38#include <asm/arch/gpio.h>
39
40unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG];
37 41
38void imx_gpio_mode(int gpio_mode) 42void imx_gpio_mode(int gpio_mode)
39{ 43{
@@ -95,6 +99,120 @@ void imx_gpio_mode(int gpio_mode)
95 99
96EXPORT_SYMBOL(imx_gpio_mode); 100EXPORT_SYMBOL(imx_gpio_mode);
97 101
102int imx_gpio_request(unsigned gpio, const char *label)
103{
104 if(gpio >= (GPIO_PORT_MAX + 1) * 32)
105 printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n",
106 gpio, label ? label : "?");
107 return -EINVAL;
108
109 if(test_and_set_bit(gpio, imx_gpio_alloc_map)) {
110 printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n",
111 gpio, label ? label : "?");
112 return -EBUSY;
113 }
114
115 return 0;
116}
117
118EXPORT_SYMBOL(imx_gpio_request);
119
120void imx_gpio_free(unsigned gpio)
121{
122 if(gpio >= (GPIO_PORT_MAX + 1) * 32)
123 return;
124
125 clear_bit(gpio, imx_gpio_alloc_map);
126}
127
128EXPORT_SYMBOL(imx_gpio_free);
129
130int imx_gpio_direction_input(unsigned gpio)
131{
132 imx_gpio_mode(gpio| GPIO_IN);
133 return 0;
134}
135
136EXPORT_SYMBOL(imx_gpio_direction_input);
137
138int imx_gpio_direction_output(unsigned gpio, int value)
139{
140 imx_gpio_set_value(gpio, value);
141 imx_gpio_mode(gpio| GPIO_OUT);
142 return 0;
143}
144
145EXPORT_SYMBOL(imx_gpio_direction_output);
146
147int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
148 int alloc_mode, const char *label)
149{
150 const int *p = pin_list;
151 int i;
152 unsigned gpio;
153 unsigned mode;
154
155 for (i = 0; i < count; i++) {
156 gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
157 mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
158
159 if (gpio >= (GPIO_PORT_MAX + 1) * 32)
160 goto setup_error;
161
162 if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE)
163 imx_gpio_free(gpio);
164 else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC))
165 if (imx_gpio_request(gpio, label))
166 if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
167 goto setup_error;
168
169 if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY |
170 IMX_GPIO_ALLOC_MODE_RELEASE)))
171 imx_gpio_mode(gpio | mode);
172
173 p++;
174 }
175 return 0;
176
177setup_error:
178 if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC |
179 IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
180 return -EINVAL;
181
182 while (p != pin_list) {
183 p--;
184 gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
185 imx_gpio_free(gpio);
186 }
187
188 return -EINVAL;
189}
190
191EXPORT_SYMBOL(imx_gpio_setup_multiple_pins);
192
193void __imx_gpio_set_value(unsigned gpio, int value)
194{
195 imx_gpio_set_value_inline(gpio, value);
196}
197
198EXPORT_SYMBOL(__imx_gpio_set_value);
199
200int imx_gpio_to_irq(unsigned gpio)
201{
202 return IRQ_GPIOA(0) + gpio;
203}
204
205EXPORT_SYMBOL(imx_gpio_to_irq);
206
207int imx_irq_to_gpio(unsigned irq)
208{
209 if (irq < IRQ_GPIOA(0))
210 return -EINVAL;
211 return irq - IRQ_GPIOA(0);
212}
213
214EXPORT_SYMBOL(imx_irq_to_gpio);
215
98/* 216/*
99 * get the system pll clock in Hz 217 * get the system pll clock in Hz
100 * 218 *
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 6960a9d04217..010f6fa984a6 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2000-2001 Deep Blue Solutions 4 * Copyright (C) 2000-2001 Deep Blue Solutions
5 * Copyright (C) 2002 Shane Nay (shane@minirl.com) 5 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
6 * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * 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 * it under the terms of the GNU General Public License version 2 as
@@ -15,6 +16,7 @@
15#include <linux/irq.h> 16#include <linux/irq.h>
16#include <linux/time.h> 17#include <linux/time.h>
17#include <linux/clocksource.h> 18#include <linux/clocksource.h>
19#include <linux/clockchips.h>
18 20
19#include <asm/hardware.h> 21#include <asm/hardware.h>
20#include <asm/io.h> 22#include <asm/io.h>
@@ -25,7 +27,8 @@
25/* Use timer 1 as system timer */ 27/* Use timer 1 as system timer */
26#define TIMER_BASE IMX_TIM1_BASE 28#define TIMER_BASE IMX_TIM1_BASE
27 29
28static unsigned long evt_diff; 30static struct clock_event_device clockevent_imx;
31static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
29 32
30/* 33/*
31 * IRQ handler for the timer 34 * IRQ handler for the timer
@@ -33,25 +36,20 @@ static unsigned long evt_diff;
33static irqreturn_t 36static irqreturn_t
34imx_timer_interrupt(int irq, void *dev_id) 37imx_timer_interrupt(int irq, void *dev_id)
35{ 38{
39 struct clock_event_device *evt = &clockevent_imx;
36 uint32_t tstat; 40 uint32_t tstat;
41 irqreturn_t ret = IRQ_NONE;
37 42
38 /* clear the interrupt */ 43 /* clear the interrupt */
39 tstat = IMX_TSTAT(TIMER_BASE); 44 tstat = IMX_TSTAT(TIMER_BASE);
40 IMX_TSTAT(TIMER_BASE) = 0; 45 IMX_TSTAT(TIMER_BASE) = 0;
41 46
42 if (tstat & TSTAT_COMP) { 47 if (tstat & TSTAT_COMP) {
43 do { 48 evt->event_handler(evt);
44 49 ret = IRQ_HANDLED;
45 write_seqlock(&xtime_lock);
46 timer_tick();
47 write_sequnlock(&xtime_lock);
48 IMX_TCMP(TIMER_BASE) += evt_diff;
49
50 } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE)
51 - IMX_TCN(TIMER_BASE)) < 0));
52 } 50 }
53 51
54 return IRQ_HANDLED; 52 return ret;
55} 53}
56 54
57static struct irqaction imx_timer_irq = { 55static struct irqaction imx_timer_irq = {
@@ -70,10 +68,8 @@ static void __init imx_timer_hardware_init(void)
70 */ 68 */
71 IMX_TCTL(TIMER_BASE) = 0; 69 IMX_TCTL(TIMER_BASE) = 0;
72 IMX_TPRER(TIMER_BASE) = 0; 70 IMX_TPRER(TIMER_BASE) = 0;
73 IMX_TCMP(TIMER_BASE) = LATCH - 1;
74 71
75 IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN; 72 IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
76 evt_diff = LATCH;
77} 73}
78 74
79cycle_t imx_get_cycles(void) 75cycle_t imx_get_cycles(void)
@@ -99,11 +95,108 @@ static int __init imx_clocksource_init(void)
99 return 0; 95 return 0;
100} 96}
101 97
98static int imx_set_next_event(unsigned long evt,
99 struct clock_event_device *unused)
100{
101 unsigned long tcmp;
102
103 tcmp = IMX_TCN(TIMER_BASE) + evt;
104 IMX_TCMP(TIMER_BASE) = tcmp;
105
106 return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
107}
108
109#ifdef DEBUG
110static const char *clock_event_mode_label[]={
111 [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
112 [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
113 [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
114 [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
115};
116#endif /*DEBUG*/
117
118static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
119{
120 unsigned long flags;
121
122 /*
123 * The timer interrupt generation is disabled at least
124 * for enough time to call imx_set_next_event()
125 */
126 local_irq_save(flags);
127 /* Disable interrupt in GPT module */
128 IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
129 if (mode != clockevent_mode) {
130 /* Set event time into far-far future */
131 IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
132 /* Clear pending interrupt */
133 IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
134 }
135
136#ifdef DEBUG
137 printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
138 clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
139#endif /*DEBUG*/
140
141 /* Remember timer mode */
142 clockevent_mode = mode;
143 local_irq_restore(flags);
144
145 switch (mode) {
146 case CLOCK_EVT_MODE_PERIODIC:
147 printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
148 break;
149 case CLOCK_EVT_MODE_ONESHOT:
150 /*
151 * Do not put overhead of interrupt enable/disable into
152 * imx_set_next_event(), the core has about 4 minutes
153 * to call imx_set_next_event() or shutdown clock after
154 * mode switching
155 */
156 local_irq_save(flags);
157 IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
158 local_irq_restore(flags);
159 break;
160 case CLOCK_EVT_MODE_SHUTDOWN:
161 case CLOCK_EVT_MODE_UNUSED:
162 /* Left event sources disabled, no more interrupts appears */
163 break;
164 }
165}
166
167static struct clock_event_device clockevent_imx = {
168 .name = "imx_timer1",
169 .features = CLOCK_EVT_FEAT_ONESHOT,
170 .shift = 32,
171 .set_mode = imx_set_mode,
172 .set_next_event = imx_set_next_event,
173 .rating = 200,
174};
175
176static int __init imx_clockevent_init(void)
177{
178 clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC,
179 clockevent_imx.shift);
180 clockevent_imx.max_delta_ns =
181 clockevent_delta2ns(0xfffffffe, &clockevent_imx);
182 clockevent_imx.min_delta_ns =
183 clockevent_delta2ns(0xf, &clockevent_imx);
184
185 clockevent_imx.cpumask = cpumask_of_cpu(0);
186
187 clockevents_register_device(&clockevent_imx);
188
189 return 0;
190}
191
192
102static void __init imx_timer_init(void) 193static void __init imx_timer_init(void)
103{ 194{
104 imx_timer_hardware_init(); 195 imx_timer_hardware_init();
105 imx_clocksource_init(); 196 imx_clocksource_init();
106 197
198 imx_clockevent_init();
199
107 /* 200 /*
108 * Make irqs happen for the system timer 201 * Make irqs happen for the system timer
109 */ 202 */
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 060909870b50..61b2dfcb89d6 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -41,6 +41,22 @@ config ARCH_ADI_COYOTE
41 Engineering Coyote Gateway Reference Platform. For more 41 Engineering Coyote Gateway Reference Platform. For more
42 information on this platform, see <file:Documentation/arm/IXP4xx>. 42 information on this platform, see <file:Documentation/arm/IXP4xx>.
43 43
44config MACH_GATEWAY7001
45 bool "Gateway 7001"
46 select PCI
47 help
48 Say 'Y' here if you want your kernel to support Gateway's
49 7001 Access Point. For more information on this platform,
50 see http://openwrt.org
51
52config MACH_WG302V2
53 bool "Netgear WG302 v2 / WAG302 v2"
54 select PCI
55 help
56 Say 'Y' here if you want your kernel to support Netgear's
57 WG302 v2 or WAG302 v2 Access Points. For more information
58 on this platform, see http://openwrt.org
59
44config ARCH_IXDP425 60config ARCH_IXDP425
45 bool "IXDP425" 61 bool "IXDP425"
46 help 62 help
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 3b87c47e06cf..77e00ade5585 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -13,6 +13,8 @@ obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
13obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o 13obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
14obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o 14obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
15obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o 15obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
16obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
17obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o
16 18
17obj-y += common.o 19obj-y += common.o
18 20
@@ -24,5 +26,7 @@ obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
24obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o 26obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o
25obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o 27obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o
26obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o 28obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o
29obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
30obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
27 31
28obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o 32obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
new file mode 100644
index 000000000000..6abf568322d3
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c
@@ -0,0 +1,63 @@
1/*
2 * arch/arch/mach-ixp4xx/gateway7001-pci.c
3 *
4 * PCI setup routines for Gateway 7001
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-pci.c:
9 * Copyright (C) 2002 Jungo Software Technologies.
10 * Copyright (C) 2003 MontaVista Softwrae, Inc.
11 *
12 * Maintainer: Imre Kaloz <kaloz@openwrt.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24
25#include <asm/mach-types.h>
26#include <asm/hardware.h>
27
28#include <asm/mach/pci.h>
29
30void __init gateway7001_pci_preinit(void)
31{
32 set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW);
33 set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW);
34
35 ixp4xx_pci_preinit();
36}
37
38static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
39{
40 if (slot == 1)
41 return IRQ_IXP4XX_GPIO11;
42 else if (slot == 2)
43 return IRQ_IXP4XX_GPIO10;
44 else return -1;
45}
46
47struct hw_pci gateway7001_pci __initdata = {
48 .nr_controllers = 1,
49 .preinit = gateway7001_pci_preinit,
50 .swizzle = pci_std_swizzle,
51 .setup = ixp4xx_setup,
52 .scan = ixp4xx_scan_bus,
53 .map_irq = gateway7001_map_irq,
54};
55
56int __init gateway7001_pci_init(void)
57{
58 if (machine_is_gateway7001())
59 pci_common_init(&gateway7001_pci);
60 return 0;
61}
62
63subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
new file mode 100644
index 000000000000..37876832e141
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -0,0 +1,108 @@
1/*
2 * arch/arm/mach-ixp4xx/gateway7001-setup.c
3 *
4 * Board setup for the Gateway 7001 board
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-setup.c:
9 * Copyright (C) 2003-2005 MontaVista Software, Inc.
10 *
11 * Author: Imre Kaloz <Kaloz@openwrt.org>
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/serial.h>
18#include <linux/tty.h>
19#include <linux/serial_8250.h>
20#include <linux/slab.h>
21
22#include <asm/types.h>
23#include <asm/setup.h>
24#include <asm/memory.h>
25#include <asm/hardware.h>
26#include <asm/irq.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/flash.h>
30
31static struct flash_platform_data gateway7001_flash_data = {
32 .map_name = "cfi_probe",
33 .width = 2,
34};
35
36static struct resource gateway7001_flash_resource = {
37 .flags = IORESOURCE_MEM,
38};
39
40static struct platform_device gateway7001_flash = {
41 .name = "IXP4XX-Flash",
42 .id = 0,
43 .dev = {
44 .platform_data = &gateway7001_flash_data,
45 },
46 .num_resources = 1,
47 .resource = &gateway7001_flash_resource,
48};
49
50static struct resource gateway7001_uart_resource = {
51 .start = IXP4XX_UART2_BASE_PHYS,
52 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
53 .flags = IORESOURCE_MEM,
54};
55
56static struct plat_serial8250_port gateway7001_uart_data[] = {
57 {
58 .mapbase = IXP4XX_UART2_BASE_PHYS,
59 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
60 .irq = IRQ_IXP4XX_UART2,
61 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
62 .iotype = UPIO_MEM,
63 .regshift = 2,
64 .uartclk = IXP4XX_UART_XTAL,
65 },
66 { },
67};
68
69static struct platform_device gateway7001_uart = {
70 .name = "serial8250",
71 .id = PLAT8250_DEV_PLATFORM,
72 .dev = {
73 .platform_data = gateway7001_uart_data,
74 },
75 .num_resources = 1,
76 .resource = &gateway7001_uart_resource,
77};
78
79static struct platform_device *gateway7001_devices[] __initdata = {
80 &gateway7001_flash,
81 &gateway7001_uart
82};
83
84static void __init gateway7001_init(void)
85{
86 ixp4xx_sys_init();
87
88 gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
89 gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
90
91 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
92 *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
93
94 platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
95}
96
97#ifdef CONFIG_MACH_GATEWAY7001
98MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
99 /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
100 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
101 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
102 .map_io = ixp4xx_map_io,
103 .init_irq = ixp4xx_init_irq,
104 .timer = &ixp4xx_timer,
105 .boot_params = 0x0100,
106 .init_machine = gateway7001_init,
107MACHINE_END
108#endif
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
index a66484b63d36..0d5a42455820 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -25,17 +25,13 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/irq.h>
29
28#include <asm/mach-types.h> 30#include <asm/mach-types.h>
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/arch/gtwx5715.h> 32#include <asm/arch/gtwx5715.h>
32#include <asm/mach/pci.h> 33#include <asm/mach/pci.h>
33 34
34extern void ixp4xx_pci_preinit(void);
35extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
36extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
37
38
39/* 35/*
40 * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h 36 * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
41 * Slot 0 isn't actually populated with a card connector but 37 * Slot 0 isn't actually populated with a card connector but
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index ec4f07950ec6..d5008d8fc9a5 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -15,6 +15,10 @@
15#include <linux/tty.h> 15#include <linux/tty.h>
16#include <linux/serial_8250.h> 16#include <linux/serial_8250.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/io.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/nand.h>
21#include <linux/mtd/partitions.h>
18 22
19#include <asm/types.h> 23#include <asm/types.h>
20#include <asm/setup.h> 24#include <asm/setup.h>
@@ -24,6 +28,7 @@
24#include <asm/irq.h> 28#include <asm/irq.h>
25#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
26#include <asm/mach/flash.h> 30#include <asm/mach/flash.h>
31#include <asm/delay.h>
27 32
28static struct flash_platform_data ixdp425_flash_data = { 33static struct flash_platform_data ixdp425_flash_data = {
29 .map_name = "cfi_probe", 34 .map_name = "cfi_probe",
@@ -44,6 +49,77 @@ static struct platform_device ixdp425_flash = {
44 .resource = &ixdp425_flash_resource, 49 .resource = &ixdp425_flash_resource,
45}; 50};
46 51
52#if defined(CONFIG_MTD_NAND_PLATFORM) || \
53 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
54
55#ifdef CONFIG_MTD_PARTITIONS
56const char *part_probes[] = { "cmdlinepart", NULL };
57
58static struct mtd_partition ixdp425_partitions[] = {
59 {
60 .name = "ixp400 NAND FS 0",
61 .offset = 0,
62 .size = SZ_8M
63 }, {
64 .name = "ixp400 NAND FS 1",
65 .offset = MTDPART_OFS_APPEND,
66 .size = MTDPART_SIZ_FULL
67 },
68};
69#endif
70
71static void
72ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
73{
74 struct nand_chip *this = mtd->priv;
75 int offset = (int)this->priv;
76
77 if (ctrl & NAND_CTRL_CHANGE) {
78 if (ctrl & NAND_NCE) {
79 gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
80 udelay(5);
81 } else
82 gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
83
84 offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
85 offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
86 this->priv = (void *)offset;
87 }
88
89 if (cmd != NAND_CMD_NONE)
90 writeb(cmd, this->IO_ADDR_W + offset);
91}
92
93static struct platform_nand_data ixdp425_flash_nand_data = {
94 .chip = {
95 .chip_delay = 30,
96 .options = NAND_NO_AUTOINCR,
97#ifdef CONFIG_MTD_PARTITIONS
98 .part_probe_types = part_probes,
99 .partitions = ixdp425_partitions,
100 .nr_partitions = ARRAY_SIZE(ixdp425_partitions),
101#endif
102 },
103 .ctrl = {
104 .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl
105 }
106};
107
108static struct resource ixdp425_flash_nand_resource = {
109 .flags = IORESOURCE_MEM,
110};
111
112static struct platform_device ixdp425_flash_nand = {
113 .name = "gen_nand",
114 .id = -1,
115 .dev = {
116 .platform_data = &ixdp425_flash_nand_data,
117 },
118 .num_resources = 1,
119 .resource = &ixdp425_flash_nand_resource,
120};
121#endif /* CONFIG_MTD_NAND_PLATFORM */
122
47static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { 123static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
48 .sda_pin = IXDP425_SDA_PIN, 124 .sda_pin = IXDP425_SDA_PIN,
49 .scl_pin = IXDP425_SCL_PIN, 125 .scl_pin = IXDP425_SCL_PIN,
@@ -104,6 +180,10 @@ static struct platform_device ixdp425_uart = {
104static struct platform_device *ixdp425_devices[] __initdata = { 180static struct platform_device *ixdp425_devices[] __initdata = {
105 &ixdp425_i2c_controller, 181 &ixdp425_i2c_controller,
106 &ixdp425_flash, 182 &ixdp425_flash,
183#if defined(CONFIG_MTD_NAND_PLATFORM) || \
184 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
185 &ixdp425_flash_nand,
186#endif
107 &ixdp425_uart 187 &ixdp425_uart
108}; 188};
109 189
@@ -115,6 +195,22 @@ static void __init ixdp425_init(void)
115 ixdp425_flash_resource.end = 195 ixdp425_flash_resource.end =
116 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; 196 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
117 197
198#if defined(CONFIG_MTD_NAND_PLATFORM) || \
199 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
200 ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
201 ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
202
203 gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
204
205 /* Configure expansion bus for NAND Flash */
206 *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
207 IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */
208 IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */
209 IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/
210 IXP4XX_EXP_BUS_WR_EN |
211 IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */
212#endif
213
118 if (cpu_is_ixp43x()) { 214 if (cpu_is_ixp43x()) {
119 ixdp425_uart.num_resources = 1; 215 ixdp425_uart.num_resources = 1;
120 ixdp425_uart_data[1].flags = 0; 216 ixdp425_uart_data[1].flags = 0;
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
new file mode 100644
index 000000000000..6588f2c758e2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -0,0 +1,63 @@
1/*
2 * arch/arch/mach-ixp4xx/wg302v2-pci.c
3 *
4 * PCI setup routines for the Netgear WG302 v2 and WAG302 v2
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-pci.c:
9 * Copyright (C) 2002 Jungo Software Technologies.
10 * Copyright (C) 2003 MontaVista Software, Inc.
11 *
12 * Maintainer: Imre Kaloz <kaloz@openwrt.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24
25#include <asm/mach-types.h>
26#include <asm/hardware.h>
27
28#include <asm/mach/pci.h>
29
30void __init wg302v2_pci_preinit(void)
31{
32 set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW);
33 set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW);
34
35 ixp4xx_pci_preinit();
36}
37
38static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
39{
40 if (slot == 1)
41 return IRQ_IXP4XX_GPIO8;
42 else if (slot == 2)
43 return IRQ_IXP4XX_GPIO9;
44 else return -1;
45}
46
47struct hw_pci wg302v2_pci __initdata = {
48 .nr_controllers = 1,
49 .preinit = wg302v2_pci_preinit,
50 .swizzle = pci_std_swizzle,
51 .setup = ixp4xx_setup,
52 .scan = ixp4xx_scan_bus,
53 .map_irq = wg302v2_map_irq,
54};
55
56int __init wg302v2_pci_init(void)
57{
58 if (machine_is_wg302v2())
59 pci_common_init(&wg302v2_pci);
60 return 0;
61}
62
63subsys_initcall(wg302v2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
new file mode 100644
index 000000000000..f7e09ad804e8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -0,0 +1,109 @@
1/*
2 * arch/arm/mach-ixp4xx/wg302-setup.c
3 *
4 * Board setup for the Netgear WG302 v2 and WAG302 v2
5 *
6 * Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
7 *
8 * based on coyote-setup.c:
9 * Copyright (C) 2003-2005 MontaVista Software, Inc.
10 *
11 * Author: Imre Kaloz <kaloz@openwrt.org>
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/serial.h>
19#include <linux/tty.h>
20#include <linux/serial_8250.h>
21#include <linux/slab.h>
22
23#include <asm/types.h>
24#include <asm/setup.h>
25#include <asm/memory.h>
26#include <asm/hardware.h>
27#include <asm/irq.h>
28#include <asm/mach-types.h>
29#include <asm/mach/arch.h>
30#include <asm/mach/flash.h>
31
32static struct flash_platform_data wg302v2_flash_data = {
33 .map_name = "cfi_probe",
34 .width = 2,
35};
36
37static struct resource wg302v2_flash_resource = {
38 .flags = IORESOURCE_MEM,
39};
40
41static struct platform_device wg302v2_flash = {
42 .name = "IXP4XX-Flash",
43 .id = 0,
44 .dev = {
45 .platform_data = &wg302v2_flash_data,
46 },
47 .num_resources = 1,
48 .resource = &wg302v2_flash_resource,
49};
50
51static struct resource wg302v2_uart_resource = {
52 .start = IXP4XX_UART2_BASE_PHYS,
53 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
54 .flags = IORESOURCE_MEM,
55};
56
57static struct plat_serial8250_port wg302v2_uart_data[] = {
58 {
59 .mapbase = IXP4XX_UART2_BASE_PHYS,
60 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
61 .irq = IRQ_IXP4XX_UART2,
62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
63 .iotype = UPIO_MEM,
64 .regshift = 2,
65 .uartclk = IXP4XX_UART_XTAL,
66 },
67 { },
68};
69
70static struct platform_device wg302v2_uart = {
71 .name = "serial8250",
72 .id = PLAT8250_DEV_PLATFORM,
73 .dev = {
74 .platform_data = wg302v2_uart_data,
75 },
76 .num_resources = 1,
77 .resource = &wg302v2_uart_resource,
78};
79
80static struct platform_device *wg302v2_devices[] __initdata = {
81 &wg302v2_flash,
82 &wg302v2_uart,
83};
84
85static void __init wg302v2_init(void)
86{
87 ixp4xx_sys_init();
88
89 wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
90 wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
91
92 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
93 *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
94
95 platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
96}
97
98#ifdef CONFIG_MACH_WG302V2
99MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
100 /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
101 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
102 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
103 .map_io = ixp4xx_map_io,
104 .init_irq = ixp4xx_init_irq,
105 .timer = &ixp4xx_timer,
106 .boot_params = 0x0100,
107 .init_machine = wg302v2_init,
108MACHINE_END
109#endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
index 56b7d337333a..2a07a281fa8a 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -3,7 +3,7 @@
3# Makefile for KS8695 architecture support 3# Makefile for KS8695 architecture support
4# 4#
5 5
6obj-y := cpu.o irq.o time.o devices.o 6obj-y := cpu.o irq.o time.o gpio.o devices.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
new file mode 100644
index 000000000000..b1aa3cb3d4a3
--- /dev/null
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -0,0 +1,218 @@
1/*
2 * arch/arm/mach-ks8695/gpio.c
3 *
4 * Copyright (C) 2006 Andrew Victor
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 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/kernel.h>
21#include <linux/mm.h>
22#include <linux/init.h>
23#include <linux/module.h>
24
25#include <asm/io.h>
26#include <asm/hardware.h>
27#include <asm/mach/irq.h>
28
29#include <asm/arch/regs-gpio.h>
30#include <asm/arch/gpio.h>
31
32/*
33 * Configure a GPIO line for either GPIO function, or its internal
34 * function (Interrupt, Timer, etc).
35 */
36static void __init_or_module ks8695_gpio_mode(unsigned int pin, short gpio)
37{
38 unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
39 unsigned long x, flags;
40
41 if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */
42 return;
43
44 local_irq_save(flags);
45
46 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
47 if (gpio) /* GPIO: set bit to 0 */
48 x &= ~enable[pin];
49 else /* Internal function: set bit to 1 */
50 x |= enable[pin];
51 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
52
53 local_irq_restore(flags);
54}
55
56
57static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
58
59/*
60 * Configure GPIO pin as external interrupt source.
61 */
62int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
63{
64 unsigned long x, flags;
65
66 if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
67 return -EINVAL;
68
69 local_irq_save(flags);
70
71 /* set pin as input */
72 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
73 x &= ~IOPM_(pin);
74 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
75
76 local_irq_restore(flags);
77
78 /* Set IRQ triggering type */
79 set_irq_type(gpio_irq[pin], type);
80
81 /* enable interrupt mode */
82 ks8695_gpio_mode(pin, 0);
83
84 return 0;
85}
86EXPORT_SYMBOL(ks8695_gpio_interrupt);
87
88
89
90/* .... Generic GPIO interface .............................................. */
91
92/*
93 * Configure the GPIO line as an input.
94 */
95int __init_or_module gpio_direction_input(unsigned int pin)
96{
97 unsigned long x, flags;
98
99 if (pin > KS8695_GPIO_15)
100 return -EINVAL;
101
102 /* set pin to GPIO mode */
103 ks8695_gpio_mode(pin, 1);
104
105 local_irq_save(flags);
106
107 /* set pin as input */
108 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
109 x &= ~IOPM_(pin);
110 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
111
112 local_irq_restore(flags);
113
114 return 0;
115}
116EXPORT_SYMBOL(gpio_direction_input);
117
118
119/*
120 * Configure the GPIO line as an output, with default state.
121 */
122int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
123{
124 unsigned long x, flags;
125
126 if (pin > KS8695_GPIO_15)
127 return -EINVAL;
128
129 /* set pin to GPIO mode */
130 ks8695_gpio_mode(pin, 1);
131
132 local_irq_save(flags);
133
134 /* set line state */
135 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
136 if (state)
137 x |= (1 << pin);
138 else
139 x &= ~(1 << pin);
140 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
141
142 /* set pin as output */
143 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
144 x |= IOPM_(pin);
145 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
146
147 local_irq_restore(flags);
148
149 return 0;
150}
151EXPORT_SYMBOL(gpio_direction_output);
152
153
154/*
155 * Set the state of an output GPIO line.
156 */
157void gpio_set_value(unsigned int pin, unsigned int state)
158{
159 unsigned long x, flags;
160
161 if (pin > KS8695_GPIO_15)
162 return;
163
164 local_irq_save(flags);
165
166 /* set output line state */
167 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
168 if (state)
169 x |= (1 << pin);
170 else
171 x &= ~(1 << pin);
172 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
173
174 local_irq_restore(flags);
175}
176EXPORT_SYMBOL(gpio_set_value);
177
178
179/*
180 * Read the state of a GPIO line.
181 */
182int gpio_get_value(unsigned int pin)
183{
184 unsigned long x;
185
186 if (pin > KS8695_GPIO_15)
187 return -EINVAL;
188
189 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
190 return (x & (1 << pin)) != 0;
191}
192EXPORT_SYMBOL(gpio_get_value);
193
194
195/*
196 * Map GPIO line to IRQ number.
197 */
198int gpio_to_irq(unsigned int pin)
199{
200 if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
201 return -EINVAL;
202
203 return gpio_irq[pin];
204}
205EXPORT_SYMBOL(gpio_to_irq);
206
207
208/*
209 * Map IRQ number to GPIO line.
210 */
211int irq_to_gpio(unsigned int irq)
212{
213 if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
214 return -EINVAL;
215
216 return (irq - KS8695_IRQ_EXTERN0);
217}
218EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 8f7c90a0593b..34a31caa6f9d 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -12,7 +12,6 @@
12 12
13#include <asm/arch/pxa-regs.h> 13#include <asm/arch/pxa-regs.h>
14#include <asm/hardware.h> 14#include <asm/hardware.h>
15#include <asm/semaphore.h>
16 15
17struct clk { 16struct clk {
18 struct list_head node; 17 struct list_head node;
@@ -25,21 +24,21 @@ struct clk {
25}; 24};
26 25
27static LIST_HEAD(clocks); 26static LIST_HEAD(clocks);
28static DECLARE_MUTEX(clocks_sem); 27static DEFINE_MUTEX(clocks_mutex);
29static DEFINE_SPINLOCK(clocks_lock); 28static DEFINE_SPINLOCK(clocks_lock);
30 29
31struct clk *clk_get(struct device *dev, const char *id) 30struct clk *clk_get(struct device *dev, const char *id)
32{ 31{
33 struct clk *p, *clk = ERR_PTR(-ENOENT); 32 struct clk *p, *clk = ERR_PTR(-ENOENT);
34 33
35 down(&clocks_sem); 34 mutex_lock(&clocks_mutex);
36 list_for_each_entry(p, &clocks, node) { 35 list_for_each_entry(p, &clocks, node) {
37 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 36 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
38 clk = p; 37 clk = p;
39 break; 38 break;
40 } 39 }
41 } 40 }
42 up(&clocks_sem); 41 mutex_unlock(&clocks_mutex);
43 42
44 return clk; 43 return clk;
45} 44}
@@ -101,18 +100,18 @@ static struct clk clk_gpio27 = {
101 100
102int clk_register(struct clk *clk) 101int clk_register(struct clk *clk)
103{ 102{
104 down(&clocks_sem); 103 mutex_lock(&clocks_mutex);
105 list_add(&clk->node, &clocks); 104 list_add(&clk->node, &clocks);
106 up(&clocks_sem); 105 mutex_unlock(&clocks_mutex);
107 return 0; 106 return 0;
108} 107}
109EXPORT_SYMBOL(clk_register); 108EXPORT_SYMBOL(clk_register);
110 109
111void clk_unregister(struct clk *clk) 110void clk_unregister(struct clk *clk)
112{ 111{
113 down(&clocks_sem); 112 mutex_lock(&clocks_mutex);
114 list_del(&clk->node); 113 list_del(&clk->node);
115 up(&clocks_sem); 114 mutex_unlock(&clocks_mutex);
116} 115}
117EXPORT_SYMBOL(clk_unregister); 116EXPORT_SYMBOL(clk_unregister);
118 117
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index a1a900d16665..aab27297b3c6 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -44,6 +44,7 @@
44#include <asm/hardware/scoop.h> 44#include <asm/hardware/scoop.h>
45 45
46#include "generic.h" 46#include "generic.h"
47#include "devices.h"
47#include "sharpsl.h" 48#include "sharpsl.h"
48 49
49 50
@@ -368,7 +369,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
368 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 369 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
369 .fixup = fixup_corgi, 370 .fixup = fixup_corgi,
370 .map_io = pxa_map_io, 371 .map_io = pxa_map_io,
371 .init_irq = pxa_init_irq, 372 .init_irq = pxa25x_init_irq,
372 .init_machine = corgi_init, 373 .init_machine = corgi_init,
373 .timer = &pxa_timer, 374 .timer = &pxa_timer,
374MACHINE_END 375MACHINE_END
@@ -380,7 +381,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
380 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 381 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
381 .fixup = fixup_corgi, 382 .fixup = fixup_corgi,
382 .map_io = pxa_map_io, 383 .map_io = pxa_map_io,
383 .init_irq = pxa_init_irq, 384 .init_irq = pxa25x_init_irq,
384 .init_machine = corgi_init, 385 .init_machine = corgi_init,
385 .timer = &pxa_timer, 386 .timer = &pxa_timer,
386MACHINE_END 387MACHINE_END
@@ -392,7 +393,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
392 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 393 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
393 .fixup = fixup_corgi, 394 .fixup = fixup_corgi,
394 .map_io = pxa_map_io, 395 .map_io = pxa_map_io,
395 .init_irq = pxa_init_irq, 396 .init_irq = pxa25x_init_irq,
396 .init_machine = corgi_init, 397 .init_machine = corgi_init,
397 .timer = &pxa_timer, 398 .timer = &pxa_timer,
398MACHINE_END 399MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
new file mode 100644
index 000000000000..9a6faff8e5a7
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.h
@@ -0,0 +1,11 @@
1extern struct platform_device pxamci_device;
2extern struct platform_device pxaudc_device;
3extern struct platform_device pxafb_device;
4extern struct platform_device ffuart_device;
5extern struct platform_device btuart_device;
6extern struct platform_device stuart_device;
7extern struct platform_device hwuart_device;
8extern struct platform_device pxai2c_device;
9extern struct platform_device pxai2s_device;
10extern struct platform_device pxaficp_device;
11extern struct platform_device pxartc_device;
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 4440babe7b97..93c4f31f127f 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -25,12 +25,15 @@
25 25
26#include <asm/arch/pxa-regs.h> 26#include <asm/arch/pxa-regs.h>
27 27
28static struct dma_channel { 28struct dma_channel {
29 char *name; 29 char *name;
30 pxa_dma_prio prio;
30 void (*irq_handler)(int, void *); 31 void (*irq_handler)(int, void *);
31 void *data; 32 void *data;
32} dma_channels[PXA_DMA_CHANNELS]; 33};
33 34
35static struct dma_channel *dma_channels;
36static int num_dma_channels;
34 37
35int pxa_request_dma (char *name, pxa_dma_prio prio, 38int pxa_request_dma (char *name, pxa_dma_prio prio,
36 void (*irq_handler)(int, void *), 39 void (*irq_handler)(int, void *),
@@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
47 50
48 do { 51 do {
49 /* try grabbing a DMA channel with the requested priority */ 52 /* try grabbing a DMA channel with the requested priority */
50 pxa_for_each_dma_prio (i, prio) { 53 for (i = 0; i < num_dma_channels; i++) {
51 if (!dma_channels[i].name) { 54 if ((dma_channels[i].prio == prio) &&
55 !dma_channels[i].name) {
52 found = 1; 56 found = 1;
53 break; 57 break;
54 } 58 }
@@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
91{ 95{
92 int i, dint = DINT; 96 int i, dint = DINT;
93 97
94 for (i = 0; i < PXA_DMA_CHANNELS; i++) { 98 for (i = 0; i < num_dma_channels; i++) {
95 if (dint & (1 << i)) { 99 if (dint & (1 << i)) {
96 struct dma_channel *channel = &dma_channels[i]; 100 struct dma_channel *channel = &dma_channels[i];
97 if (channel->name && channel->irq_handler) { 101 if (channel->name && channel->irq_handler) {
@@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
109 return IRQ_HANDLED; 113 return IRQ_HANDLED;
110} 114}
111 115
112static int __init pxa_dma_init (void) 116int __init pxa_init_dma(int num_ch)
113{ 117{
114 int ret; 118 int i, ret;
115 119
116 ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL); 120 dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
117 if (ret) 121 if (dma_channels == NULL)
122 return -ENOMEM;
123
124 ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
125 if (ret) {
118 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); 126 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
119 return ret; 127 kfree(dma_channels);
120} 128 return ret;
129 }
121 130
122arch_initcall(pxa_dma_init); 131 /* dma channel priorities on pxa2xx processors:
132 * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
133 * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
134 * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
135 */
136 for (i = 0; i < num_ch; i++)
137 dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
138
139 num_dma_channels = num_ch;
140 return 0;
141}
123 142
124EXPORT_SYMBOL(pxa_request_dma); 143EXPORT_SYMBOL(pxa_request_dma);
125EXPORT_SYMBOL(pxa_free_dma); 144EXPORT_SYMBOL(pxa_free_dma);
126
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 64b08b744f9f..296539b6359c 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -43,6 +43,7 @@
43#include <asm/arch/irda.h> 43#include <asm/arch/irda.h>
44#include <asm/arch/i2c.h> 44#include <asm/arch/i2c.h>
45 45
46#include "devices.h"
46#include "generic.h" 47#include "generic.h"
47 48
48/* 49/*
@@ -242,7 +243,7 @@ static struct resource pxamci_resources[] = {
242 243
243static u64 pxamci_dmamask = 0xffffffffUL; 244static u64 pxamci_dmamask = 0xffffffffUL;
244 245
245static struct platform_device pxamci_device = { 246struct platform_device pxamci_device = {
246 .name = "pxa2xx-mci", 247 .name = "pxa2xx-mci",
247 .id = -1, 248 .id = -1,
248 .dev = { 249 .dev = {
@@ -281,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
281 282
282static u64 udc_dma_mask = ~(u32)0; 283static u64 udc_dma_mask = ~(u32)0;
283 284
284static struct platform_device udc_device = { 285struct platform_device pxaudc_device = {
285 .name = "pxa2xx-udc", 286 .name = "pxa2xx-udc",
286 .id = -1, 287 .id = -1,
287 .resource = pxa2xx_udc_resources, 288 .resource = pxa2xx_udc_resources,
@@ -307,7 +308,7 @@ static struct resource pxafb_resources[] = {
307 308
308static u64 fb_dma_mask = ~(u64)0; 309static u64 fb_dma_mask = ~(u64)0;
309 310
310static struct platform_device pxafb_device = { 311struct platform_device pxafb_device = {
311 .name = "pxa2xx-fb", 312 .name = "pxa2xx-fb",
312 .id = -1, 313 .id = -1,
313 .dev = { 314 .dev = {
@@ -328,24 +329,24 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
328 pxafb_device.dev.parent = parent_dev; 329 pxafb_device.dev.parent = parent_dev;
329} 330}
330 331
331static struct platform_device ffuart_device = { 332struct platform_device ffuart_device = {
332 .name = "pxa2xx-uart", 333 .name = "pxa2xx-uart",
333 .id = 0, 334 .id = 0,
334}; 335};
335static struct platform_device btuart_device = { 336struct platform_device btuart_device = {
336 .name = "pxa2xx-uart", 337 .name = "pxa2xx-uart",
337 .id = 1, 338 .id = 1,
338}; 339};
339static struct platform_device stuart_device = { 340struct platform_device stuart_device = {
340 .name = "pxa2xx-uart", 341 .name = "pxa2xx-uart",
341 .id = 2, 342 .id = 2,
342}; 343};
343static struct platform_device hwuart_device = { 344struct platform_device hwuart_device = {
344 .name = "pxa2xx-uart", 345 .name = "pxa2xx-uart",
345 .id = 3, 346 .id = 3,
346}; 347};
347 348
348static struct resource i2c_resources[] = { 349static struct resource pxai2c_resources[] = {
349 { 350 {
350 .start = 0x40301680, 351 .start = 0x40301680,
351 .end = 0x403016a3, 352 .end = 0x403016a3,
@@ -357,40 +358,19 @@ static struct resource i2c_resources[] = {
357 }, 358 },
358}; 359};
359 360
360static struct platform_device i2c_device = { 361struct platform_device pxai2c_device = {
361 .name = "pxa2xx-i2c", 362 .name = "pxa2xx-i2c",
362 .id = 0, 363 .id = 0,
363 .resource = i2c_resources, 364 .resource = pxai2c_resources,
364 .num_resources = ARRAY_SIZE(i2c_resources), 365 .num_resources = ARRAY_SIZE(pxai2c_resources),
365}; 366};
366 367
367#ifdef CONFIG_PXA27x
368static struct resource i2c_power_resources[] = {
369 {
370 .start = 0x40f00180,
371 .end = 0x40f001a3,
372 .flags = IORESOURCE_MEM,
373 }, {
374 .start = IRQ_PWRI2C,
375 .end = IRQ_PWRI2C,
376 .flags = IORESOURCE_IRQ,
377 },
378};
379
380static struct platform_device i2c_power_device = {
381 .name = "pxa2xx-i2c",
382 .id = 1,
383 .resource = i2c_power_resources,
384 .num_resources = ARRAY_SIZE(i2c_resources),
385};
386#endif
387
388void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) 368void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
389{ 369{
390 i2c_device.dev.platform_data = info; 370 pxai2c_device.dev.platform_data = info;
391} 371}
392 372
393static struct resource i2s_resources[] = { 373static struct resource pxai2s_resources[] = {
394 { 374 {
395 .start = 0x40400000, 375 .start = 0x40400000,
396 .end = 0x40400083, 376 .end = 0x40400083,
@@ -402,16 +382,16 @@ static struct resource i2s_resources[] = {
402 }, 382 },
403}; 383};
404 384
405static struct platform_device i2s_device = { 385struct platform_device pxai2s_device = {
406 .name = "pxa2xx-i2s", 386 .name = "pxa2xx-i2s",
407 .id = -1, 387 .id = -1,
408 .resource = i2s_resources, 388 .resource = pxai2s_resources,
409 .num_resources = ARRAY_SIZE(i2s_resources), 389 .num_resources = ARRAY_SIZE(pxai2s_resources),
410}; 390};
411 391
412static u64 pxaficp_dmamask = ~(u32)0; 392static u64 pxaficp_dmamask = ~(u32)0;
413 393
414static struct platform_device pxaficp_device = { 394struct platform_device pxaficp_device = {
415 .name = "pxa2xx-ir", 395 .name = "pxa2xx-ir",
416 .id = -1, 396 .id = -1,
417 .dev = { 397 .dev = {
@@ -425,42 +405,7 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
425 pxaficp_device.dev.platform_data = info; 405 pxaficp_device.dev.platform_data = info;
426} 406}
427 407
428static struct platform_device pxartc_device = { 408struct platform_device pxartc_device = {
429 .name = "sa1100-rtc", 409 .name = "sa1100-rtc",
430 .id = -1, 410 .id = -1,
431}; 411};
432
433static struct platform_device *devices[] __initdata = {
434 &pxamci_device,
435 &udc_device,
436 &pxafb_device,
437 &ffuart_device,
438 &btuart_device,
439 &stuart_device,
440 &pxaficp_device,
441 &i2c_device,
442#ifdef CONFIG_PXA27x
443 &i2c_power_device,
444#endif
445 &i2s_device,
446 &pxartc_device,
447};
448
449static int __init pxa_init(void)
450{
451 int cpuid, ret;
452
453 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
454 if (ret)
455 return ret;
456
457 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
458 cpuid = read_cpuid(CPUID_ID);
459 if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
460 ((cpuid >> 4) & 0xfff) == 0x290)
461 ret = platform_device_register(&hwuart_device);
462
463 return ret;
464}
465
466subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index e54a8dd63c17..91ab2ad8b34b 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,12 @@
12struct sys_timer; 12struct sys_timer;
13 13
14extern struct sys_timer pxa_timer; 14extern struct sys_timer pxa_timer;
15extern void __init pxa_init_irq_low(void);
16extern void __init pxa_init_irq_high(void);
17extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa25x_init_irq(void);
19extern void __init pxa27x_init_irq(void);
15extern void __init pxa_map_io(void); 20extern void __init pxa_map_io(void);
16extern void __init pxa_init_irq(void);
17 21
18extern unsigned int get_clk_frequency_khz(int info); 22extern unsigned int get_clk_frequency_khz(int info);
19 23
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 64df44043a65..465108da2851 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -38,6 +38,7 @@
38#include <asm/arch/mmc.h> 38#include <asm/arch/mmc.h>
39 39
40#include "generic.h" 40#include "generic.h"
41#include "devices.h"
41 42
42/* TODO: 43/* TODO:
43 * - add pxa2xx_audio_ops_t device structure 44 * - add pxa2xx_audio_ops_t device structure
@@ -152,7 +153,7 @@ static void __init idp_init(void)
152static void __init idp_init_irq(void) 153static void __init idp_init_irq(void)
153{ 154{
154 155
155 pxa_init_irq(); 156 pxa25x_init_irq();
156 157
157 set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE); 158 set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
158} 159}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 4619d5fe606c..4b867b0789d5 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -30,12 +30,12 @@
30 30
31static void pxa_mask_low_irq(unsigned int irq) 31static void pxa_mask_low_irq(unsigned int irq)
32{ 32{
33 ICMR &= ~(1 << (irq + PXA_IRQ_SKIP)); 33 ICMR &= ~(1 << irq);
34} 34}
35 35
36static void pxa_unmask_low_irq(unsigned int irq) 36static void pxa_unmask_low_irq(unsigned int irq)
37{ 37{
38 ICMR |= (1 << (irq + PXA_IRQ_SKIP)); 38 ICMR |= (1 << irq);
39} 39}
40 40
41static int pxa_set_wake(unsigned int irq, unsigned int on) 41static int pxa_set_wake(unsigned int irq, unsigned int on)
@@ -67,7 +67,27 @@ static struct irq_chip pxa_internal_chip_low = {
67 .set_wake = pxa_set_wake, 67 .set_wake = pxa_set_wake,
68}; 68};
69 69
70#if PXA_INTERNAL_IRQS > 32 70void __init pxa_init_irq_low(void)
71{
72 int irq;
73
74 /* disable all IRQs */
75 ICMR = 0;
76
77 /* all IRQs are IRQ, not FIQ */
78 ICLR = 0;
79
80 /* only unmasked interrupts kick us out of idle */
81 ICCR = 1;
82
83 for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
84 set_irq_chip(irq, &pxa_internal_chip_low);
85 set_irq_handler(irq, handle_level_irq);
86 set_irq_flags(irq, IRQF_VALID);
87 }
88}
89
90#ifdef CONFIG_PXA27x
71 91
72/* 92/*
73 * This is for the second set of internal IRQs as found on the PXA27x. 93 * This is for the second set of internal IRQs as found on the PXA27x.
@@ -75,12 +95,12 @@ static struct irq_chip pxa_internal_chip_low = {
75 95
76static void pxa_mask_high_irq(unsigned int irq) 96static void pxa_mask_high_irq(unsigned int irq)
77{ 97{
78 ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP)); 98 ICMR2 &= ~(1 << (irq - 32));
79} 99}
80 100
81static void pxa_unmask_high_irq(unsigned int irq) 101static void pxa_unmask_high_irq(unsigned int irq)
82{ 102{
83 ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP)); 103 ICMR2 |= (1 << (irq - 32));
84} 104}
85 105
86static struct irq_chip pxa_internal_chip_high = { 106static struct irq_chip pxa_internal_chip_high = {
@@ -90,6 +110,19 @@ static struct irq_chip pxa_internal_chip_high = {
90 .unmask = pxa_unmask_high_irq, 110 .unmask = pxa_unmask_high_irq,
91}; 111};
92 112
113void __init pxa_init_irq_high(void)
114{
115 int irq;
116
117 ICMR2 = 0;
118 ICLR2 = 0;
119
120 for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
121 set_irq_chip(irq, &pxa_internal_chip_high);
122 set_irq_handler(irq, handle_level_irq);
123 set_irq_flags(irq, IRQF_VALID);
124 }
125}
93#endif 126#endif
94 127
95/* Note that if an input/irq line ever gets changed to an output during 128/* Note that if an input/irq line ever gets changed to an output during
@@ -217,7 +250,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
217 do { 250 do {
218 loop = 0; 251 loop = 0;
219 252
220 mask = GEDR0 & ~3; 253 mask = GEDR0 & GPIO_IRQ_mask[0] & ~3;
221 if (mask) { 254 if (mask) {
222 GEDR0 = mask; 255 GEDR0 = mask;
223 irq = IRQ_GPIO(2); 256 irq = IRQ_GPIO(2);
@@ -233,7 +266,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
233 loop = 1; 266 loop = 1;
234 } 267 }
235 268
236 mask = GEDR1; 269 mask = GEDR1 & GPIO_IRQ_mask[1];
237 if (mask) { 270 if (mask) {
238 GEDR1 = mask; 271 GEDR1 = mask;
239 irq = IRQ_GPIO(32); 272 irq = IRQ_GPIO(32);
@@ -248,7 +281,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
248 loop = 1; 281 loop = 1;
249 } 282 }
250 283
251 mask = GEDR2; 284 mask = GEDR2 & GPIO_IRQ_mask[2];
252 if (mask) { 285 if (mask) {
253 GEDR2 = mask; 286 GEDR2 = mask;
254 irq = IRQ_GPIO(64); 287 irq = IRQ_GPIO(64);
@@ -263,8 +296,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
263 loop = 1; 296 loop = 1;
264 } 297 }
265 298
266#if PXA_LAST_GPIO >= 96 299 mask = GEDR3 & GPIO_IRQ_mask[3];
267 mask = GEDR3;
268 if (mask) { 300 if (mask) {
269 GEDR3 = mask; 301 GEDR3 = mask;
270 irq = IRQ_GPIO(96); 302 irq = IRQ_GPIO(96);
@@ -278,7 +310,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
278 } while (mask); 310 } while (mask);
279 loop = 1; 311 loop = 1;
280 } 312 }
281#endif
282 } while (loop); 313 } while (loop);
283} 314}
284 315
@@ -314,64 +345,27 @@ static struct irq_chip pxa_muxed_gpio_chip = {
314 .set_wake = pxa_set_gpio_wake, 345 .set_wake = pxa_set_gpio_wake,
315}; 346};
316 347
317 348void __init pxa_init_irq_gpio(int gpio_nr)
318void __init pxa_init_irq(void)
319{ 349{
320 int irq; 350 int irq, i;
321
322 /* disable all IRQs */
323 ICMR = 0;
324
325 /* all IRQs are IRQ, not FIQ */
326 ICLR = 0;
327 351
328 /* clear all GPIO edge detects */ 352 /* clear all GPIO edge detects */
329 GFER0 = 0; 353 for (i = 0; i < gpio_nr; i += 32) {
330 GFER1 = 0; 354 GFER(i) = 0;
331 GFER2 = 0; 355 GRER(i) = 0;
332 GRER0 = 0; 356 GEDR(i) = GEDR(i);
333 GRER1 = 0; 357 }
334 GRER2 = 0;
335 GEDR0 = GEDR0;
336 GEDR1 = GEDR1;
337 GEDR2 = GEDR2;
338
339#ifdef CONFIG_PXA27x
340 /* And similarly for the extra regs on the PXA27x */
341 ICMR2 = 0;
342 ICLR2 = 0;
343 GFER3 = 0;
344 GRER3 = 0;
345 GEDR3 = GEDR3;
346#endif
347
348 /* only unmasked interrupts kick us out of idle */
349 ICCR = 1;
350 358
351 /* GPIO 0 and 1 must have their mask bit always set */ 359 /* GPIO 0 and 1 must have their mask bit always set */
352 GPIO_IRQ_mask[0] = 3; 360 GPIO_IRQ_mask[0] = 3;
353 361
354 for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
355 set_irq_chip(irq, &pxa_internal_chip_low);
356 set_irq_handler(irq, handle_level_irq);
357 set_irq_flags(irq, IRQF_VALID);
358 }
359
360#if PXA_INTERNAL_IRQS > 32
361 for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
362 set_irq_chip(irq, &pxa_internal_chip_high);
363 set_irq_handler(irq, handle_level_irq);
364 set_irq_flags(irq, IRQF_VALID);
365 }
366#endif
367
368 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { 362 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
369 set_irq_chip(irq, &pxa_low_gpio_chip); 363 set_irq_chip(irq, &pxa_low_gpio_chip);
370 set_irq_handler(irq, handle_edge_irq); 364 set_irq_handler(irq, handle_edge_irq);
371 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 365 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
372 } 366 }
373 367
374 for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { 368 for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(gpio_nr); irq++) {
375 set_irq_chip(irq, &pxa_muxed_gpio_chip); 369 set_irq_chip(irq, &pxa_muxed_gpio_chip);
376 set_irq_handler(irq, handle_edge_irq); 370 set_irq_handler(irq, handle_edge_irq);
377 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 371 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index e3097664ffe1..26116440a7c9 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -46,6 +46,7 @@
46#include <asm/arch/ohci.h> 46#include <asm/arch/ohci.h>
47 47
48#include "generic.h" 48#include "generic.h"
49#include "devices.h"
49 50
50 51
51static unsigned int lpd270_irq_enabled; 52static unsigned int lpd270_irq_enabled;
@@ -97,7 +98,7 @@ static void __init lpd270_init_irq(void)
97{ 98{
98 int irq; 99 int irq;
99 100
100 pxa_init_irq(); 101 pxa27x_init_irq();
101 102
102 __raw_writew(0, LPD270_INT_MASK); 103 __raw_writew(0, LPD270_INT_MASK);
103 __raw_writew(0, LPD270_INT_STATUS); 104 __raw_writew(0, LPD270_INT_STATUS);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6377b2e29ff0..e70048fd00a5 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -48,6 +48,7 @@
48#include <asm/arch/mmc.h> 48#include <asm/arch/mmc.h>
49 49
50#include "generic.h" 50#include "generic.h"
51#include "devices.h"
51 52
52 53
53#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080) 54#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
@@ -103,7 +104,7 @@ static void __init lubbock_init_irq(void)
103{ 104{
104 int irq; 105 int irq;
105 106
106 pxa_init_irq(); 107 pxa25x_init_irq();
107 108
108 /* setup extra lubbock irqs */ 109 /* setup extra lubbock irqs */
109 for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { 110 for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index ed99a81b98f3..b02c79c7e6a3 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -46,6 +46,7 @@
46#include <asm/arch/ohci.h> 46#include <asm/arch/ohci.h>
47 47
48#include "generic.h" 48#include "generic.h"
49#include "devices.h"
49 50
50 51
51static unsigned long mainstone_irq_enabled; 52static unsigned long mainstone_irq_enabled;
@@ -89,7 +90,7 @@ static void __init mainstone_init_irq(void)
89{ 90{
90 int irq; 91 int irq;
91 92
92 pxa_init_irq(); 93 pxa27x_init_irq();
93 94
94 /* setup extra Mainstone irqs */ 95 /* setup extra Mainstone irqs */
95 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { 96 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 6bf15ae73848..e66dbc26add1 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -77,7 +77,6 @@ int pxa_pm_enter(suspend_state_t state)
77{ 77{
78 unsigned long sleep_save[SLEEP_SAVE_SIZE]; 78 unsigned long sleep_save[SLEEP_SAVE_SIZE];
79 unsigned long checksum = 0; 79 unsigned long checksum = 0;
80 struct timespec delta, rtc;
81 int i; 80 int i;
82 extern void pxa_cpu_pm_enter(suspend_state_t state); 81 extern void pxa_cpu_pm_enter(suspend_state_t state);
83 82
@@ -87,11 +86,6 @@ int pxa_pm_enter(suspend_state_t state)
87 iwmmxt_task_disable(NULL); 86 iwmmxt_task_disable(NULL);
88#endif 87#endif
89 88
90 /* preserve current time */
91 rtc.tv_sec = RCNR;
92 rtc.tv_nsec = 0;
93 save_time_delta(&delta, &rtc);
94
95 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); 89 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
96 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); 90 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
97 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); 91 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
@@ -183,10 +177,6 @@ int pxa_pm_enter(suspend_state_t state)
183 177
184 RESTORE(PSTR); 178 RESTORE(PSTR);
185 179
186 /* restore current time */
187 rtc.tv_sec = RCNR;
188 restore_time_delta(&delta, &rtc);
189
190#ifdef DEBUG 180#ifdef DEBUG
191 printk(KERN_DEBUG "*** made it back from resume\n"); 181 printk(KERN_DEBUG "*** made it back from resume\n");
192#endif 182#endif
@@ -200,40 +190,3 @@ unsigned long sleep_phys_sp(void *sp)
200{ 190{
201 return virt_to_phys(sp); 191 return virt_to_phys(sp);
202} 192}
203
204/*
205 * Called after processes are frozen, but before we shut down devices.
206 */
207int pxa_pm_prepare(suspend_state_t state)
208{
209 extern int pxa_cpu_pm_prepare(suspend_state_t state);
210
211 return pxa_cpu_pm_prepare(state);
212}
213
214EXPORT_SYMBOL_GPL(pxa_pm_prepare);
215
216/*
217 * Called after devices are re-setup, but before processes are thawed.
218 */
219int pxa_pm_finish(suspend_state_t state)
220{
221 return 0;
222}
223
224EXPORT_SYMBOL_GPL(pxa_pm_finish);
225
226static struct pm_ops pxa_pm_ops = {
227 .prepare = pxa_pm_prepare,
228 .enter = pxa_pm_enter,
229 .finish = pxa_pm_finish,
230 .valid = pm_valid_only_mem,
231};
232
233static int __init pxa_pm_init(void)
234{
235 pm_set_ops(&pxa_pm_ops);
236 return 0;
237}
238
239device_initcall(pxa_pm_init);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 34fb80b37023..655668d4d0e9 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -45,6 +45,7 @@
45#include <asm/mach/sharpsl_param.h> 45#include <asm/mach/sharpsl_param.h>
46 46
47#include "generic.h" 47#include "generic.h"
48#include "devices.h"
48#include "sharpsl.h" 49#include "sharpsl.h"
49 50
50static struct resource poodle_scoop_resources[] = { 51static struct resource poodle_scoop_resources[] = {
@@ -412,7 +413,7 @@ MACHINE_START(POODLE, "SHARP Poodle")
412 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 413 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
413 .fixup = fixup_poodle, 414 .fixup = fixup_poodle,
414 .map_io = pxa_map_io, 415 .map_io = pxa_map_io,
415 .init_irq = pxa_init_irq, 416 .init_irq = pxa25x_init_irq,
416 .timer = &pxa_timer, 417 .timer = &pxa_timer,
417 .init_machine = poodle_init, 418 .init_machine = poodle_init,
418MACHINE_END 419MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index c1f21739bf71..f36ca448338e 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -19,12 +19,17 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/platform_device.h>
22#include <linux/pm.h> 23#include <linux/pm.h>
23 24
24#include <asm/hardware.h> 25#include <asm/hardware.h>
26#include <asm/arch/irqs.h>
25#include <asm/arch/pxa-regs.h> 27#include <asm/arch/pxa-regs.h>
28#include <asm/arch/pm.h>
29#include <asm/arch/dma.h>
26 30
27#include "generic.h" 31#include "generic.h"
32#include "devices.h"
28 33
29/* 34/*
30 * Various clock factors driven by the CCCR register. 35 * Various clock factors driven by the CCCR register.
@@ -105,18 +110,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
105 110
106#ifdef CONFIG_PM 111#ifdef CONFIG_PM
107 112
108int pxa_cpu_pm_prepare(suspend_state_t state)
109{
110 switch (state) {
111 case PM_SUSPEND_MEM:
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120void pxa_cpu_pm_enter(suspend_state_t state) 113void pxa_cpu_pm_enter(suspend_state_t state)
121{ 114{
122 extern void pxa_cpu_suspend(unsigned int); 115 extern void pxa_cpu_suspend(unsigned int);
@@ -133,4 +126,49 @@ void pxa_cpu_pm_enter(suspend_state_t state)
133 } 126 }
134} 127}
135 128
129static struct pm_ops pxa25x_pm_ops = {
130 .enter = pxa_pm_enter,
131 .valid = pm_valid_only_mem,
132};
133#endif
134
135void __init pxa25x_init_irq(void)
136{
137 pxa_init_irq_low();
138 pxa_init_irq_gpio(85);
139}
140
141static struct platform_device *pxa25x_devices[] __initdata = {
142 &pxamci_device,
143 &pxaudc_device,
144 &pxafb_device,
145 &ffuart_device,
146 &btuart_device,
147 &stuart_device,
148 &pxai2c_device,
149 &pxai2s_device,
150 &pxaficp_device,
151 &pxartc_device,
152};
153
154static int __init pxa25x_init(void)
155{
156 int ret = 0;
157
158 if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
159 if ((ret = pxa_init_dma(16)))
160 return ret;
161#ifdef CONFIG_PM
162 pm_set_ops(&pxa25x_pm_ops);
136#endif 163#endif
164 ret = platform_add_devices(pxa25x_devices,
165 ARRAY_SIZE(pxa25x_devices));
166 }
167 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
168 if (cpu_is_pxa25x())
169 ret = platform_device_register(&hwuart_device);
170
171 return ret;
172}
173
174subsys_initcall(pxa25x_init);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 1939acc3f9f7..aa5bb02c897b 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -19,10 +19,14 @@
19 19
20#include <asm/hardware.h> 20#include <asm/hardware.h>
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/arch/irqs.h>
22#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
23#include <asm/arch/ohci.h> 24#include <asm/arch/ohci.h>
25#include <asm/arch/pm.h>
26#include <asm/arch/dma.h>
24 27
25#include "generic.h" 28#include "generic.h"
29#include "devices.h"
26 30
27/* Crystal clock: 13MHz */ 31/* Crystal clock: 13MHz */
28#define BASE_CLK 13000000 32#define BASE_CLK 13000000
@@ -122,17 +126,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
122 126
123#ifdef CONFIG_PM 127#ifdef CONFIG_PM
124 128
125int pxa_cpu_pm_prepare(suspend_state_t state)
126{
127 switch (state) {
128 case PM_SUSPEND_MEM:
129 case PM_SUSPEND_STANDBY:
130 return 0;
131 default:
132 return -EINVAL;
133 }
134}
135
136void pxa_cpu_pm_enter(suspend_state_t state) 129void pxa_cpu_pm_enter(suspend_state_t state)
137{ 130{
138 extern void pxa_cpu_standby(void); 131 extern void pxa_cpu_standby(void);
@@ -162,6 +155,15 @@ void pxa_cpu_pm_enter(suspend_state_t state)
162 } 155 }
163} 156}
164 157
158static int pxa27x_pm_valid(suspend_state_t state)
159{
160 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
161}
162
163static struct pm_ops pxa27x_pm_ops = {
164 .enter = pxa_pm_enter,
165 .valid = pxa27x_pm_valid,
166};
165#endif 167#endif
166 168
167/* 169/*
@@ -183,7 +185,7 @@ static struct resource pxa27x_ohci_resources[] = {
183 }, 185 },
184}; 186};
185 187
186static struct platform_device ohci_device = { 188static struct platform_device pxaohci_device = {
187 .name = "pxa27x-ohci", 189 .name = "pxa27x-ohci",
188 .id = -1, 190 .id = -1,
189 .dev = { 191 .dev = {
@@ -196,16 +198,62 @@ static struct platform_device ohci_device = {
196 198
197void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) 199void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
198{ 200{
199 ohci_device.dev.platform_data = info; 201 pxaohci_device.dev.platform_data = info;
200} 202}
201 203
204static struct resource i2c_power_resources[] = {
205 {
206 .start = 0x40f00180,
207 .end = 0x40f001a3,
208 .flags = IORESOURCE_MEM,
209 }, {
210 .start = IRQ_PWRI2C,
211 .end = IRQ_PWRI2C,
212 .flags = IORESOURCE_IRQ,
213 },
214};
215
216static struct platform_device pxai2c_power_device = {
217 .name = "pxa2xx-i2c",
218 .id = 1,
219 .resource = i2c_power_resources,
220 .num_resources = ARRAY_SIZE(i2c_power_resources),
221};
222
202static struct platform_device *devices[] __initdata = { 223static struct platform_device *devices[] __initdata = {
203 &ohci_device, 224 &pxamci_device,
225 &pxaudc_device,
226 &pxafb_device,
227 &ffuart_device,
228 &btuart_device,
229 &stuart_device,
230 &pxai2c_device,
231 &pxai2c_power_device,
232 &pxai2s_device,
233 &pxaficp_device,
234 &pxartc_device,
235 &pxaohci_device,
204}; 236};
205 237
238void __init pxa27x_init_irq(void)
239{
240 pxa_init_irq_low();
241 pxa_init_irq_high();
242 pxa_init_irq_gpio(128);
243}
244
206static int __init pxa27x_init(void) 245static int __init pxa27x_init(void)
207{ 246{
208 return platform_add_devices(devices, ARRAY_SIZE(devices)); 247 int ret = 0;
248 if (cpu_is_pxa27x()) {
249 if ((ret = pxa_init_dma(32)))
250 return ret;
251#ifdef CONFIG_PM
252 pm_set_ops(&pxa27x_pm_ops);
253#endif
254 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
255 }
256 return ret;
209} 257}
210 258
211subsys_initcall(pxa27x_init); 259subsys_initcall(pxa27x_init);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 3cbac63bed3c..bae47e145de8 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -48,6 +48,7 @@
48#include <asm/hardware/scoop.h> 48#include <asm/hardware/scoop.h>
49 49
50#include "generic.h" 50#include "generic.h"
51#include "devices.h"
51#include "sharpsl.h" 52#include "sharpsl.h"
52 53
53/* 54/*
@@ -560,7 +561,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
560 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 561 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
561 .fixup = fixup_spitz, 562 .fixup = fixup_spitz,
562 .map_io = pxa_map_io, 563 .map_io = pxa_map_io,
563 .init_irq = pxa_init_irq, 564 .init_irq = pxa27x_init_irq,
564 .init_machine = spitz_init, 565 .init_machine = spitz_init,
565 .timer = &pxa_timer, 566 .timer = &pxa_timer,
566MACHINE_END 567MACHINE_END
@@ -572,7 +573,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
572 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 573 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
573 .fixup = fixup_spitz, 574 .fixup = fixup_spitz,
574 .map_io = pxa_map_io, 575 .map_io = pxa_map_io,
575 .init_irq = pxa_init_irq, 576 .init_irq = pxa27x_init_irq,
576 .init_machine = spitz_init, 577 .init_machine = spitz_init,
577 .timer = &pxa_timer, 578 .timer = &pxa_timer,
578MACHINE_END 579MACHINE_END
@@ -584,7 +585,7 @@ MACHINE_START(AKITA, "SHARP Akita")
584 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 585 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
585 .fixup = fixup_spitz, 586 .fixup = fixup_spitz,
586 .map_io = pxa_map_io, 587 .map_io = pxa_map_io,
587 .init_irq = pxa_init_irq, 588 .init_irq = pxa27x_init_irq,
588 .init_machine = akita_init, 589 .init_machine = akita_init,
589 .timer = &pxa_timer, 590 .timer = &pxa_timer,
590MACHINE_END 591MACHINE_END
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 5248abe334d2..6f91fd2d061a 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -30,11 +30,6 @@
30#include <asm/arch/pxa-regs.h> 30#include <asm/arch/pxa-regs.h>
31 31
32 32
33static inline unsigned long pxa_get_rtc_time(void)
34{
35 return RCNR;
36}
37
38static int pxa_set_rtc(void) 33static int pxa_set_rtc(void)
39{ 34{
40 unsigned long current_time = xtime.tv_sec; 35 unsigned long current_time = xtime.tv_sec;
@@ -122,10 +117,6 @@ static void __init pxa_timer_init(void)
122 117
123 set_rtc = pxa_set_rtc; 118 set_rtc = pxa_set_rtc;
124 119
125 tv.tv_nsec = 0;
126 tv.tv_sec = pxa_get_rtc_time();
127 do_settimeofday(&tv);
128
129 OIER = 0; /* disable any timer interrupts */ 120 OIER = 0; /* disable any timer interrupts */
130 OSSR = 0xf; /* clear status on all timers */ 121 OSSR = 0xf; /* clear status on all timers */
131 setup_irq(IRQ_OST0, &pxa_timer_irq); 122 setup_irq(IRQ_OST0, &pxa_timer_irq);
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 72738771fb57..240fd042083d 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -42,7 +42,7 @@
42#include <asm/mach/sharpsl_param.h> 42#include <asm/mach/sharpsl_param.h>
43 43
44#include "generic.h" 44#include "generic.h"
45 45#include "devices.h"
46 46
47/* 47/*
48 * SCOOP Device 48 * SCOOP Device
@@ -332,7 +332,7 @@ MACHINE_START(TOSA, "SHARP Tosa")
332 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 332 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
333 .fixup = fixup_tosa, 333 .fixup = fixup_tosa,
334 .map_io = pxa_map_io, 334 .map_io = pxa_map_io,
335 .init_irq = pxa_init_irq, 335 .init_irq = pxa25x_init_irq,
336 .init_machine = tosa_init, 336 .init_machine = tosa_init,
337 .timer = &pxa_timer, 337 .timer = &pxa_timer,
338MACHINE_END 338MACHINE_END
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 28c79bd0a3a0..e4ba43bdf85d 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -49,6 +49,7 @@
49#include <asm/arch/ohci.h> 49#include <asm/arch/ohci.h>
50 50
51#include "generic.h" 51#include "generic.h"
52#include "devices.h"
52 53
53/******************************************************************************************** 54/********************************************************************************************
54 * ONBOARD FLASH 55 * ONBOARD FLASH
@@ -503,7 +504,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
503 .boot_params = TRIZEPS4_SDRAM_BASE + 0x100, 504 .boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
504 .init_machine = trizeps4_init, 505 .init_machine = trizeps4_init,
505 .map_io = trizeps4_map_io, 506 .map_io = trizeps4_map_io,
506 .init_irq = pxa_init_irq, 507 .init_irq = pxa27x_init_irq,
507 .timer = &pxa_timer, 508 .timer = &pxa_timer,
508MACHINE_END 509MACHINE_END
509 510
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index f01de807b72f..8b52ea95d4f6 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -20,6 +20,8 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/dm9000.h> 21#include <linux/dm9000.h>
22 22
23#include <net/ax88796.h>
24
23#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
24#include <asm/mach/map.h> 26#include <asm/mach/map.h>
25#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
@@ -409,6 +411,61 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
409 .max_freq = 130*1000, 411 .max_freq = 130*1000,
410}; 412};
411 413
414/* Asix AX88796 10/100 ethernet controller */
415
416static struct ax_plat_data bast_asix_platdata = {
417 .flags = AXFLG_MAC_FROMDEV,
418 .wordlength = 2,
419 .dcr_val = 0x48,
420 .rcr_val = 0x40,
421};
422
423static struct resource bast_asix_resource[] = {
424 [0] = {
425 .start = S3C2410_CS5 + BAST_PA_ASIXNET,
426 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
427 .flags = IORESOURCE_MEM,
428 },
429 [1] = {
430 .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
431 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
432 .flags = IORESOURCE_MEM,
433 },
434 [2] = {
435 .start = IRQ_ASIX,
436 .end = IRQ_ASIX,
437 .flags = IORESOURCE_IRQ
438 }
439};
440
441static struct platform_device bast_device_asix = {
442 .name = "ax88796",
443 .id = 0,
444 .num_resources = ARRAY_SIZE(bast_asix_resource),
445 .resource = bast_asix_resource,
446 .dev = {
447 .platform_data = &bast_asix_platdata
448 }
449};
450
451/* Asix AX88796 10/100 ethernet controller parallel port */
452
453static struct resource bast_asixpp_resource[] = {
454 [0] = {
455 .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
456 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
457 .flags = IORESOURCE_MEM,
458 }
459};
460
461static struct platform_device bast_device_axpp = {
462 .name = "ax88796-pp",
463 .id = 0,
464 .num_resources = ARRAY_SIZE(bast_asixpp_resource),
465 .resource = bast_asixpp_resource,
466};
467
468/* LCD/VGA controller */
412 469
413static struct s3c2410fb_mach_info __initdata bast_lcd_info = { 470static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
414 .width = 640, 471 .width = 640,
@@ -453,6 +510,8 @@ static struct platform_device *bast_devices[] __initdata = {
453 &s3c_device_nand, 510 &s3c_device_nand,
454 &bast_device_nor, 511 &bast_device_nor,
455 &bast_device_dm9k, 512 &bast_device_dm9k,
513 &bast_device_asix,
514 &bast_device_axpp,
456 &bast_sio, 515 &bast_sio,
457}; 516};
458 517
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index bff7ddd06a52..29c163d300d4 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -18,6 +18,9 @@
18#include <linux/serial_core.h> 18#include <linux/serial_core.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <linux/sm501.h>
22#include <linux/sm501-regs.h>
23
21#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
22#include <asm/mach/map.h> 25#include <asm/mach/map.h>
23#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
@@ -42,6 +45,8 @@
42#include <linux/mtd/nand_ecc.h> 45#include <linux/mtd/nand_ecc.h>
43#include <linux/mtd/partitions.h> 46#include <linux/mtd/partitions.h>
44 47
48#include <net/ax88796.h>
49
45#include <asm/plat-s3c24xx/clock.h> 50#include <asm/plat-s3c24xx/clock.h>
46#include <asm/plat-s3c24xx/devs.h> 51#include <asm/plat-s3c24xx/devs.h>
47#include <asm/plat-s3c24xx/cpu.h> 52#include <asm/plat-s3c24xx/cpu.h>
@@ -153,6 +158,29 @@ static struct mtd_partition anubis_default_nand_part[] = {
153 } 158 }
154}; 159};
155 160
161static struct mtd_partition anubis_default_nand_part_large[] = {
162 [0] = {
163 .name = "Boot Agent",
164 .size = SZ_128K,
165 .offset = 0,
166 },
167 [1] = {
168 .name = "/boot",
169 .size = SZ_4M - SZ_128K,
170 .offset = SZ_128K,
171 },
172 [2] = {
173 .name = "user1",
174 .offset = SZ_4M,
175 .size = SZ_32M - SZ_4M,
176 },
177 [3] = {
178 .name = "user2",
179 .offset = SZ_32M,
180 .size = MTDPART_SIZ_FULL,
181 }
182};
183
156/* the Anubis has 3 selectable slots for nand-flash, the two 184/* the Anubis has 3 selectable slots for nand-flash, the two
157 * on-board chip areas, as well as the external slot. 185 * on-board chip areas, as well as the external slot.
158 * 186 *
@@ -260,6 +288,104 @@ static struct platform_device anubis_device_ide1 = {
260 .resource = anubis_ide1_resource, 288 .resource = anubis_ide1_resource,
261}; 289};
262 290
291/* Asix AX88796 10/100 ethernet controller */
292
293static struct ax_plat_data anubis_asix_platdata = {
294 .flags = AXFLG_MAC_FROMDEV,
295 .wordlength = 2,
296 .dcr_val = 0x48,
297 .rcr_val = 0x40,
298};
299
300static struct resource anubis_asix_resource[] = {
301 [0] = {
302 .start = S3C2410_CS5,
303 .end = S3C2410_CS5 + (0x20 * 0x20) -1,
304 .flags = IORESOURCE_MEM
305 },
306 [1] = {
307 .start = IRQ_ASIX,
308 .end = IRQ_ASIX,
309 .flags = IORESOURCE_IRQ
310 }
311};
312
313static struct platform_device anubis_device_asix = {
314 .name = "ax88796",
315 .id = 0,
316 .num_resources = ARRAY_SIZE(anubis_asix_resource),
317 .resource = anubis_asix_resource,
318 .dev = {
319 .platform_data = &anubis_asix_platdata,
320 }
321};
322
323/* SM501 */
324
325static struct resource anubis_sm501_resource[] = {
326 [0] = {
327 .start = S3C2410_CS2,
328 .end = S3C2410_CS2 + SZ_8M,
329 .flags = IORESOURCE_MEM,
330 },
331 [1] = {
332 .start = S3C2410_CS2 + SZ_64M - SZ_2M,
333 .end = S3C2410_CS2 + SZ_64M - 1,
334 .flags = IORESOURCE_MEM,
335 },
336 [2] = {
337 .start = IRQ_EINT0,
338 .end = IRQ_EINT0,
339 .flags = IORESOURCE_IRQ,
340 },
341};
342
343static struct sm501_initdata anubis_sm501_initdata = {
344 .gpio_high = {
345 .set = 0x3F000000, /* 24bit panel */
346 .mask = 0x0,
347 },
348 .misc_timing = {
349 .set = 0x010100, /* SDRAM timing */
350 .mask = 0x1F1F00,
351 },
352 .misc_control = {
353 .set = SM501_MISC_PNL_24BIT,
354 .mask = 0,
355 },
356
357 /* set the SDRAM and bus clocks */
358 .mclk = 72 * MHZ,
359 .m1xclk = 144 * MHZ,
360};
361
362static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
363 [0] = {
364 .pin_scl = 44,
365 .pin_sda = 45,
366 },
367 [1] = {
368 .pin_scl = 40,
369 .pin_sda = 41,
370 },
371};
372
373static struct sm501_platdata anubis_sm501_platdata = {
374 .init = &anubis_sm501_initdata,
375 .gpio_i2c = anubis_sm501_gpio_i2c,
376 .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c),
377};
378
379static struct platform_device anubis_device_sm501 = {
380 .name = "sm501",
381 .id = 0,
382 .num_resources = ARRAY_SIZE(anubis_sm501_resource),
383 .resource = anubis_sm501_resource,
384 .dev = {
385 .platform_data = &anubis_sm501_platdata,
386 },
387};
388
263/* Standard Anubis devices */ 389/* Standard Anubis devices */
264 390
265static struct platform_device *anubis_devices[] __initdata = { 391static struct platform_device *anubis_devices[] __initdata = {
@@ -271,6 +397,8 @@ static struct platform_device *anubis_devices[] __initdata = {
271 &s3c_device_nand, 397 &s3c_device_nand,
272 &anubis_device_ide0, 398 &anubis_device_ide0,
273 &anubis_device_ide1, 399 &anubis_device_ide1,
400 &anubis_device_asix,
401 &anubis_device_sm501,
274}; 402};
275 403
276static struct clk *anubis_clocks[] = { 404static struct clk *anubis_clocks[] = {
@@ -304,8 +432,17 @@ static void __init anubis_map_io(void)
304 s3c24xx_init_clocks(0); 432 s3c24xx_init_clocks(0);
305 s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); 433 s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
306 434
307 /* ensure that the GPIO is setup */ 435 /* check for the newer revision boards with large page nand */
308 s3c2410_gpio_setpin(S3C2410_GPA0, 1); 436
437 if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
438 printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
439 __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
440 anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
441 anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
442 } else {
443 /* ensure that the GPIO is setup */
444 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
445 }
309} 446}
310 447
311static void __init anubis_init(void) 448static void __init anubis_init(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 15811601f03d..89f4c9c5777b 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -166,6 +166,29 @@ static struct mtd_partition osiris_default_nand_part[] = {
166 } 166 }
167}; 167};
168 168
169static struct mtd_partition osiris_default_nand_part_large[] = {
170 [0] = {
171 .name = "Boot Agent",
172 .size = SZ_128K,
173 .offset = 0,
174 },
175 [1] = {
176 .name = "/boot",
177 .size = SZ_4M - SZ_128K,
178 .offset = SZ_128K,
179 },
180 [2] = {
181 .name = "user1",
182 .offset = SZ_4M,
183 .size = SZ_32M - SZ_4M,
184 },
185 [3] = {
186 .name = "user2",
187 .offset = SZ_32M,
188 .size = MTDPART_SIZ_FULL,
189 }
190};
191
169/* the Osiris has 3 selectable slots for nand-flash, the two 192/* the Osiris has 3 selectable slots for nand-flash, the two
170 * on-board chip areas, as well as the external slot. 193 * on-board chip areas, as well as the external slot.
171 * 194 *
@@ -322,14 +345,23 @@ static void __init osiris_map_io(void)
322 s3c24xx_init_clocks(0); 345 s3c24xx_init_clocks(0);
323 s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); 346 s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
324 347
348 /* check for the newer revision boards with large page nand */
349
350 if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
351 printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
352 __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
353 osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
354 osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
355 } else {
356 /* write-protect line to the NAND */
357 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
358 }
359
325 /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ 360 /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
326 361
327 local_irq_save(flags); 362 local_irq_save(flags);
328 __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON); 363 __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
329 local_irq_restore(flags); 364 local_irq_restore(flags);
330
331 /* write-protect line to the NAND */
332 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
333} 365}
334 366
335static void __init osiris_init(void) 367static void __init osiris_init(void)
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index d674cf343156..01a37d3c0727 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -57,12 +57,7 @@ enum { SLEEP_SAVE_SP = 0,
57static int sa11x0_pm_enter(suspend_state_t state) 57static int sa11x0_pm_enter(suspend_state_t state)
58{ 58{
59 unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE]; 59 unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
60 struct timespec delta, rtc;
61 60
62 /* preserve current time */
63 rtc.tv_sec = RCNR;
64 rtc.tv_nsec = 0;
65 save_time_delta(&delta, &rtc);
66 gpio = GPLR; 61 gpio = GPLR;
67 62
68 /* save vital registers */ 63 /* save vital registers */
@@ -119,10 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
119 */ 114 */
120 PSSR = PSSR_PH; 115 PSSR = PSSR_PH;
121 116
122 /* restore current time */
123 rtc.tv_sec = RCNR;
124 restore_time_delta(&delta, &rtc);
125
126 return 0; 117 return 0;
127} 118}
128 119
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 29cb0c1604ab..fdf7b016e7ad 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -21,25 +21,6 @@
21#define RTC_DEF_DIVIDER (32768 - 1) 21#define RTC_DEF_DIVIDER (32768 - 1)
22#define RTC_DEF_TRIM 0 22#define RTC_DEF_TRIM 0
23 23
24static unsigned long __init sa1100_get_rtc_time(void)
25{
26 /*
27 * According to the manual we should be able to let RTTR be zero
28 * and then a default divisor for a 32.768KHz clock is used.
29 * Apparently this doesn't work, at least for my SA1110 rev 5.
30 * If the clock divider is uninitialized then reset it to the
31 * default value to get the 1Hz clock.
32 */
33 if (RTTR == 0) {
34 RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
35 printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n");
36 /* The current RTC value probably doesn't make sense either */
37 RCNR = 0;
38 return 0;
39 }
40 return RCNR;
41}
42
43static int sa1100_set_rtc(void) 24static int sa1100_set_rtc(void)
44{ 25{
45 unsigned long current_time = xtime.tv_sec; 26 unsigned long current_time = xtime.tv_sec;
@@ -117,15 +98,10 @@ static struct irqaction sa1100_timer_irq = {
117 98
118static void __init sa1100_timer_init(void) 99static void __init sa1100_timer_init(void)
119{ 100{
120 struct timespec tv;
121 unsigned long flags; 101 unsigned long flags;
122 102
123 set_rtc = sa1100_set_rtc; 103 set_rtc = sa1100_set_rtc;
124 104
125 tv.tv_nsec = 0;
126 tv.tv_sec = sa1100_get_rtc_time();
127 do_settimeofday(&tv);
128
129 OIER = 0; /* disable any timer interrupts */ 105 OIER = 0; /* disable any timer interrupts */
130 OSSR = 0xf; /* clear status on all timers */ 106 OSSR = 0xf; /* clear status on all timers */
131 setup_irq(IRQ_OST0, &sa1100_timer_irq); 107 setup_irq(IRQ_OST0, &sa1100_timer_irq);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index f3ade18862aa..75952779ce19 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -280,7 +280,10 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
280 if (!type) 280 if (!type)
281 return NULL; 281 return NULL;
282 282
283 size = PAGE_ALIGN(size); 283 /*
284 * Page align the mapping size, taking account of any offset.
285 */
286 size = PAGE_ALIGN(offset + size);
284 287
285 area = get_vm_area(size, VM_IOREMAP); 288 area = get_vm_area(size, VM_IOREMAP);
286 if (!area) 289 if (!area)
@@ -325,11 +328,6 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
325 if (!size || last_addr < phys_addr) 328 if (!size || last_addr < phys_addr)
326 return NULL; 329 return NULL;
327 330
328 /*
329 * Page align the mapping size
330 */
331 size = PAGE_ALIGN(last_addr + 1) - phys_addr;
332
333 return __arm_ioremap_pfn(pfn, offset, size, mtype); 331 return __arm_ioremap_pfn(pfn, offset, size, mtype);
334} 332}
335EXPORT_SYMBOL(__arm_ioremap); 333EXPORT_SYMBOL(__arm_ioremap);