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