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/irq.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 no_action(int cpl
, void *dev_id
, struct pt_regs
*regs
)
29 adir_onboard_pic_init(void)
31 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
33 /* Disable all Adirondack onboard interrupts */
34 out_be16(maskreg
, 0xFFFF);
38 adir_onboard_pic_get_irq(void)
40 volatile u_short
*statreg
= (volatile u_short
*) ADIR_PROCA_INT_STAT
;
42 u_short int_status
, int_test
;
44 int_status
= in_be16(statreg
);
45 for (irq
= 0, int_test
= 1; irq
< 16; irq
++, int_test
<<= 1) {
46 if (int_status
& int_test
)
57 adir_onboard_pic_enable(unsigned int irq
)
59 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
61 /* Change irq to Adirondack onboard native value */
64 /* Enable requested irq number */
65 out_be16(maskreg
, in_be16(maskreg
) & ~(1 << irq
));
69 adir_onboard_pic_disable(unsigned int irq
)
71 volatile u_short
*maskreg
= (volatile u_short
*) ADIR_PROCA_INT_MASK
;
73 /* Change irq to Adirondack onboard native value */
76 /* Disable requested irq number */
77 out_be16(maskreg
, in_be16(maskreg
) | (1 << irq
));
80 static struct hw_interrupt_type adir_onboard_pic
= {
84 adir_onboard_pic_enable
, /* unmask */
85 adir_onboard_pic_disable
, /* mask */
86 adir_onboard_pic_disable
, /* mask and ack */
92 * Linux interrupt values are assigned as follows:
94 * 0-15 VT82C686 8259 interrupts
95 * 16-31 Adirondack CPLD interrupts
102 /* Initialize the cascaded 8259's on the VT82C686 */
104 irq_desc
[i
].handler
= &i8259_pic
;
107 /* Initialize Adirondack CPLD PIC and enable 8259 interrupt cascade */
108 for (i
=16; i
<32; i
++)
109 irq_desc
[i
].handler
= &adir_onboard_pic
;
110 adir_onboard_pic_init();
112 /* Enable 8259 interrupt cascade */
113 request_irq(ADIR_IRQ_VT82C686_INTR
,
116 "82c59 primary cascade",
121 adir_get_irq(struct pt_regs
*regs
)
125 if ((irq
= adir_onboard_pic_get_irq()) < 0)
128 if (irq
== ADIR_IRQ_VT82C686_INTR
)
129 irq
= i8259_irq(regs
);