linux/arch/mn10300/unit-asb2364/irq-fpga.c
<<
>>
Prefs
   1/* ASB2364 FPGA interrupt multiplexing
   2 *
   3 * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public Licence
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the Licence, or (at your option) any later version.
  10 */
  11
  12#include <linux/interrupt.h>
  13#include <linux/init.h>
  14#include <linux/irq.h>
  15#include <unit/fpga-regs.h>
  16
  17/*
  18 * FPGA PIC operations
  19 */
  20static void asb2364_fpga_mask(struct irq_data *d)
  21{
  22        ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0001;
  23        SyncExBus();
  24}
  25
  26static void asb2364_fpga_ack(struct irq_data *d)
  27{
  28        ASB2364_FPGA_REG_IRQ(d->irq - NR_CPU_IRQS) = 0x0001;
  29        SyncExBus();
  30}
  31
  32static void asb2364_fpga_mask_ack(struct irq_data *d)
  33{
  34        ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0001;
  35        SyncExBus();
  36        ASB2364_FPGA_REG_IRQ(d->irq - NR_CPU_IRQS) = 0x0001;
  37        SyncExBus();
  38}
  39
  40static void asb2364_fpga_unmask(struct irq_data *d)
  41{
  42        ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0000;
  43        SyncExBus();
  44}
  45
  46static struct irq_chip asb2364_fpga_pic = {
  47        .name           = "fpga",
  48        .irq_ack        = asb2364_fpga_ack,
  49        .irq_mask       = asb2364_fpga_mask,
  50        .irq_mask_ack   = asb2364_fpga_mask_ack,
  51        .irq_unmask     = asb2364_fpga_unmask,
  52};
  53
  54/*
  55 * FPGA PIC interrupt handler
  56 */
  57static irqreturn_t fpga_interrupt(int irq, void *_mask)
  58{
  59        if ((ASB2364_FPGA_REG_IRQ_LAN  & 0x0001) != 0x0001)
  60                generic_handle_irq(FPGA_LAN_IRQ);
  61        if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) != 0x0001)
  62                generic_handle_irq(FPGA_UART_IRQ);
  63        if ((ASB2364_FPGA_REG_IRQ_I2C  & 0x0001) != 0x0001)
  64                generic_handle_irq(FPGA_I2C_IRQ);
  65        if ((ASB2364_FPGA_REG_IRQ_USB  & 0x0001) != 0x0001)
  66                generic_handle_irq(FPGA_USB_IRQ);
  67        if ((ASB2364_FPGA_REG_IRQ_FPGA & 0x0001) != 0x0001)
  68                generic_handle_irq(FPGA_FPGA_IRQ);
  69
  70        return IRQ_HANDLED;
  71}
  72
  73/*
  74 * Define an interrupt action for each FPGA PIC output
  75 */
  76static struct irqaction fpga_irq[]  = {
  77        [0] = {
  78                .handler        = fpga_interrupt,
  79                .flags          = IRQF_SHARED,
  80                .name           = "fpga",
  81        },
  82};
  83
  84/*
  85 * Initialise the FPGA's PIC
  86 */
  87void __init irq_fpga_init(void)
  88{
  89        int irq;
  90
  91        ASB2364_FPGA_REG_MASK_LAN  = 0x0001;
  92        SyncExBus();
  93        ASB2364_FPGA_REG_MASK_UART = 0x0001;
  94        SyncExBus();
  95        ASB2364_FPGA_REG_MASK_I2C  = 0x0001;
  96        SyncExBus();
  97        ASB2364_FPGA_REG_MASK_USB  = 0x0001;
  98        SyncExBus();
  99        ASB2364_FPGA_REG_MASK_FPGA = 0x0001;
 100        SyncExBus();
 101
 102        for (irq = NR_CPU_IRQS; irq < NR_IRQS; irq++)
 103                irq_set_chip_and_handler(irq, &asb2364_fpga_pic,
 104                                         handle_level_irq);
 105
 106        /* the FPGA drives the XIRQ1 input on the CPU PIC */
 107        setup_irq(XIRQ1, &fpga_irq[0]);
 108}
 109