linux/arch/m68k/mac/baboon.c
<<
>>
Prefs
   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#if 0
  31extern int macide_ack_intr(struct ata_channel *);
  32#endif
  33
  34/*
  35 * Baboon initialization.
  36 */
  37
  38void __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
  49        printk("Baboon detected at %p\n", baboon);
  50}
  51
  52/*
  53 * Baboon interrupt handler. This works a lot like a VIA.
  54 */
  55
  56static irqreturn_t baboon_irq(int irq, void *dev_id)
  57{
  58        int irq_bit, irq_num;
  59        unsigned char events;
  60
  61#ifdef DEBUG_IRQS
  62        printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n",
  63                (uint) baboon->mb_control, (uint) baboon->mb_ifr,
  64                (uint) baboon->mb_status);
  65#endif
  66
  67        if (!(events = baboon->mb_ifr & 0x07))
  68                return IRQ_NONE;
  69
  70        irq_num = IRQ_BABOON_0;
  71        irq_bit = 1;
  72        do {
  73                if (events & irq_bit) {
  74                        baboon->mb_ifr &= ~irq_bit;
  75                        m68k_handle_int(irq_num);
  76                }
  77                irq_bit <<= 1;
  78                irq_num++;
  79        } while(events >= irq_bit);
  80#if 0
  81        if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL);
  82        /* for now we need to smash all interrupts */
  83        baboon->mb_ifr &= ~events;
  84#endif
  85        return IRQ_HANDLED;
  86}
  87
  88/*
  89 * Register the Baboon interrupt dispatcher on nubus slot $C.
  90 */
  91
  92void __init baboon_register_interrupts(void)
  93{
  94        baboon_disabled = 0;
  95        if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
  96                pr_err("Couldn't register baboon interrupt\n");
  97}
  98
  99/*
 100 * The means for masking individual baboon interrupts remains a mystery, so
 101 * enable the umbrella interrupt only when no baboon interrupt is disabled.
 102 */
 103
 104void baboon_irq_enable(int irq)
 105{
 106        int irq_idx = IRQ_IDX(irq);
 107
 108#ifdef DEBUG_IRQUSE
 109        printk("baboon_irq_enable(%d)\n", irq);
 110#endif
 111
 112        baboon_disabled &= ~(1 << irq_idx);
 113        if (!baboon_disabled)
 114                mac_enable_irq(IRQ_NUBUS_C);
 115}
 116
 117void baboon_irq_disable(int irq)
 118{
 119        int irq_idx = IRQ_IDX(irq);
 120
 121#ifdef DEBUG_IRQUSE
 122        printk("baboon_irq_disable(%d)\n", irq);
 123#endif
 124
 125        baboon_disabled |= 1 << irq_idx;
 126        if (baboon_disabled)
 127                mac_disable_irq(IRQ_NUBUS_C);
 128}
 129
 130void baboon_irq_clear(int irq)
 131{
 132        int irq_idx = IRQ_IDX(irq);
 133
 134        baboon->mb_ifr &= ~(1 << irq_idx);
 135}
 136
 137int baboon_irq_pending(int irq)
 138{
 139        int irq_idx = IRQ_IDX(irq);
 140
 141        return baboon->mb_ifr & (1 << irq_idx);
 142}
 143
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.