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)  * arch/sh/boards/superh/microdev/irq.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * SuperH SH4-202 MicroDev board support.
^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/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <mach/microdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define NUM_EXTERNAL_IRQS 16	/* IRL0 .. IRL15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	unsigned char fpgaIrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	unsigned char mapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) } fpgaIrqTable[NUM_EXTERNAL_IRQS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	{ 0,				0,	"unused"   },		/* IRQ #0	IRL=15	0x200  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	{ MICRODEV_FPGA_IRQ_KEYBOARD,	1,	"keyboard" },		/* IRQ #1	IRL=14	0x220  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	{ MICRODEV_FPGA_IRQ_SERIAL1,	1,	"Serial #1"},		/* IRQ #2	IRL=13	0x240  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	{ MICRODEV_FPGA_IRQ_ETHERNET,	1,	"Ethernet" },		/* IRQ #3	IRL=12	0x260  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	{ MICRODEV_FPGA_IRQ_SERIAL2,	0,	"Serial #2"},		/* IRQ #4	IRL=11	0x280  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	{ 0,				0,	"unused"   },		/* IRQ #5	IRL=10	0x2a0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	{ 0,				0,	"unused"   },		/* IRQ #6	IRL=9	0x2c0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	{ MICRODEV_FPGA_IRQ_USB_HC,	1,	"USB"	   },		/* IRQ #7	IRL=8	0x2e0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	{ MICRODEV_IRQ_PCI_INTA,	1,	"PCI INTA" },		/* IRQ #8	IRL=7	0x300  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	{ MICRODEV_IRQ_PCI_INTB,	1,	"PCI INTB" },		/* IRQ #9	IRL=6	0x320  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	{ MICRODEV_IRQ_PCI_INTC,	1,	"PCI INTC" },		/* IRQ #10	IRL=5	0x340  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	{ MICRODEV_IRQ_PCI_INTD,	1,	"PCI INTD" },		/* IRQ #11	IRL=4	0x360  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	{ MICRODEV_FPGA_IRQ_MOUSE,	1,	"mouse"    },		/* IRQ #12	IRL=3	0x380  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	{ MICRODEV_FPGA_IRQ_IDE2,	1,	"IDE #2"   },		/* IRQ #13	IRL=2	0x3a0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	{ MICRODEV_FPGA_IRQ_IDE1,	1,	"IDE #1"   },		/* IRQ #14	IRL=1	0x3c0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	{ 0,				0,	"unused"   },		/* IRQ #15	IRL=0	0x3e0  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #  error Inconsistancy in defining the IRQ# for Keyboard!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #if (MICRODEV_LINUX_IRQ_ETHERNET != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #  error Inconsistancy in defining the IRQ# for Ethernet!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #if (MICRODEV_LINUX_IRQ_USB_HC != 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #  error Inconsistancy in defining the IRQ# for USB!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #if (MICRODEV_LINUX_IRQ_MOUSE != 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #  error Inconsistancy in defining the IRQ# for PS/2 Mouse!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #if (MICRODEV_LINUX_IRQ_IDE2 != 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #  error Inconsistancy in defining the IRQ# for secondary IDE!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #if (MICRODEV_LINUX_IRQ_IDE1 != 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #  error Inconsistancy in defining the IRQ# for primary IDE!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static void disable_microdev_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	unsigned int irq = data->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	unsigned int fpgaIrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (irq >= NUM_EXTERNAL_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	if (!fpgaIrqTable[irq].mapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	/* disable interrupts on the FPGA INTC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static void enable_microdev_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned int irq = data->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	unsigned long priorityReg, priorities, pri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	unsigned int fpgaIrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (unlikely(irq >= NUM_EXTERNAL_IRQS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (unlikely(!fpgaIrqTable[irq].mapped))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	pri = 15 - irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* set priority for the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	priorities = __raw_readl(priorityReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	__raw_writel(priorities, priorityReg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/* enable interrupts on the FPGA INTC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct irq_chip microdev_irq_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.name = "MicroDev-IRQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.irq_unmask = enable_microdev_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	.irq_mask = disable_microdev_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* This function sets the desired irq handler to be a MicroDev type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void __init make_microdev_irq(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	disable_irq_nosync(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	irq_set_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	disable_microdev_irq(irq_get_irq_data(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) extern void __init init_microdev_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* disable interrupts on the FPGA INTC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	__raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		make_microdev_irq(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) extern void microdev_print_fpga_intc_status(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	printk("FPGA_INTENB = 0x%08x\n", *intenb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	printk("FPGA_INTDSB = 0x%08x\n", *intdsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	printk("FPGA_INTSRC = 0x%08x\n", *intsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	printk("FPGA_INTREQ = 0x%08x\n", *intreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	printk("-------------------------------------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }