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 236398fbc083..8c64baa30364 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 61b402a3f5d7..031c814e6e76 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) | ||
