linux/arch/arm/mach-iop33x/irq.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-iop33x/irq.c
   3 *
   4 * Generic IOP331 IRQ handling functionality
   5 *
   6 * Author: Dave Jiang <dave.jiang@intel.com>
   7 * Copyright (C) 2003 Intel Corp.
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/init.h>
  15#include <linux/interrupt.h>
  16#include <linux/list.h>
  17#include <asm/mach/irq.h>
  18#include <asm/irq.h>
  19#include <mach/hardware.h>
  20#include <asm/mach-types.h>
  21
  22static u32 iop33x_mask0;
  23static u32 iop33x_mask1;
  24
  25static void intctl0_write(u32 val)
  26{
  27        asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
  28}
  29
  30static void intctl1_write(u32 val)
  31{
  32        asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val));
  33}
  34
  35static void intstr0_write(u32 val)
  36{
  37        asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val));
  38}
  39
  40static void intstr1_write(u32 val)
  41{
  42        asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val));
  43}
  44
  45static void intbase_write(u32 val)
  46{
  47        asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val));
  48}
  49
  50static void intsize_write(u32 val)
  51{
  52        asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val));
  53}
  54
  55static void
  56iop33x_irq_mask1 (struct irq_data *d)
  57{
  58        iop33x_mask0 &= ~(1 << d->irq);
  59        intctl0_write(iop33x_mask0);
  60}
  61
  62static void
  63iop33x_irq_mask2 (struct irq_data *d)
  64{
  65        iop33x_mask1 &= ~(1 << (d->irq - 32));
  66        intctl1_write(iop33x_mask1);
  67}
  68
  69static void
  70iop33x_irq_unmask1(struct irq_data *d)
  71{
  72        iop33x_mask0 |= 1 << d->irq;
  73        intctl0_write(iop33x_mask0);
  74}
  75
  76static void
  77iop33x_irq_unmask2(struct irq_data *d)
  78{
  79        iop33x_mask1 |= (1 << (d->irq - 32));
  80        intctl1_write(iop33x_mask1);
  81}
  82
  83struct irq_chip iop33x_irqchip1 = {
  84        .name           = "IOP33x-1",
  85        .irq_ack        = iop33x_irq_mask1,
  86        .irq_mask       = iop33x_irq_mask1,
  87        .irq_unmask     = iop33x_irq_unmask1,
  88};
  89
  90struct irq_chip iop33x_irqchip2 = {
  91        .name           = "IOP33x-2",
  92        .irq_ack        = iop33x_irq_mask2,
  93        .irq_mask       = iop33x_irq_mask2,
  94        .irq_unmask     = iop33x_irq_unmask2,
  95};
  96
  97void __init iop33x_init_irq(void)
  98{
  99        int i;
 100
 101        iop_init_cp6_handler();
 102
 103        intctl0_write(0);
 104        intctl1_write(0);
 105        intstr0_write(0);
 106        intstr1_write(0);
 107        intbase_write(0);
 108        intsize_write(1);
 109        if (machine_is_iq80331())
 110                *IOP3XX_PCIIRSR = 0x0f;
 111
 112        for (i = 0; i < NR_IRQS; i++) {
 113                irq_set_chip_and_handler(i,
 114                                         (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2,
 115                                         handle_level_irq);
 116                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 117        }
 118}
 119