Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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