diff options
Diffstat (limited to 'arch')
25 files changed, 490 insertions, 497 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f943736541cb..235d4514e0a9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -133,6 +133,7 @@ config LASAT | |||
133 | select DMA_NONCOHERENT | 133 | select DMA_NONCOHERENT |
134 | select SYS_HAS_EARLY_PRINTK | 134 | select SYS_HAS_EARLY_PRINTK |
135 | select HW_HAS_PCI | 135 | select HW_HAS_PCI |
136 | select IRQ_CPU | ||
136 | select PCI_GT64XXX_PCI0 | 137 | select PCI_GT64XXX_PCI0 |
137 | select MIPS_NILE4 | 138 | select MIPS_NILE4 |
138 | select R5000_CPU_SCACHE | 139 | select R5000_CPU_SCACHE |
@@ -410,6 +411,7 @@ config SGI_IP32 | |||
410 | select BOOT_ELF32 | 411 | select BOOT_ELF32 |
411 | select DMA_NONCOHERENT | 412 | select DMA_NONCOHERENT |
412 | select HW_HAS_PCI | 413 | select HW_HAS_PCI |
414 | select IRQ_CPU | ||
413 | select R5000_CPU_SCACHE | 415 | select R5000_CPU_SCACHE |
414 | select RM7000_CPU_SCACHE | 416 | select RM7000_CPU_SCACHE |
415 | select SYS_HAS_CPU_R5000 | 417 | select SYS_HAS_CPU_R5000 |
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c index 7acfe9bf5fc3..98a4e34b0248 100644 --- a/arch/mips/au1000/common/au1xxx_irqmap.c +++ b/arch/mips/au1000/common/au1xxx_irqmap.c | |||
@@ -54,7 +54,7 @@ | |||
54 | * Careful if you change match 2 request! | 54 | * Careful if you change match 2 request! |
55 | * The interrupt handler is called directly from the low level dispatch code. | 55 | * The interrupt handler is called directly from the low level dispatch code. |
56 | */ | 56 | */ |
57 | au1xxx_irq_map_t __initdata au1xxx_ic0_map[] = { | 57 | struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { |
58 | 58 | ||
59 | #if defined(CONFIG_SOC_AU1000) | 59 | #if defined(CONFIG_SOC_AU1000) |
60 | { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, | 60 | { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, |
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index 461cf0139737..9d6ad43fded6 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c | |||
@@ -859,7 +859,7 @@ dbdma_interrupt(int irq, void *dev_id) | |||
859 | 859 | ||
860 | intstat = dbdma_gptr->ddma_intstat; | 860 | intstat = dbdma_gptr->ddma_intstat; |
861 | au_sync(); | 861 | au_sync(); |
862 | chan_index = au_ffs(intstat) - 1; | 862 | chan_index = ffs(intstat); |
863 | 863 | ||
864 | ctp = chan_tab_ptr[chan_index]; | 864 | ctp = chan_tab_ptr[chan_index]; |
865 | cp = ctp->chan_ptr; | 865 | cp = ctp->chan_ptr; |
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index a6640b998c6e..c00f308fd505 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -26,39 +26,18 @@ | |||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | 26 | * with this program; if not, write to the Free Software Foundation, Inc., |
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 27 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
28 | */ | 28 | */ |
29 | #include <linux/errno.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/irq.h> | 31 | #include <linux/io.h> |
32 | #include <linux/kernel_stat.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/signal.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/types.h> | ||
37 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
38 | #include <linux/ioport.h> | 33 | #include <linux/irq.h> |
39 | #include <linux/timex.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/random.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/bitops.h> | ||
44 | 34 | ||
45 | #include <asm/bootinfo.h> | ||
46 | #include <asm/io.h> | ||
47 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
48 | #include <asm/system.h> | ||
49 | #include <asm/mach-au1x00/au1000.h> | 36 | #include <asm/mach-au1x00/au1000.h> |
50 | #ifdef CONFIG_MIPS_PB1000 | 37 | #ifdef CONFIG_MIPS_PB1000 |
51 | #include <asm/mach-pb1x00/pb1000.h> | 38 | #include <asm/mach-pb1x00/pb1000.h> |
52 | #endif | 39 | #endif |
53 | 40 | ||
54 | #undef DEBUG_IRQ | ||
55 | #ifdef DEBUG_IRQ | ||
56 | /* note: prints function name for you */ | ||
57 | #define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) | ||
58 | #else | ||
59 | #define DPRINTK(fmt, args...) | ||
60 | #endif | ||
61 | |||
62 | #define EXT_INTC0_REQ0 2 /* IP 2 */ | 41 | #define EXT_INTC0_REQ0 2 /* IP 2 */ |
63 | #define EXT_INTC0_REQ1 3 /* IP 3 */ | 42 | #define EXT_INTC0_REQ1 3 /* IP 3 */ |
64 | #define EXT_INTC1_REQ0 4 /* IP 4 */ | 43 | #define EXT_INTC1_REQ0 4 /* IP 4 */ |
@@ -69,16 +48,98 @@ void (*board_init_irq)(void); | |||
69 | 48 | ||
70 | static DEFINE_SPINLOCK(irq_lock); | 49 | static DEFINE_SPINLOCK(irq_lock); |
71 | 50 | ||
51 | #ifdef CONFIG_PM | ||
52 | |||
53 | /* | ||
54 | * Save/restore the interrupt controller state. | ||
55 | * Called from the save/restore core registers as part of the | ||
56 | * au_sleep function in power.c.....maybe I should just pm_register() | ||
57 | * them instead? | ||
58 | */ | ||
59 | static unsigned int sleep_intctl_config0[2]; | ||
60 | static unsigned int sleep_intctl_config1[2]; | ||
61 | static unsigned int sleep_intctl_config2[2]; | ||
62 | static unsigned int sleep_intctl_src[2]; | ||
63 | static unsigned int sleep_intctl_assign[2]; | ||
64 | static unsigned int sleep_intctl_wake[2]; | ||
65 | static unsigned int sleep_intctl_mask[2]; | ||
66 | |||
67 | void save_au1xxx_intctl(void) | ||
68 | { | ||
69 | sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); | ||
70 | sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); | ||
71 | sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); | ||
72 | sleep_intctl_src[0] = au_readl(IC0_SRCRD); | ||
73 | sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); | ||
74 | sleep_intctl_wake[0] = au_readl(IC0_WAKERD); | ||
75 | sleep_intctl_mask[0] = au_readl(IC0_MASKRD); | ||
76 | |||
77 | sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); | ||
78 | sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); | ||
79 | sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); | ||
80 | sleep_intctl_src[1] = au_readl(IC1_SRCRD); | ||
81 | sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); | ||
82 | sleep_intctl_wake[1] = au_readl(IC1_WAKERD); | ||
83 | sleep_intctl_mask[1] = au_readl(IC1_MASKRD); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * For most restore operations, we clear the entire register and | ||
88 | * then set the bits we found during the save. | ||
89 | */ | ||
90 | void restore_au1xxx_intctl(void) | ||
91 | { | ||
92 | au_writel(0xffffffff, IC0_MASKCLR); au_sync(); | ||
93 | |||
94 | au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); | ||
95 | au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); | ||
96 | au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); | ||
97 | au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); | ||
98 | au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); | ||
99 | au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); | ||
100 | au_writel(0xffffffff, IC0_SRCCLR); au_sync(); | ||
101 | au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); | ||
102 | au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); | ||
103 | au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); | ||
104 | au_writel(0xffffffff, IC0_WAKECLR); au_sync(); | ||
105 | au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); | ||
106 | au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); | ||
107 | au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); | ||
108 | au_writel(0x00000000, IC0_TESTBIT); au_sync(); | ||
109 | |||
110 | au_writel(0xffffffff, IC1_MASKCLR); au_sync(); | ||
111 | |||
112 | au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); | ||
113 | au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); | ||
114 | au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); | ||
115 | au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); | ||
116 | au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); | ||
117 | au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); | ||
118 | au_writel(0xffffffff, IC1_SRCCLR); au_sync(); | ||
119 | au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); | ||
120 | au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); | ||
121 | au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); | ||
122 | au_writel(0xffffffff, IC1_WAKECLR); au_sync(); | ||
123 | au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); | ||
124 | au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); | ||
125 | au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); | ||
126 | au_writel(0x00000000, IC1_TESTBIT); au_sync(); | ||
127 | |||
128 | au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); | ||
129 | |||
130 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); | ||
131 | } | ||
132 | #endif /* CONFIG_PM */ | ||
133 | |||
72 | 134 | ||
73 | inline void local_enable_irq(unsigned int irq_nr) | 135 | inline void local_enable_irq(unsigned int irq_nr) |
74 | { | 136 | { |
75 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 137 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
76 | au_writel(1<<(irq_nr-32), IC1_MASKSET); | 138 | au_writel(1 << (irq_nr - 32), IC1_MASKSET); |
77 | au_writel(1<<(irq_nr-32), IC1_WAKESET); | 139 | au_writel(1 << (irq_nr - 32), IC1_WAKESET); |
78 | } | 140 | } else { |
79 | else { | 141 | au_writel(1 << irq_nr, IC0_MASKSET); |
80 | au_writel(1<<irq_nr, IC0_MASKSET); | 142 | au_writel(1 << irq_nr, IC0_WAKESET); |
81 | au_writel(1<<irq_nr, IC0_WAKESET); | ||
82 | } | 143 | } |
83 | au_sync(); | 144 | au_sync(); |
84 | } | 145 | } |
@@ -87,12 +148,11 @@ inline void local_enable_irq(unsigned int irq_nr) | |||
87 | inline void local_disable_irq(unsigned int irq_nr) | 148 | inline void local_disable_irq(unsigned int irq_nr) |
88 | { | 149 | { |
89 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 150 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
90 | au_writel(1<<(irq_nr-32), IC1_MASKCLR); | 151 | au_writel(1 << (irq_nr - 32), IC1_MASKCLR); |
91 | au_writel(1<<(irq_nr-32), IC1_WAKECLR); | 152 | au_writel(1 << (irq_nr - 32), IC1_WAKECLR); |
92 | } | 153 | } else { |
93 | else { | 154 | au_writel(1 << irq_nr, IC0_MASKCLR); |
94 | au_writel(1<<irq_nr, IC0_MASKCLR); | 155 | au_writel(1 << irq_nr, IC0_WAKECLR); |
95 | au_writel(1<<irq_nr, IC0_WAKECLR); | ||
96 | } | 156 | } |
97 | au_sync(); | 157 | au_sync(); |
98 | } | 158 | } |
@@ -101,12 +161,11 @@ inline void local_disable_irq(unsigned int irq_nr) | |||
101 | static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) | 161 | static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) |
102 | { | 162 | { |
103 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 163 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
104 | au_writel(1<<(irq_nr-32), IC1_RISINGCLR); | 164 | au_writel(1 << (irq_nr - 32), IC1_RISINGCLR); |
105 | au_writel(1<<(irq_nr-32), IC1_MASKCLR); | 165 | au_writel(1 << (irq_nr - 32), IC1_MASKCLR); |
106 | } | 166 | } else { |
107 | else { | 167 | au_writel(1 << irq_nr, IC0_RISINGCLR); |
108 | au_writel(1<<irq_nr, IC0_RISINGCLR); | 168 | au_writel(1 << irq_nr, IC0_MASKCLR); |
109 | au_writel(1<<irq_nr, IC0_MASKCLR); | ||
110 | } | 169 | } |
111 | au_sync(); | 170 | au_sync(); |
112 | } | 171 | } |
@@ -115,12 +174,11 @@ static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) | |||
115 | static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr) | 174 | static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr) |
116 | { | 175 | { |
117 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 176 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
118 | au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); | 177 | au_writel(1 << (irq_nr - 32), IC1_FALLINGCLR); |
119 | au_writel(1<<(irq_nr-32), IC1_MASKCLR); | 178 | au_writel(1 << (irq_nr - 32), IC1_MASKCLR); |
120 | } | 179 | } else { |
121 | else { | 180 | au_writel(1 << irq_nr, IC0_FALLINGCLR); |
122 | au_writel(1<<irq_nr, IC0_FALLINGCLR); | 181 | au_writel(1 << irq_nr, IC0_MASKCLR); |
123 | au_writel(1<<irq_nr, IC0_MASKCLR); | ||
124 | } | 182 | } |
125 | au_sync(); | 183 | au_sync(); |
126 | } | 184 | } |
@@ -132,14 +190,13 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr) | |||
132 | * both edges at once, or if we do, that we don't care. | 190 | * both edges at once, or if we do, that we don't care. |
133 | */ | 191 | */ |
134 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 192 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
135 | au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); | 193 | au_writel(1 << (irq_nr - 32), IC1_FALLINGCLR); |
136 | au_writel(1<<(irq_nr-32), IC1_RISINGCLR); | 194 | au_writel(1 << (irq_nr - 32), IC1_RISINGCLR); |
137 | au_writel(1<<(irq_nr-32), IC1_MASKCLR); | 195 | au_writel(1 << (irq_nr - 32), IC1_MASKCLR); |
138 | } | 196 | } else { |
139 | else { | 197 | au_writel(1 << irq_nr, IC0_FALLINGCLR); |
140 | au_writel(1<<irq_nr, IC0_FALLINGCLR); | 198 | au_writel(1 << irq_nr, IC0_RISINGCLR); |
141 | au_writel(1<<irq_nr, IC0_RISINGCLR); | 199 | au_writel(1 << irq_nr, IC0_MASKCLR); |
142 | au_writel(1<<irq_nr, IC0_MASKCLR); | ||
143 | } | 200 | } |
144 | au_sync(); | 201 | au_sync(); |
145 | } | 202 | } |
@@ -162,9 +219,9 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr) | |||
162 | 219 | ||
163 | static void end_irq(unsigned int irq_nr) | 220 | static void end_irq(unsigned int irq_nr) |
164 | { | 221 | { |
165 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { | 222 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) |
166 | local_enable_irq(irq_nr); | 223 | local_enable_irq(irq_nr); |
167 | } | 224 | |
168 | #if defined(CONFIG_MIPS_PB1000) | 225 | #if defined(CONFIG_MIPS_PB1000) |
169 | if (irq_nr == AU1000_GPIO_15) { | 226 | if (irq_nr == AU1000_GPIO_15) { |
170 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 227 | au_writel(0x4000, PB1000_MDR); /* enable int */ |
@@ -181,15 +238,12 @@ unsigned long save_local_and_disable(int controller) | |||
181 | spin_lock_irqsave(&irq_lock, flags); | 238 | spin_lock_irqsave(&irq_lock, flags); |
182 | if (controller) { | 239 | if (controller) { |
183 | mask = au_readl(IC1_MASKSET); | 240 | mask = au_readl(IC1_MASKSET); |
184 | for (i=32; i<64; i++) { | 241 | for (i = 32; i < 64; i++) |
185 | local_disable_irq(i); | 242 | local_disable_irq(i); |
186 | } | 243 | } else { |
187 | } | ||
188 | else { | ||
189 | mask = au_readl(IC0_MASKSET); | 244 | mask = au_readl(IC0_MASKSET); |
190 | for (i=0; i<32; i++) { | 245 | for (i = 0; i < 32; i++) |
191 | local_disable_irq(i); | 246 | local_disable_irq(i); |
192 | } | ||
193 | } | 247 | } |
194 | spin_unlock_irqrestore(&irq_lock, flags); | 248 | spin_unlock_irqrestore(&irq_lock, flags); |
195 | 249 | ||
@@ -202,10 +256,10 @@ void restore_local_and_enable(int controller, unsigned long mask) | |||
202 | unsigned long flags, new_mask; | 256 | unsigned long flags, new_mask; |
203 | 257 | ||
204 | spin_lock_irqsave(&irq_lock, flags); | 258 | spin_lock_irqsave(&irq_lock, flags); |
205 | for (i=0; i<32; i++) { | 259 | for (i = 0; i < 32; i++) { |
206 | if (mask & (1<<i)) { | 260 | if (mask & (1 << i)) { |
207 | if (controller) | 261 | if (controller) |
208 | local_enable_irq(i+32); | 262 | local_enable_irq(i + 32); |
209 | else | 263 | else |
210 | local_enable_irq(i); | 264 | local_enable_irq(i); |
211 | } | 265 | } |
@@ -220,39 +274,39 @@ void restore_local_and_enable(int controller, unsigned long mask) | |||
220 | 274 | ||
221 | 275 | ||
222 | static struct irq_chip rise_edge_irq_type = { | 276 | static struct irq_chip rise_edge_irq_type = { |
223 | .name = "Au1000 Rise Edge", | 277 | .name = "Au1000 Rise Edge", |
224 | .ack = mask_and_ack_rise_edge_irq, | 278 | .ack = mask_and_ack_rise_edge_irq, |
225 | .mask = local_disable_irq, | 279 | .mask = local_disable_irq, |
226 | .mask_ack = mask_and_ack_rise_edge_irq, | 280 | .mask_ack = mask_and_ack_rise_edge_irq, |
227 | .unmask = local_enable_irq, | 281 | .unmask = local_enable_irq, |
228 | .end = end_irq, | 282 | .end = end_irq, |
229 | }; | 283 | }; |
230 | 284 | ||
231 | static struct irq_chip fall_edge_irq_type = { | 285 | static struct irq_chip fall_edge_irq_type = { |
232 | .name = "Au1000 Fall Edge", | 286 | .name = "Au1000 Fall Edge", |
233 | .ack = mask_and_ack_fall_edge_irq, | 287 | .ack = mask_and_ack_fall_edge_irq, |
234 | .mask = local_disable_irq, | 288 | .mask = local_disable_irq, |
235 | .mask_ack = mask_and_ack_fall_edge_irq, | 289 | .mask_ack = mask_and_ack_fall_edge_irq, |
236 | .unmask = local_enable_irq, | 290 | .unmask = local_enable_irq, |
237 | .end = end_irq, | 291 | .end = end_irq, |
238 | }; | 292 | }; |
239 | 293 | ||
240 | static struct irq_chip either_edge_irq_type = { | 294 | static struct irq_chip either_edge_irq_type = { |
241 | .name = "Au1000 Rise or Fall Edge", | 295 | .name = "Au1000 Rise or Fall Edge", |
242 | .ack = mask_and_ack_either_edge_irq, | 296 | .ack = mask_and_ack_either_edge_irq, |
243 | .mask = local_disable_irq, | 297 | .mask = local_disable_irq, |
244 | .mask_ack = mask_and_ack_either_edge_irq, | 298 | .mask_ack = mask_and_ack_either_edge_irq, |
245 | .unmask = local_enable_irq, | 299 | .unmask = local_enable_irq, |
246 | .end = end_irq, | 300 | .end = end_irq, |
247 | }; | 301 | }; |
248 | 302 | ||
249 | static struct irq_chip level_irq_type = { | 303 | static struct irq_chip level_irq_type = { |
250 | .name = "Au1000 Level", | 304 | .name = "Au1000 Level", |
251 | .ack = mask_and_ack_level_irq, | 305 | .ack = mask_and_ack_level_irq, |
252 | .mask = local_disable_irq, | 306 | .mask = local_disable_irq, |
253 | .mask_ack = mask_and_ack_level_irq, | 307 | .mask_ack = mask_and_ack_level_irq, |
254 | .unmask = local_enable_irq, | 308 | .unmask = local_enable_irq, |
255 | .end = end_irq, | 309 | .end = end_irq, |
256 | }; | 310 | }; |
257 | 311 | ||
258 | #ifdef CONFIG_PM | 312 | #ifdef CONFIG_PM |
@@ -263,7 +317,8 @@ void startup_match20_interrupt(irq_handler_t handler) | |||
263 | static struct irqaction action; | 317 | static struct irqaction action; |
264 | memset(&action, 0, sizeof(struct irqaction)); | 318 | memset(&action, 0, sizeof(struct irqaction)); |
265 | 319 | ||
266 | /* This is a big problem.... since we didn't use request_irq | 320 | /* |
321 | * This is a big problem.... since we didn't use request_irq | ||
267 | * when kernel/irq.c calls probe_irq_xxx this interrupt will | 322 | * when kernel/irq.c calls probe_irq_xxx this interrupt will |
268 | * be probed for usage. This will end up disabling the device :( | 323 | * be probed for usage. This will end up disabling the device :( |
269 | * Give it a bogus "action" pointer -- this will keep it from | 324 | * Give it a bogus "action" pointer -- this will keep it from |
@@ -292,173 +347,112 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) | |||
292 | /* Config2[n], Config1[n], Config0[n] */ | 347 | /* Config2[n], Config1[n], Config0[n] */ |
293 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 348 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
294 | switch (type) { | 349 | switch (type) { |
295 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ | 350 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ |
296 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 351 | au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); |
297 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 352 | au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); |
298 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 353 | au_writel(1 << (irq_nr - 32), IC1_CFG0SET); |
299 | set_irq_chip(irq_nr, &rise_edge_irq_type); | 354 | set_irq_chip(irq_nr, &rise_edge_irq_type); |
300 | break; | 355 | break; |
301 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 356 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
302 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 357 | au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); |
303 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 358 | au_writel(1 << (irq_nr - 32), IC1_CFG1SET); |
304 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 359 | au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); |
305 | set_irq_chip(irq_nr, &fall_edge_irq_type); | 360 | set_irq_chip(irq_nr, &fall_edge_irq_type); |
306 | break; | 361 | break; |
307 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 362 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
308 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 363 | au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); |
309 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 364 | au_writel(1 << (irq_nr - 32), IC1_CFG1SET); |
310 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 365 | au_writel(1 << (irq_nr - 32), IC1_CFG0SET); |
311 | set_irq_chip(irq_nr, &either_edge_irq_type); | 366 | set_irq_chip(irq_nr, &either_edge_irq_type); |
312 | break; | 367 | break; |
313 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 368 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
314 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 369 | au_writel(1 << (irq_nr - 32), IC1_CFG2SET); |
315 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 370 | au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); |
316 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 371 | au_writel(1 << (irq_nr - 32), IC1_CFG0SET); |
317 | set_irq_chip(irq_nr, &level_irq_type); | 372 | set_irq_chip(irq_nr, &level_irq_type); |
318 | break; | 373 | break; |
319 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 374 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
320 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 375 | au_writel(1 << (irq_nr - 32), IC1_CFG2SET); |
321 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 376 | au_writel(1 << (irq_nr - 32), IC1_CFG1SET); |
322 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 377 | au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); |
323 | set_irq_chip(irq_nr, &level_irq_type); | 378 | set_irq_chip(irq_nr, &level_irq_type); |
324 | break; | 379 | break; |
325 | case INTC_INT_DISABLED: /* 0:0:0 */ | 380 | case INTC_INT_DISABLED: /* 0:0:0 */ |
326 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 381 | au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); |
327 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 382 | au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); |
328 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 383 | au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); |
329 | break; | 384 | break; |
330 | default: /* disable the interrupt */ | 385 | default: /* disable the interrupt */ |
331 | printk("unexpected int type %d (irq %d)\n", type, irq_nr); | 386 | printk(KERN_WARNING "unexpected int type %d (irq %d)\n", |
332 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 387 | type, irq_nr); |
333 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 388 | au_writel(1 << (irq_nr - 32), IC1_CFG0CLR); |
334 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 389 | au_writel(1 << (irq_nr - 32), IC1_CFG1CLR); |
335 | return; | 390 | au_writel(1 << (irq_nr - 32), IC1_CFG2CLR); |
391 | return; | ||
336 | } | 392 | } |
337 | if (int_req) /* assign to interrupt request 1 */ | 393 | if (int_req) /* assign to interrupt request 1 */ |
338 | au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR); | 394 | au_writel(1 << (irq_nr - 32), IC1_ASSIGNCLR); |
339 | else /* assign to interrupt request 0 */ | 395 | else /* assign to interrupt request 0 */ |
340 | au_writel(1<<(irq_nr-32), IC1_ASSIGNSET); | 396 | au_writel(1 << (irq_nr - 32), IC1_ASSIGNSET); |
341 | au_writel(1<<(irq_nr-32), IC1_SRCSET); | 397 | au_writel(1 << (irq_nr - 32), IC1_SRCSET); |
342 | au_writel(1<<(irq_nr-32), IC1_MASKCLR); | 398 | au_writel(1 << (irq_nr - 32), IC1_MASKCLR); |
343 | au_writel(1<<(irq_nr-32), IC1_WAKECLR); | 399 | au_writel(1 << (irq_nr - 32), IC1_WAKECLR); |
344 | } | 400 | } else { |
345 | else { | ||
346 | switch (type) { | 401 | switch (type) { |
347 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ | 402 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ |
348 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 403 | au_writel(1 << irq_nr, IC0_CFG2CLR); |
349 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 404 | au_writel(1 << irq_nr, IC0_CFG1CLR); |
350 | au_writel(1<<irq_nr, IC0_CFG0SET); | 405 | au_writel(1 << irq_nr, IC0_CFG0SET); |
351 | set_irq_chip(irq_nr, &rise_edge_irq_type); | 406 | set_irq_chip(irq_nr, &rise_edge_irq_type); |
352 | break; | 407 | break; |
353 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 408 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
354 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 409 | au_writel(1 << irq_nr, IC0_CFG2CLR); |
355 | au_writel(1<<irq_nr, IC0_CFG1SET); | 410 | au_writel(1 << irq_nr, IC0_CFG1SET); |
356 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 411 | au_writel(1 << irq_nr, IC0_CFG0CLR); |
357 | set_irq_chip(irq_nr, &fall_edge_irq_type); | 412 | set_irq_chip(irq_nr, &fall_edge_irq_type); |
358 | break; | 413 | break; |
359 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 414 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
360 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 415 | au_writel(1 << irq_nr, IC0_CFG2CLR); |
361 | au_writel(1<<irq_nr, IC0_CFG1SET); | 416 | au_writel(1 << irq_nr, IC0_CFG1SET); |
362 | au_writel(1<<irq_nr, IC0_CFG0SET); | 417 | au_writel(1 << irq_nr, IC0_CFG0SET); |
363 | set_irq_chip(irq_nr, &either_edge_irq_type); | 418 | set_irq_chip(irq_nr, &either_edge_irq_type); |
364 | break; | 419 | break; |
365 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 420 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
366 | au_writel(1<<irq_nr, IC0_CFG2SET); | 421 | au_writel(1 << irq_nr, IC0_CFG2SET); |
367 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 422 | au_writel(1 << irq_nr, IC0_CFG1CLR); |
368 | au_writel(1<<irq_nr, IC0_CFG0SET); | 423 | au_writel(1 << irq_nr, IC0_CFG0SET); |
369 | set_irq_chip(irq_nr, &level_irq_type); | 424 | set_irq_chip(irq_nr, &level_irq_type); |
370 | break; | 425 | break; |
371 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 426 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
372 | au_writel(1<<irq_nr, IC0_CFG2SET); | 427 | au_writel(1 << irq_nr, IC0_CFG2SET); |
373 | au_writel(1<<irq_nr, IC0_CFG1SET); | 428 | au_writel(1 << irq_nr, IC0_CFG1SET); |
374 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 429 | au_writel(1 << irq_nr, IC0_CFG0CLR); |
375 | set_irq_chip(irq_nr, &level_irq_type); | 430 | set_irq_chip(irq_nr, &level_irq_type); |
376 | break; | 431 | break; |
377 | case INTC_INT_DISABLED: /* 0:0:0 */ | 432 | case INTC_INT_DISABLED: /* 0:0:0 */ |
378 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 433 | au_writel(1 << irq_nr, IC0_CFG0CLR); |
379 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 434 | au_writel(1 << irq_nr, IC0_CFG1CLR); |
380 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 435 | au_writel(1 << irq_nr, IC0_CFG2CLR); |
381 | break; | 436 | break; |
382 | default: /* disable the interrupt */ | 437 | default: /* disable the interrupt */ |
383 | printk("unexpected int type %d (irq %d)\n", type, irq_nr); | 438 | printk(KERN_WARNING "unexpected int type %d (irq %d)\n", |
384 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 439 | type, irq_nr); |
385 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 440 | au_writel(1 << irq_nr, IC0_CFG0CLR); |
386 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 441 | au_writel(1 << irq_nr, IC0_CFG1CLR); |
387 | return; | 442 | au_writel(1 << irq_nr, IC0_CFG2CLR); |
443 | return; | ||
388 | } | 444 | } |
389 | if (int_req) /* assign to interrupt request 1 */ | 445 | if (int_req) /* assign to interrupt request 1 */ |
390 | au_writel(1<<irq_nr, IC0_ASSIGNCLR); | 446 | au_writel(1 << irq_nr, IC0_ASSIGNCLR); |
391 | else /* assign to interrupt request 0 */ | 447 | else /* assign to interrupt request 0 */ |
392 | au_writel(1<<irq_nr, IC0_ASSIGNSET); | 448 | au_writel(1 << irq_nr, IC0_ASSIGNSET); |
393 | au_writel(1<<irq_nr, IC0_SRCSET); | 449 | au_writel(1 << irq_nr, IC0_SRCSET); |
394 | au_writel(1<<irq_nr, IC0_MASKCLR); | 450 | au_writel(1 << irq_nr, IC0_MASKCLR); |
395 | au_writel(1<<irq_nr, IC0_WAKECLR); | 451 | au_writel(1 << irq_nr, IC0_WAKECLR); |
396 | } | 452 | } |
397 | au_sync(); | 453 | au_sync(); |
398 | } | 454 | } |
399 | 455 | ||
400 | |||
401 | void __init arch_init_irq(void) | ||
402 | { | ||
403 | int i; | ||
404 | unsigned long cp0_status; | ||
405 | au1xxx_irq_map_t *imp; | ||
406 | extern au1xxx_irq_map_t au1xxx_irq_map[]; | ||
407 | extern au1xxx_irq_map_t au1xxx_ic0_map[]; | ||
408 | extern int au1xxx_nr_irqs; | ||
409 | extern int au1xxx_ic0_nr_irqs; | ||
410 | |||
411 | cp0_status = read_c0_status(); | ||
412 | |||
413 | /* Initialize interrupt controllers to a safe state. | ||
414 | */ | ||
415 | au_writel(0xffffffff, IC0_CFG0CLR); | ||
416 | au_writel(0xffffffff, IC0_CFG1CLR); | ||
417 | au_writel(0xffffffff, IC0_CFG2CLR); | ||
418 | au_writel(0xffffffff, IC0_MASKCLR); | ||
419 | au_writel(0xffffffff, IC0_ASSIGNSET); | ||
420 | au_writel(0xffffffff, IC0_WAKECLR); | ||
421 | au_writel(0xffffffff, IC0_SRCSET); | ||
422 | au_writel(0xffffffff, IC0_FALLINGCLR); | ||
423 | au_writel(0xffffffff, IC0_RISINGCLR); | ||
424 | au_writel(0x00000000, IC0_TESTBIT); | ||
425 | |||
426 | au_writel(0xffffffff, IC1_CFG0CLR); | ||
427 | au_writel(0xffffffff, IC1_CFG1CLR); | ||
428 | au_writel(0xffffffff, IC1_CFG2CLR); | ||
429 | au_writel(0xffffffff, IC1_MASKCLR); | ||
430 | au_writel(0xffffffff, IC1_ASSIGNSET); | ||
431 | au_writel(0xffffffff, IC1_WAKECLR); | ||
432 | au_writel(0xffffffff, IC1_SRCSET); | ||
433 | au_writel(0xffffffff, IC1_FALLINGCLR); | ||
434 | au_writel(0xffffffff, IC1_RISINGCLR); | ||
435 | au_writel(0x00000000, IC1_TESTBIT); | ||
436 | |||
437 | /* Initialize IC0, which is fixed per processor. | ||
438 | */ | ||
439 | imp = au1xxx_ic0_map; | ||
440 | for (i=0; i<au1xxx_ic0_nr_irqs; i++) { | ||
441 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | ||
442 | imp++; | ||
443 | } | ||
444 | |||
445 | /* Now set up the irq mapping for the board. | ||
446 | */ | ||
447 | imp = au1xxx_irq_map; | ||
448 | for (i=0; i<au1xxx_nr_irqs; i++) { | ||
449 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | ||
450 | imp++; | ||
451 | } | ||
452 | |||
453 | set_c0_status(ALLINTS); | ||
454 | |||
455 | /* Board specific IRQ initialization. | ||
456 | */ | ||
457 | if (board_init_irq) | ||
458 | (*board_init_irq)(); | ||
459 | } | ||
460 | |||
461 | |||
462 | /* | 456 | /* |
463 | * Interrupts are nested. Even if an interrupt handler is registered | 457 | * Interrupts are nested. Even if an interrupt handler is registered |
464 | * as "fast", we might get another interrupt before we return from | 458 | * as "fast", we might get another interrupt before we return from |
@@ -468,26 +462,27 @@ void __init arch_init_irq(void) | |||
468 | static void intc0_req0_irqdispatch(void) | 462 | static void intc0_req0_irqdispatch(void) |
469 | { | 463 | { |
470 | int irq = 0; | 464 | int irq = 0; |
471 | static unsigned long intc0_req0 = 0; | 465 | static unsigned long intc0_req0; |
472 | 466 | ||
473 | intc0_req0 |= au_readl(IC0_REQ0INT); | 467 | intc0_req0 |= au_readl(IC0_REQ0INT); |
474 | 468 | ||
475 | if (!intc0_req0) | 469 | if (!intc0_req0) |
476 | return; | 470 | return; |
471 | |||
477 | #ifdef AU1000_USB_DEV_REQ_INT | 472 | #ifdef AU1000_USB_DEV_REQ_INT |
478 | /* | 473 | /* |
479 | * Because of the tight timing of SETUP token to reply | 474 | * Because of the tight timing of SETUP token to reply |
480 | * transactions, the USB devices-side packet complete | 475 | * transactions, the USB devices-side packet complete |
481 | * interrupt needs the highest priority. | 476 | * interrupt needs the highest priority. |
482 | */ | 477 | */ |
483 | if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) { | 478 | if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) { |
484 | intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT); | 479 | intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT); |
485 | do_IRQ(AU1000_USB_DEV_REQ_INT); | 480 | do_IRQ(AU1000_USB_DEV_REQ_INT); |
486 | return; | 481 | return; |
487 | } | 482 | } |
488 | #endif | 483 | #endif |
489 | irq = au_ffs(intc0_req0) - 1; | 484 | irq = ffs(intc0_req0); |
490 | intc0_req0 &= ~(1<<irq); | 485 | intc0_req0 &= ~(1 << irq); |
491 | do_IRQ(irq); | 486 | do_IRQ(irq); |
492 | } | 487 | } |
493 | 488 | ||
@@ -495,15 +490,15 @@ static void intc0_req0_irqdispatch(void) | |||
495 | static void intc0_req1_irqdispatch(void) | 490 | static void intc0_req1_irqdispatch(void) |
496 | { | 491 | { |
497 | int irq = 0; | 492 | int irq = 0; |
498 | static unsigned long intc0_req1 = 0; | 493 | static unsigned long intc0_req1; |
499 | 494 | ||
500 | intc0_req1 |= au_readl(IC0_REQ1INT); | 495 | intc0_req1 |= au_readl(IC0_REQ1INT); |
501 | 496 | ||
502 | if (!intc0_req1) | 497 | if (!intc0_req1) |
503 | return; | 498 | return; |
504 | 499 | ||
505 | irq = au_ffs(intc0_req1) - 1; | 500 | irq = ffs(intc0_req1); |
506 | intc0_req1 &= ~(1<<irq); | 501 | intc0_req1 &= ~(1 << irq); |
507 | do_IRQ(irq); | 502 | do_IRQ(irq); |
508 | } | 503 | } |
509 | 504 | ||
@@ -515,15 +510,15 @@ static void intc0_req1_irqdispatch(void) | |||
515 | static void intc1_req0_irqdispatch(void) | 510 | static void intc1_req0_irqdispatch(void) |
516 | { | 511 | { |
517 | int irq = 0; | 512 | int irq = 0; |
518 | static unsigned long intc1_req0 = 0; | 513 | static unsigned long intc1_req0; |
519 | 514 | ||
520 | intc1_req0 |= au_readl(IC1_REQ0INT); | 515 | intc1_req0 |= au_readl(IC1_REQ0INT); |
521 | 516 | ||
522 | if (!intc1_req0) | 517 | if (!intc1_req0) |
523 | return; | 518 | return; |
524 | 519 | ||
525 | irq = au_ffs(intc1_req0) - 1; | 520 | irq = ffs(intc1_req0); |
526 | intc1_req0 &= ~(1<<irq); | 521 | intc1_req0 &= ~(1 << irq); |
527 | irq += 32; | 522 | irq += 32; |
528 | do_IRQ(irq); | 523 | do_IRQ(irq); |
529 | } | 524 | } |
@@ -532,102 +527,19 @@ static void intc1_req0_irqdispatch(void) | |||
532 | static void intc1_req1_irqdispatch(void) | 527 | static void intc1_req1_irqdispatch(void) |
533 | { | 528 | { |
534 | int irq = 0; | 529 | int irq = 0; |
535 | static unsigned long intc1_req1 = 0; | 530 | static unsigned long intc1_req1; |
536 | 531 | ||
537 | intc1_req1 |= au_readl(IC1_REQ1INT); | 532 | intc1_req1 |= au_readl(IC1_REQ1INT); |
538 | 533 | ||
539 | if (!intc1_req1) | 534 | if (!intc1_req1) |
540 | return; | 535 | return; |
541 | 536 | ||
542 | irq = au_ffs(intc1_req1) - 1; | 537 | irq = ffs(intc1_req1); |
543 | intc1_req1 &= ~(1<<irq); | 538 | intc1_req1 &= ~(1 << irq); |
544 | irq += 32; | 539 | irq += 32; |
545 | do_IRQ(irq); | 540 | do_IRQ(irq); |
546 | } | 541 | } |
547 | 542 | ||
548 | #ifdef CONFIG_PM | ||
549 | |||
550 | /* Save/restore the interrupt controller state. | ||
551 | * Called from the save/restore core registers as part of the | ||
552 | * au_sleep function in power.c.....maybe I should just pm_register() | ||
553 | * them instead? | ||
554 | */ | ||
555 | static unsigned int sleep_intctl_config0[2]; | ||
556 | static unsigned int sleep_intctl_config1[2]; | ||
557 | static unsigned int sleep_intctl_config2[2]; | ||
558 | static unsigned int sleep_intctl_src[2]; | ||
559 | static unsigned int sleep_intctl_assign[2]; | ||
560 | static unsigned int sleep_intctl_wake[2]; | ||
561 | static unsigned int sleep_intctl_mask[2]; | ||
562 | |||
563 | void | ||
564 | save_au1xxx_intctl(void) | ||
565 | { | ||
566 | sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); | ||
567 | sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); | ||
568 | sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); | ||
569 | sleep_intctl_src[0] = au_readl(IC0_SRCRD); | ||
570 | sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); | ||
571 | sleep_intctl_wake[0] = au_readl(IC0_WAKERD); | ||
572 | sleep_intctl_mask[0] = au_readl(IC0_MASKRD); | ||
573 | |||
574 | sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); | ||
575 | sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); | ||
576 | sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); | ||
577 | sleep_intctl_src[1] = au_readl(IC1_SRCRD); | ||
578 | sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); | ||
579 | sleep_intctl_wake[1] = au_readl(IC1_WAKERD); | ||
580 | sleep_intctl_mask[1] = au_readl(IC1_MASKRD); | ||
581 | } | ||
582 | |||
583 | /* For most restore operations, we clear the entire register and | ||
584 | * then set the bits we found during the save. | ||
585 | */ | ||
586 | void | ||
587 | restore_au1xxx_intctl(void) | ||
588 | { | ||
589 | au_writel(0xffffffff, IC0_MASKCLR); au_sync(); | ||
590 | |||
591 | au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); | ||
592 | au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); | ||
593 | au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); | ||
594 | au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); | ||
595 | au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); | ||
596 | au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); | ||
597 | au_writel(0xffffffff, IC0_SRCCLR); au_sync(); | ||
598 | au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); | ||
599 | au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); | ||
600 | au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); | ||
601 | au_writel(0xffffffff, IC0_WAKECLR); au_sync(); | ||
602 | au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); | ||
603 | au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); | ||
604 | au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); | ||
605 | au_writel(0x00000000, IC0_TESTBIT); au_sync(); | ||
606 | |||
607 | au_writel(0xffffffff, IC1_MASKCLR); au_sync(); | ||
608 | |||
609 | au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); | ||
610 | au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); | ||
611 | au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); | ||
612 | au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); | ||
613 | au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); | ||
614 | au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); | ||
615 | au_writel(0xffffffff, IC1_SRCCLR); au_sync(); | ||
616 | au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); | ||
617 | au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); | ||
618 | au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); | ||
619 | au_writel(0xffffffff, IC1_WAKECLR); au_sync(); | ||
620 | au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); | ||
621 | au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); | ||
622 | au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); | ||
623 | au_writel(0x00000000, IC1_TESTBIT); au_sync(); | ||
624 | |||
625 | au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); | ||
626 | |||
627 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); | ||
628 | } | ||
629 | #endif /* CONFIG_PM */ | ||
630 | |||
631 | asmlinkage void plat_irq_dispatch(void) | 543 | asmlinkage void plat_irq_dispatch(void) |
632 | { | 544 | { |
633 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; | 545 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; |
@@ -645,3 +557,63 @@ asmlinkage void plat_irq_dispatch(void) | |||
645 | else | 557 | else |
646 | spurious_interrupt(); | 558 | spurious_interrupt(); |
647 | } | 559 | } |
560 | |||
561 | void __init arch_init_irq(void) | ||
562 | { | ||
563 | int i; | ||
564 | unsigned long cp0_status; | ||
565 | struct au1xxx_irqmap *imp; | ||
566 | extern struct au1xxx_irqmap au1xxx_irq_map[]; | ||
567 | extern struct au1xxx_irqmap au1xxx_ic0_map[]; | ||
568 | extern int au1xxx_nr_irqs; | ||
569 | extern int au1xxx_ic0_nr_irqs; | ||
570 | |||
571 | cp0_status = read_c0_status(); | ||
572 | |||
573 | /* Initialize interrupt controllers to a safe state. | ||
574 | */ | ||
575 | au_writel(0xffffffff, IC0_CFG0CLR); | ||
576 | au_writel(0xffffffff, IC0_CFG1CLR); | ||
577 | au_writel(0xffffffff, IC0_CFG2CLR); | ||
578 | au_writel(0xffffffff, IC0_MASKCLR); | ||
579 | au_writel(0xffffffff, IC0_ASSIGNSET); | ||
580 | au_writel(0xffffffff, IC0_WAKECLR); | ||
581 | au_writel(0xffffffff, IC0_SRCSET); | ||
582 | au_writel(0xffffffff, IC0_FALLINGCLR); | ||
583 | au_writel(0xffffffff, IC0_RISINGCLR); | ||
584 | au_writel(0x00000000, IC0_TESTBIT); | ||
585 | |||
586 | au_writel(0xffffffff, IC1_CFG0CLR); | ||
587 | au_writel(0xffffffff, IC1_CFG1CLR); | ||
588 | au_writel(0xffffffff, IC1_CFG2CLR); | ||
589 | au_writel(0xffffffff, IC1_MASKCLR); | ||
590 | au_writel(0xffffffff, IC1_ASSIGNSET); | ||
591 | au_writel(0xffffffff, IC1_WAKECLR); | ||
592 | au_writel(0xffffffff, IC1_SRCSET); | ||
593 | au_writel(0xffffffff, IC1_FALLINGCLR); | ||
594 | au_writel(0xffffffff, IC1_RISINGCLR); | ||
595 | au_writel(0x00000000, IC1_TESTBIT); | ||
596 | |||
597 | /* Initialize IC0, which is fixed per processor. | ||
598 | */ | ||
599 | imp = au1xxx_ic0_map; | ||
600 | for (i = 0; i < au1xxx_ic0_nr_irqs; i++) { | ||
601 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | ||
602 | imp++; | ||
603 | } | ||
604 | |||
605 | /* Now set up the irq mapping for the board. | ||
606 | */ | ||
607 | imp = au1xxx_irq_map; | ||
608 | for (i = 0; i < au1xxx_nr_irqs; i++) { | ||
609 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | ||
610 | imp++; | ||
611 | } | ||
612 | |||
613 | set_c0_status(ALLINTS); | ||
614 | |||
615 | /* Board specific IRQ initialization. | ||
616 | */ | ||
617 | if (board_init_irq) | ||
618 | (*board_init_irq)(); | ||
619 | } | ||
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c index 3e5729145c2b..09cea03411b0 100644 --- a/arch/mips/au1000/db1x00/irqmap.c +++ b/arch/mips/au1000/db1x00/irqmap.c | |||
@@ -79,7 +79,7 @@ char irq_tab_alchemy[][5] __initdata = { | |||
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | 81 | ||
82 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 82 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
83 | 83 | ||
84 | #ifndef CONFIG_MIPS_MIRAGE | 84 | #ifndef CONFIG_MIPS_MIRAGE |
85 | #ifdef CONFIG_MIPS_DB1550 | 85 | #ifdef CONFIG_MIPS_DB1550 |
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c index a4fa0f227e42..49c612aeddcf 100644 --- a/arch/mips/au1000/mtx-1/irqmap.c +++ b/arch/mips/au1000/mtx-1/irqmap.c | |||
@@ -58,7 +58,7 @@ char irq_tab_alchemy[][5] __initdata = { | |||
58 | [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ | 58 | [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 61 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
62 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, | 62 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, |
63 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | 63 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, |
64 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | 64 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, |
diff --git a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c index 156500ba467f..88e354508204 100644 --- a/arch/mips/au1000/pb1000/irqmap.c +++ b/arch/mips/au1000/pb1000/irqmap.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | #include <asm/mach-au1x00/au1000.h> | 48 | #include <asm/mach-au1x00/au1000.h> |
49 | 49 | ||
50 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 50 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
51 | { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, | 51 | { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, |
52 | }; | 52 | }; |
53 | 53 | ||
diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c index d986916221b7..880456bf8c11 100644 --- a/arch/mips/au1000/pb1100/irqmap.c +++ b/arch/mips/au1000/pb1100/irqmap.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | #include <asm/mach-au1x00/au1000.h> | 48 | #include <asm/mach-au1x00/au1000.h> |
49 | 49 | ||
50 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 50 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
51 | { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# | 51 | { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# |
52 | { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# | 52 | { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# |
53 | { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# | 53 | { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# |
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c index 7c708db04a88..3bee274445f5 100644 --- a/arch/mips/au1000/pb1200/irqmap.c +++ b/arch/mips/au1000/pb1200/irqmap.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #define PB1200_INT_END DB1200_INT_END | 54 | #define PB1200_INT_END DB1200_INT_END |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 57 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
58 | { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade | 58 | { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade |
59 | }; | 59 | }; |
60 | 60 | ||
@@ -74,7 +74,7 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id) | |||
74 | bcsr->int_status = bisr; | 74 | bcsr->int_status = bisr; |
75 | for( ; bisr; bisr &= (bisr-1) ) | 75 | for( ; bisr; bisr &= (bisr-1) ) |
76 | { | 76 | { |
77 | extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr); | 77 | extirq_nr = PB1200_INT_BEGIN + au_ffs(bisr); |
78 | /* Ack and dispatch IRQ */ | 78 | /* Ack and dispatch IRQ */ |
79 | do_IRQ(extirq_nr); | 79 | do_IRQ(extirq_nr); |
80 | } | 80 | } |
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c index 409d1612bb63..810f695e24bb 100644 --- a/arch/mips/au1000/pb1500/irqmap.c +++ b/arch/mips/au1000/pb1500/irqmap.c | |||
@@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = { | |||
52 | [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ | 52 | [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 55 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
56 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, | 56 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, |
57 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | 57 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, |
58 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | 58 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, |
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c index 24a9d186cf5a..56becab28e5d 100644 --- a/arch/mips/au1000/pb1550/irqmap.c +++ b/arch/mips/au1000/pb1550/irqmap.c | |||
@@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = { | |||
52 | [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */ | 52 | [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 55 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
56 | { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, | 56 | { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, |
57 | { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, | 57 | { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, |
58 | }; | 58 | }; |
diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c index 3844c6429e27..389349295d70 100644 --- a/arch/mips/au1000/xxs1500/irqmap.c +++ b/arch/mips/au1000/xxs1500/irqmap.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | #include <asm/au1000.h> | 48 | #include <asm/au1000.h> |
49 | 49 | ||
50 | au1xxx_irq_map_t __initdata au1xxx_irq_map[] = { | 50 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
51 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, | 51 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, |
52 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | 52 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, |
53 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | 53 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, |
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 5892491b40eb..05b365167a09 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -421,7 +421,7 @@ void __cpuinit mips_clockevent_init(void) | |||
421 | cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); | 421 | cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); |
422 | cd->shift = 32; | 422 | cd->shift = 32; |
423 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | 423 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); |
424 | cd->min_delta_ns = clockevent_delta2ns(0x30, cd); | 424 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); |
425 | 425 | ||
426 | cd->rating = 300; | 426 | cd->rating = 300; |
427 | cd->irq = irq; | 427 | cd->irq = irq; |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 632bce1bf420..9c0c478d71ac 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -104,7 +104,7 @@ static int __init set_raw_show_trace(char *str) | |||
104 | __setup("raw_show_trace", set_raw_show_trace); | 104 | __setup("raw_show_trace", set_raw_show_trace); |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | static void show_backtrace(struct task_struct *task, struct pt_regs *regs) | 107 | static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) |
108 | { | 108 | { |
109 | unsigned long sp = regs->regs[29]; | 109 | unsigned long sp = regs->regs[29]; |
110 | unsigned long ra = regs->regs[31]; | 110 | unsigned long ra = regs->regs[31]; |
@@ -126,7 +126,8 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs) | |||
126 | * This routine abuses get_user()/put_user() to reference pointers | 126 | * This routine abuses get_user()/put_user() to reference pointers |
127 | * with at least a bit of error checking ... | 127 | * with at least a bit of error checking ... |
128 | */ | 128 | */ |
129 | static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) | 129 | static void show_stacktrace(struct task_struct *task, |
130 | const struct pt_regs *regs) | ||
130 | { | 131 | { |
131 | const int field = 2 * sizeof(unsigned long); | 132 | const int field = 2 * sizeof(unsigned long); |
132 | long stackdata; | 133 | long stackdata; |
@@ -203,7 +204,7 @@ static void show_code(unsigned int __user *pc) | |||
203 | } | 204 | } |
204 | } | 205 | } |
205 | 206 | ||
206 | void show_regs(struct pt_regs *regs) | 207 | static void __show_regs(const struct pt_regs *regs) |
207 | { | 208 | { |
208 | const int field = 2 * sizeof(unsigned long); | 209 | const int field = 2 * sizeof(unsigned long); |
209 | unsigned int cause = regs->cp0_cause; | 210 | unsigned int cause = regs->cp0_cause; |
@@ -299,9 +300,17 @@ void show_regs(struct pt_regs *regs) | |||
299 | cpu_name_string()); | 300 | cpu_name_string()); |
300 | } | 301 | } |
301 | 302 | ||
302 | void show_registers(struct pt_regs *regs) | 303 | /* |
304 | * FIXME: really the generic show_regs should take a const pointer argument. | ||
305 | */ | ||
306 | void show_regs(struct pt_regs *regs) | ||
307 | { | ||
308 | __show_regs((struct pt_regs *)regs); | ||
309 | } | ||
310 | |||
311 | void show_registers(const struct pt_regs *regs) | ||
303 | { | 312 | { |
304 | show_regs(regs); | 313 | __show_regs(regs); |
305 | print_modules(); | 314 | print_modules(); |
306 | printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", | 315 | printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", |
307 | current->comm, current->pid, current_thread_info(), current); | 316 | current->comm, current->pid, current_thread_info(), current); |
@@ -312,7 +321,7 @@ void show_registers(struct pt_regs *regs) | |||
312 | 321 | ||
313 | static DEFINE_SPINLOCK(die_lock); | 322 | static DEFINE_SPINLOCK(die_lock); |
314 | 323 | ||
315 | void __noreturn die(const char * str, struct pt_regs * regs) | 324 | void __noreturn die(const char * str, const struct pt_regs * regs) |
316 | { | 325 | { |
317 | static int die_counter; | 326 | static int die_counter; |
318 | #ifdef CONFIG_MIPS_MT_SMTC | 327 | #ifdef CONFIG_MIPS_MT_SMTC |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 84f9a4cc6f2f..2781cff1485e 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -5,6 +5,10 @@ | |||
5 | #define mips mips | 5 | #define mips mips |
6 | OUTPUT_ARCH(mips) | 6 | OUTPUT_ARCH(mips) |
7 | ENTRY(kernel_entry) | 7 | ENTRY(kernel_entry) |
8 | PHDRS { | ||
9 | text PT_LOAD FLAGS(7); /* RWX */ | ||
10 | note PT_NOTE FLAGS(4); /* R__ */ | ||
11 | } | ||
8 | jiffies = JIFFIES; | 12 | jiffies = JIFFIES; |
9 | 13 | ||
10 | SECTIONS | 14 | SECTIONS |
@@ -22,7 +26,6 @@ SECTIONS | |||
22 | */ | 26 | */ |
23 | 27 | ||
24 | /* . = 0xa800000000300000; */ | 28 | /* . = 0xa800000000300000; */ |
25 | /* . = 0xa800000000300000; */ | ||
26 | . = 0xffffffff80300000; | 29 | . = 0xffffffff80300000; |
27 | #endif | 30 | #endif |
28 | . = LOADADDR; | 31 | . = LOADADDR; |
@@ -32,9 +35,10 @@ SECTIONS | |||
32 | TEXT_TEXT | 35 | TEXT_TEXT |
33 | SCHED_TEXT | 36 | SCHED_TEXT |
34 | LOCK_TEXT | 37 | LOCK_TEXT |
38 | KPROBES_TEXT | ||
35 | *(.fixup) | 39 | *(.fixup) |
36 | *(.gnu.warning) | 40 | *(.gnu.warning) |
37 | } =0 | 41 | } :text = 0 |
38 | _etext = .; /* End of text section */ | 42 | _etext = .; /* End of text section */ |
39 | 43 | ||
40 | /* Exception table */ | 44 | /* Exception table */ |
@@ -51,6 +55,10 @@ SECTIONS | |||
51 | *(__dbe_table) | 55 | *(__dbe_table) |
52 | __stop___dbe_table = .; | 56 | __stop___dbe_table = .; |
53 | } | 57 | } |
58 | |||
59 | NOTES :text :note | ||
60 | .dummy : { *(.dummy) } :text | ||
61 | |||
54 | RODATA | 62 | RODATA |
55 | 63 | ||
56 | /* writeable */ | 64 | /* writeable */ |
@@ -201,7 +209,4 @@ SECTIONS | |||
201 | *(.gptab.bss) | 209 | *(.gptab.bss) |
202 | *(.gptab.sbss) | 210 | *(.gptab.sbss) |
203 | } | 211 | } |
204 | .note : { | ||
205 | *(.note) | ||
206 | } | ||
207 | } | 212 | } |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 61b729fa0548..df8cbe4c7c0d 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -1317,7 +1317,8 @@ static void kspd_sp_exit( int sp_id) | |||
1317 | } | 1317 | } |
1318 | #endif | 1318 | #endif |
1319 | 1319 | ||
1320 | static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len) | 1320 | static ssize_t store_kill(struct device *dev, struct device_attribute *attr, |
1321 | const char *buf, size_t len) | ||
1321 | { | 1322 | { |
1322 | struct vpe *vpe = get_vpe(tclimit); | 1323 | struct vpe *vpe = get_vpe(tclimit); |
1323 | struct vpe_notifications *not; | 1324 | struct vpe_notifications *not; |
@@ -1334,14 +1335,16 @@ static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len) | |||
1334 | return len; | 1335 | return len; |
1335 | } | 1336 | } |
1336 | 1337 | ||
1337 | static ssize_t show_ntcs(struct class_device *cd, char *buf) | 1338 | static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, |
1339 | char *buf) | ||
1338 | { | 1340 | { |
1339 | struct vpe *vpe = get_vpe(tclimit); | 1341 | struct vpe *vpe = get_vpe(tclimit); |
1340 | 1342 | ||
1341 | return sprintf(buf, "%d\n", vpe->ntcs); | 1343 | return sprintf(buf, "%d\n", vpe->ntcs); |
1342 | } | 1344 | } |
1343 | 1345 | ||
1344 | static ssize_t store_ntcs(struct class_device *dev, const char *buf, size_t len) | 1346 | static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, |
1347 | const char *buf, size_t len) | ||
1345 | { | 1348 | { |
1346 | struct vpe *vpe = get_vpe(tclimit); | 1349 | struct vpe *vpe = get_vpe(tclimit); |
1347 | unsigned long new; | 1350 | unsigned long new; |
@@ -1362,13 +1365,13 @@ out_einval: | |||
1362 | return -EINVAL;; | 1365 | return -EINVAL;; |
1363 | } | 1366 | } |
1364 | 1367 | ||
1365 | static struct class_device_attribute vpe_class_attributes[] = { | 1368 | static struct device_attribute vpe_class_attributes[] = { |
1366 | __ATTR(kill, S_IWUSR, NULL, store_kill), | 1369 | __ATTR(kill, S_IWUSR, NULL, store_kill), |
1367 | __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), | 1370 | __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), |
1368 | {} | 1371 | {} |
1369 | }; | 1372 | }; |
1370 | 1373 | ||
1371 | static void vpe_class_device_release(struct class_device *cd) | 1374 | static void vpe_device_release(struct device *cd) |
1372 | { | 1375 | { |
1373 | kfree(cd); | 1376 | kfree(cd); |
1374 | } | 1377 | } |
@@ -1376,11 +1379,11 @@ static void vpe_class_device_release(struct class_device *cd) | |||
1376 | struct class vpe_class = { | 1379 | struct class vpe_class = { |
1377 | .name = "vpe", | 1380 | .name = "vpe", |
1378 | .owner = THIS_MODULE, | 1381 | .owner = THIS_MODULE, |
1379 | .release = vpe_class_device_release, | 1382 | .dev_release = vpe_device_release, |
1380 | .class_dev_attrs = vpe_class_attributes, | 1383 | .dev_attrs = vpe_class_attributes, |
1381 | }; | 1384 | }; |
1382 | 1385 | ||
1383 | struct class_device vpe_device; | 1386 | struct device vpe_device; |
1384 | 1387 | ||
1385 | static int __init vpe_module_init(void) | 1388 | static int __init vpe_module_init(void) |
1386 | { | 1389 | { |
@@ -1423,12 +1426,12 @@ static int __init vpe_module_init(void) | |||
1423 | goto out_chrdev; | 1426 | goto out_chrdev; |
1424 | } | 1427 | } |
1425 | 1428 | ||
1426 | class_device_initialize(&vpe_device); | 1429 | device_initialize(&vpe_device); |
1427 | vpe_device.class = &vpe_class, | 1430 | vpe_device.class = &vpe_class, |
1428 | vpe_device.parent = NULL, | 1431 | vpe_device.parent = NULL, |
1429 | strlcpy(vpe_device.class_id, "vpe1", BUS_ID_SIZE); | 1432 | strlcpy(vpe_device.bus_id, "vpe1", BUS_ID_SIZE); |
1430 | vpe_device.devt = MKDEV(major, minor); | 1433 | vpe_device.devt = MKDEV(major, minor); |
1431 | err = class_device_add(&vpe_device); | 1434 | err = device_add(&vpe_device); |
1432 | if (err) { | 1435 | if (err) { |
1433 | printk(KERN_ERR "Adding vpe_device failed\n"); | 1436 | printk(KERN_ERR "Adding vpe_device failed\n"); |
1434 | goto out_class; | 1437 | goto out_class; |
@@ -1573,7 +1576,7 @@ static void __exit vpe_module_exit(void) | |||
1573 | } | 1576 | } |
1574 | } | 1577 | } |
1575 | 1578 | ||
1576 | class_device_del(&vpe_device); | 1579 | device_del(&vpe_device); |
1577 | unregister_chrdev(major, module_name); | 1580 | unregister_chrdev(major, module_name); |
1578 | } | 1581 | } |
1579 | 1582 | ||
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 5f35289bfff5..ba9692be3564 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel_stat.h> | 26 | #include <linux/kernel_stat.h> |
27 | 27 | ||
28 | #include <asm/bootinfo.h> | 28 | #include <asm/bootinfo.h> |
29 | #include <asm/irq_cpu.h> | ||
29 | #include <asm/lasat/lasatint.h> | 30 | #include <asm/lasat/lasatint.h> |
30 | #include <asm/time.h> | 31 | #include <asm/time.h> |
31 | #include <asm/gdb-stub.h> | 32 | #include <asm/gdb-stub.h> |
@@ -88,7 +89,7 @@ asmlinkage void plat_irq_dispatch(void) | |||
88 | int irq; | 89 | int irq; |
89 | 90 | ||
90 | if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ | 91 | if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ |
91 | ll_timer_interrupt(7); | 92 | do_IRQ(7); |
92 | return; | 93 | return; |
93 | } | 94 | } |
94 | 95 | ||
@@ -96,7 +97,7 @@ asmlinkage void plat_irq_dispatch(void) | |||
96 | 97 | ||
97 | /* if int_status == 0, then the interrupt has already been cleared */ | 98 | /* if int_status == 0, then the interrupt has already been cleared */ |
98 | if (int_status) { | 99 | if (int_status) { |
99 | irq = ls1bit32(int_status); | 100 | irq = LASATINT_BASE + ls1bit32(int_status); |
100 | 101 | ||
101 | do_IRQ(irq); | 102 | do_IRQ(irq); |
102 | } | 103 | } |
@@ -125,6 +126,7 @@ void __init arch_init_irq(void) | |||
125 | panic("arch_init_irq: mips_machtype incorrect"); | 126 | panic("arch_init_irq: mips_machtype incorrect"); |
126 | } | 127 | } |
127 | 128 | ||
128 | for (i = 0; i <= LASATINT_END; i++) | 129 | mips_cpu_irq_init(); |
130 | for (i = LASATINT_BASE; i <= LASATINT_END; i++) | ||
129 | set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); | 131 | set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); |
130 | } | 132 | } |
diff --git a/arch/mips/mipssim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c index c63021a5dc6c..74240e1ce5a5 100644 --- a/arch/mips/mipssim/sim_cmdline.c +++ b/arch/mips/mipssim/sim_cmdline.c | |||
@@ -28,8 +28,5 @@ char * __init prom_getcmdline(void) | |||
28 | 28 | ||
29 | void __init prom_init_cmdline(void) | 29 | void __init prom_init_cmdline(void) |
30 | { | 30 | { |
31 | char *cp; | 31 | /* XXX: Get boot line from environment? */ |
32 | cp = arcs_cmdline; | ||
33 | /* Get boot line from environment? */ | ||
34 | *cp = '\0'; | ||
35 | } | 32 | } |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 971f6c047b8a..d7088331fb0f 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -983,11 +983,15 @@ static void __init probe_pcache(void) | |||
983 | 983 | ||
984 | printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", | 984 | printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", |
985 | icache_size >> 10, | 985 | icache_size >> 10, |
986 | cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", | 986 | cpu_has_vtag_icache ? "VIVT" : "VIPT", |
987 | way_string[c->icache.ways], c->icache.linesz); | 987 | way_string[c->icache.ways], c->icache.linesz); |
988 | 988 | ||
989 | printk("Primary data cache %ldkB, %s, linesize %d bytes.\n", | 989 | printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n", |
990 | dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); | 990 | dcache_size >> 10, way_string[c->dcache.ways], |
991 | (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT", | ||
992 | (c->dcache.flags & MIPS_CACHE_ALIASES) ? | ||
993 | "cache aliases" : "no aliases", | ||
994 | c->dcache.linesz); | ||
991 | } | 995 | } |
992 | 996 | ||
993 | /* | 997 | /* |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 5240432e6d1d..110ee7656b41 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -211,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from, | |||
211 | void *vfrom, *vto; | 211 | void *vfrom, *vto; |
212 | 212 | ||
213 | vto = kmap_atomic(to, KM_USER1); | 213 | vto = kmap_atomic(to, KM_USER1); |
214 | if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) { | 214 | if (cpu_has_dc_aliases && page_mapped(from)) { |
215 | vfrom = kmap_coherent(from, vaddr); | 215 | vfrom = kmap_coherent(from, vaddr); |
216 | copy_page(vto, vfrom); | 216 | copy_page(vto, vfrom); |
217 | kunmap_coherent(); | 217 | kunmap_coherent(); |
@@ -234,12 +234,15 @@ void copy_to_user_page(struct vm_area_struct *vma, | |||
234 | struct page *page, unsigned long vaddr, void *dst, const void *src, | 234 | struct page *page, unsigned long vaddr, void *dst, const void *src, |
235 | unsigned long len) | 235 | unsigned long len) |
236 | { | 236 | { |
237 | if (cpu_has_dc_aliases) { | 237 | if (cpu_has_dc_aliases && page_mapped(page)) { |
238 | void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); | 238 | void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); |
239 | memcpy(vto, src, len); | 239 | memcpy(vto, src, len); |
240 | kunmap_coherent(); | 240 | kunmap_coherent(); |
241 | } else | 241 | } else { |
242 | memcpy(dst, src, len); | 242 | memcpy(dst, src, len); |
243 | if (cpu_has_dc_aliases) | ||
244 | SetPageDcacheDirty(page); | ||
245 | } | ||
243 | if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) | 246 | if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) |
244 | flush_cache_page(vma, vaddr, page_to_pfn(page)); | 247 | flush_cache_page(vma, vaddr, page_to_pfn(page)); |
245 | } | 248 | } |
@@ -250,13 +253,15 @@ void copy_from_user_page(struct vm_area_struct *vma, | |||
250 | struct page *page, unsigned long vaddr, void *dst, const void *src, | 253 | struct page *page, unsigned long vaddr, void *dst, const void *src, |
251 | unsigned long len) | 254 | unsigned long len) |
252 | { | 255 | { |
253 | if (cpu_has_dc_aliases) { | 256 | if (cpu_has_dc_aliases && page_mapped(page)) { |
254 | void *vfrom = | 257 | void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); |
255 | kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); | ||
256 | memcpy(dst, vfrom, len); | 258 | memcpy(dst, vfrom, len); |
257 | kunmap_coherent(); | 259 | kunmap_coherent(); |
258 | } else | 260 | } else { |
259 | memcpy(dst, src, len); | 261 | memcpy(dst, src, len); |
262 | if (cpu_has_dc_aliases) | ||
263 | SetPageDcacheDirty(page); | ||
264 | } | ||
260 | } | 265 | } |
261 | 266 | ||
262 | EXPORT_SYMBOL(copy_from_user_page); | 267 | EXPORT_SYMBOL(copy_from_user_page); |
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 5abd5c7119be..174f314933b5 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <asm/bootinfo.h> | 12 | #include <asm/bootinfo.h> |
13 | #include <asm/lasat/lasatint.h> | ||
13 | 14 | ||
14 | extern struct pci_ops nile4_pci_ops; | 15 | extern struct pci_ops nile4_pci_ops; |
15 | extern struct pci_ops gt64xxx_pci0_ops; | 16 | extern struct pci_ops gt64xxx_pci0_ops; |
@@ -54,15 +55,15 @@ static int __init lasat_pci_setup(void) | |||
54 | 55 | ||
55 | arch_initcall(lasat_pci_setup); | 56 | arch_initcall(lasat_pci_setup); |
56 | 57 | ||
57 | #define LASATINT_ETH1 0 | 58 | #define LASATINT_ETH1 (LASATINT_BASE + 0) |
58 | #define LASATINT_ETH0 1 | 59 | #define LASATINT_ETH0 (LASATINT_BASE + 1) |
59 | #define LASATINT_HDC 2 | 60 | #define LASATINT_HDC (LASATINT_BASE + 2) |
60 | #define LASATINT_COMP 3 | 61 | #define LASATINT_COMP (LASATINT_BASE + 3) |
61 | #define LASATINT_HDLC 4 | 62 | #define LASATINT_HDLC (LASATINT_BASE + 4) |
62 | #define LASATINT_PCIA 5 | 63 | #define LASATINT_PCIA (LASATINT_BASE + 5) |
63 | #define LASATINT_PCIB 6 | 64 | #define LASATINT_PCIB (LASATINT_BASE + 6) |
64 | #define LASATINT_PCIC 7 | 65 | #define LASATINT_PCIC (LASATINT_BASE + 7) |
65 | #define LASATINT_PCID 8 | 66 | #define LASATINT_PCID (LASATINT_BASE + 8) |
66 | 67 | ||
67 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 68 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
68 | { | 69 | { |
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index 1fb3e353e212..e3acb51b70b5 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile | |||
@@ -7,3 +7,5 @@ obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ | |||
7 | ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o | 7 | ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o |
8 | 8 | ||
9 | obj-$(CONFIG_EISA) += ip22-eisa.o | 9 | obj-$(CONFIG_EISA) += ip22-eisa.o |
10 | |||
11 | EXTRA_CFLAGS += -Werror | ||
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 63afd7e44428..a435b31cf031 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c | |||
@@ -232,11 +232,18 @@ static struct notifier_block panic_block = { | |||
232 | 232 | ||
233 | static int __init reboot_setup(void) | 233 | static int __init reboot_setup(void) |
234 | { | 234 | { |
235 | int res; | ||
236 | |||
235 | _machine_restart = sgi_machine_restart; | 237 | _machine_restart = sgi_machine_restart; |
236 | _machine_halt = sgi_machine_halt; | 238 | _machine_halt = sgi_machine_halt; |
237 | pm_power_off = sgi_machine_power_off; | 239 | pm_power_off = sgi_machine_power_off; |
238 | 240 | ||
239 | request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); | 241 | res = request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); |
242 | if (res) { | ||
243 | printk(KERN_ERR "Allocation of front panel IRQ failed\n"); | ||
244 | return res; | ||
245 | } | ||
246 | |||
240 | init_timer(&blink_timer); | 247 | init_timer(&blink_timer); |
241 | blink_timer.function = blink_timeout; | 248 | blink_timer.function = blink_timeout; |
242 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | 249 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 7f4b793c3df3..7e8094f617bf 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/random.h> | 20 | #include <linux/random.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | 22 | ||
23 | #include <asm/irq_cpu.h> | ||
23 | #include <asm/mipsregs.h> | 24 | #include <asm/mipsregs.h> |
24 | #include <asm/signal.h> | 25 | #include <asm/signal.h> |
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
@@ -46,7 +47,8 @@ static void inline flush_mace_bus(void) | |||
46 | #define DBG(x...) | 47 | #define DBG(x...) |
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | /* O2 irq map | 50 | /* |
51 | * O2 irq map | ||
50 | * | 52 | * |
51 | * IP0 -> software (ignored) | 53 | * IP0 -> software (ignored) |
52 | * IP1 -> software (ignored) | 54 | * IP1 -> software (ignored) |
@@ -55,60 +57,60 @@ static void inline flush_mace_bus(void) | |||
55 | * IP4 -> (irq2) X unknown | 57 | * IP4 -> (irq2) X unknown |
56 | * IP5 -> (irq3) X unknown | 58 | * IP5 -> (irq3) X unknown |
57 | * IP6 -> (irq4) X unknown | 59 | * IP6 -> (irq4) X unknown |
58 | * IP7 -> (irq5) 0 CPU count/compare timer (system timer) | 60 | * IP7 -> (irq5) 7 CPU count/compare timer (system timer) |
59 | * | 61 | * |
60 | * crime: (C) | 62 | * crime: (C) |
61 | * | 63 | * |
62 | * CRIME_INT_STAT 31:0: | 64 | * CRIME_INT_STAT 31:0: |
63 | * | 65 | * |
64 | * 0 -> 1 Video in 1 | 66 | * 0 -> 8 Video in 1 |
65 | * 1 -> 2 Video in 2 | 67 | * 1 -> 9 Video in 2 |
66 | * 2 -> 3 Video out | 68 | * 2 -> 10 Video out |
67 | * 3 -> 4 Mace ethernet | 69 | * 3 -> 11 Mace ethernet |
68 | * 4 -> S SuperIO sub-interrupt | 70 | * 4 -> S SuperIO sub-interrupt |
69 | * 5 -> M Miscellaneous sub-interrupt | 71 | * 5 -> M Miscellaneous sub-interrupt |
70 | * 6 -> A Audio sub-interrupt | 72 | * 6 -> A Audio sub-interrupt |
71 | * 7 -> 8 PCI bridge errors | 73 | * 7 -> 15 PCI bridge errors |
72 | * 8 -> 9 PCI SCSI aic7xxx 0 | 74 | * 8 -> 16 PCI SCSI aic7xxx 0 |
73 | * 9 -> 10 PCI SCSI aic7xxx 1 | 75 | * 9 -> 17 PCI SCSI aic7xxx 1 |
74 | * 10 -> 11 PCI slot 0 | 76 | * 10 -> 18 PCI slot 0 |
75 | * 11 -> 12 unused (PCI slot 1) | 77 | * 11 -> 19 unused (PCI slot 1) |
76 | * 12 -> 13 unused (PCI slot 2) | 78 | * 12 -> 20 unused (PCI slot 2) |
77 | * 13 -> 14 unused (PCI shared 0) | 79 | * 13 -> 21 unused (PCI shared 0) |
78 | * 14 -> 15 unused (PCI shared 1) | 80 | * 14 -> 22 unused (PCI shared 1) |
79 | * 15 -> 16 unused (PCI shared 2) | 81 | * 15 -> 23 unused (PCI shared 2) |
80 | * 16 -> 17 GBE0 (E) | 82 | * 16 -> 24 GBE0 (E) |
81 | * 17 -> 18 GBE1 (E) | 83 | * 17 -> 25 GBE1 (E) |
82 | * 18 -> 19 GBE2 (E) | 84 | * 18 -> 26 GBE2 (E) |
83 | * 19 -> 20 GBE3 (E) | 85 | * 19 -> 27 GBE3 (E) |
84 | * 20 -> 21 CPU errors | 86 | * 20 -> 28 CPU errors |
85 | * 21 -> 22 Memory errors | 87 | * 21 -> 29 Memory errors |
86 | * 22 -> 23 RE empty edge (E) | 88 | * 22 -> 30 RE empty edge (E) |
87 | * 23 -> 24 RE full edge (E) | 89 | * 23 -> 31 RE full edge (E) |
88 | * 24 -> 25 RE idle edge (E) | 90 | * 24 -> 32 RE idle edge (E) |
89 | * 25 -> 26 RE empty level | 91 | * 25 -> 33 RE empty level |
90 | * 26 -> 27 RE full level | 92 | * 26 -> 34 RE full level |
91 | * 27 -> 28 RE idle level | 93 | * 27 -> 35 RE idle level |
92 | * 28 -> 29 unused (software 0) (E) | 94 | * 28 -> 36 unused (software 0) (E) |
93 | * 29 -> 30 unused (software 1) (E) | 95 | * 29 -> 37 unused (software 1) (E) |
94 | * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) | 96 | * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E) |
95 | * 31 -> 32 VICE | 97 | * 31 -> 39 VICE |
96 | * | 98 | * |
97 | * S, M, A: Use the MACE ISA interrupt register | 99 | * S, M, A: Use the MACE ISA interrupt register |
98 | * MACE_ISA_INT_STAT 31:0 | 100 | * MACE_ISA_INT_STAT 31:0 |
99 | * | 101 | * |
100 | * 0-7 -> 33-40 Audio | 102 | * 0-7 -> 40-47 Audio |
101 | * 8 -> 41 RTC | 103 | * 8 -> 48 RTC |
102 | * 9 -> 42 Keyboard | 104 | * 9 -> 49 Keyboard |
103 | * 10 -> X Keyboard polled | 105 | * 10 -> X Keyboard polled |
104 | * 11 -> 44 Mouse | 106 | * 11 -> 51 Mouse |
105 | * 12 -> X Mouse polled | 107 | * 12 -> X Mouse polled |
106 | * 13-15 -> 46-48 Count/compare timers | 108 | * 13-15 -> 53-55 Count/compare timers |
107 | * 16-19 -> 49-52 Parallel (16 E) | 109 | * 16-19 -> 56-59 Parallel (16 E) |
108 | * 20-25 -> 53-58 Serial 1 (22 E) | 110 | * 20-25 -> 60-62 Serial 1 (22 E) |
109 | * 26-31 -> 59-64 Serial 2 (28 E) | 111 | * 26-31 -> 66-71 Serial 2 (28 E) |
110 | * | 112 | * |
111 | * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a | 113 | * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a |
112 | * different IRQ map than IRIX uses, but that's OK as Linux irq handling | 114 | * different IRQ map than IRIX uses, but that's OK as Linux irq handling |
113 | * is quite different anyway. | 115 | * is quite different anyway. |
114 | */ | 116 | */ |
@@ -131,36 +133,6 @@ struct irqaction cpuerr_irq = { | |||
131 | }; | 133 | }; |
132 | 134 | ||
133 | /* | 135 | /* |
134 | * For interrupts wired from a single device to the CPU. Only the clock | ||
135 | * uses this it seems, which is IRQ 0 and IP7. | ||
136 | */ | ||
137 | |||
138 | static void enable_cpu_irq(unsigned int irq) | ||
139 | { | ||
140 | set_c0_status(STATUSF_IP7); | ||
141 | } | ||
142 | |||
143 | static void disable_cpu_irq(unsigned int irq) | ||
144 | { | ||
145 | clear_c0_status(STATUSF_IP7); | ||
146 | } | ||
147 | |||
148 | static void end_cpu_irq(unsigned int irq) | ||
149 | { | ||
150 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
151 | enable_cpu_irq(irq); | ||
152 | } | ||
153 | |||
154 | static struct irq_chip ip32_cpu_interrupt = { | ||
155 | .name = "IP32 CPU", | ||
156 | .ack = disable_cpu_irq, | ||
157 | .mask = disable_cpu_irq, | ||
158 | .mask_ack = disable_cpu_irq, | ||
159 | .unmask = enable_cpu_irq, | ||
160 | .end = end_cpu_irq, | ||
161 | }; | ||
162 | |||
163 | /* | ||
164 | * This is for pure CRIME interrupts - ie not MACE. The advantage? | 136 | * This is for pure CRIME interrupts - ie not MACE. The advantage? |
165 | * We get to split the register in half and do faster lookups. | 137 | * We get to split the register in half and do faster lookups. |
166 | */ | 138 | */ |
@@ -422,15 +394,23 @@ static void ip32_irq0(void) | |||
422 | uint64_t crime_int; | 394 | uint64_t crime_int; |
423 | int irq = 0; | 395 | int irq = 0; |
424 | 396 | ||
397 | /* | ||
398 | * Sanity check interrupt numbering enum. | ||
399 | * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy | ||
400 | * chained. | ||
401 | */ | ||
402 | BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31); | ||
403 | BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31); | ||
404 | |||
425 | crime_int = crime->istat & crime_mask; | 405 | crime_int = crime->istat & crime_mask; |
426 | irq = __ffs(crime_int); | 406 | irq = MACE_VID_IN1_IRQ + __ffs(crime_int); |
427 | crime_int = 1 << irq; | 407 | crime_int = 1 << irq; |
428 | 408 | ||
429 | if (crime_int & CRIME_MACEISA_INT_MASK) { | 409 | if (crime_int & CRIME_MACEISA_INT_MASK) { |
430 | unsigned long mace_int = mace->perif.ctrl.istat; | 410 | unsigned long mace_int = mace->perif.ctrl.istat; |
431 | irq = __ffs(mace_int & maceisa_mask) + 32; | 411 | irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; |
432 | } | 412 | } |
433 | irq++; | 413 | |
434 | DBG("*irq %u*\n", irq); | 414 | DBG("*irq %u*\n", irq); |
435 | do_IRQ(irq); | 415 | do_IRQ(irq); |
436 | } | 416 | } |
@@ -457,7 +437,7 @@ static void ip32_irq4(void) | |||
457 | 437 | ||
458 | static void ip32_irq5(void) | 438 | static void ip32_irq5(void) |
459 | { | 439 | { |
460 | do_IRQ(IP32_R4K_TIMER_IRQ); | 440 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); |
461 | } | 441 | } |
462 | 442 | ||
463 | asmlinkage void plat_irq_dispatch(void) | 443 | asmlinkage void plat_irq_dispatch(void) |
@@ -490,21 +470,25 @@ void __init arch_init_irq(void) | |||
490 | mace->perif.ctrl.istat = 0; | 470 | mace->perif.ctrl.istat = 0; |
491 | mace->perif.ctrl.imask = 0; | 471 | mace->perif.ctrl.imask = 0; |
492 | 472 | ||
493 | for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { | 473 | mips_cpu_irq_init(); |
494 | struct irq_chip *controller; | 474 | for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { |
495 | 475 | struct irq_chip *chip; | |
496 | if (irq == IP32_R4K_TIMER_IRQ) | 476 | |
497 | controller = &ip32_cpu_interrupt; | 477 | switch (irq) { |
498 | else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) | 478 | case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: |
499 | controller = &ip32_mace_interrupt; | 479 | chip = &ip32_mace_interrupt; |
500 | else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) | 480 | break; |
501 | controller = &ip32_macepci_interrupt; | 481 | case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: |
502 | else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) | 482 | chip = &ip32_macepci_interrupt; |
503 | controller = &ip32_crime_interrupt; | 483 | break; |
504 | else | 484 | case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ: |
505 | controller = &ip32_maceisa_interrupt; | 485 | chip = &ip32_crime_interrupt; |
506 | 486 | break; | |
507 | set_irq_chip(irq, controller); | 487 | default: |
488 | chip = &ip32_maceisa_interrupt; | ||
489 | } | ||
490 | |||
491 | set_irq_chip(irq, chip); | ||
508 | } | 492 | } |
509 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); | 493 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); |
510 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); | 494 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); |
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index 4125a5ba119e..fc75bfcb0c0e 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c | |||
@@ -83,7 +83,7 @@ void __init plat_time_init(void) | |||
83 | void __init plat_timer_setup(struct irqaction *irq) | 83 | void __init plat_timer_setup(struct irqaction *irq) |
84 | { | 84 | { |
85 | irq->handler = no_action; | 85 | irq->handler = no_action; |
86 | setup_irq(IP32_R4K_TIMER_IRQ, irq); | 86 | setup_irq(MIPS_CPU_IRQ_BASE + 7, irq); |
87 | } | 87 | } |
88 | 88 | ||
89 | void __init plat_mem_setup(void) | 89 | void __init plat_mem_setup(void) |