baboon.c 2.36 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10
/*
 * Baboon Custom IC Management
 *
 * The Baboon custom IC controls the IDE, PCMCIA and media bay on the
 * PowerBook 190. It multiplexes multiple interrupt sources onto the
 * Nubus slot $C interrupt.
 */

#include <linux/types.h>
#include <linux/kernel.h>
11
#include <linux/irq.h>
Linus Torvalds's avatar
Linus Torvalds committed
12 13 14 15 16 17 18

#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_baboon.h>

/* #define DEBUG_IRQS */

Finn Thain's avatar
Finn Thain committed
19
int baboon_present;
Adrian Bunk's avatar
Adrian Bunk committed
20
static volatile struct baboon *baboon;
Linus Torvalds's avatar
Linus Torvalds committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

#if 0
extern int macide_ack_intr(struct ata_channel *);
#endif

/*
 * Baboon initialization.
 */

void __init baboon_init(void)
{
	if (macintosh_config->ident != MAC_MODEL_PB190) {
		baboon = NULL;
		baboon_present = 0;
		return;
	}

	baboon = (struct baboon *) BABOON_BASE;
	baboon_present = 1;

	printk("Baboon detected at %p\n", baboon);
}

/*
 * Baboon interrupt handler. This works a lot like a VIA.
 */

48
static void baboon_irq(struct irq_desc *desc)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
{
	int irq_bit, irq_num;
	unsigned char events;

#ifdef DEBUG_IRQS
	printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n",
		(uint) baboon->mb_control, (uint) baboon->mb_ifr,
		(uint) baboon->mb_status);
#endif

	events = baboon->mb_ifr & 0x07;
	if (!events)
		return;

	irq_num = IRQ_BABOON_0;
	irq_bit = 1;
	do {
	        if (events & irq_bit) {
			baboon->mb_ifr &= ~irq_bit;
			generic_handle_irq(irq_num);
		}
		irq_bit <<= 1;
		irq_num++;
	} while(events >= irq_bit);
#if 0
	if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL);
	/* for now we need to smash all interrupts */
	baboon->mb_ifr &= ~events;
#endif
}
Linus Torvalds's avatar
Linus Torvalds committed
79

Adrian Bunk's avatar
Adrian Bunk committed
80 81 82 83 84 85
/*
 * Register the Baboon interrupt dispatcher on nubus slot $C.
 */

void __init baboon_register_interrupts(void)
{
86
	irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq);
Adrian Bunk's avatar
Adrian Bunk committed
87 88
}

89
/*
90 91 92 93 94 95
 * The means for masking individual Baboon interrupts remains a mystery.
 * However, since we only use the IDE IRQ, we can just enable/disable all
 * Baboon interrupts. If/when we handle more than one Baboon IRQ, we must
 * either figure out how to mask them individually or else implement the
 * same workaround that's used for NuBus slots (see nubus_disabled and
 * via_nubus_irq_shutdown).
96 97 98 99
 */

void baboon_irq_enable(int irq)
{
Linus Torvalds's avatar
Linus Torvalds committed
100 101 102
#ifdef DEBUG_IRQUSE
	printk("baboon_irq_enable(%d)\n", irq);
#endif
103

104
	mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
Linus Torvalds's avatar
Linus Torvalds committed
105 106
}

107 108
void baboon_irq_disable(int irq)
{
Linus Torvalds's avatar
Linus Torvalds committed
109 110 111
#ifdef DEBUG_IRQUSE
	printk("baboon_irq_disable(%d)\n", irq);
#endif
112

113
	mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
Linus Torvalds's avatar
Linus Torvalds committed
114
}