1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
6 #include <linux/of_irq.h>
7 #include <linux/of_address.h>
8 #include <linux/interrupt.h>
9 #include <linux/irqdomain.h>
10 #include <linux/irqchip.h>
11 #include <nds32_intrinsic.h>
13 unsigned long wake_mask
;
15 static void ativic32_ack_irq(struct irq_data
*data
)
17 __nds32__mtsr_dsb(BIT(data
->hwirq
), NDS32_SR_INT_PEND2
);
20 static void ativic32_mask_irq(struct irq_data
*data
)
22 unsigned long int_mask2
= __nds32__mfsr(NDS32_SR_INT_MASK2
);
23 __nds32__mtsr_dsb(int_mask2
& (~(BIT(data
->hwirq
))), NDS32_SR_INT_MASK2
);
26 static void ativic32_unmask_irq(struct irq_data
*data
)
28 unsigned long int_mask2
= __nds32__mfsr(NDS32_SR_INT_MASK2
);
29 __nds32__mtsr_dsb(int_mask2
| (BIT(data
->hwirq
)), NDS32_SR_INT_MASK2
);
32 static int nointc_set_wake(struct irq_data
*data
, unsigned int on
)
34 unsigned long int_mask
= __nds32__mfsr(NDS32_SR_INT_MASK
);
35 static unsigned long irq_orig_bit
;
36 u32 bit
= 1 << data
->hwirq
;
40 __assign_bit(data
->hwirq
, &irq_orig_bit
, true);
42 __assign_bit(data
->hwirq
, &irq_orig_bit
, false);
44 __assign_bit(data
->hwirq
, &int_mask
, true);
45 __assign_bit(data
->hwirq
, &wake_mask
, true);
48 if (!(irq_orig_bit
& bit
))
49 __assign_bit(data
->hwirq
, &int_mask
, false);
51 __assign_bit(data
->hwirq
, &wake_mask
, false);
52 __assign_bit(data
->hwirq
, &irq_orig_bit
, false);
55 __nds32__mtsr_dsb(int_mask
, NDS32_SR_INT_MASK
);
60 static struct irq_chip ativic32_chip
= {
62 .irq_ack
= ativic32_ack_irq
,
63 .irq_mask
= ativic32_mask_irq
,
64 .irq_unmask
= ativic32_unmask_irq
,
65 .irq_set_wake
= nointc_set_wake
,
68 static unsigned int __initdata nivic_map
[6] = { 6, 2, 10, 16, 24, 32 };
70 static struct irq_domain
*root_domain
;
71 static int ativic32_irq_domain_map(struct irq_domain
*id
, unsigned int virq
,
75 unsigned long int_trigger_type
;
77 struct irq_data
*irq_data
;
78 int_trigger_type
= __nds32__mfsr(NDS32_SR_INT_TRIGGER
);
79 irq_data
= irq_get_irq_data(virq
);
83 if (int_trigger_type
& (BIT(hw
))) {
84 irq_set_chip_and_handler(virq
, &ativic32_chip
, handle_edge_irq
);
85 type
= IRQ_TYPE_EDGE_RISING
;
87 irq_set_chip_and_handler(virq
, &ativic32_chip
, handle_level_irq
);
88 type
= IRQ_TYPE_LEVEL_HIGH
;
91 irqd_set_trigger_type(irq_data
, type
);
95 static struct irq_domain_ops ativic32_ops
= {
96 .map
= ativic32_irq_domain_map
,
97 .xlate
= irq_domain_xlate_onecell
100 static irq_hw_number_t
get_intr_src(void)
102 return ((__nds32__mfsr(NDS32_SR_ITYPE
) & ITYPE_mskVECTOR
) >> ITYPE_offVECTOR
)
103 - NDS32_VECTOR_offINTERRUPT
;
106 asmlinkage
void asm_do_IRQ(struct pt_regs
*regs
)
108 irq_hw_number_t hwirq
= get_intr_src();
109 handle_domain_irq(root_domain
, hwirq
, regs
);
112 int __init
ativic32_init_irq(struct device_node
*node
, struct device_node
*parent
)
114 unsigned long int_vec_base
, nivic
, nr_ints
;
116 if (WARN(parent
, "non-root ativic32 are not supported"))
119 int_vec_base
= __nds32__mfsr(NDS32_SR_IVB
);
121 if (((int_vec_base
& IVB_mskIVIC_VER
) >> IVB_offIVIC_VER
) == 0)
122 panic("Unable to use atcivic32 for this cpu.\n");
124 nivic
= (int_vec_base
& IVB_mskNIVIC
) >> IVB_offNIVIC
;
125 if (nivic
>= ARRAY_SIZE(nivic_map
))
126 panic("The number of input for ativic32 is not supported.\n");
128 nr_ints
= nivic_map
[nivic
];
130 root_domain
= irq_domain_add_linear(node
, nr_ints
,
131 &ativic32_ops
, NULL
);
134 panic("%s: unable to create IRQ domain\n", node
->full_name
);
138 IRQCHIP_DECLARE(ativic32
, "andestech,ativic32", ativic32_init_irq
);