Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * irqchip for the IXP4xx interrupt controller
0004  * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
0005  *
0006  * Based on arch/arm/mach-ixp4xx/common.c
0007  * Copyright 2002 (C) Intel Corporation
0008  * Copyright 2003-2004 (C) MontaVista, Software, Inc.
0009  * Copyright (C) Deepak Saxena <dsaxena@plexity.net>
0010  */
0011 #include <linux/bitops.h>
0012 #include <linux/gpio/driver.h>
0013 #include <linux/irq.h>
0014 #include <linux/io.h>
0015 #include <linux/irqchip.h>
0016 #include <linux/irqdomain.h>
0017 #include <linux/of.h>
0018 #include <linux/of_address.h>
0019 #include <linux/of_irq.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/cpu.h>
0022 
0023 #include <asm/exception.h>
0024 #include <asm/mach/irq.h>
0025 
0026 #define IXP4XX_ICPR 0x00 /* Interrupt Status */
0027 #define IXP4XX_ICMR 0x04 /* Interrupt Enable */
0028 #define IXP4XX_ICLR 0x08 /* Interrupt IRQ/FIQ Select */
0029 #define IXP4XX_ICIP 0x0C /* IRQ Status */
0030 #define IXP4XX_ICFP 0x10 /* FIQ Status */
0031 #define IXP4XX_ICHR 0x14 /* Interrupt Priority */
0032 #define IXP4XX_ICIH 0x18 /* IRQ Highest Pri Int */
0033 #define IXP4XX_ICFH 0x1C /* FIQ Highest Pri Int */
0034 
0035 /* IXP43x and IXP46x-only */
0036 #define IXP4XX_ICPR2    0x20 /* Interrupt Status 2 */
0037 #define IXP4XX_ICMR2    0x24 /* Interrupt Enable 2 */
0038 #define IXP4XX_ICLR2    0x28 /* Interrupt IRQ/FIQ Select 2 */
0039 #define IXP4XX_ICIP2    0x2C /* IRQ Status */
0040 #define IXP4XX_ICFP2    0x30 /* FIQ Status */
0041 #define IXP4XX_ICEEN    0x34 /* Error High Pri Enable */
0042 
0043 /**
0044  * struct ixp4xx_irq - state container for the Faraday IRQ controller
0045  * @irqbase: IRQ controller memory base in virtual memory
0046  * @is_356: if this is an IXP43x, IXP45x or IX46x SoC (with 64 IRQs)
0047  * @irqchip: irqchip for this instance
0048  * @domain: IRQ domain for this instance
0049  */
0050 struct ixp4xx_irq {
0051     void __iomem *irqbase;
0052     bool is_356;
0053     struct irq_chip irqchip;
0054     struct irq_domain *domain;
0055 };
0056 
0057 /* Local static state container */
0058 static struct ixp4xx_irq ixirq;
0059 
0060 /* GPIO Clocks */
0061 #define IXP4XX_GPIO_CLK_0       14
0062 #define IXP4XX_GPIO_CLK_1       15
0063 
0064 static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
0065 {
0066     /* All are level active high (asserted) here */
0067     if (type != IRQ_TYPE_LEVEL_HIGH)
0068         return -EINVAL;
0069     return 0;
0070 }
0071 
0072 static void ixp4xx_irq_mask(struct irq_data *d)
0073 {
0074     struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
0075     u32 val;
0076 
0077     if (ixi->is_356 && d->hwirq >= 32) {
0078         val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
0079         val &= ~BIT(d->hwirq - 32);
0080         __raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
0081     } else {
0082         val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
0083         val &= ~BIT(d->hwirq);
0084         __raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
0085     }
0086 }
0087 
0088 /*
0089  * Level triggered interrupts on GPIO lines can only be cleared when the
0090  * interrupt condition disappears.
0091  */
0092 static void ixp4xx_irq_unmask(struct irq_data *d)
0093 {
0094     struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
0095     u32 val;
0096 
0097     if (ixi->is_356 && d->hwirq >= 32) {
0098         val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
0099         val |= BIT(d->hwirq - 32);
0100         __raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
0101     } else {
0102         val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
0103         val |= BIT(d->hwirq);
0104         __raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
0105     }
0106 }
0107 
0108 static asmlinkage void __exception_irq_entry
0109 ixp4xx_handle_irq(struct pt_regs *regs)
0110 {
0111     struct ixp4xx_irq *ixi = &ixirq;
0112     unsigned long status;
0113     int i;
0114 
0115     status = __raw_readl(ixi->irqbase + IXP4XX_ICIP);
0116     for_each_set_bit(i, &status, 32)
0117         generic_handle_domain_irq(ixi->domain, i);
0118 
0119     /*
0120      * IXP465/IXP435 has an upper IRQ status register
0121      */
0122     if (ixi->is_356) {
0123         status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2);
0124         for_each_set_bit(i, &status, 32)
0125             generic_handle_domain_irq(ixi->domain, i + 32);
0126     }
0127 }
0128 
0129 static int ixp4xx_irq_domain_translate(struct irq_domain *domain,
0130                        struct irq_fwspec *fwspec,
0131                        unsigned long *hwirq,
0132                        unsigned int *type)
0133 {
0134     /* We support standard DT translation */
0135     if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
0136         *hwirq = fwspec->param[0];
0137         *type = fwspec->param[1];
0138         return 0;
0139     }
0140 
0141     if (is_fwnode_irqchip(fwspec->fwnode)) {
0142         if (fwspec->param_count != 2)
0143             return -EINVAL;
0144         *hwirq = fwspec->param[0];
0145         *type = fwspec->param[1];
0146         WARN_ON(*type == IRQ_TYPE_NONE);
0147         return 0;
0148     }
0149 
0150     return -EINVAL;
0151 }
0152 
0153 static int ixp4xx_irq_domain_alloc(struct irq_domain *d,
0154                    unsigned int irq, unsigned int nr_irqs,
0155                    void *data)
0156 {
0157     struct ixp4xx_irq *ixi = d->host_data;
0158     irq_hw_number_t hwirq;
0159     unsigned int type = IRQ_TYPE_NONE;
0160     struct irq_fwspec *fwspec = data;
0161     int ret;
0162     int i;
0163 
0164     ret = ixp4xx_irq_domain_translate(d, fwspec, &hwirq, &type);
0165     if (ret)
0166         return ret;
0167 
0168     for (i = 0; i < nr_irqs; i++) {
0169         /*
0170          * TODO: after converting IXP4xx to only device tree, set
0171          * handle_bad_irq as default handler and assume all consumers
0172          * call .set_type() as this is provided in the second cell in
0173          * the device tree phandle.
0174          */
0175         irq_domain_set_info(d,
0176                     irq + i,
0177                     hwirq + i,
0178                     &ixi->irqchip,
0179                     ixi,
0180                     handle_level_irq,
0181                     NULL, NULL);
0182         irq_set_probe(irq + i);
0183     }
0184 
0185     return 0;
0186 }
0187 
0188 /*
0189  * This needs to be a hierarchical irqdomain to work well with the
0190  * GPIO irqchip (which is lower in the hierarchy)
0191  */
0192 static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
0193     .translate = ixp4xx_irq_domain_translate,
0194     .alloc = ixp4xx_irq_domain_alloc,
0195     .free = irq_domain_free_irqs_common,
0196 };
0197 
0198 /**
0199  * ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller
0200  * @ixi: State container
0201  * @irqbase: Virtual memory base for the interrupt controller
0202  * @fwnode: Corresponding fwnode abstraction for this controller
0203  * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
0204  */
0205 static int __init ixp4xx_irq_setup(struct ixp4xx_irq *ixi,
0206                    void __iomem *irqbase,
0207                    struct fwnode_handle *fwnode,
0208                    bool is_356)
0209 {
0210     int nr_irqs;
0211 
0212     ixi->irqbase = irqbase;
0213     ixi->is_356 = is_356;
0214 
0215     /* Route all sources to IRQ instead of FIQ */
0216     __raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR);
0217 
0218     /* Disable all interrupts */
0219     __raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR);
0220 
0221     if (is_356) {
0222         /* Route upper 32 sources to IRQ instead of FIQ */
0223         __raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR2);
0224 
0225         /* Disable upper 32 interrupts */
0226         __raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR2);
0227 
0228         nr_irqs = 64;
0229     } else {
0230         nr_irqs = 32;
0231     }
0232 
0233     ixi->irqchip.name = "IXP4xx";
0234     ixi->irqchip.irq_mask = ixp4xx_irq_mask;
0235     ixi->irqchip.irq_unmask = ixp4xx_irq_unmask;
0236     ixi->irqchip.irq_set_type = ixp4xx_set_irq_type;
0237 
0238     ixi->domain = irq_domain_create_linear(fwnode, nr_irqs,
0239                            &ixp4xx_irqdomain_ops,
0240                            ixi);
0241     if (!ixi->domain) {
0242         pr_crit("IXP4XX: can not add primary irqdomain\n");
0243         return -ENODEV;
0244     }
0245 
0246     set_handle_irq(ixp4xx_handle_irq);
0247 
0248     return 0;
0249 }
0250 
0251 static int __init ixp4xx_of_init_irq(struct device_node *np,
0252                      struct device_node *parent)
0253 {
0254     struct ixp4xx_irq *ixi = &ixirq;
0255     void __iomem *base;
0256     struct fwnode_handle *fwnode;
0257     bool is_356;
0258     int ret;
0259 
0260     base = of_iomap(np, 0);
0261     if (!base) {
0262         pr_crit("IXP4XX: could not ioremap interrupt controller\n");
0263         return -ENODEV;
0264     }
0265     fwnode = of_node_to_fwnode(np);
0266 
0267     /* These chip variants have 64 interrupts */
0268     is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") ||
0269         of_device_is_compatible(np, "intel,ixp45x-interrupt") ||
0270         of_device_is_compatible(np, "intel,ixp46x-interrupt");
0271 
0272     ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
0273     if (ret)
0274         pr_crit("IXP4XX: failed to set up irqchip\n");
0275 
0276     return ret;
0277 }
0278 IRQCHIP_DECLARE(ixp42x, "intel,ixp42x-interrupt",
0279         ixp4xx_of_init_irq);
0280 IRQCHIP_DECLARE(ixp43x, "intel,ixp43x-interrupt",
0281         ixp4xx_of_init_irq);
0282 IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt",
0283         ixp4xx_of_init_irq);
0284 IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt",
0285         ixp4xx_of_init_irq);