linux/arch/nios2/kernel/irq.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Altera Corporation
   3 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
   4 * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
   5 *
   6 * based on irq.c from m68k which is:
   7 *
   8 * Copyright (C) 2007 Greg Ungerer <gerg@snapgear.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22 *
  23 */
  24
  25#include <linux/init.h>
  26#include <linux/interrupt.h>
  27#include <linux/of.h>
  28
  29static u32 ienable;
  30
  31asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
  32{
  33        struct pt_regs *oldregs = set_irq_regs(regs);
  34        int irq;
  35
  36        irq_enter();
  37        irq = irq_find_mapping(NULL, hwirq);
  38        generic_handle_irq(irq);
  39        irq_exit();
  40
  41        set_irq_regs(oldregs);
  42}
  43
  44static void chip_unmask(struct irq_data *d)
  45{
  46        ienable |= (1 << d->hwirq);
  47        WRCTL(CTL_IENABLE, ienable);
  48}
  49
  50static void chip_mask(struct irq_data *d)
  51{
  52        ienable &= ~(1 << d->hwirq);
  53        WRCTL(CTL_IENABLE, ienable);
  54}
  55
  56static struct irq_chip m_irq_chip = {
  57        .name           = "NIOS2-INTC",
  58        .irq_unmask     = chip_unmask,
  59        .irq_mask       = chip_mask,
  60};
  61
  62static int irq_map(struct irq_domain *h, unsigned int virq,
  63                                irq_hw_number_t hw_irq_num)
  64{
  65        irq_set_chip_and_handler(virq, &m_irq_chip, handle_level_irq);
  66
  67        return 0;
  68}
  69
  70static struct irq_domain_ops irq_ops = {
  71        .map    = irq_map,
  72        .xlate  = irq_domain_xlate_onecell,
  73};
  74
  75void __init init_IRQ(void)
  76{
  77        struct irq_domain *domain;
  78        struct device_node *node;
  79
  80        node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.0");
  81        if (!node)
  82                node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.1");
  83
  84        BUG_ON(!node);
  85
  86        domain = irq_domain_add_linear(node, NIOS2_CPU_NR_IRQS, &irq_ops, NULL);
  87        BUG_ON(!domain);
  88
  89        irq_set_default_host(domain);
  90        of_node_put(node);
  91        /* Load the initial ienable value */
  92        ienable = RDCTL(CTL_IENABLE);
  93}
  94