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 #include <linux/ide.h> 15 16 #include <asm/traps.h> 17 #include <asm/bootinfo.h> 18 #include <asm/macintosh.h> 19 #include <asm/macints.h> 20 #include <asm/mac_baboon.h> 21 22 /* #define DEBUG_BABOON */ 23 /* #define DEBUG_IRQS */ 24 25 int baboon_present,baboon_active; 26 volatile struct baboon *baboon; 27 28 irqreturn_t baboon_irq(int, void *, struct pt_regs *); 29 30 #if 0 31 extern int macide_ack_intr(struct ata_channel *); 32 #endif 33 34 /* 35 * Baboon initialization. 36 */ 37 38 void __init baboon_init(void) 39 { 40 if (macintosh_config->ident != MAC_MODEL_PB190) { 41 baboon = NULL; 42 baboon_present = 0; 43 return; 44 } 45 46 baboon = (struct baboon *) BABOON_BASE; 47 baboon_present = 1; 48 baboon_active = 0; 49 50 printk("Baboon detected at %p\n", baboon); 51 } 52 53 /* 54 * Register the Baboon interrupt dispatcher on nubus slot $C. 55 */ 56 57 void __init baboon_register_interrupts(void) 58 { 59 request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, 60 "baboon", (void *) baboon); 61 } 62 63 /* 64 * Baboon interrupt handler. This works a lot like a VIA. 65 */ 66 67 irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs) 68 { 69 int irq_bit,i; 70 unsigned char events; 71 72 #ifdef DEBUG_IRQS 73 printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X active %02X\n", 74 (uint) baboon->mb_control, (uint) baboon->mb_ifr, 75 (uint) baboon->mb_status, baboon_active); 76 #endif 77 78 if (!(events = baboon->mb_ifr & 0x07)) 79 return IRQ_NONE; 80 81 for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { 82 if (events & irq_bit/* & baboon_active*/) { 83 baboon_active &= ~irq_bit; 84 mac_do_irq_list(IRQ_BABOON_0 + i, regs); 85 baboon_active |= irq_bit; 86 baboon->mb_ifr &= ~irq_bit; 87 } 88 } 89 #if 0 90 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); 91 /* for now we need to smash all interrupts */ 92 baboon->mb_ifr &= ~events; 93 #endif 94 return IRQ_HANDLED; 95 } 96 97 void baboon_irq_enable(int irq) { 98 int irq_idx = IRQ_IDX(irq); 99 100 #ifdef DEBUG_IRQUSE 101 printk("baboon_irq_enable(%d)\n", irq); 102 #endif 103 baboon_active |= (1 << irq_idx); 104 } 105 106 void baboon_irq_disable(int irq) { 107 int irq_idx = IRQ_IDX(irq); 108 109 #ifdef DEBUG_IRQUSE 110 printk("baboon_irq_disable(%d)\n", irq); 111 #endif 112 baboon_active &= ~(1 << irq_idx); 113 } 114 115 void baboon_irq_clear(int irq) { 116 int irq_idx = IRQ_IDX(irq); 117 118 baboon->mb_ifr &= ~(1 << irq_idx); 119 } 120 121 int baboon_irq_pending(int irq) 122 { 123 int irq_idx = IRQ_IDX(irq); 124 125 return baboon->mb_ifr & (1 << irq_idx); 126 } 127