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)  * SPEAr platform shared irq layer source file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2009-2012 ST Microelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Viresh Kumar <vireshk@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2012 ST Microelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/irqchip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * struct spear_shirq: shared irq structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * base:	Base register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * status_reg:	Status register offset for chained interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * mask_reg:	Mask register offset for irq chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * mask:	Mask to apply to the status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * virq_base:	Base virtual interrupt number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * nr_irqs:	Number of interrupts handled by this block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * offset:	Bit offset of the first interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * irq_chip:	Interrupt controller chip used for this instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *		if NULL group is disabled, but accounted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) struct spear_shirq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	void __iomem		*base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	u32			status_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u32			mask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	u32			mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	u32			virq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	u32			nr_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	u32			offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	struct irq_chip		*irq_chip;
^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) /* spear300 shared irq registers offsets and masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define SPEAR300_INT_ENB_MASK_REG	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define SPEAR300_INT_STS_MASK_REG	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static DEFINE_RAW_SPINLOCK(shirq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static void shirq_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	u32 __iomem *reg = shirq->base + shirq->mask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	raw_spin_lock(&shirq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	val = readl(reg) & ~(0x1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	writel(val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	raw_spin_unlock(&shirq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static void shirq_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u32 __iomem *reg = shirq->base + shirq->mask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	raw_spin_lock(&shirq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	val = readl(reg) | (0x1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	writel(val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	raw_spin_unlock(&shirq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static struct irq_chip shirq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	.name		= "spear-shirq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	.irq_mask	= shirq_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	.irq_unmask	= shirq_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static struct spear_shirq spear300_shirq_ras1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	.offset		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	.nr_irqs	= 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	.mask		= ((0x1 << 9) - 1) << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	.irq_chip	= &shirq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	.status_reg	= SPEAR300_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	.mask_reg	= SPEAR300_INT_ENB_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) static struct spear_shirq *spear300_shirq_blocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	&spear300_shirq_ras1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* spear310 shared irq registers offsets and masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SPEAR310_INT_STS_MASK_REG	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct spear_shirq spear310_shirq_ras1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	.offset		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	.nr_irqs	= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	.mask		= ((0x1 << 8) - 1) << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.status_reg	= SPEAR310_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct spear_shirq spear310_shirq_ras2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	.offset		= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.nr_irqs	= 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	.mask		= ((0x1 << 5) - 1) << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.status_reg	= SPEAR310_INT_STS_MASK_REG,
^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 struct spear_shirq spear310_shirq_ras3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	.offset		= 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	.nr_irqs	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	.mask		= ((0x1 << 1) - 1) << 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	.status_reg	= SPEAR310_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct spear_shirq spear310_shirq_intrcomm_ras = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	.offset		= 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	.nr_irqs	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	.mask		= ((0x1 << 3) - 1) << 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	.status_reg	= SPEAR310_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static struct spear_shirq *spear310_shirq_blocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	&spear310_shirq_ras1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	&spear310_shirq_ras2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	&spear310_shirq_ras3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	&spear310_shirq_intrcomm_ras,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* spear320 shared irq registers offsets and masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define SPEAR320_INT_STS_MASK_REG		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define SPEAR320_INT_CLR_MASK_REG		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define SPEAR320_INT_ENB_MASK_REG		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static struct spear_shirq spear320_shirq_ras3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	.offset		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	.nr_irqs	= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	.mask		= ((0x1 << 7) - 1) << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static struct spear_shirq spear320_shirq_ras1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	.offset		= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	.nr_irqs	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	.mask		= ((0x1 << 3) - 1) << 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	.status_reg	= SPEAR320_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct spear_shirq spear320_shirq_ras2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	.offset		= 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	.nr_irqs	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	.mask		= ((0x1 << 1) - 1) << 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	.status_reg	= SPEAR320_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static struct spear_shirq spear320_shirq_intrcomm_ras = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.offset		= 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	.nr_irqs	= 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.mask		= ((0x1 << 11) - 1) << 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.irq_chip	= &dummy_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	.status_reg	= SPEAR320_INT_STS_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static struct spear_shirq *spear320_shirq_blocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	&spear320_shirq_ras3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	&spear320_shirq_ras1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	&spear320_shirq_ras2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	&spear320_shirq_intrcomm_ras,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void shirq_handler(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct spear_shirq *shirq = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	u32 pend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	pend = readl(shirq->base + shirq->status_reg) & shirq->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	pend >>= shirq->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	while (pend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		int irq = __ffs(pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		pend &= ~(0x1 << irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		generic_handle_irq(shirq->virq_base + irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void __init spear_shirq_register(struct spear_shirq *shirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 					int parent_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (!shirq->irq_chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	irq_set_chained_handler_and_data(parent_irq, shirq_handler, shirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	for (i = 0; i < shirq->nr_irqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		irq_set_chip_and_handler(shirq->virq_base + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 					 shirq->irq_chip, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		irq_set_chip_data(shirq->virq_base + i, shirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int i, parent_irq, virq_base, hwirq = 0, nr_irqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct irq_domain *shirq_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		pr_err("%s: failed to map shirq registers\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	for (i = 0; i < block_nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		nr_irqs += shirq_blocks[i]->nr_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	virq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (virq_base < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		pr_err("%s: irq desc alloc failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		goto err_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	shirq_domain = irq_domain_add_legacy(np, nr_irqs, virq_base, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			&irq_domain_simple_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (WARN_ON(!shirq_domain)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		pr_warn("%s: irq domain init failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		goto err_free_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	for (i = 0; i < block_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		shirq_blocks[i]->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		shirq_blocks[i]->virq_base = irq_find_mapping(shirq_domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		parent_irq = irq_of_parse_and_map(np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		spear_shirq_register(shirq_blocks[i], parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		hwirq += shirq_blocks[i]->nr_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) err_free_desc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	irq_free_descs(virq_base, nr_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) err_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	iounmap(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int __init spear300_shirq_of_init(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 					 struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return shirq_init(spear300_shirq_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			ARRAY_SIZE(spear300_shirq_blocks), np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) IRQCHIP_DECLARE(spear300_shirq, "st,spear300-shirq", spear300_shirq_of_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int __init spear310_shirq_of_init(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					 struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	return shirq_init(spear310_shirq_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			ARRAY_SIZE(spear310_shirq_blocks), np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) IRQCHIP_DECLARE(spear310_shirq, "st,spear310-shirq", spear310_shirq_of_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int __init spear320_shirq_of_init(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 					 struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return shirq_init(spear320_shirq_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			ARRAY_SIZE(spear320_shirq_blocks), np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) IRQCHIP_DECLARE(spear320_shirq, "st,spear320-shirq", spear320_shirq_of_init);