Blame view
arch/mips/kernel/irq-msc01.c
3.96 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 |
* This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. |
27f768192 [MIPS] Cleanup un... |
6 7 8 9 10 |
* * Copyright (c) 2004 MIPS Inc * Author: chris@mips.com * * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org> |
1da177e4c Linux-2.6.12-rc2 |
11 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/interrupt.h> #include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 17 18 |
#include <linux/sched.h> #include <linux/kernel_stat.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/msc01_ic.h> |
411ba7fcb [MIPS] Fix some s... |
19 |
#include <asm/traps.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 25 26 27 28 29 |
static unsigned long _icctrl_msc; #define MSC01_IC_REG_BASE _icctrl_msc #define MSCIC_WRITE(reg, data) do { *(volatile u32 *)(reg) = data; } while (0) #define MSCIC_READ(reg, data) do { data = *(volatile u32 *)(reg); } while (0) static unsigned int irq_base; /* mask off an interrupt */ |
e15883da8 MIPS: MSC01: Conv... |
30 |
static inline void mask_msc_irq(struct irq_data *d) |
1da177e4c Linux-2.6.12-rc2 |
31 |
{ |
e15883da8 MIPS: MSC01: Conv... |
32 |
unsigned int irq = d->irq; |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 37 38 39 |
if (irq < (irq_base + 32)) MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base)); else MSCIC_WRITE(MSC01_IC_DISH, 1<<(irq - irq_base - 32)); } /* unmask an interrupt */ |
e15883da8 MIPS: MSC01: Conv... |
40 |
static inline void unmask_msc_irq(struct irq_data *d) |
1da177e4c Linux-2.6.12-rc2 |
41 |
{ |
e15883da8 MIPS: MSC01: Conv... |
42 |
unsigned int irq = d->irq; |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 46 47 48 49 |
if (irq < (irq_base + 32)) MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base)); else MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32)); } /* |
1da177e4c Linux-2.6.12-rc2 |
50 51 |
* Masks and ACKs an IRQ */ |
e15883da8 MIPS: MSC01: Conv... |
52 |
static void level_mask_and_ack_msc_irq(struct irq_data *d) |
1da177e4c Linux-2.6.12-rc2 |
53 |
{ |
e15883da8 MIPS: MSC01: Conv... |
54 55 56 |
unsigned int irq = d->irq; mask_msc_irq(d); |
e01402b11 More AP / SP bits... |
57 |
if (!cpu_has_veic) |
1da177e4c Linux-2.6.12-rc2 |
58 |
MSCIC_WRITE(MSC01_IC_EOI, 0); |
41c594ab6 [MIPS] MT: Improv... |
59 |
/* This actually needs to be a call into platform code */ |
1146fe305 [MIPS] SMTC: Make... |
60 |
smtc_im_ack_irq(irq); |
1da177e4c Linux-2.6.12-rc2 |
61 62 63 64 65 |
} /* * Masks and ACKs an IRQ */ |
e15883da8 MIPS: MSC01: Conv... |
66 |
static void edge_mask_and_ack_msc_irq(struct irq_data *d) |
1da177e4c Linux-2.6.12-rc2 |
67 |
{ |
e15883da8 MIPS: MSC01: Conv... |
68 69 70 |
unsigned int irq = d->irq; mask_msc_irq(d); |
e01402b11 More AP / SP bits... |
71 |
if (!cpu_has_veic) |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 77 78 |
MSCIC_WRITE(MSC01_IC_EOI, 0); else { u32 r; MSCIC_READ(MSC01_IC_SUP+irq*8, r); MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); } |
1146fe305 [MIPS] SMTC: Make... |
79 |
smtc_im_ack_irq(irq); |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 |
} /* |
1da177e4c Linux-2.6.12-rc2 |
83 84 |
* Interrupt handler for interrupts coming from SOC-it. */ |
937a80157 [MIPS] Complete f... |
85 |
void ll_msc_irq(void) |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 89 90 91 |
{ unsigned int irq; /* read the interrupt vector register */ MSCIC_READ(MSC01_IC_VEC, irq); if (irq < 64) |
937a80157 [MIPS] Complete f... |
92 |
do_IRQ(irq + irq_base); |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 |
else { /* Ignore spurious interrupt */ } } |
411ba7fcb [MIPS] Fix some s... |
97 |
static void msc_bind_eic_interrupt(int irq, int set) |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 101 |
{ MSCIC_WRITE(MSC01_IC_RAMW, (irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF)); } |
411ba7fcb [MIPS] Fix some s... |
102 |
static struct irq_chip msc_levelirq_type = { |
70d21cdee [MIPS] use name i... |
103 |
.name = "SOC-it-Level", |
e15883da8 MIPS: MSC01: Conv... |
104 105 106 107 108 |
.irq_ack = level_mask_and_ack_msc_irq, .irq_mask = mask_msc_irq, .irq_mask_ack = level_mask_and_ack_msc_irq, .irq_unmask = unmask_msc_irq, .irq_eoi = unmask_msc_irq, |
1da177e4c Linux-2.6.12-rc2 |
109 |
}; |
411ba7fcb [MIPS] Fix some s... |
110 |
static struct irq_chip msc_edgeirq_type = { |
70d21cdee [MIPS] use name i... |
111 |
.name = "SOC-it-Edge", |
e15883da8 MIPS: MSC01: Conv... |
112 113 114 115 116 |
.irq_ack = edge_mask_and_ack_msc_irq, .irq_mask = mask_msc_irq, .irq_mask_ack = edge_mask_and_ack_msc_irq, .irq_unmask = unmask_msc_irq, .irq_eoi = unmask_msc_irq, |
1da177e4c Linux-2.6.12-rc2 |
117 |
}; |
d725cf381 [MIPS] MT: Reenab... |
118 |
void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq) |
1da177e4c Linux-2.6.12-rc2 |
119 |
{ |
49a89efbb [MIPS] Fix "no sp... |
120 |
_icctrl_msc = (unsigned long) ioremap(icubase, 0x40000); |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 126 127 128 129 130 131 |
/* Reset interrupt controller - initialises all registers to 0 */ MSCIC_WRITE(MSC01_IC_RST, MSC01_IC_RST_RST_BIT); board_bind_eic_interrupt = &msc_bind_eic_interrupt; for (; nirq >= 0; nirq--, imp++) { int n = imp->im_irq; switch (imp->im_type) { case MSC01_IRQ_EDGE: |
e4ec7989b MIPS: Convert the... |
132 133 134 135 |
irq_set_chip_and_handler_name(irqbase + n, &msc_edgeirq_type, handle_edge_irq, "edge"); |
e01402b11 More AP / SP bits... |
136 |
if (cpu_has_veic) |
1da177e4c Linux-2.6.12-rc2 |
137 138 139 140 141 |
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: |
e4ec7989b MIPS: Convert the... |
142 143 144 145 |
irq_set_chip_and_handler_name(irqbase + n, &msc_levelirq_type, handle_level_irq, "level"); |
e01402b11 More AP / SP bits... |
146 |
if (cpu_has_veic) |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 151 |
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl); } } |
d725cf381 [MIPS] MT: Reenab... |
152 |
irq_base = irqbase; |
1da177e4c Linux-2.6.12-rc2 |
153 154 155 156 |
MSCIC_WRITE(MSC01_IC_GENA, MSC01_IC_GENA_GENA_BIT); /* Enable interrupt generation */ } |