1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
4 * Copyright (C) 1999-2001 Nicolas Pitre
6 * Generic IRQ handling for the SA11x0.
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/interrupt.h>
12 #include <linux/irq.h>
13 #include <linux/irqdomain.h>
14 #include <linux/syscore_ops.h>
15 #include <linux/irqchip/irq-sa11x0.h>
17 #include <soc/sa1100/pwer.h>
19 #include <asm/exception.h>
21 #define ICIP 0x00 /* IC IRQ Pending reg. */
22 #define ICMR 0x04 /* IC Mask Reg. */
23 #define ICLR 0x08 /* IC Level Reg. */
24 #define ICCR 0x0C /* IC Control Reg. */
25 #define ICFP 0x10 /* IC FIQ Pending reg. */
26 #define ICPR 0x20 /* IC Pending Reg. */
28 static void __iomem
*iobase
;
31 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
32 * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
34 static void sa1100_mask_irq(struct irq_data
*d
)
38 reg
= readl_relaxed(iobase
+ ICMR
);
39 reg
&= ~BIT(d
->hwirq
);
40 writel_relaxed(reg
, iobase
+ ICMR
);
43 static void sa1100_unmask_irq(struct irq_data
*d
)
47 reg
= readl_relaxed(iobase
+ ICMR
);
49 writel_relaxed(reg
, iobase
+ ICMR
);
52 static int sa1100_set_wake(struct irq_data
*d
, unsigned int on
)
54 return sa11x0_sc_set_wake(d
->hwirq
, on
);
57 static struct irq_chip sa1100_normal_chip
= {
59 .irq_ack
= sa1100_mask_irq
,
60 .irq_mask
= sa1100_mask_irq
,
61 .irq_unmask
= sa1100_unmask_irq
,
62 .irq_set_wake
= sa1100_set_wake
,
65 static int sa1100_normal_irqdomain_map(struct irq_domain
*d
,
66 unsigned int irq
, irq_hw_number_t hwirq
)
68 irq_set_chip_and_handler(irq
, &sa1100_normal_chip
,
74 static const struct irq_domain_ops sa1100_normal_irqdomain_ops
= {
75 .map
= sa1100_normal_irqdomain_map
,
76 .xlate
= irq_domain_xlate_onetwocell
,
79 static struct irq_domain
*sa1100_normal_irqdomain
;
81 static struct sa1100irq_state
{
88 static int sa1100irq_suspend(void)
90 struct sa1100irq_state
*st
= &sa1100irq_state
;
93 st
->icmr
= readl_relaxed(iobase
+ ICMR
);
94 st
->iclr
= readl_relaxed(iobase
+ ICLR
);
95 st
->iccr
= readl_relaxed(iobase
+ ICCR
);
98 * Disable all GPIO-based interrupts.
100 writel_relaxed(st
->icmr
& 0xfffff000, iobase
+ ICMR
);
105 static void sa1100irq_resume(void)
107 struct sa1100irq_state
*st
= &sa1100irq_state
;
110 writel_relaxed(st
->iccr
, iobase
+ ICCR
);
111 writel_relaxed(st
->iclr
, iobase
+ ICLR
);
113 writel_relaxed(st
->icmr
, iobase
+ ICMR
);
117 static struct syscore_ops sa1100irq_syscore_ops
= {
118 .suspend
= sa1100irq_suspend
,
119 .resume
= sa1100irq_resume
,
122 static int __init
sa1100irq_init_devicefs(void)
124 register_syscore_ops(&sa1100irq_syscore_ops
);
128 device_initcall(sa1100irq_init_devicefs
);
130 static asmlinkage
void __exception_irq_entry
131 sa1100_handle_irq(struct pt_regs
*regs
)
133 uint32_t icip
, icmr
, mask
;
136 icip
= readl_relaxed(iobase
+ ICIP
);
137 icmr
= readl_relaxed(iobase
+ ICMR
);
143 handle_domain_irq(sa1100_normal_irqdomain
,
144 ffs(mask
) - 1, regs
);
148 void __init
sa11x0_init_irq_nodt(int irq_start
, resource_size_t io_start
)
150 iobase
= ioremap(io_start
, SZ_64K
);
151 if (WARN_ON(!iobase
))
154 /* disable all IRQs */
155 writel_relaxed(0, iobase
+ ICMR
);
157 /* all IRQs are IRQ, not FIQ */
158 writel_relaxed(0, iobase
+ ICLR
);
161 * Whatever the doc says, this has to be set for the wait-on-irq
162 * instruction to work... on a SA1100 rev 9 at least.
164 writel_relaxed(1, iobase
+ ICCR
);
166 sa1100_normal_irqdomain
= irq_domain_add_simple(NULL
,
168 &sa1100_normal_irqdomain_ops
, NULL
);
170 set_handle_irq(sa1100_handle_irq
);