irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
authorMarc Zyngier <maz@kernel.org>
Tue, 16 Jul 2019 13:35:17 +0000 (14:35 +0100)
committerMarc Zyngier <maz@kernel.org>
Tue, 20 Aug 2019 09:04:09 +0000 (10:04 +0100)
gic_configure_irq is currently passed the (re)distributor address,
to which it applies an a fixed offset to get to the configuration
registers. This offset is constant across all GICs, or rather it was
until to v3.1...

An easy way out is for the individual drivers to pass the base
address of the configuration register for the considered interrupt.
At the same time, move part of the error handling back to the
individual drivers, as things are about to change on that front.

Signed-off-by: Marc Zyngier <maz@kernel.org>
drivers/irqchip/irq-gic-common.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic.c
drivers/irqchip/irq-hip04.c

index b0a8215a13fc086958932f96557d1c1113022c40..6900b6f0921cfaebaf390dc6ffb1dc3c691c8163 100644 (file)
@@ -63,7 +63,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
         * for "irq", depending on "type".
         */
        raw_spin_lock_irqsave(&irq_controller_lock, flags);
-       val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+       val = oldval = readl_relaxed(base + confoff);
        if (type & IRQ_TYPE_LEVEL_MASK)
                val &= ~confmask;
        else if (type & IRQ_TYPE_EDGE_BOTH)
@@ -83,14 +83,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
         * does not allow us to set the configuration or we are in a
         * non-secure mode, and hence it may not be catastrophic.
         */
-       writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
-       if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
-               if (WARN_ON(irq >= 32))
-                       ret = -EINVAL;
-               else
-                       pr_warn("GIC: PPI%d is secure or misconfigured\n",
-                               irq - 16);
-       }
+       writel_relaxed(val, base + confoff);
+       if (readl_relaxed(base + confoff) != val)
+               ret = -EINVAL;
+
        raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 
        if (sync_access)
index be961c261093b5ba34df9695a34ede76473133be..efc531975302a5edea7b4fba3a05f9d1ab049178 100644 (file)
@@ -407,6 +407,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
        unsigned int irq = gic_irq(d);
        void (*rwp_wait)(void);
        void __iomem *base;
+       int ret;
 
        /* Interrupt configuration for SGIs can't be changed */
        if (irq < 16)
@@ -425,7 +426,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
                rwp_wait = gic_dist_wait_for_rwp;
        }
 
-       return gic_configure_irq(irq, type, base, rwp_wait);
+
+       ret = gic_configure_irq(irq, type, base + GICD_ICFGR, rwp_wait);
+       if (ret && irq < 32) {
+               /* Misconfigured PPIs are usually not fatal */
+               pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
+               ret = 0;
+       }
+
+       return ret;
 }
 
 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
index b6b857377763aedf60f4d6fec2042ea5df7c620a..5ca7d5545a343a4d01997c0c7721e5cdda3a86d6 100644 (file)
@@ -291,6 +291,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 {
        void __iomem *base = gic_dist_base(d);
        unsigned int gicirq = gic_irq(d);
+       int ret;
 
        /* Interrupt configuration for SGIs can't be changed */
        if (gicirq < 16)
@@ -301,7 +302,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
                            type != IRQ_TYPE_EDGE_RISING)
                return -EINVAL;
 
-       return gic_configure_irq(gicirq, type, base, NULL);
+       ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
+       if (ret && gicirq < 32) {
+               /* Misconfigured PPIs are usually not fatal */
+               pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
+               ret = 0;
+       }
+
+       return ret;
 }
 
 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
index cf705827599ca268b1045f56afd692790fa393e5..1626131834a63303254c8942a128beed22ba9ed1 100644 (file)
@@ -130,7 +130,12 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
 
        raw_spin_lock(&irq_controller_lock);
 
-       ret = gic_configure_irq(irq, type, base, NULL);
+       ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL);
+       if (ret && irq < 32) {
+               /* Misconfigured PPIs are usually not fatal */
+               pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
+               ret = 0;
+       }
 
        raw_spin_unlock(&irq_controller_lock);