Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2002 ARM Limited, All Rights Reserved.
0004  */
0005 
0006 #include <linux/interrupt.h>
0007 #include <linux/io.h>
0008 #include <linux/irq.h>
0009 #include <linux/irqchip/arm-gic.h>
0010 
0011 #include "irq-gic-common.h"
0012 
0013 static DEFINE_RAW_SPINLOCK(irq_controller_lock);
0014 
0015 void gic_enable_of_quirks(const struct device_node *np,
0016               const struct gic_quirk *quirks, void *data)
0017 {
0018     for (; quirks->desc; quirks++) {
0019         if (!of_device_is_compatible(np, quirks->compatible))
0020             continue;
0021         if (quirks->init(data))
0022             pr_info("GIC: enabling workaround for %s\n",
0023                 quirks->desc);
0024     }
0025 }
0026 
0027 void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
0028         void *data)
0029 {
0030     for (; quirks->desc; quirks++) {
0031         if (quirks->compatible)
0032             continue;
0033         if (quirks->iidr != (quirks->mask & iidr))
0034             continue;
0035         if (quirks->init(data))
0036             pr_info("GIC: enabling workaround for %s\n",
0037                 quirks->desc);
0038     }
0039 }
0040 
0041 int gic_configure_irq(unsigned int irq, unsigned int type,
0042                void __iomem *base, void (*sync_access)(void))
0043 {
0044     u32 confmask = 0x2 << ((irq % 16) * 2);
0045     u32 confoff = (irq / 16) * 4;
0046     u32 val, oldval;
0047     int ret = 0;
0048     unsigned long flags;
0049 
0050     /*
0051      * Read current configuration register, and insert the config
0052      * for "irq", depending on "type".
0053      */
0054     raw_spin_lock_irqsave(&irq_controller_lock, flags);
0055     val = oldval = readl_relaxed(base + confoff);
0056     if (type & IRQ_TYPE_LEVEL_MASK)
0057         val &= ~confmask;
0058     else if (type & IRQ_TYPE_EDGE_BOTH)
0059         val |= confmask;
0060 
0061     /* If the current configuration is the same, then we are done */
0062     if (val == oldval) {
0063         raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
0064         return 0;
0065     }
0066 
0067     /*
0068      * Write back the new configuration, and possibly re-enable
0069      * the interrupt. If we fail to write a new configuration for
0070      * an SPI then WARN and return an error. If we fail to write the
0071      * configuration for a PPI this is most likely because the GIC
0072      * does not allow us to set the configuration or we are in a
0073      * non-secure mode, and hence it may not be catastrophic.
0074      */
0075     writel_relaxed(val, base + confoff);
0076     if (readl_relaxed(base + confoff) != val)
0077         ret = -EINVAL;
0078 
0079     raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
0080 
0081     if (sync_access)
0082         sync_access();
0083 
0084     return ret;
0085 }
0086 
0087 void gic_dist_config(void __iomem *base, int gic_irqs,
0088              void (*sync_access)(void))
0089 {
0090     unsigned int i;
0091 
0092     /*
0093      * Set all global interrupts to be level triggered, active low.
0094      */
0095     for (i = 32; i < gic_irqs; i += 16)
0096         writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
0097                     base + GIC_DIST_CONFIG + i / 4);
0098 
0099     /*
0100      * Set priority on all global interrupts.
0101      */
0102     for (i = 32; i < gic_irqs; i += 4)
0103         writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
0104 
0105     /*
0106      * Deactivate and disable all SPIs. Leave the PPI and SGIs
0107      * alone as they are in the redistributor registers on GICv3.
0108      */
0109     for (i = 32; i < gic_irqs; i += 32) {
0110         writel_relaxed(GICD_INT_EN_CLR_X32,
0111                    base + GIC_DIST_ACTIVE_CLEAR + i / 8);
0112         writel_relaxed(GICD_INT_EN_CLR_X32,
0113                    base + GIC_DIST_ENABLE_CLEAR + i / 8);
0114     }
0115 
0116     if (sync_access)
0117         sync_access();
0118 }
0119 
0120 void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
0121 {
0122     int i;
0123 
0124     /*
0125      * Deal with the banked PPI and SGI interrupts - disable all
0126      * private interrupts. Make sure everything is deactivated.
0127      */
0128     for (i = 0; i < nr; i += 32) {
0129         writel_relaxed(GICD_INT_EN_CLR_X32,
0130                    base + GIC_DIST_ACTIVE_CLEAR + i / 8);
0131         writel_relaxed(GICD_INT_EN_CLR_X32,
0132                    base + GIC_DIST_ENABLE_CLEAR + i / 8);
0133     }
0134 
0135     /*
0136      * Set priority on PPI and SGI interrupts
0137      */
0138     for (i = 0; i < nr; i += 4)
0139         writel_relaxed(GICD_INT_DEF_PRI_X4,
0140                     base + GIC_DIST_PRI + i * 4 / 4);
0141 
0142     if (sync_access)
0143         sync_access();
0144 }