2 * arch/ppc/platforms/adir_pic.c
4 * Interrupt controller support for SBS Adirondack
6 * By Michael Sokolov <msokolov@ivan.Harhan.ORG>
7 * based on the K2 and SCM versions by Matt Porter <mporter@mvista.com>
10 #include <linux/stddef.h>
11 #include <linux/init.h>
12 #include <linux/sched.h>
13 #include <linux/pci.h>
14 #include <linux/interrupt.h>
17 #include <asm/i8259.h>
20 static void adir_onboard_pic_enable(unsigned int irq
);
21 static void adir_onboard_pic_disable(unsigned int irq
);
24 adir_onboard_pic_init(void)
26 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
28 /* Disable all Adirondack onboard interrupts */
29 out_be16(maskreg
, 0xFFFF);
33 adir_onboard_pic_get_irq(void)
35 volatile u_short
*statreg
= (volatile u_short
*) ADIR_PROCA_INT_STAT
;
37 u_short int_status
, int_test
;
39 int_status
= in_be16(statreg
);
40 for (irq
= 0, int_test
= 1; irq
< 16; irq
++, int_test
<<= 1) {
41 if (int_status
& int_test
)
52 adir_onboard_pic_enable(unsigned int irq
)
54 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
56 /* Change irq to Adirondack onboard native value */
59 /* Enable requested irq number */
60 out_be16(maskreg
, in_be16(maskreg
) & ~(1 << irq
));
64 adir_onboard_pic_disable(unsigned int irq
)
66 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
68 /* Change irq to Adirondack onboard native value */
71 /* Disable requested irq number */
72 out_be16(maskreg
, in_be16(maskreg
) | (1 << irq
));
75 static struct hw_interrupt_type adir_onboard_pic
= {
79 adir_onboard_pic_enable
, /* unmask */
80 adir_onboard_pic_disable
, /* mask */
81 adir_onboard_pic_disable
, /* mask and ack */
86 static struct irqaction noop_action
= {
88 .flags
= SA_INTERRUPT
,
89 .mask
= CPU_MASK_NONE
,
90 .name
= "82c59 primary cascade",
94 * Linux interrupt values are assigned as follows:
96 * 0-15 VT82C686 8259 interrupts
97 * 16-31 Adirondack CPLD interrupts
104 /* Initialize the cascaded 8259's on the VT82C686 */
106 irq_desc
[i
].handler
= &i8259_pic
;
109 /* Initialize Adirondack CPLD PIC and enable 8259 interrupt cascade */
110 for (i
=16; i
<32; i
++)
111 irq_desc
[i
].handler
= &adir_onboard_pic
;
112 adir_onboard_pic_init();
114 /* Enable 8259 interrupt cascade */
115 setup_irq(ADIR_IRQ_VT82C686_INTR
, &noop_action
);
119 adir_get_irq(struct pt_regs
*regs
)
123 if ((irq
= adir_onboard_pic_get_irq()) < 0)
126 if (irq
== ADIR_IRQ_VT82C686_INTR
)
127 irq
= i8259_irq(regs
);