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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (C) 2011-2012 Texas Instruments Incorporated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  This borrows heavily from powerpc version, which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Derived from arch/i386/kernel/irq.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *    Copyright (C) 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Adapted from arch/i386 by Gary Thomas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *    Copyright (C) 1996-2001 Cort Dougan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  Adapted for Power Macintosh by Paul Mackerras
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/radix-tree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/kernel_stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/megamod-pic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <asm/special_insns.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) unsigned long irq_err_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static DEFINE_RAW_SPINLOCK(core_irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static void mask_core_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	unsigned int prio = data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	raw_spin_lock(&core_irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	and_creg(IER, ~(1 << prio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	raw_spin_unlock(&core_irq_lock);
^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) static void unmask_core_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned int prio = data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	raw_spin_lock(&core_irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	or_creg(IER, 1 << prio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	raw_spin_unlock(&core_irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static struct irq_chip core_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	.name		= "core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	.irq_mask	= mask_core_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	.irq_unmask	= unmask_core_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static int prio_to_virq[NR_PRIORITY_IRQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct pt_regs *old_regs = set_irq_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	irq_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	generic_handle_irq(prio_to_virq[prio]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	irq_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	set_irq_regs(old_regs);
^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) static struct irq_domain *core_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static int core_domain_map(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			   irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (hw < 4 || hw >= NR_PRIORITY_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	prio_to_virq[hw] = virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	irq_set_status_flags(virq, IRQ_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	irq_set_chip_and_handler(virq, &core_chip, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static const struct irq_domain_ops core_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	.map = core_domain_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.xlate = irq_domain_xlate_onecell,
^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) void __init init_IRQ(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	/* Mask all priority IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	and_creg(IER, ~0xfff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (np != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		/* create the core host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		core_domain = irq_domain_add_linear(np, NR_PRIORITY_IRQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 						    &core_domain_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		if (core_domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			irq_set_default_host(core_domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	printk(KERN_INFO "Core interrupt controller initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* now we're ready for other SoC controllers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	megamod_pic_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	/* Clear all general IRQ flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	set_creg(ICR, 0xfff0);
^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) void ack_bad_irq(int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	irq_err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int arch_show_interrupts(struct seq_file *p, int prec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }