0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <linux/gpio.h>
0039 #include <linux/init.h>
0040 #include <linux/module.h>
0041 #include <linux/sched.h>
0042 #include <linux/interrupt.h>
0043 #include <linux/io.h>
0044
0045 #include <asm/irq.h>
0046 #include <asm/exception.h>
0047 #include <asm/mach/irq.h>
0048
0049 #include "soc.h"
0050 #include "hardware.h"
0051 #include "common.h"
0052
0053 #define IRQ_BANK(irq) ((irq) >> 5)
0054 #define IRQ_BIT(irq) ((irq) & 0x1f)
0055
0056 struct omap_irq_bank {
0057 unsigned long base_reg;
0058 void __iomem *va;
0059 unsigned long trigger_map;
0060 unsigned long wake_enable;
0061 };
0062
0063 static u32 omap_l2_irq;
0064 static unsigned int irq_bank_count;
0065 static struct omap_irq_bank *irq_banks;
0066 static struct irq_domain *domain;
0067
0068 static inline unsigned int irq_bank_readl(int bank, int offset)
0069 {
0070 return readl_relaxed(irq_banks[bank].va + offset);
0071 }
0072 static inline void irq_bank_writel(unsigned long value, int bank, int offset)
0073 {
0074 writel_relaxed(value, irq_banks[bank].va + offset);
0075 }
0076
0077 static void omap_ack_irq(int irq)
0078 {
0079 if (irq > 31)
0080 writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET);
0081
0082 writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET);
0083 }
0084
0085 static void omap_mask_ack_irq(struct irq_data *d)
0086 {
0087 struct irq_chip_type *ct = irq_data_get_chip_type(d);
0088
0089 ct->chip.irq_mask(d);
0090 omap_ack_irq(d->irq);
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100 static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
0101 {
0102 signed int bank;
0103 unsigned long val, offset;
0104
0105 bank = IRQ_BANK(irq);
0106
0107 fiq = bank ? 0 : (fiq & 0x1);
0108 val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
0109 offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
0110 irq_bank_writel(val, bank, offset);
0111 }
0112
0113 #if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
0114 static struct omap_irq_bank omap7xx_irq_banks[] = {
0115 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
0116 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
0117 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
0118 };
0119 #endif
0120
0121 #ifdef CONFIG_ARCH_OMAP15XX
0122 static struct omap_irq_bank omap1510_irq_banks[] = {
0123 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
0124 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
0125 };
0126 static struct omap_irq_bank omap310_irq_banks[] = {
0127 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
0128 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
0129 };
0130 #endif
0131
0132 #if defined(CONFIG_ARCH_OMAP16XX)
0133
0134 static struct omap_irq_bank omap1610_irq_banks[] = {
0135 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
0136 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
0137 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff },
0138 { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff },
0139 };
0140 #endif
0141
0142 asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
0143 {
0144 void __iomem *l1 = irq_banks[0].va;
0145 void __iomem *l2 = irq_banks[1].va;
0146 u32 irqnr;
0147
0148 do {
0149 irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET);
0150 irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff);
0151 if (!irqnr)
0152 break;
0153
0154 irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET);
0155 if (irqnr)
0156 goto irq;
0157
0158 irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET);
0159 if (irqnr == omap_l2_irq) {
0160 irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET);
0161 if (irqnr)
0162 irqnr += 32;
0163 }
0164 irq:
0165 if (irqnr)
0166 generic_handle_domain_irq(domain, irqnr);
0167 else
0168 break;
0169 } while (irqnr);
0170 }
0171
0172 static __init void
0173 omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
0174 {
0175 struct irq_chip_generic *gc;
0176 struct irq_chip_type *ct;
0177
0178 gc = irq_alloc_generic_chip("MPU", 1, irq_start, base,
0179 handle_level_irq);
0180 ct = gc->chip_types;
0181 ct->chip.irq_ack = omap_mask_ack_irq;
0182 ct->chip.irq_mask = irq_gc_mask_set_bit;
0183 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
0184 ct->chip.irq_set_wake = irq_gc_set_wake;
0185 ct->regs.mask = IRQ_MIR_REG_OFFSET;
0186 irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
0187 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
0188 }
0189
0190 void __init omap1_init_irq(void)
0191 {
0192 struct irq_chip_type *ct;
0193 struct irq_data *d = NULL;
0194 int i, j, irq_base;
0195 unsigned long nr_irqs;
0196
0197 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
0198 if (cpu_is_omap7xx()) {
0199 irq_banks = omap7xx_irq_banks;
0200 irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
0201 }
0202 #endif
0203 #ifdef CONFIG_ARCH_OMAP15XX
0204 if (cpu_is_omap1510()) {
0205 irq_banks = omap1510_irq_banks;
0206 irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
0207 }
0208 if (cpu_is_omap310()) {
0209 irq_banks = omap310_irq_banks;
0210 irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
0211 }
0212 #endif
0213 #if defined(CONFIG_ARCH_OMAP16XX)
0214 if (cpu_is_omap16xx()) {
0215 irq_banks = omap1610_irq_banks;
0216 irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
0217 }
0218 #endif
0219
0220 for (i = 0; i < irq_bank_count; i++) {
0221 irq_banks[i].va = ioremap(irq_banks[i].base_reg, 0xff);
0222 if (WARN_ON(!irq_banks[i].va))
0223 return;
0224 }
0225
0226 nr_irqs = irq_bank_count * 32;
0227
0228 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
0229 if (irq_base < 0) {
0230 pr_warn("Couldn't allocate IRQ numbers\n");
0231 irq_base = 0;
0232 }
0233 omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base;
0234 omap_l2_irq -= NR_IRQS_LEGACY;
0235
0236 domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0,
0237 &irq_domain_simple_ops, NULL);
0238
0239 pr_info("Total of %lu interrupts in %i interrupt banks\n",
0240 nr_irqs, irq_bank_count);
0241
0242
0243 for (i = 0; i < irq_bank_count; i++) {
0244 irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
0245 irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
0246 }
0247
0248
0249 irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
0250 irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
0251
0252
0253 if (cpu_is_omap7xx())
0254 irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
0255
0256
0257 for (i = 0; i < irq_bank_count; i++) {
0258 for (j = i * 32; j < (i + 1) * 32; j++) {
0259 int irq_trigger;
0260
0261 irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
0262 omap_irq_set_cfg(j, 0, 0, irq_trigger);
0263 irq_clear_status_flags(j, IRQ_NOREQUEST);
0264 }
0265 omap_alloc_gc(irq_banks[i].va, irq_base + i * 32, 32);
0266 }
0267
0268
0269 d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq));
0270 if (d) {
0271 ct = irq_data_get_chip_type(d);
0272 ct->chip.irq_unmask(d);
0273 }
0274 }