mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
1.9 KiB
98 lines
1.9 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* linux/arch/h8300/kernel/irq.c |
|
* |
|
* Copyright 2014-2015 Yoshinori Sato <[email protected]> |
|
*/ |
|
|
|
#include <linux/init.h> |
|
#include <linux/interrupt.h> |
|
#include <linux/irq.h> |
|
#include <linux/irqdomain.h> |
|
#include <linux/of_irq.h> |
|
#include <asm/traps.h> |
|
|
|
#ifdef CONFIG_RAMKERNEL |
|
typedef void (*h8300_vector)(void); |
|
|
|
static const h8300_vector __initconst trap_table[] = { |
|
0, 0, 0, 0, |
|
_trace_break, |
|
0, 0, |
|
_nmi, |
|
_system_call, |
|
0, 0, |
|
_trace_break, |
|
}; |
|
|
|
static unsigned long __init *get_vector_address(void) |
|
{ |
|
unsigned long *rom_vector = CPU_VECTOR; |
|
unsigned long base, tmp; |
|
int vec_no; |
|
|
|
base = rom_vector[EXT_IRQ0] & ADDR_MASK; |
|
|
|
/* check romvector format */ |
|
for (vec_no = EXT_IRQ0 + 1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) { |
|
if ((base+(vec_no - EXT_IRQ0)*4) != |
|
(rom_vector[vec_no] & ADDR_MASK)) |
|
return NULL; |
|
} |
|
|
|
/* ramvector base address */ |
|
base -= EXT_IRQ0*4; |
|
|
|
/* writerble? */ |
|
tmp = ~(*(volatile unsigned long *)base); |
|
(*(volatile unsigned long *)base) = tmp; |
|
if ((*(volatile unsigned long *)base) != tmp) |
|
return NULL; |
|
return (unsigned long *)base; |
|
} |
|
|
|
static void __init setup_vector(void) |
|
{ |
|
int i; |
|
unsigned long *ramvec, *ramvec_p; |
|
const h8300_vector *trap_entry; |
|
|
|
ramvec = get_vector_address(); |
|
if (ramvec == NULL) |
|
panic("interrupt vector serup failed."); |
|
else |
|
pr_debug("virtual vector at 0x%p\n", ramvec); |
|
|
|
/* create redirect table */ |
|
ramvec_p = ramvec; |
|
trap_entry = trap_table; |
|
for (i = 0; i < NR_IRQS; i++) { |
|
if (i < 12) { |
|
if (*trap_entry) |
|
*ramvec_p = VECTOR(*trap_entry); |
|
ramvec_p++; |
|
trap_entry++; |
|
} else |
|
*ramvec_p++ = REDIRECT(_interrupt_entry); |
|
} |
|
_interrupt_redirect_table = ramvec; |
|
} |
|
#else |
|
void setup_vector(void) |
|
{ |
|
/* noting do */ |
|
} |
|
#endif |
|
|
|
void __init init_IRQ(void) |
|
{ |
|
setup_vector(); |
|
irqchip_init(); |
|
} |
|
|
|
asmlinkage void do_IRQ(int irq) |
|
{ |
|
irq_enter(); |
|
generic_handle_irq(irq); |
|
irq_exit(); |
|
}
|
|
|