1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Baboon Custom IC Management
4 *
5 * The Baboon custom IC controls the IDE, PCMCIA and media bay on the
6 * PowerBook 190. It multiplexes multiple interrupt sources onto the
7 * Nubus slot $C interrupt.
8 */
9
10#include <linux/types.h>
11#include <linux/kernel.h>
12#include <linux/irq.h>
13
14#include <asm/macintosh.h>
15#include <asm/macints.h>
16#include <asm/mac_baboon.h>
17
18#include "mac.h"
19
20int baboon_present;
21static volatile struct baboon *baboon;
22
23/*
24 * Baboon initialization.
25 */
26
27void __init baboon_init(void)
28{
29	if (macintosh_config->ident != MAC_MODEL_PB190) {
30		baboon = NULL;
31		baboon_present = 0;
32		return;
33	}
34
35	baboon = (struct baboon *) BABOON_BASE;
36	baboon_present = 1;
37
38	pr_debug("Baboon detected at %p\n", baboon);
39}
40
41/*
42 * Baboon interrupt handler.
43 * XXX how do you clear a pending IRQ? is it even necessary?
44 */
45
46static void baboon_irq(struct irq_desc *desc)
47{
48	short events, irq_bit;
49	int irq_num;
50
51	events = baboon->mb_ifr & 0x07;
52	irq_num = IRQ_BABOON_0;
53	irq_bit = 1;
54	do {
55		if (events & irq_bit) {
56			events &= ~irq_bit;
57			generic_handle_irq(irq_num);
58		}
59		++irq_num;
60		irq_bit <<= 1;
61	} while (events);
62}
63
64/*
65 * Register the Baboon interrupt dispatcher on nubus slot $C.
66 */
67
68void __init baboon_register_interrupts(void)
69{
70	irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq);
71}
72
73/*
74 * The means for masking individual Baboon interrupts remains a mystery.
75 * However, since we only use the IDE IRQ, we can just enable/disable all
76 * Baboon interrupts. If/when we handle more than one Baboon IRQ, we must
77 * either figure out how to mask them individually or else implement the
78 * same workaround that's used for NuBus slots (see nubus_disabled and
79 * via_nubus_irq_shutdown).
80 */
81
82void baboon_irq_enable(int irq)
83{
84	mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
85}
86
87void baboon_irq_disable(int irq)
88{
89	mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
90}
91