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)  * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * licenses.  You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * COPYING in the main directory of this source tree, or the NetLogic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *    notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *    notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *    the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *    distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <asm/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <asm/netlogic/mips-extns.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #include <asm/netlogic/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #include <asm/netlogic/haldefs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #include <asm/netlogic/common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #if defined(CONFIG_CPU_XLP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #include <asm/netlogic/xlp-hal/iomap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #include <asm/netlogic/xlp-hal/xlp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #include <asm/netlogic/xlp-hal/pic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #elif defined(CONFIG_CPU_XLR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #include <asm/netlogic/xlr/iomap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #include <asm/netlogic/xlr/pic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #include <asm/netlogic/xlr/fmn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #error "Unknown CPU"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define SMP_IRQ_MASK	((1ULL << IRQ_IPI_SMP_FUNCTION) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 				 (1ULL << IRQ_IPI_SMP_RESCHEDULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define SMP_IRQ_MASK	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define PERCPU_IRQ_MASK (SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				(1ull << IRQ_FMN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) struct nlm_pic_irq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	void	(*extra_ack)(struct irq_data *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct	nlm_soc_info *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int	picirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	int	irt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static void xlp_pic_enable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	BUG_ON(!pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	spin_lock_irqsave(&pd->node->piclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	nlm_pic_enable_irt(pd->node->picbase, pd->irt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	spin_unlock_irqrestore(&pd->node->piclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static void xlp_pic_disable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	BUG_ON(!pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	spin_lock_irqsave(&pd->node->piclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	nlm_pic_disable_irt(pd->node->picbase, pd->irt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	spin_unlock_irqrestore(&pd->node->piclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void xlp_pic_mask_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	clear_c0_eimr(pd->picirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	ack_c0_eirr(pd->picirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void xlp_pic_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	BUG_ON(!pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (pd->extra_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		pd->extra_ack(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	/* re-enable the intr on this cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	set_c0_eimr(pd->picirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/* Ack is a single write, no need to lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	nlm_pic_ack(pd->node->picbase, pd->irt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct irq_chip xlp_pic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	.name		= "XLP-PIC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	.irq_enable	= xlp_pic_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	.irq_disable	= xlp_pic_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	.irq_mask_ack	= xlp_pic_mask_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	.irq_unmask	= xlp_pic_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void cpuintr_disable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	clear_c0_eimr(d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void cpuintr_enable(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	set_c0_eimr(d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void cpuintr_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ack_c0_eirr(d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Chip definition for CPU originated interrupts(timer, msg) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * IPIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct irq_chip nlm_cpu_intr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	.name		= "XLP-CPU-INTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	.irq_enable	= cpuintr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	.irq_disable	= cpuintr_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	.irq_mask	= cpuintr_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	.irq_ack	= cpuintr_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	.irq_eoi	= cpuintr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void __init nlm_init_percpu_irqs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			 nlm_smp_function_ipi_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			 nlm_smp_resched_ipi_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct nlm_pic_irq *pic_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int xirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	xirq = nlm_irq_to_xirq(node, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	pic_data = kzalloc(sizeof(*pic_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	BUG_ON(pic_data == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	pic_data->irt = irt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	pic_data->picirq = picirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	pic_data->node = nlm_get_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	irq_set_chip_data(xirq, pic_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	struct nlm_pic_irq *pic_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int xirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	xirq = nlm_irq_to_xirq(node, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	pic_data = irq_get_chip_data(xirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (WARN_ON(!pic_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	pic_data->extra_ack = xack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void nlm_init_node_irqs(int node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct nlm_soc_info *nodep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int i, irt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	pr_info("Init IRQ for node %d\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	nodep = nlm_get_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	nodep->irqmask = PERCPU_IRQ_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		irt = nlm_irq_to_irt(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (irt == -1)		/* unused irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		nodep->irqmask |= 1ull << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (irt == -2)		/* not a direct PIC irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		nlm_pic_init_irt(nodep->picbase, irt, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				node * nlm_threads_per_node(), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		nlm_setup_pic_irq(node, i, i, irt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) void nlm_smp_irq_init(int hwtid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	int cpu, node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	cpu = hwtid % nlm_threads_per_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	node = hwtid / nlm_threads_per_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (cpu == 0 && node != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		nlm_init_node_irqs(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	write_c0_eimr(nlm_get_node(node)->irqmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) asmlinkage void plat_irq_dispatch(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	uint64_t eirr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	int i, node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	node = nlm_nodeid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	eirr = read_c0_eirr_and_eimr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (eirr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	i = __ffs64(eirr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/* per-CPU IRQs don't need translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (i < PIC_IRQ_BASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		do_IRQ(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #if defined(CONFIG_PCI_MSI) && defined(CONFIG_CPU_XLP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	/* PCI interrupts need a second level dispatch for MSI bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (i >= PIC_PCIE_LINK_MSI_IRQ(0) && i <= PIC_PCIE_LINK_MSI_IRQ(3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		nlm_dispatch_msi(node, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (i >= PIC_PCIE_MSIX_IRQ(0) && i <= PIC_PCIE_MSIX_IRQ(3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		nlm_dispatch_msix(node, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	/* top level irq handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	do_IRQ(nlm_irq_to_xirq(node, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #ifdef CONFIG_CPU_XLP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static const struct irq_domain_ops xlp_pic_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	.xlate = irq_domain_xlate_onetwocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int __init xlp_of_pic_init(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 					struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	const int n_picirqs = PIC_IRT_LAST_IRQ - PIC_IRQ_BASE + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct irq_domain *xlp_pic_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	int socid, ret, bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	/* we need a hack to get the PIC's SoC chip id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	ret = of_address_to_resource(node, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		pr_err("PIC %pOFn: reg property not found!\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (cpu_is_xlp9xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		bus = (res.start >> 20) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		for (socid = 0; socid < NLM_NR_NODES; socid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			if (!nlm_node_present(socid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			if (nlm_get_node(socid)->socbus == bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		if (socid == NLM_NR_NODES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			pr_err("PIC %pOFn: Node mapping for bus %d not found!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 					node, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		socid = (res.start >> 18) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		if (!nlm_node_present(socid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			pr_err("PIC %pOFn: node %d does not exist!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 							node, socid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (!nlm_node_present(socid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		pr_err("PIC %pOFn: node %d does not exist!\n", node, socid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	xlp_pic_domain = irq_domain_add_legacy(node, n_picirqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		nlm_irq_to_xirq(socid, PIC_IRQ_BASE), PIC_IRQ_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		&xlp_pic_irq_domain_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (xlp_pic_domain == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		pr_err("PIC %pOFn: Creating legacy domain failed!\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	pr_info("Node %d: IRQ domain created for PIC@%pR\n", socid, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static struct of_device_id __initdata xlp_pic_irq_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	{ .compatible = "netlogic,xlp-pic", .data = xlp_of_pic_init },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) void __init arch_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	/* Initialize the irq descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	nlm_init_percpu_irqs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	nlm_init_node_irqs(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	write_c0_eimr(nlm_current_node()->irqmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #if defined(CONFIG_CPU_XLR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	nlm_setup_fmn_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) #ifdef CONFIG_CPU_XLP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	of_irq_init(xlp_pic_irq_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }