linux/arch/powerpc/sysdev/xilinx_intc.c
<<
>>
Prefs
   1/*
   2 * Interrupt controller driver for Xilinx Virtex FPGAs
   3 *
   4 * Copyright (C) 2007 Secret Lab Technologies Ltd.
   5 *
   6 * This file is licensed under the terms of the GNU General Public License
   7 * version 2. This program is licensed "as is" without any warranty of any
   8 * kind, whether express or implied.
   9 *
  10 */
  11
  12/*
  13 * This is a driver for the interrupt controller typically found in
  14 * Xilinx Virtex FPGA designs.
  15 *
  16 * The interrupt sense levels are hard coded into the FPGA design with
  17 * typically a 1:1 relationship between irq lines and devices (no shared
  18 * irq lines).  Therefore, this driver does not attempt to handle edge
  19 * and level interrupts differently.
  20 */
  21#undef DEBUG
  22
  23#include <linux/kernel.h>
  24#include <linux/irq.h>
  25#include <linux/of.h>
  26#include <linux/of_address.h>
  27#include <linux/of_irq.h>
  28#include <asm/io.h>
  29#include <asm/processor.h>
  30#include <asm/i8259.h>
  31#include <asm/irq.h>
  32#include <linux/irqchip.h>
  33
  34#if defined(CONFIG_PPC_I8259)
  35/*
  36 * Support code for cascading to 8259 interrupt controllers
  37 */
  38static void xilinx_i8259_cascade(struct irq_desc *desc)
  39{
  40        struct irq_chip *chip = irq_desc_get_chip(desc);
  41        unsigned int cascade_irq = i8259_irq();
  42
  43        if (cascade_irq)
  44                generic_handle_irq(cascade_irq);
  45
  46        /* Let xilinx_intc end the interrupt */
  47        chip->irq_unmask(&desc->irq_data);
  48}
  49
  50static void __init xilinx_i8259_setup_cascade(void)
  51{
  52        struct device_node *cascade_node;
  53        int cascade_irq;
  54
  55        /* Initialize i8259 controller */
  56        cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic");
  57        if (!cascade_node)
  58                return;
  59
  60        cascade_irq = irq_of_parse_and_map(cascade_node, 0);
  61        if (!cascade_irq) {
  62                pr_err("virtex_ml510: Failed to map cascade interrupt\n");
  63                goto out;
  64        }
  65
  66        i8259_init(cascade_node, 0);
  67        irq_set_chained_handler(cascade_irq, xilinx_i8259_cascade);
  68
  69        /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */
  70        /* This looks like a dirty hack to me --gcl */
  71        outb(0xc0, 0x4d0);
  72        outb(0xc0, 0x4d1);
  73
  74 out:
  75        of_node_put(cascade_node);
  76}
  77#else
  78static inline void xilinx_i8259_setup_cascade(void) { return; }
  79#endif /* defined(CONFIG_PPC_I8259) */
  80
  81/*
  82 * Initialize master Xilinx interrupt controller
  83 */
  84void __init xilinx_intc_init_tree(void)
  85{
  86        irqchip_init();
  87        xilinx_i8259_setup_cascade();
  88}
  89