25 #include <linux/types.h>
27 #include <asm/machdep.h>
32 #define MAX_IRQS NR_IRQS
45 static inline void beatic_update_irq_mask(
unsigned int irq_plug)
48 unsigned long masks[4];
50 off = (irq_plug / 256) * 4;
51 masks[0] = beatic_irq_mask_enable[off + 0]
52 & beatic_irq_mask_ack[off + 0];
53 masks[1] = beatic_irq_mask_enable[off + 1]
54 & beatic_irq_mask_ack[off + 1];
55 masks[2] = beatic_irq_mask_enable[off + 2]
56 & beatic_irq_mask_ack[off + 2];
57 masks[3] = beatic_irq_mask_enable[off + 3]
58 & beatic_irq_mask_ack[off + 3];
59 if (beat_set_interrupt_mask(irq_plug&~255
UL,
60 masks[0], masks[1], masks[2], masks[3]) != 0)
61 panic(
"Failed to set mask IRQ!");
64 static void beatic_mask_irq(
struct irq_data *
d)
69 beatic_irq_mask_enable[d->
irq/64] &= ~(1
UL << (63 - (d->
irq%64)));
70 beatic_update_irq_mask(
d->irq);
74 static void beatic_unmask_irq(
struct irq_data *
d)
79 beatic_irq_mask_enable[d->
irq/64] |= 1
UL << (63 - (d->
irq%64));
80 beatic_update_irq_mask(
d->irq);
84 static void beatic_ack_irq(
struct irq_data *
d)
89 beatic_irq_mask_ack[d->
irq/64] &= ~(1
UL << (63 - (d->
irq%64)));
90 beatic_update_irq_mask(
d->irq);
94 static void beatic_end_irq(
struct irq_data *
d)
99 err = beat_downcount_of_interrupt(d->
irq);
101 if ((err & 0xFFFFFFFF) != 0xFFFFFFF5)
102 panic(
"Failed to downcount IRQ! Error = %16llx", err);
107 beatic_irq_mask_ack[d->
irq/64] |= 1
UL << (63 - (d->
irq%64));
108 beatic_update_irq_mask(d->
irq);
112 static struct irq_chip beatic_pic = {
114 .irq_unmask = beatic_unmask_irq,
115 .irq_mask = beatic_mask_irq,
116 .irq_eoi = beatic_end_irq,
125 static void beatic_pic_host_unmap(
struct irq_domain *
h,
unsigned int virq)
127 beat_destruct_irq_plug(virq);
136 static int beatic_pic_host_map(
struct irq_domain *
h,
unsigned int virq,
141 err = beat_construct_and_connect_irq_plug(virq, hw);
158 const u32 *intspec,
unsigned int intsize,
160 unsigned int *out_flags)
162 const u64 *intspec2 = (
const u64 *)intspec;
164 *out_hwirq = *intspec2;
176 .map = beatic_pic_host_map,
177 .unmap = beatic_pic_host_unmap,
178 .xlate = beatic_pic_host_xlate,
179 .match = beatic_pic_host_match,
186 static inline unsigned int beatic_get_irq_plug(
void)
191 for (i = 0; i <
MAX_IRQS; i += 256) {
192 beat_detect_pending_interrupts(i, pending);
193 __asm__ (
"cntlzd %0,%1":
"=r"(ub):
194 "r"(pending[0] & beatic_irq_mask_enable[i/64+0]
195 & beatic_irq_mask_ack[i/64+0]));
198 __asm__ (
"cntlzd %0,%1":
"=r"(ub):
199 "r"(pending[1] & beatic_irq_mask_enable[i/64+1]
200 & beatic_irq_mask_ack[i/64+1]));
203 __asm__ (
"cntlzd %0,%1":
"=r"(ub):
204 "r"(pending[2] & beatic_irq_mask_enable[i/64+2]
205 & beatic_irq_mask_ack[i/64+2]));
208 __asm__ (
"cntlzd %0,%1":
"=r"(ub):
209 "r"(pending[3] & beatic_irq_mask_enable[i/64+3]
210 & beatic_irq_mask_ack[i/64+3]));
221 ret = beatic_get_irq_plug();
233 memset(beatic_irq_mask_enable, 0,
sizeof(beatic_irq_mask_enable));
234 memset(beatic_irq_mask_ack, 255,
sizeof(beatic_irq_mask_ack));
236 beat_set_interrupt_mask(i, 0
L, 0
L, 0
L, 0
L);
252 beat_destruct_irq_plug(i);