root/arch/mips/kernel/irq_txx9.c

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

DEFINITIONS

This source file includes following definitions.
  1. txx9_irq_unmask
  2. txx9_irq_mask
  3. txx9_irq_mask_ack
  4. txx9_irq_set_type
  5. txx9_irq_init
  6. txx9_irq_set_pri
  7. txx9_irq

   1 /*
   2  * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c,
   3  *          linux/arch/mips/tx4927/common/tx4927_irq.c,
   4  *          linux/arch/mips/tx4938/common/irq.c
   5  *
   6  * Copyright 2001, 2003-2005 MontaVista Software Inc.
   7  * Author: MontaVista Software, Inc.
   8  *         ahennessy@mvista.com
   9  *         source@mvista.com
  10  * Copyright (C) 2000-2001 Toshiba Corporation
  11  *
  12  * This file is subject to the terms and conditions of the GNU General Public
  13  * License.  See the file "COPYING" in the main directory of this archive
  14  * for more details.
  15  */
  16 #include <linux/init.h>
  17 #include <linux/interrupt.h>
  18 #include <linux/types.h>
  19 #include <linux/irq.h>
  20 #include <asm/txx9irq.h>
  21 
  22 struct txx9_irc_reg {
  23         u32 cer;
  24         u32 cr[2];
  25         u32 unused0;
  26         u32 ilr[8];
  27         u32 unused1[4];
  28         u32 imr;
  29         u32 unused2[7];
  30         u32 scr;
  31         u32 unused3[7];
  32         u32 ssr;
  33         u32 unused4[7];
  34         u32 csr;
  35 };
  36 
  37 /* IRCER : Int. Control Enable */
  38 #define TXx9_IRCER_ICE  0x00000001
  39 
  40 /* IRCR : Int. Control */
  41 #define TXx9_IRCR_LOW   0x00000000
  42 #define TXx9_IRCR_HIGH  0x00000001
  43 #define TXx9_IRCR_DOWN  0x00000002
  44 #define TXx9_IRCR_UP    0x00000003
  45 #define TXx9_IRCR_EDGE(cr)      ((cr) & 0x00000002)
  46 
  47 /* IRSCR : Int. Status Control */
  48 #define TXx9_IRSCR_EIClrE       0x00000100
  49 #define TXx9_IRSCR_EIClr_MASK   0x0000000f
  50 
  51 /* IRCSR : Int. Current Status */
  52 #define TXx9_IRCSR_IF   0x00010000
  53 #define TXx9_IRCSR_ILV_MASK     0x00000700
  54 #define TXx9_IRCSR_IVL_MASK     0x0000001f
  55 
  56 #define irc_dlevel      0
  57 #define irc_elevel      1
  58 
  59 static struct txx9_irc_reg __iomem *txx9_ircptr __read_mostly;
  60 
  61 static struct {
  62         unsigned char level;
  63         unsigned char mode;
  64 } txx9irq[TXx9_MAX_IR] __read_mostly;
  65 
  66 static void txx9_irq_unmask(struct irq_data *d)
  67 {
  68         unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
  69         u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
  70         int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
  71 
  72         __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
  73                      | (txx9irq[irq_nr].level << ofs),
  74                      ilrp);
  75 #ifdef CONFIG_CPU_TX39XX
  76         /* update IRCSR */
  77         __raw_writel(0, &txx9_ircptr->imr);
  78         __raw_writel(irc_elevel, &txx9_ircptr->imr);
  79 #endif
  80 }
  81 
  82 static inline void txx9_irq_mask(struct irq_data *d)
  83 {
  84         unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
  85         u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
  86         int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
  87 
  88         __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
  89                      | (irc_dlevel << ofs),
  90                      ilrp);
  91 #ifdef CONFIG_CPU_TX39XX
  92         /* update IRCSR */
  93         __raw_writel(0, &txx9_ircptr->imr);
  94         __raw_writel(irc_elevel, &txx9_ircptr->imr);
  95         /* flush write buffer */
  96         __raw_readl(&txx9_ircptr->ssr);
  97 #else
  98         mmiowb();
  99 #endif
 100 }
 101 
 102 static void txx9_irq_mask_ack(struct irq_data *d)
 103 {
 104         unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
 105 
 106         txx9_irq_mask(d);
 107         /* clear edge detection */
 108         if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
 109                 __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
 110 }
 111 
 112 static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type)
 113 {
 114         unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
 115         u32 cr;
 116         u32 __iomem *crp;
 117         int ofs;
 118         int mode;
 119 
 120         if (flow_type & IRQF_TRIGGER_PROBE)
 121                 return 0;
 122         switch (flow_type & IRQF_TRIGGER_MASK) {
 123         case IRQF_TRIGGER_RISING:       mode = TXx9_IRCR_UP;    break;
 124         case IRQF_TRIGGER_FALLING:      mode = TXx9_IRCR_DOWN;  break;
 125         case IRQF_TRIGGER_HIGH: mode = TXx9_IRCR_HIGH;  break;
 126         case IRQF_TRIGGER_LOW:  mode = TXx9_IRCR_LOW;   break;
 127         default:
 128                 return -EINVAL;
 129         }
 130         crp = &txx9_ircptr->cr[(unsigned int)irq_nr / 8];
 131         cr = __raw_readl(crp);
 132         ofs = (irq_nr & (8 - 1)) * 2;
 133         cr &= ~(0x3 << ofs);
 134         cr |= (mode & 0x3) << ofs;
 135         __raw_writel(cr, crp);
 136         txx9irq[irq_nr].mode = mode;
 137         return 0;
 138 }
 139 
 140 static struct irq_chip txx9_irq_chip = {
 141         .name           = "TXX9",
 142         .irq_ack        = txx9_irq_mask_ack,
 143         .irq_mask       = txx9_irq_mask,
 144         .irq_mask_ack   = txx9_irq_mask_ack,
 145         .irq_unmask     = txx9_irq_unmask,
 146         .irq_set_type   = txx9_irq_set_type,
 147 };
 148 
 149 void __init txx9_irq_init(unsigned long baseaddr)
 150 {
 151         int i;
 152 
 153         txx9_ircptr = ioremap(baseaddr, sizeof(struct txx9_irc_reg));
 154         for (i = 0; i < TXx9_MAX_IR; i++) {
 155                 txx9irq[i].level = 4; /* middle level */
 156                 txx9irq[i].mode = TXx9_IRCR_LOW;
 157                 irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &txx9_irq_chip,
 158                                          handle_level_irq);
 159         }
 160 
 161         /* mask all IRC interrupts */
 162         __raw_writel(0, &txx9_ircptr->imr);
 163         for (i = 0; i < 8; i++)
 164                 __raw_writel(0, &txx9_ircptr->ilr[i]);
 165         /* setup IRC interrupt mode (Low Active) */
 166         for (i = 0; i < 2; i++)
 167                 __raw_writel(0, &txx9_ircptr->cr[i]);
 168         /* enable interrupt control */
 169         __raw_writel(TXx9_IRCER_ICE, &txx9_ircptr->cer);
 170         __raw_writel(irc_elevel, &txx9_ircptr->imr);
 171 }
 172 
 173 int __init txx9_irq_set_pri(int irc_irq, int new_pri)
 174 {
 175         int old_pri;
 176 
 177         if ((unsigned int)irc_irq >= TXx9_MAX_IR)
 178                 return 0;
 179         old_pri = txx9irq[irc_irq].level;
 180         txx9irq[irc_irq].level = new_pri;
 181         return old_pri;
 182 }
 183 
 184 int txx9_irq(void)
 185 {
 186         u32 csr = __raw_readl(&txx9_ircptr->csr);
 187 
 188         if (likely(!(csr & TXx9_IRCSR_IF)))
 189                 return TXX9_IRQ_BASE + (csr & (TXx9_MAX_IR - 1));
 190         return -1;
 191 }

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