^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * S3C24XX IRQ handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2003-2004 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.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 <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/irqchip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/irqchip/chained_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/exception.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/mach/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "regs-irq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "regs-gpio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "cpu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "regs-irqtype.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define S3C_IRQTYPE_NONE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define S3C_IRQTYPE_EINT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define S3C_IRQTYPE_EDGE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define S3C_IRQTYPE_LEVEL 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct s3c_irq_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned long parent_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* data gets filled during init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct s3c_irq_intc *intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long sub_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct s3c_irq_intc *sub_intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Structure holding the controller data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @reg_pending register holding pending irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @reg_intpnd special register intpnd in main intc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @reg_mask mask register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @domain irq_domain of the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @parent parent controller for ext and sub irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @irqs irq-data, always s3c_irq_data[32]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct s3c_irq_intc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) void __iomem *reg_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void __iomem *reg_intpnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) void __iomem *reg_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct s3c_irq_intc *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct s3c_irq_data *irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Array holding pointers to the global controller structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * [0] ... main_intc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * [1] ... sub_intc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * [2] ... main_intc2 on s3c2416
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static struct s3c_irq_intc *s3c_intc[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void s3c_irq_mask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct s3c_irq_intc *intc = irq_data->intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct s3c_irq_intc *parent_intc = intc->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct s3c_irq_data *parent_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned int irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mask = readl_relaxed(intc->reg_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mask |= (1UL << irq_data->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) writel_relaxed(mask, intc->reg_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (parent_intc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) parent_data = &parent_intc->irqs[irq_data->parent_irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* check to see if we need to mask the parent IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * The parent_irq is always in main_intc, so the hwirq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * for find_mapping does not need an offset in any case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) irqno = irq_find_mapping(parent_intc->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) irq_data->parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) s3c_irq_mask(irq_get_irq_data(irqno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^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) static void s3c_irq_unmask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct s3c_irq_intc *intc = irq_data->intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct s3c_irq_intc *parent_intc = intc->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mask = readl_relaxed(intc->reg_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mask &= ~(1UL << irq_data->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) writel_relaxed(mask, intc->reg_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (parent_intc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) irqno = irq_find_mapping(parent_intc->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) irq_data->parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) s3c_irq_unmask(irq_get_irq_data(irqno));
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline void s3c_irq_ack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct s3c_irq_intc *intc = irq_data->intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long bitval = 1UL << irq_data->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) writel_relaxed(bitval, intc->reg_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (intc->reg_intpnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) writel_relaxed(bitval, intc->reg_intpnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int s3c_irq_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case IRQ_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) irq_set_handler(data->irq, handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) irq_set_handler(data->irq, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pr_err("No such irq type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int s3c_irqext_type_set(void __iomem *gpcon_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void __iomem *extint_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned long gpcon_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long extint_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned long newvalue = 0, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Set the GPIO to external interrupt mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) value = readl_relaxed(gpcon_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) writel_relaxed(value, gpcon_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Set the external interrupt to pointed trigger type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) switch (type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case IRQ_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_warn("No edge setting!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) newvalue = S3C2410_EXTINT_RISEEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) newvalue = S3C2410_EXTINT_FALLEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) newvalue = S3C2410_EXTINT_BOTHEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) newvalue = S3C2410_EXTINT_LOWLEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) newvalue = S3C2410_EXTINT_HILEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pr_err("No such irq type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) value = readl_relaxed(extint_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) writel_relaxed(value, extint_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int s3c_irqext_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) void __iomem *extint_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) void __iomem *gpcon_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned long gpcon_offset, extint_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) gpcon_reg = S3C2410_GPFCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) extint_reg = S3C24XX_EXTINT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) gpcon_offset = (data->hwirq) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) extint_offset = (data->hwirq) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) gpcon_reg = S3C2410_GPGCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) extint_reg = S3C24XX_EXTINT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) gpcon_offset = (data->hwirq - 8) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) extint_offset = (data->hwirq - 8) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) gpcon_reg = S3C2410_GPGCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) extint_reg = S3C24XX_EXTINT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) gpcon_offset = (data->hwirq - 8) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) extint_offset = (data->hwirq - 16) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) extint_offset, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void __iomem *extint_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void __iomem *gpcon_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned long gpcon_offset, extint_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (data->hwirq <= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) gpcon_reg = S3C2410_GPFCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) extint_reg = S3C24XX_EXTINT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) gpcon_offset = (data->hwirq) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) extint_offset = (data->hwirq) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) extint_offset, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static struct irq_chip s3c_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .name = "s3c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .irq_ack = s3c_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .irq_mask = s3c_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .irq_unmask = s3c_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .irq_set_type = s3c_irq_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .irq_set_wake = s3c_irq_wake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static struct irq_chip s3c_irq_level_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .name = "s3c-level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .irq_mask = s3c_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .irq_unmask = s3c_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .irq_ack = s3c_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .irq_set_type = s3c_irq_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static struct irq_chip s3c_irqext_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .name = "s3c-ext",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .irq_mask = s3c_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .irq_unmask = s3c_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .irq_ack = s3c_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .irq_set_type = s3c_irqext_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .irq_set_wake = s3c_irqext_wake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static struct irq_chip s3c_irq_eint0t4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .name = "s3c-ext0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .irq_ack = s3c_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .irq_mask = s3c_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .irq_unmask = s3c_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .irq_set_wake = s3c_irq_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .irq_set_type = s3c_irqext0_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void s3c_irq_demux(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct irq_chip *chip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct s3c_irq_intc *intc = irq_data->intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned int n, offset, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned long src, msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* we're using individual domains for the non-dt case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * and one big domain for the dt case where the subintc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * starts at hwirq number 32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) offset = irq_domain_get_of_node(intc->domain) ? 32 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) chained_irq_enter(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) src = readl_relaxed(sub_intc->reg_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) msk = readl_relaxed(sub_intc->reg_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) src &= ~msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) src &= irq_data->sub_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) while (src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) n = __ffs(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) src &= ~(1 << n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) irq = irq_find_mapping(sub_intc->domain, offset + n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) chained_irq_exit(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct pt_regs *regs, int intc_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int pnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) pnd = readl_relaxed(intc->reg_intpnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!pnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* non-dt machines use individual domains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!irq_domain_get_of_node(intc->domain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) intc_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* We have a problem that the INTOFFSET register does not always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * show one interrupt. Occasionally we get two interrupts through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * the prioritiser, and this causes the INTOFFSET register to show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * what looks like the logical-or of the two interrupt numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Thanks to Klaus, Shannon, et al for helping to debug this problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) offset = readl_relaxed(intc->reg_intpnd + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Find the bit manually, when the offset is wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * The pending register only ever contains the one bit of the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * interrupt to handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!(pnd & (1 << offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) offset = __ffs(pnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) handle_domain_irq(intc->domain, intc_offset + offset, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * For platform based machines, neither ERR nor NULL can happen here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * s3c_intc[0] = s3c24xx_init_intc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * If this fails, the next calls to s3c24xx_init_intc() won't be executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * For DT machine, s3c_init_intc_of() could set the IRQ handler without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * such code path, so again the s3c_intc[0] will have a valid pointer if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * set_handle_irq() is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!IS_ERR_OR_NULL(s3c_intc[2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * s3c24xx_set_fiq - set the FIQ routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * @irq: IRQ number to route to FIQ on processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @ack_ptr: pointer to a location for storing the bit mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * @on is true, the @irq is checked to see if it can be routed and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * interrupt controller updated to route the IRQ. If @on is false, the FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * routing is cleared, regardless of which @irq is specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * returns the mask value for the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int s3c24xx_set_fiq(unsigned int irq, u32 *ack_ptr, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u32 intmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) unsigned offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) offs = irq - FIQ_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (offs > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) intmod = 1 << offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) intmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ack_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) *ack_ptr = intmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) writel_relaxed(intmod, S3C2410_INTMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return intmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct s3c_irq_intc *intc = h->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct s3c_irq_data *irq_data = &intc->irqs[hw];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct s3c_irq_intc *parent_intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct s3c_irq_data *parent_irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* attach controller pointer to irq_data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) irq_data->intc = intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) irq_data->offset = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) parent_intc = intc->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* set handler and flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) switch (irq_data->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case S3C_IRQTYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case S3C_IRQTYPE_EINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* On the S3C2412, the EINT0to3 have a parent irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * but need the s3c_irq_eint0t4 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) irq_set_chip_and_handler(virq, &s3c_irqext_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case S3C_IRQTYPE_EDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) irq_set_chip_and_handler(virq, &s3c_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case S3C_IRQTYPE_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (parent_intc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) irq_set_chip_and_handler(virq, &s3c_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) irq_set_chip_data(virq, irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (irq_data->parent_irq > 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) irq_data->parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) parent_irq_data->sub_intc = intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) parent_irq_data->sub_bits |= (1UL << hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* attach the demuxer to the parent irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) irqno = irq_find_mapping(parent_intc->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) irq_data->parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!irqno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) irq_data->parent_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) irq_set_chained_handler(irqno, s3c_irq_demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static const struct irq_domain_ops s3c24xx_irq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .map = s3c24xx_irq_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .xlate = irq_domain_xlate_twocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) void __iomem *reg_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long pend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned long last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* if intpnd is set, read the next pending irq from there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) last = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) pend = readl_relaxed(reg_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (pend == 0 || pend == last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) writel_relaxed(pend, intc->reg_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (intc->reg_intpnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) writel_relaxed(pend, intc->reg_intpnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pr_info("irq: clearing pending status %08x\n", (int)pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) last = pend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct s3c_irq_data *irq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct s3c_irq_intc *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned long address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct s3c_irq_intc *intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) void __iomem *base = (void *)0xf6000000; /* static mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int irq_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!intc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) intc->irqs = irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) intc->parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* select the correct data for the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * Need to hard code the irq num start and offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * to preserve the static mapping for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) switch (address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case 0x4a000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) pr_debug("irq: found main intc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) intc->reg_pending = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) intc->reg_mask = base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) intc->reg_intpnd = base + 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) irq_num = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) irq_start = S3C2410_IRQ(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case 0x4a000018:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) pr_debug("irq: found subintc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) intc->reg_pending = base + 0x18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) intc->reg_mask = base + 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) irq_num = 29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) irq_start = S3C2410_IRQSUB(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case 0x4a000040:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) pr_debug("irq: found intc2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) intc->reg_pending = base + 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) intc->reg_mask = base + 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) intc->reg_intpnd = base + 0x50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) irq_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) irq_start = S3C2416_IRQ(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case 0x560000a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) pr_debug("irq: found eintc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) base = (void *)0xfd000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) intc->reg_mask = base + 0xa4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) intc->reg_pending = base + 0xa8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) irq_num = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) irq_start = S3C2410_IRQ(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pr_err("irq: unsupported controller address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* now that all the data is complete, init the irq-domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) s3c24xx_clear_intc(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 0, &s3c24xx_irq_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!intc->domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pr_err("irq: could not create irq-domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) set_handle_irq(s3c24xx_handle_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) kfree(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static struct s3c_irq_data __maybe_unused init_eint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) #ifdef CONFIG_CPU_S3C2410
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static struct s3c_irq_data init_s3c2410base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static struct s3c_irq_data init_s3c2410subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) void __init s3c2410_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) #ifdef CONFIG_CPU_S3C2412
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static struct s3c_irq_data init_s3c2412base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static struct s3c_irq_data init_s3c2412eint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static struct s3c_irq_data init_s3c2412subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) { .type = S3C_IRQTYPE_NONE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) { .type = S3C_IRQTYPE_NONE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) void __init s3c2412_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pr_info("S3C2412: IRQ Support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) #ifdef CONFIG_CPU_S3C2416
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static struct s3c_irq_data init_s3c2416base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) { .type = S3C_IRQTYPE_NONE, }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) { .type = S3C_IRQTYPE_NONE, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static struct s3c_irq_data init_s3c2416subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static struct s3c_irq_data init_s3c2416_second[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) { .type = S3C_IRQTYPE_EDGE }, /* 2D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) void __init s3c2416_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) pr_info("S3C2416: IRQ Support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) NULL, 0x4a000040);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) #ifdef CONFIG_CPU_S3C2440
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static struct s3c_irq_data init_s3c2440base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static struct s3c_irq_data init_s3c2440subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) void __init s3c2440_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) pr_info("S3C2440: IRQ Support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) #ifdef CONFIG_CPU_S3C2442
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static struct s3c_irq_data init_s3c2442base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static struct s3c_irq_data init_s3c2442subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) void __init s3c2442_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) pr_info("S3C2442: IRQ Support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2442subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) #ifdef CONFIG_CPU_S3C2443
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static struct s3c_irq_data init_s3c2443base[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static struct s3c_irq_data init_s3c2443subint[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) { .type = S3C_IRQTYPE_NONE }, /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) void __init s3c2443_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) pr_info("S3C2443: IRQ Support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #ifdef CONFIG_FIQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) init_FIQ(FIQ_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 0x4a000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (IS_ERR(s3c_intc[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) pr_err("irq: could not create main interrupt controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2443subint[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) s3c_intc[0], 0x4a000018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) unsigned int ctrl_num = hw / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) unsigned int intc_hw = hw % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct s3c_irq_intc *intc = s3c_intc[ctrl_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct s3c_irq_intc *parent_intc = intc->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct s3c_irq_data *irq_data = &intc->irqs[intc_hw];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* attach controller pointer to irq_data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) irq_data->intc = intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) irq_data->offset = intc_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (!parent_intc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) irq_set_chip_data(virq, irq_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* Translate our of irq notation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * format: <ctrl_num ctrl_irq parent_irq type>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) const u32 *intspec, unsigned int intsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) irq_hw_number_t *out_hwirq, unsigned int *out_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct s3c_irq_intc *intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) struct s3c_irq_intc *parent_intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) struct s3c_irq_data *irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct s3c_irq_data *parent_irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) int irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (WARN_ON(intsize < 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (intspec[0] > 2 || !s3c_intc[intspec[0]]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) pr_err("controller number %d invalid\n", intspec[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) intc = s3c_intc[intspec[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) *out_hwirq = intspec[0] * 32 + intspec[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) parent_intc = intc->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (parent_intc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) irq_data = &intc->irqs[intspec[2]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) irq_data->parent_irq = intspec[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) parent_irq_data->sub_intc = intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) parent_irq_data->sub_bits |= (1UL << intspec[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* parent_intc is always s3c_intc[0], so no offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) irqno = irq_create_mapping(parent_intc->domain, intspec[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (irqno < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) pr_err("irq: could not map parent interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return irqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) irq_set_chained_handler(irqno, s3c_irq_demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static const struct irq_domain_ops s3c24xx_irq_ops_of = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) .map = s3c24xx_irq_map_of,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .xlate = s3c24xx_irq_xlate_of,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct s3c24xx_irq_of_ctrl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct s3c_irq_intc **handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct s3c_irq_intc **parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct irq_domain_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static int __init s3c_init_intc_of(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct device_node *interrupt_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct s3c_irq_intc *intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct s3c24xx_irq_of_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) reg_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (!reg_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) pr_err("irq-s3c24xx: could not map irq registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) domain = irq_domain_add_linear(np, num_ctrl * 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) &s3c24xx_irq_ops_of, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (!domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) pr_err("irq: could not create irq-domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) for (i = 0; i < num_ctrl; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ctrl = &s3c_ctrl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) pr_debug("irq: found controller %s\n", ctrl->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (!intc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) intc->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (!intc->irqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) kfree(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ctrl->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) intc->reg_pending = reg_base + ctrl->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) intc->reg_mask = reg_base + ctrl->offset + 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (*(ctrl->parent)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) intc->parent = *(ctrl->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) pr_warn("irq: parent of %s missing\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ctrl->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) kfree(intc->irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) kfree(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) intc->reg_pending = reg_base + ctrl->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) intc->reg_mask = reg_base + ctrl->offset + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) s3c24xx_clear_intc(intc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) s3c_intc[i] = intc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) set_handle_irq(s3c24xx_handle_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .name = "intc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .name = "subintc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .parent = &s3c_intc[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) int __init s3c2410_init_intc_of(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct device_node *interrupt_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return s3c_init_intc_of(np, interrupt_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .name = "intc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .name = "subintc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .parent = &s3c_intc[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .name = "intc2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) .offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) int __init s3c2416_init_intc_of(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) struct device_node *interrupt_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return s3c_init_intc_of(np, interrupt_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) #endif