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)  * linux/arch/h8300/kernel/irq.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Copyright 2014-2015 Yoshinori Sato <ysato@users.sourceforge.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #ifdef CONFIG_RAMKERNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) typedef void (*h8300_vector)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static const h8300_vector __initconst trap_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 	0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	_trace_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 	0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 	_nmi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	_system_call,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	_trace_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static unsigned long __init *get_vector_address(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 	unsigned long *rom_vector = CPU_VECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 	unsigned long base, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 	int vec_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 	base = rom_vector[EXT_IRQ0] & ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	/* check romvector format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 	for (vec_no = EXT_IRQ0 + 1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 		if ((base+(vec_no - EXT_IRQ0)*4) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 		    (rom_vector[vec_no] & ADDR_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	/* ramvector base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 	base -= EXT_IRQ0*4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	/* writerble? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	tmp = ~(*(volatile unsigned long *)base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 	(*(volatile unsigned long *)base) = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	if ((*(volatile unsigned long *)base) != tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	return (unsigned long *)base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static void __init setup_vector(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 	unsigned long *ramvec, *ramvec_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 	const h8300_vector *trap_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 	ramvec = get_vector_address();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	if (ramvec == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 		panic("interrupt vector serup failed.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 		pr_debug("virtual vector at 0x%p\n", ramvec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	/* create redirect table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 	ramvec_p = ramvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 	trap_entry = trap_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 	for (i = 0; i < NR_IRQS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 		if (i < 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 			if (*trap_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 				*ramvec_p = VECTOR(*trap_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 			ramvec_p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 			trap_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 			*ramvec_p++ = REDIRECT(_interrupt_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	_interrupt_redirect_table = ramvec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) void setup_vector(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 	/* noting do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void __init init_IRQ(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 	setup_vector();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 	irqchip_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) asmlinkage void do_IRQ(int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 	irq_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 	generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 	irq_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }