^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2005-2017 Andes Technology Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/irqchip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <nds32_intrinsic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) unsigned long wake_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static void ativic32_ack_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) __nds32__mtsr_dsb(BIT(data->hwirq), NDS32_SR_INT_PEND2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void ativic32_mask_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) __nds32__mtsr_dsb(int_mask2 & (~(BIT(data->hwirq))), NDS32_SR_INT_MASK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static void ativic32_unmask_irq(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) __nds32__mtsr_dsb(int_mask2 | (BIT(data->hwirq)), NDS32_SR_INT_MASK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int nointc_set_wake(struct irq_data *data, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned long int_mask = __nds32__mfsr(NDS32_SR_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static unsigned long irq_orig_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 bit = 1 << data->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (int_mask & bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __assign_bit(data->hwirq, &irq_orig_bit, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __assign_bit(data->hwirq, &irq_orig_bit, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __assign_bit(data->hwirq, &int_mask, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __assign_bit(data->hwirq, &wake_mask, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (!(irq_orig_bit & bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) __assign_bit(data->hwirq, &int_mask, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) __assign_bit(data->hwirq, &wake_mask, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __assign_bit(data->hwirq, &irq_orig_bit, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __nds32__mtsr_dsb(int_mask, NDS32_SR_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct irq_chip ativic32_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .name = "ativic32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .irq_ack = ativic32_ack_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .irq_mask = ativic32_mask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .irq_unmask = ativic32_unmask_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .irq_set_wake = nointc_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct irq_domain *root_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int ativic32_irq_domain_map(struct irq_domain *id, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned long int_trigger_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct irq_data *irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int_trigger_type = __nds32__mfsr(NDS32_SR_INT_TRIGGER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) irq_data = irq_get_irq_data(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!irq_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (int_trigger_type & (BIT(hw))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) irq_set_chip_and_handler(virq, &ativic32_chip, handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) type = IRQ_TYPE_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) irq_set_chip_and_handler(virq, &ativic32_chip, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) type = IRQ_TYPE_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) irqd_set_trigger_type(irq_data, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const struct irq_domain_ops ativic32_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .map = ativic32_irq_domain_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .xlate = irq_domain_xlate_onecell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static irq_hw_number_t get_intr_src(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return ((__nds32__mfsr(NDS32_SR_ITYPE) & ITYPE_mskVECTOR) >> ITYPE_offVECTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) - NDS32_VECTOR_offINTERRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) asmlinkage void asm_do_IRQ(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) irq_hw_number_t hwirq = get_intr_src();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) handle_domain_irq(root_domain, hwirq, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int __init ativic32_init_irq(struct device_node *node, struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long int_vec_base, nivic, nr_ints;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (WARN(parent, "non-root ativic32 are not supported"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int_vec_base = __nds32__mfsr(NDS32_SR_IVB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) panic("Unable to use atcivic32 for this cpu.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (nivic >= ARRAY_SIZE(nivic_map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) panic("The number of input for ativic32 is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) nr_ints = nivic_map[nivic];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) root_domain = irq_domain_add_linear(node, nr_ints,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) &ativic32_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!root_domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) panic("%s: unable to create IRQ domain\n", node->full_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) IRQCHIP_DECLARE(ativic32, "andestech,ativic32", ativic32_init_irq);