diff options
Diffstat (limited to 'arch/mips/jazz/irq.c')
-rw-r--r-- | arch/mips/jazz/irq.c | 142 |
1 files changed, 75 insertions, 67 deletions
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 015cf4bb51dd..835b056cea36 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c | |||
@@ -6,20 +6,23 @@ | |||
6 | * Copyright (C) 1992 Linus Torvalds | 6 | * Copyright (C) 1992 Linus Torvalds |
7 | * Copyright (C) 1994 - 2001, 2003 Ralf Baechle | 7 | * Copyright (C) 1994 - 2001, 2003 Ralf Baechle |
8 | */ | 8 | */ |
9 | #include <linux/clockchips.h> | ||
9 | #include <linux/init.h> | 10 | #include <linux/init.h> |
10 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
13 | 14 | ||
15 | #include <asm/irq_cpu.h> | ||
14 | #include <asm/i8259.h> | 16 | #include <asm/i8259.h> |
15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
16 | #include <asm/jazz.h> | 18 | #include <asm/jazz.h> |
19 | #include <asm/pgtable.h> | ||
17 | 20 | ||
18 | static DEFINE_SPINLOCK(r4030_lock); | 21 | static DEFINE_SPINLOCK(r4030_lock); |
19 | 22 | ||
20 | static void enable_r4030_irq(unsigned int irq) | 23 | static void enable_r4030_irq(unsigned int irq) |
21 | { | 24 | { |
22 | unsigned int mask = 1 << (irq - JAZZ_PARALLEL_IRQ); | 25 | unsigned int mask = 1 << (irq - JAZZ_IRQ_START); |
23 | unsigned long flags; | 26 | unsigned long flags; |
24 | 27 | ||
25 | spin_lock_irqsave(&r4030_lock, flags); | 28 | spin_lock_irqsave(&r4030_lock, flags); |
@@ -30,7 +33,7 @@ static void enable_r4030_irq(unsigned int irq) | |||
30 | 33 | ||
31 | void disable_r4030_irq(unsigned int irq) | 34 | void disable_r4030_irq(unsigned int irq) |
32 | { | 35 | { |
33 | unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ)); | 36 | unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START)); |
34 | unsigned long flags; | 37 | unsigned long flags; |
35 | 38 | ||
36 | spin_lock_irqsave(&r4030_lock, flags); | 39 | spin_lock_irqsave(&r4030_lock, flags); |
@@ -51,7 +54,7 @@ void __init init_r4030_ints(void) | |||
51 | { | 54 | { |
52 | int i; | 55 | int i; |
53 | 56 | ||
54 | for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) | 57 | for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++) |
55 | set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); | 58 | set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); |
56 | 59 | ||
57 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); | 60 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); |
@@ -66,82 +69,87 @@ void __init init_r4030_ints(void) | |||
66 | */ | 69 | */ |
67 | void __init arch_init_irq(void) | 70 | void __init arch_init_irq(void) |
68 | { | 71 | { |
72 | /* | ||
73 | * this is a hack to get back the still needed wired mapping | ||
74 | * killed by init_mm() | ||
75 | */ | ||
76 | |||
77 | /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */ | ||
78 | add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K); | ||
79 | /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */ | ||
80 | add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M); | ||
81 | /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */ | ||
82 | add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M); | ||
83 | |||
69 | init_i8259_irqs(); /* Integrated i8259 */ | 84 | init_i8259_irqs(); /* Integrated i8259 */ |
85 | mips_cpu_irq_init(); | ||
70 | init_r4030_ints(); | 86 | init_r4030_ints(); |
71 | 87 | ||
72 | change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); | 88 | change_c0_status(ST0_IM, IE_IRQ2 | IE_IRQ1); |
73 | } | ||
74 | |||
75 | static void loc_call(unsigned int irq, unsigned int mask) | ||
76 | { | ||
77 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
78 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); | ||
79 | do_IRQ(irq); | ||
80 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
81 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); | ||
82 | } | ||
83 | |||
84 | static void ll_local_dev(void) | ||
85 | { | ||
86 | switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { | ||
87 | case 0: | ||
88 | panic("Unimplemented loc_no_irq handler"); | ||
89 | break; | ||
90 | case 4: | ||
91 | loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_PARALLEL); | ||
92 | break; | ||
93 | case 8: | ||
94 | loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_FLOPPY); | ||
95 | break; | ||
96 | case 12: | ||
97 | panic("Unimplemented loc_sound handler"); | ||
98 | break; | ||
99 | case 16: | ||
100 | panic("Unimplemented loc_video handler"); | ||
101 | break; | ||
102 | case 20: | ||
103 | loc_call(JAZZ_ETHERNET_IRQ, JAZZ_IE_ETHERNET); | ||
104 | break; | ||
105 | case 24: | ||
106 | loc_call(JAZZ_SCSI_IRQ, JAZZ_IE_SCSI); | ||
107 | break; | ||
108 | case 28: | ||
109 | loc_call(JAZZ_KEYBOARD_IRQ, JAZZ_IE_KEYBOARD); | ||
110 | break; | ||
111 | case 32: | ||
112 | loc_call(JAZZ_MOUSE_IRQ, JAZZ_IE_MOUSE); | ||
113 | break; | ||
114 | case 36: | ||
115 | loc_call(JAZZ_SERIAL1_IRQ, JAZZ_IE_SERIAL1); | ||
116 | break; | ||
117 | case 40: | ||
118 | loc_call(JAZZ_SERIAL2_IRQ, JAZZ_IE_SERIAL2); | ||
119 | break; | ||
120 | } | ||
121 | } | 89 | } |
122 | 90 | ||
123 | asmlinkage void plat_irq_dispatch(void) | 91 | asmlinkage void plat_irq_dispatch(void) |
124 | { | 92 | { |
125 | unsigned int pending = read_c0_cause() & read_c0_status(); | 93 | unsigned int pending = read_c0_cause() & read_c0_status(); |
94 | unsigned int irq; | ||
126 | 95 | ||
127 | if (pending & IE_IRQ5) | 96 | if (pending & IE_IRQ4) { |
128 | write_c0_compare(0); | ||
129 | else if (pending & IE_IRQ4) { | ||
130 | r4030_read_reg32(JAZZ_TIMER_REGISTER); | 97 | r4030_read_reg32(JAZZ_TIMER_REGISTER); |
131 | do_IRQ(JAZZ_TIMER_IRQ); | 98 | do_IRQ(JAZZ_TIMER_IRQ); |
132 | } else if (pending & IE_IRQ3) | 99 | } else if (pending & IE_IRQ2) |
133 | panic("Unimplemented ISA NMI handler"); | ||
134 | else if (pending & IE_IRQ2) | ||
135 | do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); | 100 | do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); |
136 | else if (pending & IE_IRQ1) { | 101 | else if (pending & IE_IRQ1) { |
137 | ll_local_dev(); | 102 | irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2; |
138 | } else if (unlikely(pending & IE_IRQ0)) | 103 | if (likely(irq > 0)) |
139 | panic("Unimplemented local_dma handler"); | 104 | do_IRQ(irq + JAZZ_IRQ_START - 1); |
140 | else if (pending & IE_SW1) { | 105 | else |
141 | clear_c0_cause(IE_SW1); | 106 | panic("Unimplemented loc_no_irq handler"); |
142 | panic("Unimplemented sw1 handler"); | ||
143 | } else if (pending & IE_SW0) { | ||
144 | clear_c0_cause(IE_SW0); | ||
145 | panic("Unimplemented sw0 handler"); | ||
146 | } | 107 | } |
147 | } | 108 | } |
109 | |||
110 | static void r4030_set_mode(enum clock_event_mode mode, | ||
111 | struct clock_event_device *evt) | ||
112 | { | ||
113 | /* Nothing to do ... */ | ||
114 | } | ||
115 | |||
116 | struct clock_event_device r4030_clockevent = { | ||
117 | .name = "r4030", | ||
118 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
119 | .rating = 100, | ||
120 | .irq = JAZZ_TIMER_IRQ, | ||
121 | .cpumask = CPU_MASK_CPU0, | ||
122 | .set_mode = r4030_set_mode, | ||
123 | }; | ||
124 | |||
125 | static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) | ||
126 | { | ||
127 | r4030_clockevent.event_handler(&r4030_clockevent); | ||
128 | |||
129 | return IRQ_HANDLED; | ||
130 | } | ||
131 | |||
132 | static struct irqaction r4030_timer_irqaction = { | ||
133 | .handler = r4030_timer_interrupt, | ||
134 | .flags = IRQF_DISABLED, | ||
135 | .mask = CPU_MASK_CPU0, | ||
136 | .name = "timer", | ||
137 | }; | ||
138 | |||
139 | void __init plat_timer_setup(struct irqaction *ignored) | ||
140 | { | ||
141 | struct irqaction *irq = &r4030_timer_irqaction; | ||
142 | |||
143 | BUG_ON(HZ != 100); | ||
144 | |||
145 | /* | ||
146 | * Set clock to 100Hz. | ||
147 | * | ||
148 | * The R4030 timer receives an input clock of 1kHz which is divieded by | ||
149 | * a programmable 4-bit divider. This makes it fairly inflexible. | ||
150 | */ | ||
151 | r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); | ||
152 | setup_irq(JAZZ_TIMER_IRQ, irq); | ||
153 | |||
154 | clockevents_register_device(&r4030_clockevent); | ||
155 | } | ||