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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * intc.c  -- support for the old ColdFire interrupt controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * License.  See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/coldfire.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/mcfsim.h>
^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)  * The mapping of irq number to a mask register bit is not one-to-one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * The irq numbers are either based on "level" of interrupt or fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * for an autovector-able interrupt. So we keep a local data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * that maps from irq to mask register. Not all interrupts will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * an IMR bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) unsigned char mcf_irq2imr[NR_IRQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * Define the miniumun and maximum external interrupt numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * This is also used as the "level" interrupt numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define	EIRQ1	25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define	EIRQ7	31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * In the early version 2 core ColdFire parts the IMR register was 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * in size. Version 3 (and later version 2) core parts have a 32 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * sized IMR register. Provide some size independent methods to access the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * IMR register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #ifdef MCFSIM_IMR_IS_16BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) void mcf_setimr(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	u16 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	imr = __raw_readw(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	__raw_writew(imr | (0x1 << index), MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) void mcf_clrimr(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	u16 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	imr = __raw_readw(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	__raw_writew(imr & ~(0x1 << index), MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) void mcf_maskimr(unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u16 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	imr = __raw_readw(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	imr |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	__raw_writew(imr, MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) void mcf_setimr(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	u32 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	imr = __raw_readl(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	__raw_writel(imr | (0x1 << index), MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) void mcf_clrimr(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u32 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	imr = __raw_readl(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	__raw_writel(imr & ~(0x1 << index), MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) void mcf_maskimr(unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u32 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	imr = __raw_readl(MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	imr |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	__raw_writel(imr, MCFSIM_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * Interrupts can be "vectored" on the ColdFire cores that support this old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * interrupt controller. That is, the device raising the interrupt can also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * supply the vector number to interrupt through. The AVR register of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * interrupt controller enables or disables this for each external interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * so provide generic support for this. Setting this up is out-of-band for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * the interrupt system API's, and needs to be done by the driver that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * supports this device. Very few devices actually use this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) void mcf_autovector(int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #ifdef MCFSIM_AVR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		u8 avec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		avec = __raw_readb(MCFSIM_AVR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		avec |= (0x1 << (irq - EIRQ1 + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		__raw_writeb(avec, MCFSIM_AVR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void intc_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (mcf_irq2imr[d->irq])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		mcf_setimr(mcf_irq2imr[d->irq]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void intc_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (mcf_irq2imr[d->irq])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		mcf_clrimr(mcf_irq2imr[d->irq]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int intc_irq_set_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static struct irq_chip intc_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	.name		= "CF-INTC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	.irq_mask	= intc_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	.irq_unmask	= intc_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	.irq_set_type	= intc_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) void __init init_IRQ(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	mcf_maskimr(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	for (irq = 0; (irq < NR_IRQS); irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		irq_set_chip(irq, &intc_irq_chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		irq_set_handler(irq, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)