2 * Support for Versatile FPGA-based IRQ controllers
7 #include <asm/mach/irq.h>
8 #include <plat/fpga-irq.h>
10 #define IRQ_STATUS 0x00
11 #define IRQ_RAW_STATUS 0x04
12 #define IRQ_ENABLE_SET 0x08
13 #define IRQ_ENABLE_CLEAR 0x0c
15 static void fpga_irq_mask(struct irq_data
*d
)
17 struct fpga_irq_data
*f
= irq_data_get_irq_chip_data(d
);
18 u32 mask
= 1 << (d
->irq
- f
->irq_start
);
20 writel(mask
, f
->base
+ IRQ_ENABLE_CLEAR
);
23 static void fpga_irq_unmask(struct irq_data
*d
)
25 struct fpga_irq_data
*f
= irq_data_get_irq_chip_data(d
);
26 u32 mask
= 1 << (d
->irq
- f
->irq_start
);
28 writel(mask
, f
->base
+ IRQ_ENABLE_SET
);
31 static void fpga_irq_handle(unsigned int irq
, struct irq_desc
*desc
)
33 struct fpga_irq_data
*f
= irq_desc_get_handler_data(desc
);
34 u32 status
= readl(f
->base
+ IRQ_STATUS
);
37 do_bad_IRQ(irq
, desc
);
42 irq
= ffs(status
) - 1;
43 status
&= ~(1 << irq
);
45 generic_handle_irq(irq
+ f
->irq_start
);
49 void __init
fpga_irq_init(int parent_irq
, u32 valid
, struct fpga_irq_data
*f
)
53 f
->chip
.irq_ack
= fpga_irq_mask
;
54 f
->chip
.irq_mask
= fpga_irq_mask
;
55 f
->chip
.irq_unmask
= fpga_irq_unmask
;
57 if (parent_irq
!= -1) {
58 irq_set_handler_data(parent_irq
, f
);
59 irq_set_chained_handler(parent_irq
, fpga_irq_handle
);
62 for (i
= 0; i
< 32; i
++) {
63 if (valid
& (1 << i
)) {
64 unsigned int irq
= f
->irq_start
+ i
;
66 irq_set_chip_data(irq
, f
);
67 irq_set_chip_and_handler(irq
, &f
->chip
,
69 set_irq_flags(irq
, IRQF_VALID
| IRQF_PROBE
);