blob: 66502e6207fea86a8289d8697cf2db6c8cb6363c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#include <linux/init.h>
2#include <linux/list.h>
Russell Kingfced80c2008-09-06 12:10:45 +01003#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5#include <asm/mach/irq.h>
6#include <asm/hardware/iomd.h>
7#include <asm/irq.h>
Rob Herring78cbaac2012-02-08 18:24:23 -06008#include <asm/fiq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010010static void iomd_ack_irq_a(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070011{
12 unsigned int val, mask;
13
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010014 mask = 1 << d->irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 val = iomd_readb(IOMD_IRQMASKA);
16 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
17 iomd_writeb(mask, IOMD_IRQCLRA);
18}
19
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010020static void iomd_mask_irq_a(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070021{
22 unsigned int val, mask;
23
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010024 mask = 1 << d->irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 val = iomd_readb(IOMD_IRQMASKA);
26 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
27}
28
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010029static void iomd_unmask_irq_a(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070030{
31 unsigned int val, mask;
32
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010033 mask = 1 << d->irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 val = iomd_readb(IOMD_IRQMASKA);
35 iomd_writeb(val | mask, IOMD_IRQMASKA);
36}
37
Russell King10dd5ce2006-11-23 11:41:32 +000038static struct irq_chip iomd_a_chip = {
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010039 .irq_ack = iomd_ack_irq_a,
40 .irq_mask = iomd_mask_irq_a,
41 .irq_unmask = iomd_unmask_irq_a,
Linus Torvalds1da177e2005-04-16 15:20:36 -070042};
43
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010044static void iomd_mask_irq_b(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070045{
46 unsigned int val, mask;
47
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010048 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 val = iomd_readb(IOMD_IRQMASKB);
50 iomd_writeb(val & ~mask, IOMD_IRQMASKB);
51}
52
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010053static void iomd_unmask_irq_b(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054{
55 unsigned int val, mask;
56
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010057 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 val = iomd_readb(IOMD_IRQMASKB);
59 iomd_writeb(val | mask, IOMD_IRQMASKB);
60}
61
Russell King10dd5ce2006-11-23 11:41:32 +000062static struct irq_chip iomd_b_chip = {
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010063 .irq_ack = iomd_mask_irq_b,
64 .irq_mask = iomd_mask_irq_b,
65 .irq_unmask = iomd_unmask_irq_b,
Linus Torvalds1da177e2005-04-16 15:20:36 -070066};
67
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010068static void iomd_mask_irq_dma(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069{
70 unsigned int val, mask;
71
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010072 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 val = iomd_readb(IOMD_DMAMASK);
74 iomd_writeb(val & ~mask, IOMD_DMAMASK);
75}
76
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010077static void iomd_unmask_irq_dma(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070078{
79 unsigned int val, mask;
80
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010081 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 val = iomd_readb(IOMD_DMAMASK);
83 iomd_writeb(val | mask, IOMD_DMAMASK);
84}
85
Russell King10dd5ce2006-11-23 11:41:32 +000086static struct irq_chip iomd_dma_chip = {
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010087 .irq_ack = iomd_mask_irq_dma,
88 .irq_mask = iomd_mask_irq_dma,
89 .irq_unmask = iomd_unmask_irq_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -070090};
91
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010092static void iomd_mask_irq_fiq(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -070093{
94 unsigned int val, mask;
95
Lennert Buytenhek9a364da2010-11-29 11:07:20 +010096 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 val = iomd_readb(IOMD_FIQMASK);
98 iomd_writeb(val & ~mask, IOMD_FIQMASK);
99}
100
Lennert Buytenhek9a364da2010-11-29 11:07:20 +0100101static void iomd_unmask_irq_fiq(struct irq_data *d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102{
103 unsigned int val, mask;
104
Lennert Buytenhek9a364da2010-11-29 11:07:20 +0100105 mask = 1 << (d->irq & 7);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 val = iomd_readb(IOMD_FIQMASK);
107 iomd_writeb(val | mask, IOMD_FIQMASK);
108}
109
Russell King10dd5ce2006-11-23 11:41:32 +0000110static struct irq_chip iomd_fiq_chip = {
Lennert Buytenhek9a364da2010-11-29 11:07:20 +0100111 .irq_ack = iomd_mask_irq_fiq,
112 .irq_mask = iomd_mask_irq_fiq,
113 .irq_unmask = iomd_unmask_irq_fiq,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114};
115
Rob Herring78cbaac2012-02-08 18:24:23 -0600116extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
117
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118void __init rpc_init_irq(void)
119{
Rob Herringe8d36d52015-07-27 15:55:13 -0500120 unsigned int irq, clr, set = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
122 iomd_writeb(0, IOMD_IRQMASKA);
123 iomd_writeb(0, IOMD_IRQMASKB);
124 iomd_writeb(0, IOMD_FIQMASK);
125 iomd_writeb(0, IOMD_DMAMASK);
126
Rob Herring78cbaac2012-02-08 18:24:23 -0600127 set_fiq_handler(&rpc_default_fiq_start,
128 &rpc_default_fiq_end - &rpc_default_fiq_start);
129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 for (irq = 0; irq < NR_IRQS; irq++) {
Rob Herringe8d36d52015-07-27 15:55:13 -0500131 clr = IRQ_NOREQUEST;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133 if (irq <= 6 || (irq >= 9 && irq <= 15))
Rob Herringe8d36d52015-07-27 15:55:13 -0500134 clr |= IRQ_NOPROBE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136 if (irq == 21 || (irq >= 16 && irq <= 19) ||
137 irq == IRQ_KEYBOARDTX)
Rob Herringe8d36d52015-07-27 15:55:13 -0500138 set |= IRQ_NOAUTOEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
140 switch (irq) {
141 case 0 ... 7:
Thomas Gleixnerf38c02f2011-03-24 13:35:09 +0100142 irq_set_chip_and_handler(irq, &iomd_a_chip,
143 handle_level_irq);
Rob Herringe8d36d52015-07-27 15:55:13 -0500144 irq_modify_status(irq, clr, set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 break;
146
147 case 8 ... 15:
Thomas Gleixnerf38c02f2011-03-24 13:35:09 +0100148 irq_set_chip_and_handler(irq, &iomd_b_chip,
149 handle_level_irq);
Rob Herringe8d36d52015-07-27 15:55:13 -0500150 irq_modify_status(irq, clr, set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 break;
152
153 case 16 ... 21:
Thomas Gleixnerf38c02f2011-03-24 13:35:09 +0100154 irq_set_chip_and_handler(irq, &iomd_dma_chip,
155 handle_level_irq);
Rob Herringe8d36d52015-07-27 15:55:13 -0500156 irq_modify_status(irq, clr, set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 break;
158
159 case 64 ... 71:
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100160 irq_set_chip(irq, &iomd_fiq_chip);
Rob Herringe8d36d52015-07-27 15:55:13 -0500161 irq_modify_status(irq, clr, set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 break;
163 }
164 }
165
Shawn Guobc896632012-06-28 14:42:08 +0800166 init_FIQ(FIQ_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167}
168