This source file includes following definitions.
- irq_bank_readl
 
- irq_bank_writel
 
- omap_ack_irq
 
- omap_mask_ack_irq
 
- omap_irq_set_cfg
 
- omap1_handle_irq
 
- omap_alloc_gc
 
- omap1_init_irq
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 #include <linux/gpio.h>
  39 #include <linux/init.h>
  40 #include <linux/module.h>
  41 #include <linux/sched.h>
  42 #include <linux/interrupt.h>
  43 #include <linux/io.h>
  44 
  45 #include <asm/irq.h>
  46 #include <asm/exception.h>
  47 #include <asm/mach/irq.h>
  48 
  49 #include "soc.h"
  50 
  51 #include <mach/hardware.h>
  52 
  53 #include "common.h"
  54 
  55 #define IRQ_BANK(irq) ((irq) >> 5)
  56 #define IRQ_BIT(irq)  ((irq) & 0x1f)
  57 
  58 struct omap_irq_bank {
  59         unsigned long base_reg;
  60         void __iomem *va;
  61         unsigned long trigger_map;
  62         unsigned long wake_enable;
  63 };
  64 
  65 static u32 omap_l2_irq;
  66 static unsigned int irq_bank_count;
  67 static struct omap_irq_bank *irq_banks;
  68 static struct irq_domain *domain;
  69 
  70 static inline unsigned int irq_bank_readl(int bank, int offset)
  71 {
  72         return readl_relaxed(irq_banks[bank].va + offset);
  73 }
  74 static inline void irq_bank_writel(unsigned long value, int bank, int offset)
  75 {
  76         writel_relaxed(value, irq_banks[bank].va + offset);
  77 }
  78 
  79 static void omap_ack_irq(int irq)
  80 {
  81         if (irq > 31)
  82                 writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET);
  83 
  84         writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET);
  85 }
  86 
  87 static void omap_mask_ack_irq(struct irq_data *d)
  88 {
  89         struct irq_chip_type *ct = irq_data_get_chip_type(d);
  90 
  91         ct->chip.irq_mask(d);
  92         omap_ack_irq(d->irq);
  93 }
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
 103 {
 104         signed int bank;
 105         unsigned long val, offset;
 106 
 107         bank = IRQ_BANK(irq);
 108         
 109         fiq = bank ? 0 : (fiq & 0x1);
 110         val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
 111         offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
 112         irq_bank_writel(val, bank, offset);
 113 }
 114 
 115 #if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
 116 static struct omap_irq_bank omap7xx_irq_banks[] = {
 117         { .base_reg = OMAP_IH1_BASE,            .trigger_map = 0xb3f8e22f },
 118         { .base_reg = OMAP_IH2_BASE,            .trigger_map = 0xfdb9c1f2 },
 119         { .base_reg = OMAP_IH2_BASE + 0x100,    .trigger_map = 0x800040f3 },
 120 };
 121 #endif
 122 
 123 #ifdef CONFIG_ARCH_OMAP15XX
 124 static struct omap_irq_bank omap1510_irq_banks[] = {
 125         { .base_reg = OMAP_IH1_BASE,            .trigger_map = 0xb3febfff },
 126         { .base_reg = OMAP_IH2_BASE,            .trigger_map = 0xffbfffed },
 127 };
 128 static struct omap_irq_bank omap310_irq_banks[] = {
 129         { .base_reg = OMAP_IH1_BASE,            .trigger_map = 0xb3faefc3 },
 130         { .base_reg = OMAP_IH2_BASE,            .trigger_map = 0x65b3c061 },
 131 };
 132 #endif
 133 
 134 #if defined(CONFIG_ARCH_OMAP16XX)
 135 
 136 static struct omap_irq_bank omap1610_irq_banks[] = {
 137         { .base_reg = OMAP_IH1_BASE,            .trigger_map = 0xb3fefe8f },
 138         { .base_reg = OMAP_IH2_BASE,            .trigger_map = 0xfdb7c1fd },
 139         { .base_reg = OMAP_IH2_BASE + 0x100,    .trigger_map = 0xffffb7ff },
 140         { .base_reg = OMAP_IH2_BASE + 0x200,    .trigger_map = 0xffffffff },
 141 };
 142 #endif
 143 
 144 asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
 145 {
 146         void __iomem *l1 = irq_banks[0].va;
 147         void __iomem *l2 = irq_banks[1].va;
 148         u32 irqnr;
 149 
 150         do {
 151                 irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET);
 152                 irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff);
 153                 if (!irqnr)
 154                         break;
 155 
 156                 irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET);
 157                 if (irqnr)
 158                         goto irq;
 159 
 160                 irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET);
 161                 if (irqnr == omap_l2_irq) {
 162                         irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET);
 163                         if (irqnr)
 164                                 irqnr += 32;
 165                 }
 166 irq:
 167                 if (irqnr)
 168                         handle_domain_irq(domain, irqnr, regs);
 169                 else
 170                         break;
 171         } while (irqnr);
 172 }
 173 
 174 static __init void
 175 omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
 176 {
 177         struct irq_chip_generic *gc;
 178         struct irq_chip_type *ct;
 179 
 180         gc = irq_alloc_generic_chip("MPU", 1, irq_start, base,
 181                                     handle_level_irq);
 182         ct = gc->chip_types;
 183         ct->chip.irq_ack = omap_mask_ack_irq;
 184         ct->chip.irq_mask = irq_gc_mask_set_bit;
 185         ct->chip.irq_unmask = irq_gc_mask_clr_bit;
 186         ct->chip.irq_set_wake = irq_gc_set_wake;
 187         ct->regs.mask = IRQ_MIR_REG_OFFSET;
 188         irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
 189                                IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 190 }
 191 
 192 void __init omap1_init_irq(void)
 193 {
 194         struct irq_chip_type *ct;
 195         struct irq_data *d = NULL;
 196         int i, j, irq_base;
 197         unsigned long nr_irqs;
 198 
 199 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 200         if (cpu_is_omap7xx()) {
 201                 irq_banks = omap7xx_irq_banks;
 202                 irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
 203         }
 204 #endif
 205 #ifdef CONFIG_ARCH_OMAP15XX
 206         if (cpu_is_omap1510()) {
 207                 irq_banks = omap1510_irq_banks;
 208                 irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
 209         }
 210         if (cpu_is_omap310()) {
 211                 irq_banks = omap310_irq_banks;
 212                 irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
 213         }
 214 #endif
 215 #if defined(CONFIG_ARCH_OMAP16XX)
 216         if (cpu_is_omap16xx()) {
 217                 irq_banks = omap1610_irq_banks;
 218                 irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
 219         }
 220 #endif
 221 
 222         for (i = 0; i < irq_bank_count; i++) {
 223                 irq_banks[i].va = ioremap(irq_banks[i].base_reg, 0xff);
 224                 if (WARN_ON(!irq_banks[i].va))
 225                         return;
 226         }
 227 
 228         nr_irqs = irq_bank_count * 32;
 229 
 230         irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
 231         if (irq_base < 0) {
 232                 pr_warn("Couldn't allocate IRQ numbers\n");
 233                 irq_base = 0;
 234         }
 235         omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base;
 236         omap_l2_irq -= NR_IRQS_LEGACY;
 237 
 238         domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0,
 239                                        &irq_domain_simple_ops, NULL);
 240 
 241         pr_info("Total of %lu interrupts in %i interrupt banks\n",
 242                 nr_irqs, irq_bank_count);
 243 
 244         
 245         for (i = 0; i < irq_bank_count; i++) {
 246                 irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
 247                 irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
 248         }
 249 
 250         
 251         irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
 252         irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
 253 
 254         
 255         if (cpu_is_omap7xx())
 256                 irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
 257 
 258         
 259         for (i = 0; i < irq_bank_count; i++) {
 260                 for (j = i * 32; j < (i + 1) * 32; j++) {
 261                         int irq_trigger;
 262 
 263                         irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
 264                         omap_irq_set_cfg(j, 0, 0, irq_trigger);
 265                         irq_clear_status_flags(j, IRQ_NOREQUEST);
 266                 }
 267                 omap_alloc_gc(irq_banks[i].va, irq_base + i * 32, 32);
 268         }
 269 
 270         
 271         d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq));
 272         if (d) {
 273                 ct = irq_data_get_chip_type(d);
 274                 ct->chip.irq_unmask(d);
 275         }
 276 }