diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:44:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 13:44:35 -0400 |
| commit | ebc283118ee448dcb6e6cae74a8a43f17a1ccc3f (patch) | |
| tree | daeb82c70de678ac10a5cec153097294dd772cb1 /arch/mips | |
| parent | fc8a327db6c46de783b1a4276d846841b9abc24c (diff) | |
| parent | 8bb00d83d8fc2de5c0614f5d55780107e0c375fe (diff) | |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
[MIPS] Increase cp0 compare clockevent min_delta_ns from 0x30 to 0x300.
[MIPS] Cache: Provide more information on cache policy on bootup.
[MIPS] Fix aliasing bug in copy_user_highpage, take 2.
[MIPS] VPE loader: convert from struct class_ device to struct device
[MIPS] MIPSsim: Fix booting from NFS root
[MIPS] Alchemy: Get rid of au1xxx_irq_map_t.
[MIPS] Alchemy: Get rid of au_ffz().
[MIPS] Alchemy: Get rid of au_ffs().
[MIPS] Alchemy: cleanup interrupt code.
[MIPS] Lasat: Fix build by conversion to irq_cpu.c.
[MIPS] Lasat: Add #ifndef ... #endif include warpper to lasatint.h.
[MIPS] IP22: Enable -Werror.
[MIPS] IP22: Fix warning.
[MIPS] IP22: Complain if requesting the front panel irq failed.
[MIPS] vmlinux.lds.S: Handle KPROBES_TEXT.
[MIPS] vmlinux.lds.S: Fix handling of .notes in final link.
[MIPS] vmlinux.lds.S: Remove duplicate comment.
[MIPS] MSP71XX: Add workarounds file.
[MIPS] IP32: Fix build by conversion to irq_cpu.c.
Diffstat (limited to 'arch/mips')
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) |
