xref: /openbmc/linux/arch/m68k/mac/baboon.c (revision 9ac8d3fb)
1 /*
2  * Baboon Custom IC Management
3  *
4  * The Baboon custom IC controls the IDE, PCMCIA and media bay on the
5  * PowerBook 190. It multiplexes multiple interrupt sources onto the
6  * Nubus slot $C interrupt.
7  */
8 
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <linux/mm.h>
12 #include <linux/delay.h>
13 #include <linux/init.h>
14 
15 #include <asm/traps.h>
16 #include <asm/bootinfo.h>
17 #include <asm/macintosh.h>
18 #include <asm/macints.h>
19 #include <asm/mac_baboon.h>
20 
21 /* #define DEBUG_BABOON */
22 /* #define DEBUG_IRQS */
23 
24 int baboon_present;
25 static volatile struct baboon *baboon;
26 
27 #if 0
28 extern int macide_ack_intr(struct ata_channel *);
29 #endif
30 
31 /*
32  * Baboon initialization.
33  */
34 
35 void __init baboon_init(void)
36 {
37 	if (macintosh_config->ident != MAC_MODEL_PB190) {
38 		baboon = NULL;
39 		baboon_present = 0;
40 		return;
41 	}
42 
43 	baboon = (struct baboon *) BABOON_BASE;
44 	baboon_present = 1;
45 
46 	printk("Baboon detected at %p\n", baboon);
47 }
48 
49 /*
50  * Baboon interrupt handler. This works a lot like a VIA.
51  */
52 
53 static irqreturn_t baboon_irq(int irq, void *dev_id)
54 {
55 	int irq_bit, irq_num;
56 	unsigned char events;
57 
58 #ifdef DEBUG_IRQS
59 	printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n",
60 		(uint) baboon->mb_control, (uint) baboon->mb_ifr,
61 		(uint) baboon->mb_status);
62 #endif
63 
64 	if (!(events = baboon->mb_ifr & 0x07))
65 		return IRQ_NONE;
66 
67 	irq_num = IRQ_BABOON_0;
68 	irq_bit = 1;
69 	do {
70 	        if (events & irq_bit) {
71 			baboon->mb_ifr &= ~irq_bit;
72 			m68k_handle_int(irq_num);
73 		}
74 		irq_bit <<= 1;
75 		irq_num++;
76 	} while(events >= irq_bit);
77 #if 0
78 	if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL);
79 	/* for now we need to smash all interrupts */
80 	baboon->mb_ifr &= ~events;
81 #endif
82 	return IRQ_HANDLED;
83 }
84 
85 /*
86  * Register the Baboon interrupt dispatcher on nubus slot $C.
87  */
88 
89 void __init baboon_register_interrupts(void)
90 {
91 	request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
92 		    "baboon", (void *) baboon);
93 }
94 
95 void baboon_irq_enable(int irq) {
96 #ifdef DEBUG_IRQUSE
97 	printk("baboon_irq_enable(%d)\n", irq);
98 #endif
99 	/* FIXME: figure out how to mask and unmask baboon interrupt sources */
100 	enable_irq(IRQ_NUBUS_C);
101 }
102 
103 void baboon_irq_disable(int irq) {
104 #ifdef DEBUG_IRQUSE
105 	printk("baboon_irq_disable(%d)\n", irq);
106 #endif
107 	disable_irq(IRQ_NUBUS_C);
108 }
109 
110 void baboon_irq_clear(int irq) {
111 	int irq_idx	= IRQ_IDX(irq);
112 
113 	baboon->mb_ifr &= ~(1 << irq_idx);
114 }
115 
116 int baboon_irq_pending(int irq)
117 {
118 	int irq_idx	= IRQ_IDX(irq);
119 
120 	return baboon->mb_ifr & (1 << irq_idx);
121 }
122