aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 16:25:24 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 16:25:24 -0400
commit82afee684fe3badaf5ee3fc5b6fda687d558bfb5 (patch)
tree295abb35451a7eb1e46d6066e536e23d1a75668b /arch/blackfin/mach-common
parent068345f4a873e8b0b511e8f94a595a20e176eeff (diff)
parentf4d640c9be1979a603ed017e1e03a16ba3a4d7a1 (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/Makefile4
-rw-r--r--arch/blackfin/mach-common/cacheinit.S89
-rw-r--r--arch/blackfin/mach-common/cplbinfo.c13
-rw-r--r--arch/blackfin/mach-common/entry.S76
-rw-r--r--arch/blackfin/mach-common/interrupt.S8
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c13
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c405
-rw-r--r--arch/blackfin/mach-common/pm.c4
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
5obj-y := \ 5obj-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
9obj-$(CONFIG_CPLB_INFO) += cplbinfo.o 9obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
10obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o 10obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o
11obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o 11obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o
12obj-$(CONFIG_PM) += pm.o 12obj-$(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)
42ENTRY(_bfin_icache_init) 43ENTRY(_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
90ENDPROC(_bfin_icache_init) 58ENDPROC(_bfin_write_IMEM_CONTROL)
91#endif 59#endif
92 60
93#if defined(CONFIG_BLKFIN_DCACHE) 61#if defined(CONFIG_BLKFIN_DCACHE)
94ENTRY(_bfin_dcache_init) 62ENTRY(_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
140ENDPROC(_bfin_dcache_init) 71ENDPROC(_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;
117ENDPROC(_ex_icplb) 98ENDPROC(_ex_icplb)
118 99
119ENTRY(_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. */
128ENDPROC(_ex_spinlock)
129
130ENTRY(_ex_syscall) 100ENTRY(_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
137ENDPROC(_ex_syscall) 107ENDPROC(_ex_syscall)
138 108
139ENTRY(_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;
157ENDPROC(_spinlock_bh)
158
159ENTRY(_ex_soft_bp) 109ENTRY(_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)
790ALIGN 744ALIGN
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];
1711: 1721:
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
66struct ivgx { 66struct 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
73struct ivg_slice { 73struct 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
142static void bfin_internal_mask_irq(unsigned int irq) 141static 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
149static void bfin_internal_unmask_irq(unsigned int irq) 156static 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
208static void bfin_demux_error_irq(unsigned int int_err_irq, 223static 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
288static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; 302static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
289static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; 303static 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
411static struct irq_chip bfin_gpio_irqchip = { 423static 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
421static void bfin_demux_gpio_irq(unsigned int intb_irq, 433static 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
467static unsigned char irq2pint_lut[NR_PINTS];
468static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
469
470struct 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
483static 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
490unsigned 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! */
506void 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
536static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
537
538static 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
546static 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
557static 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
565static 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
576static 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
597static 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
604static 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
665static 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
675static 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
548void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); 864void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text));
549#endif 865#endif
550 866
551void do_irq(int vec, struct pt_regs *fp) 867void 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