blob: 3acb133668dc12f5731aab6b611c8756a6fa89a1 [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 = {
Atsushi Nemoto70d21cd2007-01-15 00:07:25 +090065 .name = "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};
71
72
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090073#define unmask_ioasic_dma_irq unmask_ioasic_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090075#define mask_ioasic_dma_irq mask_ioasic_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
77#define ack_ioasic_dma_irq ack_ioasic_irq
78
79static inline void end_ioasic_dma_irq(unsigned int irq)
80{
81 clear_ioasic_irq(irq);
82 fast_iob();
83 end_ioasic_irq(irq);
84}
85
Ralf Baechle94dee172006-07-02 14:41:42 +010086static struct irq_chip ioasic_dma_irq_type = {
Atsushi Nemoto70d21cd2007-01-15 00:07:25 +090087 .name = "IO-ASIC-DMA",
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 .ack = ack_ioasic_dma_irq,
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +090089 .mask = mask_ioasic_dma_irq,
90 .mask_ack = ack_ioasic_dma_irq,
91 .unmask = unmask_ioasic_dma_irq,
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 .end = end_ioasic_dma_irq,
93};
94
95
96void __init init_ioasic_irqs(int base)
97{
98 int i;
99
100 /* Mask interrupts. */
101 ioasic_write(IO_REG_SIMR, 0);
102 fast_iob();
103
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +0900104 for (i = base; i < base + IO_INR_DMA; i++)
Atsushi Nemoto14178362006-11-14 01:13:18 +0900105 set_irq_chip_and_handler(i, &ioasic_irq_type,
106 handle_level_irq);
Atsushi Nemoto1603b5a2006-11-02 02:08:36 +0900107 for (; i < base + IO_IRQ_LINES; i++)
Atsushi Nemoto25ba2f52006-12-02 00:08:03 +0900108 set_irq_chip(i, &ioasic_dma_irq_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110 ioasic_irq_base = base;
111}