^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) 2018 Hangzhou C-SKY Microsystems co.,ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/of.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/module.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 <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define INTC_IRQS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define CK_INTC_ICR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CK_INTC_PEN31_00 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CK_INTC_PEN63_32 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define CK_INTC_NEN31_00 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define CK_INTC_NEN63_32 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CK_INTC_SOURCE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CK_INTC_DUAL_BASE 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define GX_INTC_PEN31_00 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define GX_INTC_PEN63_32 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define GX_INTC_NEN31_00 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define GX_INTC_NEN63_32 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define GX_INTC_NMASK31_00 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define GX_INTC_NMASK63_32 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define GX_INTC_SOURCE 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static struct irq_domain *root_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int nr_irq = INTC_IRQS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * When controller support pulse signal, the PEN_reg will hold on signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * without software trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * So, to support pulse signal we need to clear IFR_reg and the address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * IFR_offset is NEN_offset - 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static void irq_ck_mask_set_bit(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct irq_chip_type *ct = irq_data_get_chip_type(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned long ifr = ct->regs.mask - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u32 mask = d->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) irq_gc_lock(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *ct->mask_cache |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) irq_reg_writel(gc, irq_reg_readl(gc, ifr) & ~mask, ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) irq_gc_unlock(gc);
^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 void __init ck_set_gc(struct device_node *node, void __iomem *reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u32 mask_reg, u32 irq_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct irq_chip_generic *gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) gc = irq_get_domain_generic_chip(root_domain, irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) gc->reg_base = reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) gc->chip_types[0].regs.mask = mask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (of_find_property(node, "csky,support-pulse-signal", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) gc->chip_types[0].chip.irq_unmask = irq_ck_mask_set_bit;
^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) static inline u32 build_channel_val(u32 idx, u32 magic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u32 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Set the same index for each channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) res = idx | (idx << 8) | (idx << 16) | (idx << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Set the channel magic number in descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * The magic is 0x00010203 for ck-intc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * The magic is 0x03020100 for gx6605s-intc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return res | magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline void setup_irq_channel(u32 magic, void __iomem *reg_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Setup 64 channel slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) for (i = 0; i < INTC_IRQS; i += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) writel(build_channel_val(i, magic), reg_addr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ck_intc_init_comm(struct device_node *node, struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) pr_err("C-SKY Intc not a root irq controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) reg_base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!reg_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) pr_err("C-SKY Intc unable to map: %p.\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) root_domain = irq_domain_add_linear(node, nr_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) &irq_generic_chip_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!root_domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) pr_err("C-SKY Intc irq_domain_add failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret = irq_alloc_domain_generic_chips(root_domain, 32, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "csky_intc", handle_level_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pr_err("C-SKY Intc irq_alloc_gc failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static inline bool handle_irq_perbit(struct pt_regs *regs, u32 hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 irq_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (hwirq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) handle_domain_irq(root_domain, irq_base + __fls(hwirq), regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* gx6605s 64 irqs interrupt controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void gx_irq_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = handle_irq_perbit(regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) readl(reg_base + GX_INTC_PEN63_32), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ret = handle_irq_perbit(regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) readl(reg_base + GX_INTC_PEN31_00), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) gx_intc_init(struct device_node *node, struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ret = ck_intc_init_comm(node, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * Initial enable reg to disable all interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) writel(0x0, reg_base + GX_INTC_NEN31_00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) writel(0x0, reg_base + GX_INTC_NEN63_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * Initial mask reg with all unmasked, because we only use enalbe reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) writel(0x0, reg_base + GX_INTC_NMASK31_00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) writel(0x0, reg_base + GX_INTC_NMASK63_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) setup_irq_channel(0x03020100, reg_base + GX_INTC_SOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ck_set_gc(node, reg_base, GX_INTC_NEN31_00, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ck_set_gc(node, reg_base, GX_INTC_NEN63_32, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) set_handle_irq(gx_irq_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) IRQCHIP_DECLARE(csky_gx6605s_intc, "csky,gx6605s-intc", gx_intc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * C-SKY simple 64 irqs interrupt controller, dual-together could support 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * irqs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void ck_irq_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) void __iomem *reg_pen_lo = reg_base + CK_INTC_PEN31_00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void __iomem *reg_pen_hi = reg_base + CK_INTC_PEN63_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* handle 0 - 63 irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = handle_irq_perbit(regs, readl(reg_pen_hi), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = handle_irq_perbit(regs, readl(reg_pen_lo), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (nr_irq == INTC_IRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* handle 64 - 127 irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = handle_irq_perbit(regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) readl(reg_pen_hi + CK_INTC_DUAL_BASE), 96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = handle_irq_perbit(regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) readl(reg_pen_lo + CK_INTC_DUAL_BASE), 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ck_intc_init(struct device_node *node, struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = ck_intc_init_comm(node, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Initial enable reg to disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) writel(0, reg_base + CK_INTC_NEN31_00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) writel(0, reg_base + CK_INTC_NEN63_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* Enable irq intc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) writel(BIT(31), reg_base + CK_INTC_ICR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ck_set_gc(node, reg_base, CK_INTC_NEN31_00, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ck_set_gc(node, reg_base, CK_INTC_NEN63_32, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) setup_irq_channel(0x00010203, reg_base + CK_INTC_SOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) set_handle_irq(ck_irq_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) IRQCHIP_DECLARE(ck_intc, "csky,apb-intc", ck_intc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ck_dual_intc_init(struct device_node *node, struct device_node *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* dual-apb-intc up to 128 irq sources*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) nr_irq = INTC_IRQS * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = ck_intc_init(node, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Initial enable reg to disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) writel(0, reg_base + CK_INTC_NEN31_00 + CK_INTC_DUAL_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) writel(0, reg_base + CK_INTC_NEN63_32 + CK_INTC_DUAL_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN31_00, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ck_set_gc(node, reg_base + CK_INTC_DUAL_BASE, CK_INTC_NEN63_32, 96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) setup_irq_channel(0x00010203,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) reg_base + CK_INTC_SOURCE + CK_INTC_DUAL_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) IRQCHIP_DECLARE(ck_dual_intc, "csky,dual-apb-intc", ck_dual_intc_init);