blob: 269b22b34313212191a70fba6154477f79318cb8 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/mips/dec/ioasic-irq.c
3 *
4 * DEC I/O ASIC interrupts.
5 *
6 * Copyright (c) 2002, 2003 Maciej W. Rozycki
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/irq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/types.h>
17
18#include <asm/dec/ioasic.h>
19#include <asm/dec/ioasic_addrs.h>
20#include <asm/dec/ioasic_ints.h>
21
22
Linus Torvalds1da177e2005-04-16 15:20:36 -070023static int ioasic_irq_base;
24
25
26static inline void unmask_ioasic_irq(unsigned int irq)
27{
28 u32 simr;
29
30 simr = ioasic_read(IO_REG_SIMR);
31 simr |= (1 << (irq - ioasic_irq_base));
32 ioasic_write(IO_REG_SIMR, simr);
33}
34
35static inline void mask_ioasic_irq(unsigned int irq)
36{
37 u32 simr;
38
39 simr = ioasic_read(IO_REG_SIMR);
40 simr &= ~(1 << (irq - ioasic_irq_base));
41 ioasic_write(IO_REG_SIMR, simr);
42}
43
44static inline void clear_ioasic_irq(unsigned int irq)
45{
46 u32 sir;
47
48 sir = ~(1 << (irq - ioasic_irq_base));
49 ioasic_write(IO_REG_SIR, sir);
50}
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052static inline void ack_ioasic_irq(unsigned int irq)
53{
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 mask_ioasic_irq(irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 fast_iob();
56}
57
58static inline void end_ioasic_irq(unsigned int irq)
59{
60 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090061 unmask_ioasic_irq(irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -070062}
63
Ralf Baechle94dee172006-07-02 14:41:42 +010064static struct irq_chip ioasic_irq_type = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 .typename = "IO-ASIC",
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 .ack = ack_ioasic_irq,
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090067 .mask = mask_ioasic_irq,
68 .mask_ack = ack_ioasic_irq,
69 .unmask = unmask_ioasic_irq,
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 .end = end_ioasic_irq,
71};
72
73
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090074#define unmask_ioasic_dma_irq unmask_ioasic_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090076#define mask_ioasic_dma_irq mask_ioasic_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78#define ack_ioasic_dma_irq ack_ioasic_irq
79
80static inline void end_ioasic_dma_irq(unsigned int irq)
81{
82 clear_ioasic_irq(irq);
83 fast_iob();
84 end_ioasic_irq(irq);
85}
86
Ralf Baechle94dee172006-07-02 14:41:42 +010087static struct irq_chip ioasic_dma_irq_type = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 .typename = "IO-ASIC-DMA",
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 .ack = ack_ioasic_dma_irq,
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090090 .mask = mask_ioasic_dma_irq,
91 .mask_ack = ack_ioasic_dma_irq,
92 .unmask = unmask_ioasic_dma_irq,
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 .end = end_ioasic_dma_irq,
94};
95
96
97void __init init_ioasic_irqs(int base)
98{
99 int i;
100
101 /* Mask interrupts. */
102 ioasic_write(IO_REG_SIMR, 0);
103 fast_iob();
104
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +0900105 for (i = base; i < base + IO_INR_DMA; i++)
Atsushi Nemoto14178362006-11-14 01:13:18 +0900106 set_irq_chip_and_handler(i, &ioasic_irq_type,
107 handle_level_irq);
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +0900108 for (; i < base + IO_IRQ_LINES; i++)
Atsushi Nemoto14178362006-11-14 01:13:18 +0900109 set_irq_chip_and_handler(i, &ioasic_dma_irq_type,
110 handle_level_irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112 ioasic_irq_base = base;
113}