aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 15:31:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 15:31:53 -0400
commit5167d09ffad5b16b574d35ce3047ed34caf1e837 (patch)
treefc45dd9cbd578f5010e7b8208ecdfc6534547989 /drivers/irqchip/irq-gic.c
parent8533ce72718871fb528d853391746f36243273af (diff)
parentea1719672f59eeb85829073b567495c4f472ac9f (diff)
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Will Deacon: "Once again, Catalin's off on holiday and I'm looking after the arm64 tree. Please can you pull the following arm64 updates for 3.17? Note that this branch also includes the new GICv3 driver (merged via a stable tag from Jason's irqchip tree), since there is a fix for older binutils on top. Changes include: - context tracking support (NO_HZ_FULL) which narrowly missed 3.16 - vDSO layout rework following Andy's work on x86 - TEXT_OFFSET fuzzing for bootloader testing - /proc/cpuinfo tidy-up - preliminary work to support 48-bit virtual addresses, but this is currently disabled until KVM has been ported to use it (the patches do, however, bring some nice clean-up) - boot-time CPU sanity checks (especially useful on heterogenous systems) - support for syscall auditing - support for CC_STACKPROTECTOR - defconfig updates" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (55 commits) arm64: add newline to I-cache policy string Revert "arm64: dmi: Add SMBIOS/DMI support" arm64: fpsimd: fix a typo in fpsimd_save_partial_state ENDPROC arm64: don't call break hooks for BRK exceptions from EL0 arm64: defconfig: enable devtmpfs mount option arm64: vdso: fix build error when switching from LE to BE arm64: defconfig: add virtio support for running as a kvm guest arm64: gicv3: Allow GICv3 compilation with older binutils arm64: fix soft lockup due to large tlb flush range arm64/crypto: fix makefile rule for aes-glue-%.o arm64: Do not invoke audit_syscall_* functions if !CONFIG_AUDIT_SYSCALL arm64: Fix barriers used for page table modifications arm64: Add support for 48-bit VA space with 64KB page configuration arm64: asm/pgtable.h pmd/pud definitions clean-up arm64: Determine the vmalloc/vmemmap space at build time based on VA_BITS arm64: Clean up the initial page table creation in head.S arm64: Remove asm/pgtable-*level-types.h files arm64: Remove asm/pgtable-*level-hwdef.h files arm64: Convert bool ARM64_x_LEVELS to int ARM64_PGTABLE_LEVELS arm64: mm: Implement 4 levels of translation tables ...
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c59
1 files changed, 4 insertions, 55 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7c131cf7cc13..9c1f883fc5a3 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -47,6 +47,7 @@
47#include <asm/exception.h> 47#include <asm/exception.h>
48#include <asm/smp_plat.h> 48#include <asm/smp_plat.h>
49 49
50#include "irq-gic-common.h"
50#include "irqchip.h" 51#include "irqchip.h"
51 52
52union gic_base { 53union gic_base {
@@ -189,12 +190,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
189{ 190{
190 void __iomem *base = gic_dist_base(d); 191 void __iomem *base = gic_dist_base(d);
191 unsigned int gicirq = gic_irq(d); 192 unsigned int gicirq = gic_irq(d);
192 u32 enablemask = 1 << (gicirq % 32);
193 u32 enableoff = (gicirq / 32) * 4;
194 u32 confmask = 0x2 << ((gicirq % 16) * 2);
195 u32 confoff = (gicirq / 16) * 4;
196 bool enabled = false;
197 u32 val;
198 193
199 /* Interrupt configuration for SGIs can't be changed */ 194 /* Interrupt configuration for SGIs can't be changed */
200 if (gicirq < 16) 195 if (gicirq < 16)
@@ -208,25 +203,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
208 if (gic_arch_extn.irq_set_type) 203 if (gic_arch_extn.irq_set_type)
209 gic_arch_extn.irq_set_type(d, type); 204 gic_arch_extn.irq_set_type(d, type);
210 205
211 val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); 206 gic_configure_irq(gicirq, type, base, NULL);
212 if (type == IRQ_TYPE_LEVEL_HIGH)
213 val &= ~confmask;
214 else if (type == IRQ_TYPE_EDGE_RISING)
215 val |= confmask;
216
217 /*
218 * As recommended by the spec, disable the interrupt before changing
219 * the configuration
220 */
221 if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
222 writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
223 enabled = true;
224 }
225
226 writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
227
228 if (enabled)
229 writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
230 207
231 raw_spin_unlock(&irq_controller_lock); 208 raw_spin_unlock(&irq_controller_lock);
232 209
@@ -388,12 +365,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
388 writel_relaxed(0, base + GIC_DIST_CTRL); 365 writel_relaxed(0, base + GIC_DIST_CTRL);
389 366
390 /* 367 /*
391 * Set all global interrupts to be level triggered, active low.
392 */
393 for (i = 32; i < gic_irqs; i += 16)
394 writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
395
396 /*
397 * Set all global interrupts to this CPU only. 368 * Set all global interrupts to this CPU only.
398 */ 369 */
399 cpumask = gic_get_cpumask(gic); 370 cpumask = gic_get_cpumask(gic);
@@ -402,18 +373,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
402 for (i = 32; i < gic_irqs; i += 4) 373 for (i = 32; i < gic_irqs; i += 4)
403 writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); 374 writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
404 375
405 /* 376 gic_dist_config(base, gic_irqs, NULL);
406 * Set priority on all global interrupts.
407 */
408 for (i = 32; i < gic_irqs; i += 4)
409 writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
410
411 /*
412 * Disable all interrupts. Leave the PPI and SGIs alone
413 * as these enables are banked registers.
414 */
415 for (i = 32; i < gic_irqs; i += 32)
416 writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
417 377
418 writel_relaxed(1, base + GIC_DIST_CTRL); 378 writel_relaxed(1, base + GIC_DIST_CTRL);
419} 379}
@@ -440,18 +400,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)
440 if (i != cpu) 400 if (i != cpu)
441 gic_cpu_map[i] &= ~cpu_mask; 401 gic_cpu_map[i] &= ~cpu_mask;
442 402
443 /* 403 gic_cpu_config(dist_base, NULL);
444 * Deal with the banked PPI and SGI interrupts - disable all
445 * PPI interrupts, ensure all SGI interrupts are enabled.
446 */
447 writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
448 writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
449
450 /*
451 * Set priority on PPI and SGI interrupts
452 */
453 for (i = 0; i < 32; i += 4)
454 writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
455 404
456 writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); 405 writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
457 writel_relaxed(1, base + GIC_CPU_CTRL); 406 writel_relaxed(1, base + GIC_CPU_CTRL);