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) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <asm/mach/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <asm/hardware/iomd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/fiq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) // These are offsets from the stat register for each IRQ bank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define STAT	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define REQ	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define CLR	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define MASK	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static void __iomem *iomd_get_base(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	void *cd = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	return (void __iomem *)(unsigned long)cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct irq_data *d = irq_get_irq_data(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	d->mask = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	irq_set_chip_data(irq, (void *)(unsigned long)base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static void iomd_irq_mask_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	void __iomem *base = iomd_get_base(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	unsigned int val, mask = d->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	val = readb(base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	writeb(val & ~mask, base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	writeb(mask, base + CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static void iomd_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	void __iomem *base = iomd_get_base(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	unsigned int val, mask = d->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	val = readb(base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	writeb(val & ~mask, base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static void iomd_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	void __iomem *base = iomd_get_base(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned int val, mask = d->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	val = readb(base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	writeb(val | mask, base + MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static struct irq_chip iomd_chip_clr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	.irq_mask_ack	= iomd_irq_mask_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	.irq_mask	= iomd_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	.irq_unmask	= iomd_irq_unmask,
^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) static struct irq_chip iomd_chip_noclr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	.irq_mask	= iomd_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	.irq_unmask	= iomd_irq_unmask,
^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) extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) void __init rpc_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	unsigned int irq, clr, set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	iomd_writeb(0, IOMD_IRQMASKA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	iomd_writeb(0, IOMD_IRQMASKB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	iomd_writeb(0, IOMD_FIQMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	iomd_writeb(0, IOMD_DMAMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	set_fiq_handler(&rpc_default_fiq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		&rpc_default_fiq_end - &rpc_default_fiq_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	for (irq = 0; irq < NR_IRQS; irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		clr = IRQ_NOREQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		if (irq <= 6 || (irq >= 9 && irq <= 15))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			clr |= IRQ_NOPROBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		if (irq == 21 || (irq >= 16 && irq <= 19) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		    irq == IRQ_KEYBOARDTX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			set |= IRQ_NOAUTOEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		switch (irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		case 0 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			irq_set_chip_and_handler(irq, &iomd_chip_clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 						 handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			irq_modify_status(irq, clr, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 					   BIT(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		case 8 ... 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			irq_set_chip_and_handler(irq, &iomd_chip_noclr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 						 handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			irq_modify_status(irq, clr, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 					   BIT(irq - 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		case 16 ... 21:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			irq_set_chip_and_handler(irq, &iomd_chip_noclr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 						 handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			irq_modify_status(irq, clr, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 					   BIT(irq - 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		case 64 ... 71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			irq_set_chip(irq, &iomd_chip_noclr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			irq_modify_status(irq, clr, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 					   BIT(irq - 64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }