Skip to content

Commit 922ac17

Browse files
Andre-ARMKAGA-KOKO
authored andcommitted
irqchip/sunxi-nmi: Support Allwinner A523 NMI controller
The NMI controller in the Allwinner A523 is almost compatible to the previous versions of this IP, but requires the extra bit 31 to be set in the enable register to actually report the NMI. Add a mask to allow such an enable bit to be specified, and add this to the per-SoC data structure. As this struct was just for different register offsets so far, it was consequently named "reg_offs", which is now no longer applicable, so rename this to the more generic "data" on the way, and move the existing offsets into a struct of its own. Also add the respective Allwinner A523 compatible string, and set bit 31 in its enable mask, to add support for this SoC. [ tglx: Mop up some coding style along with it ] Signed-off-by: Andre Przywara <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent be494a3 commit 922ac17

File tree

1 file changed

+50
-35
lines changed

1 file changed

+50
-35
lines changed

drivers/irqchip/irq-sunxi-nmi.c

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,41 @@ enum {
4848
SUNXI_SRC_TYPE_EDGE_RISING,
4949
};
5050

51-
struct sunxi_sc_nmi_reg_offs {
52-
u32 ctrl;
53-
u32 pend;
54-
u32 enable;
51+
struct sunxi_sc_nmi_data {
52+
struct {
53+
u32 ctrl;
54+
u32 pend;
55+
u32 enable;
56+
} reg_offs;
57+
u32 enable_val;
5558
};
5659

57-
static const struct sunxi_sc_nmi_reg_offs sun6i_reg_offs __initconst = {
58-
.ctrl = SUN6I_NMI_CTRL,
59-
.pend = SUN6I_NMI_PENDING,
60-
.enable = SUN6I_NMI_ENABLE,
60+
static const struct sunxi_sc_nmi_data sun6i_data __initconst = {
61+
.reg_offs.ctrl = SUN6I_NMI_CTRL,
62+
.reg_offs.pend = SUN6I_NMI_PENDING,
63+
.reg_offs.enable = SUN6I_NMI_ENABLE,
6164
};
6265

63-
static const struct sunxi_sc_nmi_reg_offs sun7i_reg_offs __initconst = {
64-
.ctrl = SUN7I_NMI_CTRL,
65-
.pend = SUN7I_NMI_PENDING,
66-
.enable = SUN7I_NMI_ENABLE,
66+
static const struct sunxi_sc_nmi_data sun7i_data __initconst = {
67+
.reg_offs.ctrl = SUN7I_NMI_CTRL,
68+
.reg_offs.pend = SUN7I_NMI_PENDING,
69+
.reg_offs.enable = SUN7I_NMI_ENABLE,
6770
};
6871

69-
static const struct sunxi_sc_nmi_reg_offs sun9i_reg_offs __initconst = {
70-
.ctrl = SUN9I_NMI_CTRL,
71-
.pend = SUN9I_NMI_PENDING,
72-
.enable = SUN9I_NMI_ENABLE,
72+
static const struct sunxi_sc_nmi_data sun9i_data __initconst = {
73+
.reg_offs.ctrl = SUN9I_NMI_CTRL,
74+
.reg_offs.pend = SUN9I_NMI_PENDING,
75+
.reg_offs.enable = SUN9I_NMI_ENABLE,
7376
};
7477

75-
static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
76-
u32 val)
78+
static const struct sunxi_sc_nmi_data sun55i_a523_data __initconst = {
79+
.reg_offs.ctrl = SUN9I_NMI_CTRL,
80+
.reg_offs.pend = SUN9I_NMI_PENDING,
81+
.reg_offs.enable = SUN9I_NMI_ENABLE,
82+
.enable_val = BIT(31),
83+
};
84+
85+
static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, u32 val)
7786
{
7887
irq_reg_writel(gc, val, off);
7988
}
@@ -143,15 +152,13 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
143152
}
144153

145154
static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
146-
const struct sunxi_sc_nmi_reg_offs *reg_offs)
155+
const struct sunxi_sc_nmi_data *data)
147156
{
148-
struct irq_domain *domain;
157+
unsigned int irq, clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
149158
struct irq_chip_generic *gc;
150-
unsigned int irq;
151-
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
159+
struct irq_domain *domain;
152160
int ret;
153161

154-
155162
domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL);
156163
if (!domain) {
157164
pr_err("Could not register interrupt domain.\n");
@@ -186,27 +193,28 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
186193
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
187194
gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit;
188195
gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
189-
gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED |
196+
gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED |
197+
IRQCHIP_EOI_IF_HANDLED |
190198
IRQCHIP_SKIP_SET_WAKE;
191-
gc->chip_types[0].regs.ack = reg_offs->pend;
192-
gc->chip_types[0].regs.mask = reg_offs->enable;
193-
gc->chip_types[0].regs.type = reg_offs->ctrl;
199+
gc->chip_types[0].regs.ack = data->reg_offs.pend;
200+
gc->chip_types[0].regs.mask = data->reg_offs.enable;
201+
gc->chip_types[0].regs.type = data->reg_offs.ctrl;
194202

195203
gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
196204
gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit;
197205
gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit;
198206
gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit;
199207
gc->chip_types[1].chip.irq_set_type = sunxi_sc_nmi_set_type;
200-
gc->chip_types[1].regs.ack = reg_offs->pend;
201-
gc->chip_types[1].regs.mask = reg_offs->enable;
202-
gc->chip_types[1].regs.type = reg_offs->ctrl;
208+
gc->chip_types[1].regs.ack = data->reg_offs.pend;
209+
gc->chip_types[1].regs.mask = data->reg_offs.enable;
210+
gc->chip_types[1].regs.type = data->reg_offs.ctrl;
203211
gc->chip_types[1].handler = handle_edge_irq;
204212

205213
/* Disable any active interrupts */
206-
sunxi_sc_nmi_write(gc, reg_offs->enable, 0);
214+
sunxi_sc_nmi_write(gc, data->reg_offs.enable, data->enable_val);
207215

208216
/* Clear any pending NMI interrupts */
209-
sunxi_sc_nmi_write(gc, reg_offs->pend, SUNXI_NMI_IRQ_BIT);
217+
sunxi_sc_nmi_write(gc, data->reg_offs.pend, SUNXI_NMI_IRQ_BIT);
210218

211219
irq_set_chained_handler_and_data(irq, sunxi_sc_nmi_handle_irq, domain);
212220

@@ -221,20 +229,27 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
221229
static int __init sun6i_sc_nmi_irq_init(struct device_node *node,
222230
struct device_node *parent)
223231
{
224-
return sunxi_sc_nmi_irq_init(node, &sun6i_reg_offs);
232+
return sunxi_sc_nmi_irq_init(node, &sun6i_data);
225233
}
226234
IRQCHIP_DECLARE(sun6i_sc_nmi, "allwinner,sun6i-a31-sc-nmi", sun6i_sc_nmi_irq_init);
227235

228236
static int __init sun7i_sc_nmi_irq_init(struct device_node *node,
229237
struct device_node *parent)
230238
{
231-
return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs);
239+
return sunxi_sc_nmi_irq_init(node, &sun7i_data);
232240
}
233241
IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init);
234242

235243
static int __init sun9i_nmi_irq_init(struct device_node *node,
236244
struct device_node *parent)
237245
{
238-
return sunxi_sc_nmi_irq_init(node, &sun9i_reg_offs);
246+
return sunxi_sc_nmi_irq_init(node, &sun9i_data);
239247
}
240248
IRQCHIP_DECLARE(sun9i_nmi, "allwinner,sun9i-a80-nmi", sun9i_nmi_irq_init);
249+
250+
static int __init sun55i_nmi_irq_init(struct device_node *node,
251+
struct device_node *parent)
252+
{
253+
return sunxi_sc_nmi_irq_init(node, &sun55i_a523_data);
254+
}
255+
IRQCHIP_DECLARE(sun55i_nmi, "allwinner,sun55i-a523-nmi", sun55i_nmi_irq_init);

0 commit comments

Comments
 (0)