• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/m68k/mac/
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_IRQS */
22
23extern void mac_enable_irq(unsigned int);
24extern void mac_disable_irq(unsigned int);
25
26int baboon_present;
27static volatile struct baboon *baboon;
28static unsigned char baboon_disabled;
29
30
31/*
32 * Baboon initialization.
33 */
34
35void __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
53static 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	return IRQ_HANDLED;
78}
79
80/*
81 * Register the Baboon interrupt dispatcher on nubus slot $C.
82 */
83
84void __init baboon_register_interrupts(void)
85{
86	baboon_disabled = 0;
87	if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
88		pr_err("Couldn't register baboon interrupt\n");
89}
90
91/*
92 * The means for masking individual baboon interrupts remains a mystery, so
93 * enable the umbrella interrupt only when no baboon interrupt is disabled.
94 */
95
96void baboon_irq_enable(int irq)
97{
98	int irq_idx = IRQ_IDX(irq);
99
100#ifdef DEBUG_IRQUSE
101	printk("baboon_irq_enable(%d)\n", irq);
102#endif
103
104	baboon_disabled &= ~(1 << irq_idx);
105	if (!baboon_disabled)
106		mac_enable_irq(IRQ_NUBUS_C);
107}
108
109void baboon_irq_disable(int irq)
110{
111	int irq_idx = IRQ_IDX(irq);
112
113#ifdef DEBUG_IRQUSE
114	printk("baboon_irq_disable(%d)\n", irq);
115#endif
116
117	baboon_disabled |= 1 << irq_idx;
118	if (baboon_disabled)
119		mac_disable_irq(IRQ_NUBUS_C);
120}
121
122void baboon_irq_clear(int irq)
123{
124	int irq_idx = IRQ_IDX(irq);
125
126	baboon->mb_ifr &= ~(1 << irq_idx);
127}
128
129int baboon_irq_pending(int irq)
130{
131	int irq_idx = IRQ_IDX(irq);
132
133	return baboon->mb_ifr & (1 << irq_idx);
134}
135