diff options
Diffstat (limited to 'arch/sh/boards/superh')
-rw-r--r-- | arch/sh/boards/superh/microdev/irq.c | 39 | ||||
-rw-r--r-- | arch/sh/boards/superh/microdev/setup.c | 113 |
2 files changed, 61 insertions, 91 deletions
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index 236398fbc08..8c64baa3036 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c | |||
@@ -11,14 +11,12 @@ | |||
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | |||
15 | #include <asm/system.h> | 14 | #include <asm/system.h> |
16 | #include <asm/io.h> | 15 | #include <asm/io.h> |
17 | #include <asm/microdev.h> | 16 | #include <asm/microdev.h> |
18 | 17 | ||
19 | #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ | 18 | #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ |
20 | 19 | ||
21 | |||
22 | static const struct { | 20 | static const struct { |
23 | unsigned char fpgaIrq; | 21 | unsigned char fpgaIrq; |
24 | unsigned char mapped; | 22 | unsigned char mapped; |
@@ -93,53 +91,42 @@ static struct hw_interrupt_type microdev_irq_type = { | |||
93 | 91 | ||
94 | static void disable_microdev_irq(unsigned int irq) | 92 | static void disable_microdev_irq(unsigned int irq) |
95 | { | 93 | { |
96 | unsigned int flags; | ||
97 | unsigned int fpgaIrq; | 94 | unsigned int fpgaIrq; |
98 | 95 | ||
99 | if (irq >= NUM_EXTERNAL_IRQS) return; | 96 | if (irq >= NUM_EXTERNAL_IRQS) |
100 | if (!fpgaIrqTable[irq].mapped) return; | 97 | return; |
98 | if (!fpgaIrqTable[irq].mapped) | ||
99 | return; | ||
101 | 100 | ||
102 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; | 101 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; |
103 | 102 | ||
104 | /* disable interrupts */ | 103 | /* disable interupts on the FPGA INTC register */ |
105 | local_irq_save(flags); | ||
106 | |||
107 | /* disable interupts on the FPGA INTC register */ | ||
108 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); | 104 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); |
109 | |||
110 | /* restore interrupts */ | ||
111 | local_irq_restore(flags); | ||
112 | } | 105 | } |
113 | 106 | ||
114 | static void enable_microdev_irq(unsigned int irq) | 107 | static void enable_microdev_irq(unsigned int irq) |
115 | { | 108 | { |
116 | unsigned long priorityReg, priorities, pri; | 109 | unsigned long priorityReg, priorities, pri; |
117 | unsigned int flags; | ||
118 | unsigned int fpgaIrq; | 110 | unsigned int fpgaIrq; |
119 | 111 | ||
120 | 112 | if (unlikely(irq >= NUM_EXTERNAL_IRQS)) | |
121 | if (irq >= NUM_EXTERNAL_IRQS) return; | 113 | return; |
122 | if (!fpgaIrqTable[irq].mapped) return; | 114 | if (unlikely(!fpgaIrqTable[irq].mapped)) |
115 | return; | ||
123 | 116 | ||
124 | pri = 15 - irq; | 117 | pri = 15 - irq; |
125 | 118 | ||
126 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; | 119 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; |
127 | priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); | 120 | priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); |
128 | 121 | ||
129 | /* disable interrupts */ | 122 | /* set priority for the interrupt */ |
130 | local_irq_save(flags); | ||
131 | |||
132 | /* set priority for the interrupt */ | ||
133 | priorities = ctrl_inl(priorityReg); | 123 | priorities = ctrl_inl(priorityReg); |
134 | priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); | 124 | priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); |
135 | priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); | 125 | priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); |
136 | ctrl_outl(priorities, priorityReg); | 126 | ctrl_outl(priorities, priorityReg); |
137 | 127 | ||
138 | /* enable interupts on the FPGA INTC register */ | 128 | /* enable interupts on the FPGA INTC register */ |
139 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); | 129 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); |
140 | |||
141 | /* restore interrupts */ | ||
142 | local_irq_restore(flags); | ||
143 | } | 130 | } |
144 | 131 | ||
145 | /* This functions sets the desired irq handler to be a MicroDev type */ | 132 | /* This functions sets the desired irq handler to be a MicroDev type */ |
@@ -158,9 +145,7 @@ static void mask_and_ack_microdev(unsigned int irq) | |||
158 | static void end_microdev_irq(unsigned int irq) | 145 | static void end_microdev_irq(unsigned int irq) |
159 | { | 146 | { |
160 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | 147 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) |
161 | { | ||
162 | enable_microdev_irq(irq); | 148 | enable_microdev_irq(irq); |
163 | } | ||
164 | } | 149 | } |
165 | 150 | ||
166 | extern void __init init_microdev_irq(void) | 151 | extern void __init init_microdev_irq(void) |
@@ -171,9 +156,7 @@ extern void __init init_microdev_irq(void) | |||
171 | ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); | 156 | ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); |
172 | 157 | ||
173 | for (i = 0; i < NUM_EXTERNAL_IRQS; i++) | 158 | for (i = 0; i < NUM_EXTERNAL_IRQS; i++) |
174 | { | ||
175 | make_microdev_irq(i); | 159 | make_microdev_irq(i); |
176 | } | ||
177 | } | 160 | } |
178 | 161 | ||
179 | extern void microdev_print_fpga_intc_status(void) | 162 | extern void microdev_print_fpga_intc_status(void) |
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index 61b402a3f5d..031c814e6e7 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * May be copied or modified under the terms of the GNU General Public | 10 | * May be copied or modified under the terms of the GNU General Public |
11 | * License. See linux/COPYING for more information. | 11 | * License. See linux/COPYING for more information. |
12 | */ | 12 | */ |
13 | |||
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
16 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
@@ -21,41 +20,6 @@ | |||
21 | 20 | ||
22 | extern void microdev_heartbeat(void); | 21 | extern void microdev_heartbeat(void); |
23 | 22 | ||
24 | /* | ||
25 | * The Machine Vector | ||
26 | */ | ||
27 | |||
28 | struct sh_machine_vector mv_sh4202_microdev __initmv = { | ||
29 | .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ | ||
30 | |||
31 | .mv_inb = microdev_inb, | ||
32 | .mv_inw = microdev_inw, | ||
33 | .mv_inl = microdev_inl, | ||
34 | .mv_outb = microdev_outb, | ||
35 | .mv_outw = microdev_outw, | ||
36 | .mv_outl = microdev_outl, | ||
37 | |||
38 | .mv_inb_p = microdev_inb_p, | ||
39 | .mv_inw_p = microdev_inw_p, | ||
40 | .mv_inl_p = microdev_inl_p, | ||
41 | .mv_outb_p = microdev_outb_p, | ||
42 | .mv_outw_p = microdev_outw_p, | ||
43 | .mv_outl_p = microdev_outl_p, | ||
44 | |||
45 | .mv_insb = microdev_insb, | ||
46 | .mv_insw = microdev_insw, | ||
47 | .mv_insl = microdev_insl, | ||
48 | .mv_outsb = microdev_outsb, | ||
49 | .mv_outsw = microdev_outsw, | ||
50 | .mv_outsl = microdev_outsl, | ||
51 | |||
52 | .mv_init_irq = init_microdev_irq, | ||
53 | |||
54 | #ifdef CONFIG_HEARTBEAT | ||
55 | .mv_heartbeat = microdev_heartbeat, | ||
56 | #endif | ||
57 | }; | ||
58 | ALIAS_MV(sh4202_microdev) | ||
59 | 23 | ||
60 | /****************************************************************************/ | 24 | /****************************************************************************/ |
61 | 25 | ||
@@ -113,11 +77,6 @@ ALIAS_MV(sh4202_microdev) | |||
113 | /* assume a Keyboard Controller is present */ | 77 | /* assume a Keyboard Controller is present */ |
114 | int microdev_kbd_controller_present = 1; | 78 | int microdev_kbd_controller_present = 1; |
115 | 79 | ||
116 | const char *get_system_type(void) | ||
117 | { | ||
118 | return "SH4-202 MicroDev"; | ||
119 | } | ||
120 | |||
121 | static struct resource smc91x_resources[] = { | 80 | static struct resource smc91x_resources[] = { |
122 | [0] = { | 81 | [0] = { |
123 | .start = 0x300, | 82 | .start = 0x300, |
@@ -291,25 +250,9 @@ static int __init microdev_devices_setup(void) | |||
291 | return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); | 250 | return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); |
292 | } | 251 | } |
293 | 252 | ||
294 | __initcall(microdev_devices_setup); | 253 | /* |
295 | 254 | * Setup for the SMSC FDC37C93xAPM | |
296 | void __init platform_setup(void) | 255 | */ |
297 | { | ||
298 | int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); | ||
299 | const int fpgaRevision = *fpgaRevisionRegister; | ||
300 | int * const CacheControlRegister = (int*)CCR; | ||
301 | |||
302 | printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", | ||
303 | get_system_type(), fpgaRevision, *CacheControlRegister); | ||
304 | } | ||
305 | |||
306 | |||
307 | /****************************************************************************/ | ||
308 | |||
309 | |||
310 | /* | ||
311 | * Setup for the SMSC FDC37C93xAPM | ||
312 | */ | ||
313 | static int __init smsc_superio_setup(void) | 256 | static int __init smsc_superio_setup(void) |
314 | { | 257 | { |
315 | 258 | ||
@@ -412,8 +355,52 @@ static int __init smsc_superio_setup(void) | |||
412 | return 0; | 355 | return 0; |
413 | } | 356 | } |
414 | 357 | ||
358 | static void __init microdev_setup(char **cmdline_p) | ||
359 | { | ||
360 | int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); | ||
361 | const int fpgaRevision = *fpgaRevisionRegister; | ||
362 | int * const CacheControlRegister = (int*)CCR; | ||
363 | |||
364 | device_initcall(microdev_devices_setup); | ||
365 | device_initcall(smsc_superio_setup); | ||
415 | 366 | ||
416 | /* This is grotty, but, because kernel is always referenced on the link line | 367 | printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", |
417 | * before any devices, this is safe. | 368 | get_system_type(), fpgaRevision, *CacheControlRegister); |
369 | } | ||
370 | |||
371 | /* | ||
372 | * The Machine Vector | ||
418 | */ | 373 | */ |
419 | __initcall(smsc_superio_setup); | 374 | struct sh_machine_vector mv_sh4202_microdev __initmv = { |
375 | .mv_name = "SH4-202 MicroDev", | ||
376 | .mv_setup = microdev_setup, | ||
377 | .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ | ||
378 | |||
379 | .mv_inb = microdev_inb, | ||
380 | .mv_inw = microdev_inw, | ||
381 | .mv_inl = microdev_inl, | ||
382 | .mv_outb = microdev_outb, | ||
383 | .mv_outw = microdev_outw, | ||
384 | .mv_outl = microdev_outl, | ||
385 | |||
386 | .mv_inb_p = microdev_inb_p, | ||
387 | .mv_inw_p = microdev_inw_p, | ||
388 | .mv_inl_p = microdev_inl_p, | ||
389 | .mv_outb_p = microdev_outb_p, | ||
390 | .mv_outw_p = microdev_outw_p, | ||
391 | .mv_outl_p = microdev_outl_p, | ||
392 | |||
393 | .mv_insb = microdev_insb, | ||
394 | .mv_insw = microdev_insw, | ||
395 | .mv_insl = microdev_insl, | ||
396 | .mv_outsb = microdev_outsb, | ||
397 | .mv_outsw = microdev_outsw, | ||
398 | .mv_outsl = microdev_outsl, | ||
399 | |||
400 | .mv_init_irq = init_microdev_irq, | ||
401 | |||
402 | #ifdef CONFIG_HEARTBEAT | ||
403 | .mv_heartbeat = microdev_heartbeat, | ||
404 | #endif | ||
405 | }; | ||
406 | ALIAS_MV(sh4202_microdev) | ||