Merge branch 'linus' into x86/gart
[sfrench/cifs-2.6.git] / arch / m68k / mac / baboon.c
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 }