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 19 int baboon_present; 20 static volatile struct baboon *baboon; 21 22 #if 0 23 extern int macide_ack_intr(struct ata_channel *); 24 #endif 25 26 /* 27 * Baboon initialization. 28 */ 29 30 void __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 48 static 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 84 void __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 98 void 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 107 void 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