root/arch/m68k/coldfire/intc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcf_setimr
  2. mcf_clrimr
  3. mcf_maskimr
  4. mcf_setimr
  5. mcf_clrimr
  6. mcf_maskimr
  7. mcf_autovector
  8. intc_irq_mask
  9. intc_irq_unmask
  10. intc_irq_set_type
  11. init_IRQ

   1 /*
   2  * intc.c  -- support for the old ColdFire interrupt controller
   3  *
   4  * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
   5  *
   6  * This file is subject to the terms and conditions of the GNU General Public
   7  * License.  See the file COPYING in the main directory of this archive
   8  * for more details.
   9  */
  10 
  11 #include <linux/types.h>
  12 #include <linux/init.h>
  13 #include <linux/kernel.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/irq.h>
  16 #include <linux/io.h>
  17 #include <asm/traps.h>
  18 #include <asm/coldfire.h>
  19 #include <asm/mcfsim.h>
  20 
  21 /*
  22  * The mapping of irq number to a mask register bit is not one-to-one.
  23  * The irq numbers are either based on "level" of interrupt or fixed
  24  * for an autovector-able interrupt. So we keep a local data structure
  25  * that maps from irq to mask register. Not all interrupts will have
  26  * an IMR bit.
  27  */
  28 unsigned char mcf_irq2imr[NR_IRQS];
  29 
  30 /*
  31  * Define the miniumun and maximum external interrupt numbers.
  32  * This is also used as the "level" interrupt numbers.
  33  */
  34 #define EIRQ1   25
  35 #define EIRQ7   31
  36 
  37 /*
  38  * In the early version 2 core ColdFire parts the IMR register was 16 bits
  39  * in size. Version 3 (and later version 2) core parts have a 32 bit
  40  * sized IMR register. Provide some size independent methods to access the
  41  * IMR register.
  42  */
  43 #ifdef MCFSIM_IMR_IS_16BITS
  44 
  45 void mcf_setimr(int index)
  46 {
  47         u16 imr;
  48         imr = __raw_readw(MCFSIM_IMR);
  49         __raw_writew(imr | (0x1 << index), MCFSIM_IMR);
  50 }
  51 
  52 void mcf_clrimr(int index)
  53 {
  54         u16 imr;
  55         imr = __raw_readw(MCFSIM_IMR);
  56         __raw_writew(imr & ~(0x1 << index), MCFSIM_IMR);
  57 }
  58 
  59 void mcf_maskimr(unsigned int mask)
  60 {
  61         u16 imr;
  62         imr = __raw_readw(MCFSIM_IMR);
  63         imr |= mask;
  64         __raw_writew(imr, MCFSIM_IMR);
  65 }
  66 
  67 #else
  68 
  69 void mcf_setimr(int index)
  70 {
  71         u32 imr;
  72         imr = __raw_readl(MCFSIM_IMR);
  73         __raw_writel(imr | (0x1 << index), MCFSIM_IMR);
  74 }
  75 
  76 void mcf_clrimr(int index)
  77 {
  78         u32 imr;
  79         imr = __raw_readl(MCFSIM_IMR);
  80         __raw_writel(imr & ~(0x1 << index), MCFSIM_IMR);
  81 }
  82 
  83 void mcf_maskimr(unsigned int mask)
  84 {
  85         u32 imr;
  86         imr = __raw_readl(MCFSIM_IMR);
  87         imr |= mask;
  88         __raw_writel(imr, MCFSIM_IMR);
  89 }
  90 
  91 #endif
  92 
  93 /*
  94  * Interrupts can be "vectored" on the ColdFire cores that support this old
  95  * interrupt controller. That is, the device raising the interrupt can also
  96  * supply the vector number to interrupt through. The AVR register of the
  97  * interrupt controller enables or disables this for each external interrupt,
  98  * so provide generic support for this. Setting this up is out-of-band for
  99  * the interrupt system API's, and needs to be done by the driver that
 100  * supports this device. Very few devices actually use this.
 101  */
 102 void mcf_autovector(int irq)
 103 {
 104 #ifdef MCFSIM_AVR
 105         if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
 106                 u8 avec;
 107                 avec = __raw_readb(MCFSIM_AVR);
 108                 avec |= (0x1 << (irq - EIRQ1 + 1));
 109                 __raw_writeb(avec, MCFSIM_AVR);
 110         }
 111 #endif
 112 }
 113 
 114 static void intc_irq_mask(struct irq_data *d)
 115 {
 116         if (mcf_irq2imr[d->irq])
 117                 mcf_setimr(mcf_irq2imr[d->irq]);
 118 }
 119 
 120 static void intc_irq_unmask(struct irq_data *d)
 121 {
 122         if (mcf_irq2imr[d->irq])
 123                 mcf_clrimr(mcf_irq2imr[d->irq]);
 124 }
 125 
 126 static int intc_irq_set_type(struct irq_data *d, unsigned int type)
 127 {
 128         return 0;
 129 }
 130 
 131 static struct irq_chip intc_irq_chip = {
 132         .name           = "CF-INTC",
 133         .irq_mask       = intc_irq_mask,
 134         .irq_unmask     = intc_irq_unmask,
 135         .irq_set_type   = intc_irq_set_type,
 136 };
 137 
 138 void __init init_IRQ(void)
 139 {
 140         int irq;
 141 
 142         mcf_maskimr(0xffffffff);
 143 
 144         for (irq = 0; (irq < NR_IRQS); irq++) {
 145                 irq_set_chip(irq, &intc_irq_chip);
 146                 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
 147                 irq_set_handler(irq, handle_level_irq);
 148         }
 149 }
 150 

/* [<][>][^][v][top][bottom][index][help] */