2 * $Id: setup_hd64461.c,v 1.9 2001/07/15 23:26:56 gniibe Exp $
3 * Copyright (C) 2000 YAEGASHI Takeshi
4 * Hitachi HD64461 companion chip support
7 #include <linux/config.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/param.h>
11 #include <linux/interrupt.h>
12 #include <linux/init.h>
13 #include <linux/irq.h>
18 #include <asm/hd64461.h>
20 static void disable_hd64461_irq(unsigned int irq)
24 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
27 nimr = inw(HD64461_NIMR);
29 outw(nimr, HD64461_NIMR);
34 static void enable_hd64461_irq(unsigned int irq)
38 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
41 nimr = inw(HD64461_NIMR);
43 outw(nimr, HD64461_NIMR);
48 static void mask_and_ack_hd64461(unsigned int irq)
50 disable_hd64461_irq(irq);
51 #ifdef CONFIG_HD64461_ENABLER
52 if (irq == HD64461_IRQBASE + 13)
53 outb(0x00, HD64461_PCC1CSCR);
58 static void end_hd64461_irq(unsigned int irq)
60 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
61 enable_hd64461_irq(irq);
65 static unsigned int startup_hd64461_irq(unsigned int irq)
67 enable_hd64461_irq(irq);
72 static void shutdown_hd64461_irq(unsigned int irq)
74 disable_hd64461_irq(irq);
78 static struct hw_interrupt_type hd64461_irq_type = {
89 static void hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
92 "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
93 inw(HD64461_NIRR), inw(HD64461_NIMR));
96 int hd64461_irq_demux(int irq)
98 if (irq == CONFIG_HD64461_IRQ) {
100 unsigned short nirr = inw(HD64461_NIRR);
101 unsigned short nimr = inw(HD64461_NIMR);
103 for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++)
104 if (nirr & bit) break;
105 if (irq == 16) irq = CONFIG_HD64461_IRQ;
106 else irq += HD64461_IRQBASE;
108 return __irq_demux(irq);
111 static struct irqaction irq0 = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL};
114 int __init setup_hd64461(void)
121 printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)\n",
122 CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ,
123 HD64461_IRQBASE, HD64461_IRQBASE+15);
125 #if defined(CONFIG_CPU_SUBTYPE_SH7709) /* Should be at processor specific part.. */
126 outw(0x2240, INTC_ICR1);
128 outw(0xffff, HD64461_NIMR);
130 for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
131 irq_desc[i].handler = &hd64461_irq_type;
134 setup_irq(CONFIG_HD64461_IRQ, &irq0);
136 #ifdef CONFIG_HD64461_ENABLER
137 printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
138 outb(0x4c, HD64461_PCC1CSCIER);
139 outb(0x00, HD64461_PCC1CSCR);
145 module_init(setup_hd64461);