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/irq.h> 12 13#include <asm/macintosh.h> 14#include <asm/macints.h> 15#include <asm/mac_baboon.h> 16 17/* #define DEBUG_IRQS */ 18 19int baboon_present; 20static volatile struct baboon *baboon; 21 22#if 0 23extern int macide_ack_intr(struct ata_channel *); 24#endif 25 26/* 27 * Baboon initialization. 28 */ 29 30void __init baboon_init(void) 31{ 32 if (macintosh_config->ident != MAC_MODEL_PB190) { 33 baboon = NULL; 34 baboon_present = 0; 35 return; 36 } 37 38 baboon = (struct baboon *) BABOON_BASE; 39 baboon_present = 1; 40 41 printk("Baboon detected at %p\n", baboon); 42} 43 44/* 45 * Baboon interrupt handler. This works a lot like a VIA. 46 */ 47 48static void baboon_irq(struct irq_desc *desc) 49{ 50 int irq_bit, irq_num; 51 unsigned char events; 52 53#ifdef DEBUG_IRQS 54 printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", 55 (uint) baboon->mb_control, (uint) baboon->mb_ifr, 56 (uint) baboon->mb_status); 57#endif 58 59 events = baboon->mb_ifr & 0x07; 60 if (!events) 61 return; 62 63 irq_num = IRQ_BABOON_0; 64 irq_bit = 1; 65 do { 66 if (events & irq_bit) { 67 baboon->mb_ifr &= ~irq_bit; 68 generic_handle_irq(irq_num); 69 } 70 irq_bit <<= 1; 71 irq_num++; 72 } while(events >= irq_bit); 73#if 0 74 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); 75 /* for now we need to smash all interrupts */ 76 baboon->mb_ifr &= ~events; 77#endif 78} 79 80/* 81 * Register the Baboon interrupt dispatcher on nubus slot $C. 82 */ 83 84void __init baboon_register_interrupts(void) 85{ 86 irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); 87} 88 89/* 90 * The means for masking individual Baboon interrupts remains a mystery. 91 * However, since we only use the IDE IRQ, we can just enable/disable all 92 * Baboon interrupts. If/when we handle more than one Baboon IRQ, we must 93 * either figure out how to mask them individually or else implement the 94 * same workaround that's used for NuBus slots (see nubus_disabled and 95 * via_nubus_irq_shutdown). 96 */ 97 98void baboon_irq_enable(int irq) 99{ 100#ifdef DEBUG_IRQUSE 101 printk("baboon_irq_enable(%d)\n", irq); 102#endif 103 104 mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C)); 105} 106 107void baboon_irq_disable(int irq) 108{ 109#ifdef DEBUG_IRQUSE 110 printk("baboon_irq_disable(%d)\n", irq); 111#endif 112 113 mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C)); 114} 115