diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:25:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:25:24 -0400 |
commit | 82afee684fe3badaf5ee3fc5b6fda687d558bfb5 (patch) | |
tree | 295abb35451a7eb1e46d6066e536e23d1a75668b /arch/blackfin/mach-common | |
parent | 068345f4a873e8b0b511e8f94a595a20e176eeff (diff) | |
parent | f4d640c9be1979a603ed017e1e03a16ba3a4d7a1 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (30 commits)
Blackfin serial driver: supporting BF548-EZKIT serial port
Video Console: Blackfin doesnt support VGA console
Blackfin arch: Add peripheral io API to gpio header file
Blackfin arch: set up gpio interrupt IRQ_PJ9 for BF54x ATAPI PATA driver
Blackfin arch: add missing CONFIG_LARGE_ALLOCS when upstream merging
Blackfin arch: as pointed out by Robert P. J. Day, update the CPU_FREQ name to match current Kconfig
Blackfin arch: extract the entry point from the linked kernel
Blackfin arch: clean up some coding style issues
Blackfin arch: combine the common code of free_initrd_mem and free_initmem
Blackfin arch: Add Support for Peripheral PortMux and resouce allocation
Blackfin arch: use PAGE_SIZE when doing aligns rather than hardcoded values
Blackfin arch: fix bug set dma_address properly in dma_map_sg
Blackfin arch: Disable CACHELINE_ALIGNED_L1 for BF54x by default
Blackfin arch: Port the dm9000 driver to Blackfin by using the correct low-level io routines
Blackfin arch: There is no CDPRIO Bit in the EBIU_AMGCTL Register of BF54x arch
Blackfin arch: scrub dead code
Blackfin arch: Fix Warning add some defines in BF54x header file
Blackfin arch: add BF54x missing GPIO access functions
Blackfin arch: Some memory and code optimizations - Fix SYS_IRQS
Blackfin arch: Enable BF54x PIN/GPIO interrupts
...
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/Makefile | 4 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cacheinit.S | 89 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cplbinfo.c | 13 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 76 | ||||
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 8 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-dc.c | 13 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-sc.c | 405 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 4 |
8 files changed, 416 insertions, 196 deletions
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index d3a49073d196..0279ede70392 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | 4 | ||
5 | obj-y := \ | 5 | obj-y := \ |
6 | cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ | 6 | cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ |
7 | interrupt.o lock.o dpmc.o irqpanic.o | 7 | interrupt.o lock.o irqpanic.o |
8 | 8 | ||
9 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | 9 | obj-$(CONFIG_CPLB_INFO) += cplbinfo.o |
10 | obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o | 10 | obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o |
11 | obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o | 11 | obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o |
12 | obj-$(CONFIG_PM) += pm.o | 12 | obj-$(CONFIG_PM) += pm.o dpmc.o |
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S index 7924a90d9658..9d475623b724 100644 --- a/arch/blackfin/mach-common/cacheinit.S +++ b/arch/blackfin/mach-common/cacheinit.S | |||
@@ -38,104 +38,37 @@ | |||
38 | 38 | ||
39 | .text | 39 | .text |
40 | 40 | ||
41 | #ifdef ANOMALY_05000125 | ||
41 | #if defined(CONFIG_BLKFIN_CACHE) | 42 | #if defined(CONFIG_BLKFIN_CACHE) |
42 | ENTRY(_bfin_icache_init) | 43 | ENTRY(_bfin_write_IMEM_CONTROL) |
43 | 44 | ||
44 | /* Initialize Instruction CPLBS */ | ||
45 | |||
46 | I0.L = (ICPLB_ADDR0 & 0xFFFF); | ||
47 | I0.H = (ICPLB_ADDR0 >> 16); | ||
48 | |||
49 | I1.L = (ICPLB_DATA0 & 0xFFFF); | ||
50 | I1.H = (ICPLB_DATA0 >> 16); | ||
51 | |||
52 | I2.L = _icplb_table; | ||
53 | I2.H = _icplb_table; | ||
54 | |||
55 | r1 = -1; /* end point comparison */ | ||
56 | r3 = 15; /* max counter */ | ||
57 | |||
58 | /* read entries from table */ | ||
59 | |||
60 | .Lread_iaddr: | ||
61 | R0 = [I2++]; | ||
62 | CC = R0 == R1; | ||
63 | IF CC JUMP .Lidone; | ||
64 | [I0++] = R0; | ||
65 | |||
66 | .Lread_idata: | ||
67 | R2 = [I2++]; | ||
68 | [I1++] = R2; | ||
69 | R3 = R3 + R1; | ||
70 | CC = R3 == R1; | ||
71 | IF !CC JUMP .Lread_iaddr; | ||
72 | |||
73 | .Lidone: | ||
74 | /* Enable Instruction Cache */ | 45 | /* Enable Instruction Cache */ |
75 | P0.l = (IMEM_CONTROL & 0xFFFF); | 46 | P0.l = (IMEM_CONTROL & 0xFFFF); |
76 | P0.h = (IMEM_CONTROL >> 16); | 47 | P0.h = (IMEM_CONTROL >> 16); |
77 | R1 = [P0]; | ||
78 | R0 = (IMC | ENICPLB); | ||
79 | R0 = R0 | R1; | ||
80 | 48 | ||
81 | /* Anomaly 05000125 */ | 49 | /* Anomaly 05000125 */ |
82 | CLI R2; | 50 | CLI R1; |
83 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | 51 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ |
84 | .align 8; | 52 | .align 8; |
85 | [P0] = R0; | 53 | [P0] = R0; |
86 | SSYNC; | 54 | SSYNC; |
87 | STI R2; | 55 | STI R1; |
88 | RTS; | 56 | RTS; |
89 | 57 | ||
90 | ENDPROC(_bfin_icache_init) | 58 | ENDPROC(_bfin_write_IMEM_CONTROL) |
91 | #endif | 59 | #endif |
92 | 60 | ||
93 | #if defined(CONFIG_BLKFIN_DCACHE) | 61 | #if defined(CONFIG_BLKFIN_DCACHE) |
94 | ENTRY(_bfin_dcache_init) | 62 | ENTRY(_bfin_write_DMEM_CONTROL) |
95 | 63 | CLI R1; | |
96 | /* Initialize Data CPLBS */ | ||
97 | |||
98 | I0.L = (DCPLB_ADDR0 & 0xFFFF); | ||
99 | I0.H = (DCPLB_ADDR0 >> 16); | ||
100 | |||
101 | I1.L = (DCPLB_DATA0 & 0xFFFF); | ||
102 | I1.H = (DCPLB_DATA0 >> 16); | ||
103 | |||
104 | I2.L = _dcplb_table; | ||
105 | I2.H = _dcplb_table; | ||
106 | |||
107 | R1 = -1; /* end point comparison */ | ||
108 | R3 = 15; /* max counter */ | ||
109 | |||
110 | /* read entries from table */ | ||
111 | .Lread_daddr: | ||
112 | R0 = [I2++]; | ||
113 | cc = R0 == R1; | ||
114 | IF CC JUMP .Lddone; | ||
115 | [I0++] = R0; | ||
116 | |||
117 | .Lread_ddata: | ||
118 | R2 = [I2++]; | ||
119 | [I1++] = R2; | ||
120 | R3 = R3 + R1; | ||
121 | CC = R3 == R1; | ||
122 | IF !CC JUMP .Lread_daddr; | ||
123 | .Lddone: | ||
124 | P0.L = (DMEM_CONTROL & 0xFFFF); | ||
125 | P0.H = (DMEM_CONTROL >> 16); | ||
126 | R1 = [P0]; | ||
127 | |||
128 | R0 = DMEM_CNTR; | ||
129 | |||
130 | R0 = R0 | R1; | ||
131 | /* Anomaly 05000125 */ | ||
132 | CLI R2; | ||
133 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | 64 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ |
134 | .align 8; | 65 | .align 8; |
135 | [P0] = R0; | 66 | [P0] = R0; |
136 | SSYNC; | 67 | SSYNC; |
137 | STI R2; | 68 | STI R1; |
138 | RTS; | 69 | RTS; |
139 | 70 | ||
140 | ENDPROC(_bfin_dcache_init) | 71 | ENDPROC(_bfin_write_DMEM_CONTROL) |
72 | #endif | ||
73 | |||
141 | #endif | 74 | #endif |
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c index caa9623e6bd6..785ca9816971 100644 --- a/arch/blackfin/mach-common/cplbinfo.c +++ b/arch/blackfin/mach-common/cplbinfo.c | |||
@@ -31,11 +31,10 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
34 | #include <linux/uaccess.h> | ||
34 | 35 | ||
35 | #include <asm/current.h> | 36 | #include <asm/current.h> |
36 | #include <asm/uaccess.h> | ||
37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
38 | |||
39 | #include <asm/cplb.h> | 38 | #include <asm/cplb.h> |
40 | #include <asm/blackfin.h> | 39 | #include <asm/blackfin.h> |
41 | 40 | ||
@@ -92,8 +91,7 @@ static char *cplb_print_entry(char *buf, int type) | |||
92 | } else | 91 | } else |
93 | buf += sprintf(buf, "Data CPLB entry:\n"); | 92 | buf += sprintf(buf, "Data CPLB entry:\n"); |
94 | 93 | ||
95 | buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\ | 94 | buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\n\tiCount\toCount\n"); |
96 | \tiCount\toCount\n"); | ||
97 | 95 | ||
98 | while (*p_addr != 0xffffffff) { | 96 | while (*p_addr != 0xffffffff) { |
99 | entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data); | 97 | entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data); |
@@ -144,8 +142,7 @@ static int cplbinfo_proc_output(char *buf) | |||
144 | 142 | ||
145 | p = buf; | 143 | p = buf; |
146 | 144 | ||
147 | p += sprintf(p, | 145 | p += sprintf(p, "------------------ CPLB Information ------------------\n\n"); |
148 | "------------------ CPLB Information ------------------\n\n"); | ||
149 | 146 | ||
150 | if (bfin_read_IMEM_CONTROL() & ENICPLB) | 147 | if (bfin_read_IMEM_CONTROL() & ENICPLB) |
151 | p = cplb_print_entry(p, CPLB_I); | 148 | p = cplb_print_entry(p, CPLB_I); |
@@ -191,9 +188,9 @@ static int __init cplbinfo_init(void) | |||
191 | { | 188 | { |
192 | struct proc_dir_entry *entry; | 189 | struct proc_dir_entry *entry; |
193 | 190 | ||
194 | if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) { | 191 | entry = create_proc_entry("cplbinfo", 0, NULL); |
192 | if (!entry) | ||
195 | return -ENOMEM; | 193 | return -ENOMEM; |
196 | } | ||
197 | 194 | ||
198 | entry->read_proc = cplbinfo_read_proc; | 195 | entry->read_proc = cplbinfo_read_proc; |
199 | entry->write_proc = cplbinfo_write_proc; | 196 | entry->write_proc = cplbinfo_write_proc; |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 40045b1386ad..d61bba98fb54 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -49,34 +49,15 @@ | |||
49 | 49 | ||
50 | 50 | ||
51 | #include <linux/linkage.h> | 51 | #include <linux/linkage.h> |
52 | #include <linux/unistd.h> | ||
52 | #include <asm/blackfin.h> | 53 | #include <asm/blackfin.h> |
53 | #include <asm/unistd.h> | ||
54 | #include <asm/errno.h> | 54 | #include <asm/errno.h> |
55 | #include <asm/thread_info.h> /* TIF_NEED_RESCHED */ | 55 | #include <asm/thread_info.h> /* TIF_NEED_RESCHED */ |
56 | #include <asm/asm-offsets.h> | 56 | #include <asm/asm-offsets.h> |
57 | #include <asm/trace.h> | ||
57 | 58 | ||
58 | #include <asm/mach-common/context.S> | 59 | #include <asm/mach-common/context.S> |
59 | 60 | ||
60 | #ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE | ||
61 | /* | ||
62 | * TODO: this should be proper save/restore, but for now | ||
63 | * we'll just cheat and use 0x1/0x13 | ||
64 | */ | ||
65 | # define DEBUG_START_HWTRACE \ | ||
66 | P5.l = LO(TBUFCTL); \ | ||
67 | P5.h = HI(TBUFCTL); \ | ||
68 | R7 = 0x13; \ | ||
69 | [P5] = R7; | ||
70 | # define DEBUG_STOP_HWTRACE \ | ||
71 | P5.l = LO(TBUFCTL); \ | ||
72 | P5.h = HI(TBUFCTL); \ | ||
73 | R7 = 0x01; \ | ||
74 | [P5] = R7; | ||
75 | #else | ||
76 | # define DEBUG_START_HWTRACE | ||
77 | # define DEBUG_STOP_HWTRACE | ||
78 | #endif | ||
79 | |||
80 | #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 | 61 | #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 |
81 | .section .l1.text | 62 | .section .l1.text |
82 | #else | 63 | #else |
@@ -110,25 +91,14 @@ ENTRY(_ex_icplb) | |||
110 | ASTAT = [sp++]; | 91 | ASTAT = [sp++]; |
111 | SAVE_ALL_SYS | 92 | SAVE_ALL_SYS |
112 | call __cplb_hdr; | 93 | call __cplb_hdr; |
113 | DEBUG_START_HWTRACE | 94 | DEBUG_START_HWTRACE(p5, r7) |
114 | RESTORE_ALL_SYS | 95 | RESTORE_ALL_SYS |
115 | SP = RETN; | 96 | SP = RETN; |
116 | rtx; | 97 | rtx; |
117 | ENDPROC(_ex_icplb) | 98 | ENDPROC(_ex_icplb) |
118 | 99 | ||
119 | ENTRY(_ex_spinlock) | ||
120 | /* Transform this into a syscall - twiddle the syscall vector. */ | ||
121 | p5.l = lo(EVT15); | ||
122 | p5.h = hi(EVT15); | ||
123 | r7.l = _spinlock_bh; | ||
124 | r7.h = _spinlock_bh; | ||
125 | [p5] = r7; | ||
126 | csync; | ||
127 | /* Fall through. */ | ||
128 | ENDPROC(_ex_spinlock) | ||
129 | |||
130 | ENTRY(_ex_syscall) | 100 | ENTRY(_ex_syscall) |
131 | DEBUG_START_HWTRACE | 101 | DEBUG_START_HWTRACE(p5, r7) |
132 | (R7:6,P5:4) = [sp++]; | 102 | (R7:6,P5:4) = [sp++]; |
133 | ASTAT = [sp++]; | 103 | ASTAT = [sp++]; |
134 | raise 15; /* invoked by TRAP #0, for sys call */ | 104 | raise 15; /* invoked by TRAP #0, for sys call */ |
@@ -136,26 +106,6 @@ ENTRY(_ex_syscall) | |||
136 | rtx | 106 | rtx |
137 | ENDPROC(_ex_syscall) | 107 | ENDPROC(_ex_syscall) |
138 | 108 | ||
139 | ENTRY(_spinlock_bh) | ||
140 | SAVE_ALL_SYS | ||
141 | /* To end up here, vector 15 was changed - so we have to change it | ||
142 | * back. | ||
143 | */ | ||
144 | p0.l = lo(EVT15); | ||
145 | p0.h = hi(EVT15); | ||
146 | p1.l = _evt_system_call; | ||
147 | p1.h = _evt_system_call; | ||
148 | [p0] = p1; | ||
149 | csync; | ||
150 | r0 = [sp + PT_R0]; | ||
151 | sp += -12; | ||
152 | call _sys_bfin_spinlock; | ||
153 | sp += 12; | ||
154 | [SP + PT_R0] = R0; | ||
155 | RESTORE_ALL_SYS | ||
156 | rti; | ||
157 | ENDPROC(_spinlock_bh) | ||
158 | |||
159 | ENTRY(_ex_soft_bp) | 109 | ENTRY(_ex_soft_bp) |
160 | r7 = retx; | 110 | r7 = retx; |
161 | r7 += -2; | 111 | r7 += -2; |
@@ -186,7 +136,7 @@ ENTRY(_ex_single_step) | |||
186 | if !cc jump _ex_trap_c; | 136 | if !cc jump _ex_trap_c; |
187 | 137 | ||
188 | _return_from_exception: | 138 | _return_from_exception: |
189 | DEBUG_START_HWTRACE | 139 | DEBUG_START_HWTRACE(p5, r7) |
190 | #ifdef ANOMALY_05000257 | 140 | #ifdef ANOMALY_05000257 |
191 | R7=LC0; | 141 | R7=LC0; |
192 | LC0=R7; | 142 | LC0=R7; |
@@ -208,7 +158,7 @@ ENTRY(_handle_bad_cplb) | |||
208 | * need to make a CPLB exception look like a normal exception | 158 | * need to make a CPLB exception look like a normal exception |
209 | */ | 159 | */ |
210 | 160 | ||
211 | DEBUG_START_HWTRACE | 161 | DEBUG_START_HWTRACE(p5, r7) |
212 | RESTORE_ALL_SYS | 162 | RESTORE_ALL_SYS |
213 | [--sp] = ASTAT; | 163 | [--sp] = ASTAT; |
214 | [--sp] = (R7:6, P5:4); | 164 | [--sp] = (R7:6, P5:4); |
@@ -251,7 +201,7 @@ ENTRY(_ex_trap_c) | |||
251 | R6 = SEQSTAT; | 201 | R6 = SEQSTAT; |
252 | [P5] = R6; | 202 | [P5] = R6; |
253 | 203 | ||
254 | DEBUG_START_HWTRACE | 204 | DEBUG_START_HWTRACE(p5, r7) |
255 | (R7:6,P5:4) = [sp++]; | 205 | (R7:6,P5:4) = [sp++]; |
256 | ASTAT = [sp++]; | 206 | ASTAT = [sp++]; |
257 | SP = RETN; | 207 | SP = RETN; |
@@ -335,7 +285,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
335 | /* Try to deal with syscalls quickly. */ | 285 | /* Try to deal with syscalls quickly. */ |
336 | [--sp] = ASTAT; | 286 | [--sp] = ASTAT; |
337 | [--sp] = (R7:6, P5:4); | 287 | [--sp] = (R7:6, P5:4); |
338 | DEBUG_STOP_HWTRACE | 288 | DEBUG_STOP_HWTRACE(p5, r7) |
339 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ | 289 | r7 = SEQSTAT; /* reason code is in bit 5:0 */ |
340 | r6.l = lo(SEQSTAT_EXCAUSE); | 290 | r6.l = lo(SEQSTAT_EXCAUSE); |
341 | r6.h = hi(SEQSTAT_EXCAUSE); | 291 | r6.h = hi(SEQSTAT_EXCAUSE); |
@@ -741,6 +691,10 @@ _schedule_and_signal_from_int: | |||
741 | r0 = [p0]; | 691 | r0 = [p0]; |
742 | sti r0; | 692 | sti r0; |
743 | 693 | ||
694 | r0 = sp; | ||
695 | sp += -12; | ||
696 | call _finish_atomic_sections; | ||
697 | sp += 12; | ||
744 | jump.s .Lresume_userspace; | 698 | jump.s .Lresume_userspace; |
745 | 699 | ||
746 | _schedule_and_signal: | 700 | _schedule_and_signal: |
@@ -790,14 +744,14 @@ ENDPROC(_init_exception_buff) | |||
790 | ALIGN | 744 | ALIGN |
791 | _extable: | 745 | _extable: |
792 | /* entry for each EXCAUSE[5:0] | 746 | /* entry for each EXCAUSE[5:0] |
793 | * This table bmust be in sync with the table in ./kernel/traps.c | 747 | * This table must be in sync with the table in ./kernel/traps.c |
794 | * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined | 748 | * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined |
795 | */ | 749 | */ |
796 | .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ | 750 | .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ |
797 | .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ | 751 | .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ |
798 | .long _ex_trap_c /* 0x02 - User Defined */ | 752 | .long _ex_trap_c /* 0x02 - User Defined */ |
799 | .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */ | 753 | .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */ |
800 | .long _ex_spinlock /* 0x04 - User Defined */ | 754 | .long _ex_trap_c /* 0x04 - User Defined */ |
801 | .long _ex_trap_c /* 0x05 - User Defined */ | 755 | .long _ex_trap_c /* 0x05 - User Defined */ |
802 | .long _ex_trap_c /* 0x06 - User Defined */ | 756 | .long _ex_trap_c /* 0x06 - User Defined */ |
803 | .long _ex_trap_c /* 0x07 - User Defined */ | 757 | .long _ex_trap_c /* 0x07 - User Defined */ |
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 8be548e061bf..203e20709163 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/linkage.h> | 34 | #include <linux/linkage.h> |
35 | #include <asm/entry.h> | 35 | #include <asm/entry.h> |
36 | #include <asm/asm-offsets.h> | 36 | #include <asm/asm-offsets.h> |
37 | #include <asm/trace.h> | ||
37 | 38 | ||
38 | #include <asm/mach-common/context.S> | 39 | #include <asm/mach-common/context.S> |
39 | 40 | ||
@@ -170,10 +171,9 @@ ENTRY(_evt_ivhw) | |||
170 | r7.l = W[p5]; | 171 | r7.l = W[p5]; |
171 | 1: | 172 | 1: |
172 | #endif | 173 | #endif |
173 | p0.l = lo(TBUFCTL); | 174 | |
174 | p0.h = hi(TBUFCTL); | 175 | trace_buffer_stop(p0, r0); |
175 | r0 = 1; | 176 | |
176 | [p0] = r0; | ||
177 | r0 = IRQ_HWERR; | 177 | r0 = IRQ_HWERR; |
178 | r1 = sp; | 178 | r1 = sp; |
179 | 179 | ||
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c index 80943bbd37c2..6b9fd03ce835 100644 --- a/arch/blackfin/mach-common/ints-priority-dc.c +++ b/arch/blackfin/mach-common/ints-priority-dc.c | |||
@@ -183,7 +183,7 @@ static void bf561_gpio_ack_irq(unsigned int irq) | |||
183 | { | 183 | { |
184 | u16 gpionr = irq - IRQ_PF0; | 184 | u16 gpionr = irq - IRQ_PF0; |
185 | 185 | ||
186 | if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 186 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { |
187 | set_gpio_data(gpionr, 0); | 187 | set_gpio_data(gpionr, 0); |
188 | SSYNC(); | 188 | SSYNC(); |
189 | } | 189 | } |
@@ -193,7 +193,7 @@ static void bf561_gpio_mask_ack_irq(unsigned int irq) | |||
193 | { | 193 | { |
194 | u16 gpionr = irq - IRQ_PF0; | 194 | u16 gpionr = irq - IRQ_PF0; |
195 | 195 | ||
196 | if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { | 196 | if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { |
197 | set_gpio_data(gpionr, 0); | 197 | set_gpio_data(gpionr, 0); |
198 | SSYNC(); | 198 | SSYNC(); |
199 | } | 199 | } |
@@ -222,7 +222,7 @@ static unsigned int bf561_gpio_irq_startup(unsigned int irq) | |||
222 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 222 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
223 | 223 | ||
224 | ret = gpio_request(gpionr, NULL); | 224 | ret = gpio_request(gpionr, NULL); |
225 | if(ret) | 225 | if (ret) |
226 | return ret; | 226 | return ret; |
227 | 227 | ||
228 | } | 228 | } |
@@ -262,7 +262,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type) | |||
262 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 262 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
263 | 263 | ||
264 | ret = gpio_request(gpionr, NULL); | 264 | ret = gpio_request(gpionr, NULL); |
265 | if(ret) | 265 | if (ret) |
266 | return ret; | 266 | return ret; |
267 | 267 | ||
268 | } | 268 | } |
@@ -371,6 +371,9 @@ int __init init_arch_irq(void) | |||
371 | bfin_write_SICA_IMASK1(SIC_UNMASK_ALL); | 371 | bfin_write_SICA_IMASK1(SIC_UNMASK_ALL); |
372 | SSYNC(); | 372 | SSYNC(); |
373 | 373 | ||
374 | bfin_write_SICA_IWR0(IWR_ENABLE_ALL); | ||
375 | bfin_write_SICA_IWR1(IWR_ENABLE_ALL); | ||
376 | |||
374 | local_irq_disable(); | 377 | local_irq_disable(); |
375 | 378 | ||
376 | init_exception_buff(); | 379 | init_exception_buff(); |
@@ -393,7 +396,7 @@ int __init init_arch_irq(void) | |||
393 | bfin_write_EVT15(evt_system_call); | 396 | bfin_write_EVT15(evt_system_call); |
394 | CSYNC(); | 397 | CSYNC(); |
395 | 398 | ||
396 | for (irq = 0; irq < SYS_IRQS; irq++) { | 399 | for (irq = 0; irq <= SYS_IRQS; irq++) { |
397 | if (irq <= IRQ_CORETMR) | 400 | if (irq <= IRQ_CORETMR) |
398 | set_irq_chip(irq, &bf561_core_irqchip); | 401 | set_irq_chip(irq, &bf561_core_irqchip); |
399 | else | 402 | else |
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c index 2cfc7d5aec5c..28a878c3577a 100644 --- a/arch/blackfin/mach-common/ints-priority-sc.c +++ b/arch/blackfin/mach-common/ints-priority-sc.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> | 13 | * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca> |
14 | * 2003 Metrowerks/Motorola | 14 | * 2003 Metrowerks/Motorola |
15 | * 2003 Bas Vermeulen <bas@buyways.nl> | 15 | * 2003 Bas Vermeulen <bas@buyways.nl> |
16 | * Copyright 2004-2006 Analog Devices Inc. | 16 | * Copyright 2004-2007 Analog Devices Inc. |
17 | * | 17 | * |
18 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 18 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
19 | * | 19 | * |
@@ -65,9 +65,9 @@ atomic_t num_spurious; | |||
65 | 65 | ||
66 | struct ivgx { | 66 | struct ivgx { |
67 | /* irq number for request_irq, available in mach-bf533/irq.h */ | 67 | /* irq number for request_irq, available in mach-bf533/irq.h */ |
68 | int irqno; | 68 | unsigned int irqno; |
69 | /* corresponding bit in the SIC_ISR register */ | 69 | /* corresponding bit in the SIC_ISR register */ |
70 | int isrflag; | 70 | unsigned int isrflag; |
71 | } ivg_table[NR_PERI_INTS]; | 71 | } ivg_table[NR_PERI_INTS]; |
72 | 72 | ||
73 | struct ivg_slice { | 73 | struct ivg_slice { |
@@ -88,17 +88,16 @@ static void __init search_IAR(void) | |||
88 | for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { | 88 | for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { |
89 | int irqn; | 89 | int irqn; |
90 | 90 | ||
91 | ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = | 91 | ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos]; |
92 | &ivg_table[irq_pos]; | ||
93 | 92 | ||
94 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { | 93 | for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { |
95 | int iar_shift = (irqn & 7) * 4; | 94 | int iar_shift = (irqn & 7) * 4; |
96 | if (ivg == | 95 | if (ivg == |
97 | (0xf & | 96 | (0xf & |
98 | bfin_read32((unsigned long *) SIC_IAR0 + | 97 | bfin_read32((unsigned long *)SIC_IAR0 + |
99 | (irqn >> 3)) >> iar_shift)) { | 98 | (irqn >> 3)) >> iar_shift)) { |
100 | ivg_table[irq_pos].irqno = IVG7 + irqn; | 99 | ivg_table[irq_pos].irqno = IVG7 + irqn; |
101 | ivg_table[irq_pos].isrflag = 1 << irqn; | 100 | ivg_table[irq_pos].isrflag = 1 << (irqn % 32); |
102 | ivg7_13[ivg].istop++; | 101 | ivg7_13[ivg].istop++; |
103 | irq_pos++; | 102 | irq_pos++; |
104 | } | 103 | } |
@@ -141,15 +140,31 @@ static void bfin_core_unmask_irq(unsigned int irq) | |||
141 | 140 | ||
142 | static void bfin_internal_mask_irq(unsigned int irq) | 141 | static void bfin_internal_mask_irq(unsigned int irq) |
143 | { | 142 | { |
143 | #ifndef CONFIG_BF54x | ||
144 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & | 144 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & |
145 | ~(1 << (irq - (IRQ_CORETMR + 1)))); | 145 | ~(1 << (irq - (IRQ_CORETMR + 1)))); |
146 | #else | ||
147 | unsigned mask_bank, mask_bit; | ||
148 | mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; | ||
149 | mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; | ||
150 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & | ||
151 | ~(1 << mask_bit)); | ||
152 | #endif | ||
146 | SSYNC(); | 153 | SSYNC(); |
147 | } | 154 | } |
148 | 155 | ||
149 | static void bfin_internal_unmask_irq(unsigned int irq) | 156 | static void bfin_internal_unmask_irq(unsigned int irq) |
150 | { | 157 | { |
158 | #ifndef CONFIG_BF54x | ||
151 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | | 159 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | |
152 | (1 << (irq - (IRQ_CORETMR + 1)))); | 160 | (1 << (irq - (IRQ_CORETMR + 1)))); |
161 | #else | ||
162 | unsigned mask_bank, mask_bit; | ||
163 | mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; | ||
164 | mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; | ||
165 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | | ||
166 | (1 << mask_bit)); | ||
167 | #endif | ||
153 | SSYNC(); | 168 | SSYNC(); |
154 | } | 169 | } |
155 | 170 | ||
@@ -206,7 +221,7 @@ static struct irq_chip bfin_generic_error_irqchip = { | |||
206 | }; | 221 | }; |
207 | 222 | ||
208 | static void bfin_demux_error_irq(unsigned int int_err_irq, | 223 | static void bfin_demux_error_irq(unsigned int int_err_irq, |
209 | struct irq_desc *intb_desc) | 224 | struct irq_desc *intb_desc) |
210 | { | 225 | { |
211 | int irq = 0; | 226 | int irq = 0; |
212 | 227 | ||
@@ -270,8 +285,8 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
270 | } | 285 | } |
271 | 286 | ||
272 | pr_debug("IRQ %d:" | 287 | pr_debug("IRQ %d:" |
273 | " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", | 288 | " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", |
274 | irq); | 289 | irq); |
275 | } | 290 | } |
276 | } else | 291 | } else |
277 | printk(KERN_ERR | 292 | printk(KERN_ERR |
@@ -279,11 +294,10 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, | |||
279 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", | 294 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", |
280 | __FUNCTION__, __FILE__, __LINE__); | 295 | __FUNCTION__, __FILE__, __LINE__); |
281 | 296 | ||
282 | |||
283 | } | 297 | } |
284 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ | 298 | #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ |
285 | 299 | ||
286 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 300 | #if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x) |
287 | 301 | ||
288 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 302 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
289 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 303 | static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -361,8 +375,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
361 | } | 375 | } |
362 | 376 | ||
363 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | 377 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | |
364 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | 378 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { |
365 | { | ||
366 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | 379 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { |
367 | ret = gpio_request(gpionr, NULL); | 380 | ret = gpio_request(gpionr, NULL); |
368 | if (ret) | 381 | if (ret) |
@@ -407,7 +420,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | |||
407 | return 0; | 420 | return 0; |
408 | } | 421 | } |
409 | 422 | ||
410 | |||
411 | static struct irq_chip bfin_gpio_irqchip = { | 423 | static struct irq_chip bfin_gpio_irqchip = { |
412 | .ack = bfin_gpio_ack_irq, | 424 | .ack = bfin_gpio_ack_irq, |
413 | .mask = bfin_gpio_mask_irq, | 425 | .mask = bfin_gpio_mask_irq, |
@@ -419,20 +431,20 @@ static struct irq_chip bfin_gpio_irqchip = { | |||
419 | }; | 431 | }; |
420 | 432 | ||
421 | static void bfin_demux_gpio_irq(unsigned int intb_irq, | 433 | static void bfin_demux_gpio_irq(unsigned int intb_irq, |
422 | struct irq_desc *intb_desc) | 434 | struct irq_desc *intb_desc) |
423 | { | 435 | { |
424 | u16 i; | 436 | u16 i; |
437 | struct irq_desc *desc; | ||
425 | 438 | ||
426 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) { | 439 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) { |
427 | int irq = IRQ_PF0 + i; | 440 | int irq = IRQ_PF0 + i; |
428 | int flag_d = get_gpiop_data(i); | 441 | int flag_d = get_gpiop_data(i); |
429 | int mask = | 442 | int mask = |
430 | flag_d & (gpio_enabled[gpio_bank(i)] & | 443 | flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i)); |
431 | get_gpiop_maska(i)); | ||
432 | 444 | ||
433 | while (mask) { | 445 | while (mask) { |
434 | if (mask & 1) { | 446 | if (mask & 1) { |
435 | struct irq_desc *desc = irq_desc + irq; | 447 | desc = irq_desc + irq; |
436 | desc->handle_irq(irq, desc); | 448 | desc->handle_irq(irq, desc); |
437 | } | 449 | } |
438 | irq++; | 450 | irq++; |
@@ -441,6 +453,264 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq, | |||
441 | } | 453 | } |
442 | } | 454 | } |
443 | 455 | ||
456 | #else /* CONFIG_IRQCHIP_DEMUX_GPIO */ | ||
457 | |||
458 | #define NR_PINT_SYS_IRQS 4 | ||
459 | #define NR_PINT_BITS 32 | ||
460 | #define NR_PINTS 160 | ||
461 | #define IRQ_NOT_AVAIL 0xFF | ||
462 | |||
463 | #define PINT_2_BANK(x) ((x) >> 5) | ||
464 | #define PINT_2_BIT(x) ((x) & 0x1F) | ||
465 | #define PINT_BIT(x) (1 << (PINT_2_BIT(x))) | ||
466 | |||
467 | static unsigned char irq2pint_lut[NR_PINTS]; | ||
468 | static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS]; | ||
469 | |||
470 | struct pin_int_t { | ||
471 | unsigned int mask_set; | ||
472 | unsigned int mask_clear; | ||
473 | unsigned int request; | ||
474 | unsigned int assign; | ||
475 | unsigned int edge_set; | ||
476 | unsigned int edge_clear; | ||
477 | unsigned int invert_set; | ||
478 | unsigned int invert_clear; | ||
479 | unsigned int pinstate; | ||
480 | unsigned int latch; | ||
481 | }; | ||
482 | |||
483 | static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { | ||
484 | (struct pin_int_t *)PINT0_MASK_SET, | ||
485 | (struct pin_int_t *)PINT1_MASK_SET, | ||
486 | (struct pin_int_t *)PINT2_MASK_SET, | ||
487 | (struct pin_int_t *)PINT3_MASK_SET, | ||
488 | }; | ||
489 | |||
490 | unsigned short get_irq_base(u8 bank, u8 bmap) | ||
491 | { | ||
492 | |||
493 | u16 irq_base; | ||
494 | |||
495 | if (bank < 2) { /*PA-PB */ | ||
496 | irq_base = IRQ_PA0 + bmap * 16; | ||
497 | } else { /*PC-PJ */ | ||
498 | irq_base = IRQ_PC0 + bmap * 16; | ||
499 | } | ||
500 | |||
501 | return irq_base; | ||
502 | |||
503 | } | ||
504 | |||
505 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | ||
506 | void init_pint_lut(void) | ||
507 | { | ||
508 | u16 bank, bit, irq_base, bit_pos; | ||
509 | u32 pint_assign; | ||
510 | u8 bmap; | ||
511 | |||
512 | memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut)); | ||
513 | |||
514 | for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) { | ||
515 | |||
516 | pint_assign = pint[bank]->assign; | ||
517 | |||
518 | for (bit = 0; bit < NR_PINT_BITS; bit++) { | ||
519 | |||
520 | bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF; | ||
521 | |||
522 | irq_base = get_irq_base(bank, bmap); | ||
523 | |||
524 | irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0); | ||
525 | bit_pos = bit + bank * NR_PINT_BITS; | ||
526 | |||
527 | pint2irq_lut[bit_pos] = irq_base - SYS_IRQS; | ||
528 | irq2pint_lut[irq_base - SYS_IRQS] = bit_pos; | ||
529 | |||
530 | } | ||
531 | |||
532 | } | ||
533 | |||
534 | } | ||
535 | |||
536 | static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
537 | |||
538 | static void bfin_gpio_ack_irq(unsigned int irq) | ||
539 | { | ||
540 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
541 | |||
542 | pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val); | ||
543 | SSYNC(); | ||
544 | } | ||
545 | |||
546 | static void bfin_gpio_mask_ack_irq(unsigned int irq) | ||
547 | { | ||
548 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
549 | u32 pintbit = PINT_BIT(pint_val); | ||
550 | u8 bank = PINT_2_BANK(pint_val); | ||
551 | |||
552 | pint[bank]->request = pintbit; | ||
553 | pint[bank]->mask_clear = pintbit; | ||
554 | SSYNC(); | ||
555 | } | ||
556 | |||
557 | static void bfin_gpio_mask_irq(unsigned int irq) | ||
558 | { | ||
559 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
560 | |||
561 | pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val); | ||
562 | SSYNC(); | ||
563 | } | ||
564 | |||
565 | static void bfin_gpio_unmask_irq(unsigned int irq) | ||
566 | { | ||
567 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
568 | u32 pintbit = PINT_BIT(pint_val); | ||
569 | u8 bank = PINT_2_BANK(pint_val); | ||
570 | |||
571 | pint[bank]->request = pintbit; | ||
572 | pint[bank]->mask_set = pintbit; | ||
573 | SSYNC(); | ||
574 | } | ||
575 | |||
576 | static unsigned int bfin_gpio_irq_startup(unsigned int irq) | ||
577 | { | ||
578 | unsigned int ret; | ||
579 | u16 gpionr = irq - IRQ_PA0; | ||
580 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
581 | |||
582 | if (pint_val == IRQ_NOT_AVAIL) | ||
583 | return -ENODEV; | ||
584 | |||
585 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | ||
586 | ret = gpio_request(gpionr, NULL); | ||
587 | if (ret) | ||
588 | return ret; | ||
589 | } | ||
590 | |||
591 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
592 | bfin_gpio_unmask_irq(irq); | ||
593 | |||
594 | return ret; | ||
595 | } | ||
596 | |||
597 | static void bfin_gpio_irq_shutdown(unsigned int irq) | ||
598 | { | ||
599 | bfin_gpio_mask_irq(irq); | ||
600 | gpio_free(irq - IRQ_PA0); | ||
601 | gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0); | ||
602 | } | ||
603 | |||
604 | static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) | ||
605 | { | ||
606 | |||
607 | unsigned int ret; | ||
608 | u16 gpionr = irq - IRQ_PA0; | ||
609 | u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; | ||
610 | u32 pintbit = PINT_BIT(pint_val); | ||
611 | u8 bank = PINT_2_BANK(pint_val); | ||
612 | |||
613 | if (pint_val == IRQ_NOT_AVAIL) | ||
614 | return -ENODEV; | ||
615 | |||
616 | if (type == IRQ_TYPE_PROBE) { | ||
617 | /* only probe unenabled GPIO interrupt lines */ | ||
618 | if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) | ||
619 | return 0; | ||
620 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
621 | } | ||
622 | |||
623 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | ||
624 | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | ||
625 | if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { | ||
626 | ret = gpio_request(gpionr, NULL); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); | ||
632 | } else { | ||
633 | gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | gpio_direction_input(gpionr); | ||
638 | |||
639 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | ||
640 | pint[bank]->edge_set = pintbit; | ||
641 | } else { | ||
642 | pint[bank]->edge_clear = pintbit; | ||
643 | } | ||
644 | |||
645 | if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | ||
646 | pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ | ||
647 | else | ||
648 | pint[bank]->invert_set = pintbit; /* high or rising edge denoted by zero */ | ||
649 | |||
650 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | ||
651 | pint[bank]->invert_set = pintbit; | ||
652 | else | ||
653 | pint[bank]->invert_set = pintbit; | ||
654 | |||
655 | SSYNC(); | ||
656 | |||
657 | if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) | ||
658 | set_irq_handler(irq, handle_edge_irq); | ||
659 | else | ||
660 | set_irq_handler(irq, handle_level_irq); | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static struct irq_chip bfin_gpio_irqchip = { | ||
666 | .ack = bfin_gpio_ack_irq, | ||
667 | .mask = bfin_gpio_mask_irq, | ||
668 | .mask_ack = bfin_gpio_mask_ack_irq, | ||
669 | .unmask = bfin_gpio_unmask_irq, | ||
670 | .set_type = bfin_gpio_irq_type, | ||
671 | .startup = bfin_gpio_irq_startup, | ||
672 | .shutdown = bfin_gpio_irq_shutdown | ||
673 | }; | ||
674 | |||
675 | static void bfin_demux_gpio_irq(unsigned int intb_irq, | ||
676 | struct irq_desc *intb_desc) | ||
677 | { | ||
678 | u8 bank, pint_val; | ||
679 | u32 request, irq; | ||
680 | struct irq_desc *desc; | ||
681 | |||
682 | switch (intb_irq) { | ||
683 | case IRQ_PINT0: | ||
684 | bank = 0; | ||
685 | break; | ||
686 | case IRQ_PINT2: | ||
687 | bank = 2; | ||
688 | break; | ||
689 | case IRQ_PINT3: | ||
690 | bank = 3; | ||
691 | break; | ||
692 | case IRQ_PINT1: | ||
693 | bank = 1; | ||
694 | break; | ||
695 | default: | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | pint_val = bank * NR_PINT_BITS; | ||
700 | |||
701 | request = pint[bank]->request; | ||
702 | |||
703 | while (request) { | ||
704 | if (request & 1) { | ||
705 | irq = pint2irq_lut[pint_val] + SYS_IRQS; | ||
706 | desc = irq_desc + irq; | ||
707 | desc->handle_irq(irq, desc); | ||
708 | } | ||
709 | pint_val++; | ||
710 | request >>= 1; | ||
711 | } | ||
712 | |||
713 | } | ||
444 | #endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ | 714 | #endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ |
445 | 715 | ||
446 | /* | 716 | /* |
@@ -452,7 +722,18 @@ int __init init_arch_irq(void) | |||
452 | int irq; | 722 | int irq; |
453 | unsigned long ilat = 0; | 723 | unsigned long ilat = 0; |
454 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ | 724 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ |
725 | #ifdef CONFIG_BF54x | ||
726 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); | ||
727 | bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); | ||
728 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); | ||
729 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | ||
730 | bfin_write_SIC_IWR1(IWR_ENABLE_ALL); | ||
731 | bfin_write_SIC_IWR2(IWR_ENABLE_ALL); | ||
732 | #else | ||
455 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); | 733 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); |
734 | bfin_write_SIC_IWR(IWR_ENABLE_ALL); | ||
735 | #endif | ||
736 | |||
456 | SSYNC(); | 737 | SSYNC(); |
457 | 738 | ||
458 | local_irq_disable(); | 739 | local_irq_disable(); |
@@ -475,7 +756,18 @@ int __init init_arch_irq(void) | |||
475 | bfin_write_EVT15(evt_system_call); | 756 | bfin_write_EVT15(evt_system_call); |
476 | CSYNC(); | 757 | CSYNC(); |
477 | 758 | ||
478 | for (irq = 0; irq < SYS_IRQS; irq++) { | 759 | #if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x) |
760 | #ifdef CONFIG_PINTx_REASSIGN | ||
761 | pint[0]->assign = CONFIG_PINT0_ASSIGN; | ||
762 | pint[1]->assign = CONFIG_PINT1_ASSIGN; | ||
763 | pint[2]->assign = CONFIG_PINT2_ASSIGN; | ||
764 | pint[3]->assign = CONFIG_PINT3_ASSIGN; | ||
765 | #endif | ||
766 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | ||
767 | init_pint_lut(); | ||
768 | #endif | ||
769 | |||
770 | for (irq = 0; irq <= SYS_IRQS; irq++) { | ||
479 | if (irq <= IRQ_CORETMR) | 771 | if (irq <= IRQ_CORETMR) |
480 | set_irq_chip(irq, &bfin_core_irqchip); | 772 | set_irq_chip(irq, &bfin_core_irqchip); |
481 | else | 773 | else |
@@ -484,20 +776,42 @@ int __init init_arch_irq(void) | |||
484 | if (irq != IRQ_GENERIC_ERROR) { | 776 | if (irq != IRQ_GENERIC_ERROR) { |
485 | #endif | 777 | #endif |
486 | 778 | ||
779 | switch (irq) { | ||
487 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 780 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO |
488 | if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ | 781 | #ifndef CONFIG_BF54x |
489 | # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | 782 | case IRQ_PROG_INTA: |
490 | && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ | 783 | set_irq_chained_handler(irq, |
491 | # endif | 784 | bfin_demux_gpio_irq); |
492 | ) { | 785 | break; |
786 | #if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) | ||
787 | case IRQ_MAC_RX: | ||
788 | set_irq_chained_handler(irq, | ||
789 | bfin_demux_gpio_irq); | ||
790 | break; | ||
493 | #endif | 791 | #endif |
494 | set_irq_handler(irq, handle_simple_irq); | 792 | #else |
495 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 793 | case IRQ_PINT0: |
496 | } else { | ||
497 | set_irq_chained_handler(irq, | 794 | set_irq_chained_handler(irq, |
498 | bfin_demux_gpio_irq); | 795 | bfin_demux_gpio_irq); |
499 | } | 796 | break; |
797 | case IRQ_PINT1: | ||
798 | set_irq_chained_handler(irq, | ||
799 | bfin_demux_gpio_irq); | ||
800 | break; | ||
801 | case IRQ_PINT2: | ||
802 | set_irq_chained_handler(irq, | ||
803 | bfin_demux_gpio_irq); | ||
804 | break; | ||
805 | case IRQ_PINT3: | ||
806 | set_irq_chained_handler(irq, | ||
807 | bfin_demux_gpio_irq); | ||
808 | break; | ||
809 | #endif /*CONFIG_BF54x */ | ||
500 | #endif | 810 | #endif |
811 | default: | ||
812 | set_irq_handler(irq, handle_simple_irq); | ||
813 | break; | ||
814 | } | ||
501 | 815 | ||
502 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX | 816 | #ifdef BF537_GENERIC_ERROR_INT_DEMUX |
503 | } else { | 817 | } else { |
@@ -513,7 +827,11 @@ int __init init_arch_irq(void) | |||
513 | #endif | 827 | #endif |
514 | 828 | ||
515 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO | 829 | #ifdef CONFIG_IRQCHIP_DEMUX_GPIO |
830 | #ifndef CONFIG_BF54x | ||
516 | for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { | 831 | for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { |
832 | #else | ||
833 | for (irq = IRQ_PA0; irq < NR_IRQS; irq++) { | ||
834 | #endif | ||
517 | set_irq_chip(irq, &bfin_gpio_irqchip); | 835 | set_irq_chip(irq, &bfin_gpio_irqchip); |
518 | /* if configured as edge, then will be changed to do_edge_IRQ */ | 836 | /* if configured as edge, then will be changed to do_edge_IRQ */ |
519 | set_irq_handler(irq, handle_level_irq); | 837 | set_irq_handler(irq, handle_level_irq); |
@@ -526,8 +844,7 @@ int __init init_arch_irq(void) | |||
526 | bfin_write_ILAT(ilat); | 844 | bfin_write_ILAT(ilat); |
527 | CSYNC(); | 845 | CSYNC(); |
528 | 846 | ||
529 | printk(KERN_INFO | 847 | printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); |
530 | "Configuring Blackfin Priority Driven Interrupts\n"); | ||
531 | /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, | 848 | /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, |
532 | * local_irq_enable() | 849 | * local_irq_enable() |
533 | */ | 850 | */ |
@@ -538,14 +855,13 @@ int __init init_arch_irq(void) | |||
538 | /* Enable interrupts IVG7-15 */ | 855 | /* Enable interrupts IVG7-15 */ |
539 | irq_flags = irq_flags | IMASK_IVG15 | | 856 | irq_flags = irq_flags | IMASK_IVG15 | |
540 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | 857 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | |
541 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | | 858 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
542 | IMASK_IVGHW; | ||
543 | 859 | ||
544 | return 0; | 860 | return 0; |
545 | } | 861 | } |
546 | 862 | ||
547 | #ifdef CONFIG_DO_IRQ_L1 | 863 | #ifdef CONFIG_DO_IRQ_L1 |
548 | void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); | 864 | void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text)); |
549 | #endif | 865 | #endif |
550 | 866 | ||
551 | void do_irq(int vec, struct pt_regs *fp) | 867 | void do_irq(int vec, struct pt_regs *fp) |
@@ -555,9 +871,25 @@ void do_irq(int vec, struct pt_regs *fp) | |||
555 | } else { | 871 | } else { |
556 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; | 872 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; |
557 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; | 873 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; |
558 | unsigned long sic_status; | 874 | #ifdef CONFIG_BF54x |
875 | unsigned long sic_status[3]; | ||
559 | 876 | ||
560 | SSYNC(); | 877 | SSYNC(); |
878 | sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0); | ||
879 | sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1); | ||
880 | sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2); | ||
881 | |||
882 | for (;; ivg++) { | ||
883 | if (ivg >= ivg_stop) { | ||
884 | atomic_inc(&num_spurious); | ||
885 | return; | ||
886 | } | ||
887 | if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag) | ||
888 | break; | ||
889 | } | ||
890 | #else | ||
891 | unsigned long sic_status; | ||
892 | SSYNC(); | ||
561 | sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); | 893 | sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); |
562 | 894 | ||
563 | for (;; ivg++) { | 895 | for (;; ivg++) { |
@@ -567,6 +899,7 @@ void do_irq(int vec, struct pt_regs *fp) | |||
567 | } else if (sic_status & ivg->isrflag) | 899 | } else if (sic_status & ivg->isrflag) |
568 | break; | 900 | break; |
569 | } | 901 | } |
902 | #endif | ||
570 | vec = ivg->irqno; | 903 | vec = ivg->irqno; |
571 | } | 904 | } |
572 | asm_do_IRQ(vec, fp); | 905 | asm_do_IRQ(vec, fp); |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 150ef5d088dc..1772d8d2c1a7 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -35,10 +35,10 @@ | |||
35 | #include <linux/pm.h> | 35 | #include <linux/pm.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/io.h> | ||
39 | #include <linux/irq.h> | ||
38 | 40 | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/dpmc.h> | 41 | #include <asm/dpmc.h> |
41 | #include <asm/irq.h> | ||
42 | #include <asm/gpio.h> | 42 | #include <asm/gpio.h> |
43 | 43 | ||
44 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H | 44 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H |