1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/irqchip/irq-zevio.c
5 * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
10 #include <linux/irqchip.h>
12 #include <linux/of_address.h>
13 #include <linux/of_irq.h>
15 #include <asm/mach/irq.h>
16 #include <asm/exception.h>
18 #define IO_STATUS 0x000
19 #define IO_RAW_STATUS 0x004
20 #define IO_ENABLE 0x008
21 #define IO_DISABLE 0x00C
22 #define IO_CURRENT 0x020
23 #define IO_RESET 0x028
24 #define IO_MAX_PRIOTY 0x02C
26 #define IO_IRQ_BASE 0x000
27 #define IO_FIQ_BASE 0x100
29 #define IO_INVERT_SEL 0x200
30 #define IO_STICKY_SEL 0x204
31 #define IO_PRIORITY_SEL 0x300
34 #define FIQ_START MAX_INTRS
36 static struct irq_domain
*zevio_irq_domain
;
37 static void __iomem
*zevio_irq_io
;
39 static void zevio_irq_ack(struct irq_data
*irqd
)
41 struct irq_chip_generic
*gc
= irq_data_get_irq_chip_data(irqd
);
42 struct irq_chip_regs
*regs
= &irq_data_get_chip_type(irqd
)->regs
;
44 readl(gc
->reg_base
+ regs
->ack
);
47 static void __exception_irq_entry
zevio_handle_irq(struct pt_regs
*regs
)
51 while (readl(zevio_irq_io
+ IO_STATUS
)) {
52 irqnr
= readl(zevio_irq_io
+ IO_CURRENT
);
53 handle_domain_irq(zevio_irq_domain
, irqnr
, regs
);
57 static void __init
zevio_init_irq_base(void __iomem
*base
)
59 /* Disable all interrupts */
60 writel(~0, base
+ IO_DISABLE
);
62 /* Accept interrupts of all priorities */
63 writel(0xF, base
+ IO_MAX_PRIOTY
);
65 /* Reset existing interrupts */
66 readl(base
+ IO_RESET
);
69 static int __init
zevio_of_init(struct device_node
*node
,
70 struct device_node
*parent
)
72 unsigned int clr
= IRQ_NOREQUEST
| IRQ_NOPROBE
| IRQ_NOAUTOEN
;
73 struct irq_chip_generic
*gc
;
76 if (WARN_ON(zevio_irq_io
|| zevio_irq_domain
))
79 zevio_irq_io
= of_iomap(node
, 0);
80 BUG_ON(!zevio_irq_io
);
82 /* Do not invert interrupt status bits */
83 writel(~0, zevio_irq_io
+ IO_INVERT_SEL
);
85 /* Disable sticky interrupts */
86 writel(0, zevio_irq_io
+ IO_STICKY_SEL
);
88 /* We don't use IRQ priorities. Set each IRQ to highest priority. */
89 memset_io(zevio_irq_io
+ IO_PRIORITY_SEL
, 0, MAX_INTRS
* sizeof(u32
));
91 /* Init IRQ and FIQ */
92 zevio_init_irq_base(zevio_irq_io
+ IO_IRQ_BASE
);
93 zevio_init_irq_base(zevio_irq_io
+ IO_FIQ_BASE
);
95 zevio_irq_domain
= irq_domain_add_linear(node
, MAX_INTRS
,
96 &irq_generic_chip_ops
, NULL
);
97 BUG_ON(!zevio_irq_domain
);
99 ret
= irq_alloc_domain_generic_chips(zevio_irq_domain
, MAX_INTRS
, 1,
100 "zevio_intc", handle_level_irq
,
101 clr
, 0, IRQ_GC_INIT_MASK_CACHE
);
104 gc
= irq_get_domain_generic_chip(zevio_irq_domain
, 0);
105 gc
->reg_base
= zevio_irq_io
;
106 gc
->chip_types
[0].chip
.irq_ack
= zevio_irq_ack
;
107 gc
->chip_types
[0].chip
.irq_mask
= irq_gc_mask_disable_reg
;
108 gc
->chip_types
[0].chip
.irq_unmask
= irq_gc_unmask_enable_reg
;
109 gc
->chip_types
[0].regs
.mask
= IO_IRQ_BASE
+ IO_ENABLE
;
110 gc
->chip_types
[0].regs
.enable
= IO_IRQ_BASE
+ IO_ENABLE
;
111 gc
->chip_types
[0].regs
.disable
= IO_IRQ_BASE
+ IO_DISABLE
;
112 gc
->chip_types
[0].regs
.ack
= IO_IRQ_BASE
+ IO_RESET
;
114 set_handle_irq(zevio_handle_irq
);
116 pr_info("TI-NSPIRE classic IRQ controller\n");
120 IRQCHIP_DECLARE(zevio_irq
, "lsi,zevio-intc", zevio_of_init
);