diff options
Diffstat (limited to 'arch/m68k/q40')
| -rw-r--r-- | arch/m68k/q40/README | 4 | ||||
| -rw-r--r-- | arch/m68k/q40/config.c | 26 | ||||
| -rw-r--r-- | arch/m68k/q40/q40ints.c | 61 |
3 files changed, 49 insertions, 42 deletions
diff --git a/arch/m68k/q40/README b/arch/m68k/q40/README index f877b724979..93f4c4cd3c4 100644 --- a/arch/m68k/q40/README +++ b/arch/m68k/q40/README @@ -31,7 +31,7 @@ drivers used by the Q40, apart from the very obvious (console etc.): char/joystick/* # most of this should work, not # in default config.in block/q40ide.c # startup for ide - ide* # see Documentation/ide.txt + ide* # see Documentation/ide/ide.txt floppy.c # normal PC driver, DMA emu in asm/floppy.h # and arch/m68k/kernel/entry.S # see drivers/block/README.fd @@ -89,7 +89,7 @@ The main interrupt register IIRQ_REG will indicate whether an IRQ was internal or from some ISA devices, EIRQ_REG can distinguish up to 8 ISA IRQs. The Q40 custom chip is programmable to provide 2 periodic timers: - - 50 or 200 Hz - level 2, !!THIS CANT BE DISABLED!! + - 50 or 200 Hz - level 2, !!THIS CAN'T BE DISABLED!! - 10 or 20 KHz - level 4, used for dma-sound Linux uses the 200 Hz interrupt for timer and beep by default. diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index ad10fecec2f..e90fe903613 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -24,11 +24,11 @@ #include <linux/rtc.h> #include <linux/vt_kern.h> #include <linux/bcd.h> +#include <linux/platform_device.h> #include <asm/io.h> #include <asm/rtc.h> #include <asm/bootinfo.h> -#include <asm/system.h> #include <asm/pgtable.h> #include <asm/setup.h> #include <asm/irq.h> @@ -40,7 +40,7 @@ extern void q40_init_IRQ(void); static void q40_get_model(char *model); extern void q40_sched_init(irq_handler_t handler); -static unsigned long q40_gettimeoffset(void); +static u32 q40_gettimeoffset(void); static int q40_hwclk(int, struct rtc_time *); static unsigned int q40_get_ss(void); static int q40_set_clock_mmss(unsigned long); @@ -154,7 +154,7 @@ static unsigned int serports[] = 0x3f8,0x2f8,0x3e8,0x2e8,0 }; -static void q40_disable_irqs(void) +static void __init q40_disable_irqs(void) { unsigned i, j; @@ -170,7 +170,7 @@ void __init config_q40(void) mach_sched_init = q40_sched_init; mach_init_IRQ = q40_init_IRQ; - mach_gettimeoffset = q40_gettimeoffset; + arch_gettimeoffset = q40_gettimeoffset; mach_hwclk = q40_hwclk; mach_get_ss = q40_get_ss; mach_get_rtc_pll = q40_get_rtc_pll; @@ -198,15 +198,15 @@ void __init config_q40(void) } -int q40_parse_bootinfo(const struct bi_record *rec) +int __init q40_parse_bootinfo(const struct bi_record *rec) { return 1; } -static unsigned long q40_gettimeoffset(void) +static u32 q40_gettimeoffset(void) { - return 5000 * (ql_ticks != 0); + return 5000 * (ql_ticks != 0) * 1000; } @@ -329,3 +329,15 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll) } else return -EINVAL; } + +static __init int q40_add_kbd_device(void) +{ + struct platform_device *pdev; + + if (!MACH_IS_Q40) + return -ENODEV; + + pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); + return PTR_ERR_OR_ZERO(pdev); +} +arch_initcall(q40_add_kbd_device); diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index 9f0e3d59bf9..513f9bb17b9 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -15,10 +15,9 @@ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <asm/ptrace.h> -#include <asm/system.h> -#include <asm/irq.h> #include <asm/traps.h> #include <asm/q40_master.h> @@ -35,35 +34,36 @@ */ static void q40_irq_handler(unsigned int, struct pt_regs *fp); -static void q40_enable_irq(unsigned int); -static void q40_disable_irq(unsigned int); +static void q40_irq_enable(struct irq_data *data); +static void q40_irq_disable(struct irq_data *data); unsigned short q40_ablecount[35]; unsigned short q40_state[35]; -static int q40_irq_startup(unsigned int irq) +static unsigned int q40_irq_startup(struct irq_data *data) { + unsigned int irq = data->irq; + /* test for ISA ints not implemented by HW */ switch (irq) { case 1: case 2: case 8: case 9: case 11: case 12: case 13: printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); - return -ENXIO; + /* FIXME return -ENXIO; */ } return 0; } -static void q40_irq_shutdown(unsigned int irq) +static void q40_irq_shutdown(struct irq_data *data) { } -static struct irq_controller q40_irq_controller = { +static struct irq_chip q40_irq_chip = { .name = "q40", - .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), - .startup = q40_irq_startup, - .shutdown = q40_irq_shutdown, - .enable = q40_enable_irq, - .disable = q40_disable_irq, + .irq_startup = q40_irq_startup, + .irq_shutdown = q40_irq_shutdown, + .irq_enable = q40_irq_enable, + .irq_disable = q40_irq_disable, }; /* @@ -81,13 +81,14 @@ static int disabled; void __init q40_init_IRQ(void) { - m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); + m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, + Q40_IRQ_MAX); /* setup handler for ISA ints */ m68k_setup_auto_interrupt(q40_irq_handler); - m68k_irq_startup(IRQ_AUTO_2); - m68k_irq_startup(IRQ_AUTO_4); + m68k_irq_startup_irq(IRQ_AUTO_2); + m68k_irq_startup_irq(IRQ_AUTO_4); /* now enable some ints.. */ master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ @@ -218,11 +219,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) switch (irq) { case 4: case 6: - __m68k_handle_int(Q40_IRQ_SAMPLE, fp); + do_IRQ(Q40_IRQ_SAMPLE, fp); return; } if (mir & Q40_IRQ_FRAME_MASK) { - __m68k_handle_int(Q40_IRQ_FRAME, fp); + do_IRQ(Q40_IRQ_FRAME, fp); master_outb(-1, FRAME_CLEAR_REG); } if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { @@ -257,7 +258,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) goto iirq; } q40_state[irq] |= IRQ_INPROGRESS; - __m68k_handle_int(irq, fp); + do_IRQ(irq, fp); q40_state[irq] &= ~IRQ_INPROGRESS; /* naively enable everything, if that fails than */ @@ -288,25 +289,29 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) mir = master_inb(IIRQ_REG); /* should test whether keyboard irq is really enabled, doing it in defhand */ if (mir & Q40_IRQ_KEYB_MASK) - __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); + do_IRQ(Q40_IRQ_KEYBOARD, fp); return; } -void q40_enable_irq(unsigned int irq) +void q40_irq_enable(struct irq_data *data) { + unsigned int irq = data->irq; + if (irq >= 5 && irq <= 15) { mext_disabled--; if (mext_disabled > 0) - printk("q40_enable_irq : nested disable/enable\n"); + printk("q40_irq_enable : nested disable/enable\n"); if (mext_disabled == 0) master_outb(1, EXT_ENABLE_REG); } } -void q40_disable_irq(unsigned int irq) +void q40_irq_disable(struct irq_data *data) { + unsigned int irq = data->irq; + /* disable ISA iqs : only do something if the driver has been * verified to be Q40 "compatible" - right now IDE, NE2K * Any driver should not attempt to sleep across disable_irq !! @@ -319,13 +324,3 @@ void q40_disable_irq(unsigned int irq) printk("disable_irq nesting count %d\n",mext_disabled); } } - -unsigned long q40_probe_irq_on(void) -{ - printk("irq probing not working - reconfigure the driver to avoid this\n"); - return -1; -} -int q40_probe_irq_off(unsigned long irqs) -{ - return -1; -} |
