-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
irqchip: gic: Move some bits of GICv2 to a library-type file
A few GICv2 low-level function are actually very useful to GICv3, and it makes some sense to share them across the two drivers. They end-up in their own file, with an additional parameter used to ensure an optional synchronization (unused on GICv2). Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Cooper <jason@lakedaemon.net> Acked-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Link: https://lkml.kernel.org/r/1404140510-5382-2-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
- Loading branch information
Marc Zyngier
authored and
Jason Cooper
committed
Jul 8, 2014
1 parent
7171511
commit d51d0af
Showing
4 changed files
with
149 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
* Copyright (C) 2002 ARM Limited, All Rights Reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <linux/interrupt.h> | ||
#include <linux/io.h> | ||
#include <linux/irq.h> | ||
#include <linux/irqchip/arm-gic.h> | ||
|
||
#include "irq-gic-common.h" | ||
|
||
void gic_configure_irq(unsigned int irq, unsigned int type, | ||
void __iomem *base, void (*sync_access)(void)) | ||
{ | ||
u32 enablemask = 1 << (irq % 32); | ||
u32 enableoff = (irq / 32) * 4; | ||
u32 confmask = 0x2 << ((irq % 16) * 2); | ||
u32 confoff = (irq / 16) * 4; | ||
bool enabled = false; | ||
u32 val; | ||
|
||
/* | ||
* Read current configuration register, and insert the config | ||
* for "irq", depending on "type". | ||
*/ | ||
val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); | ||
if (type == IRQ_TYPE_LEVEL_HIGH) | ||
val &= ~confmask; | ||
else if (type == IRQ_TYPE_EDGE_RISING) | ||
val |= confmask; | ||
|
||
/* | ||
* As recommended by the spec, disable the interrupt before changing | ||
* the configuration | ||
*/ | ||
if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { | ||
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); | ||
if (sync_access) | ||
sync_access(); | ||
enabled = true; | ||
} | ||
|
||
/* | ||
* Write back the new configuration, and possibly re-enable | ||
* the interrupt. | ||
*/ | ||
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); | ||
|
||
if (enabled) | ||
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | ||
|
||
if (sync_access) | ||
sync_access(); | ||
} | ||
|
||
void __init gic_dist_config(void __iomem *base, int gic_irqs, | ||
void (*sync_access)(void)) | ||
{ | ||
unsigned int i; | ||
|
||
/* | ||
* Set all global interrupts to be level triggered, active low. | ||
*/ | ||
for (i = 32; i < gic_irqs; i += 16) | ||
writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4); | ||
|
||
/* | ||
* Set priority on all global interrupts. | ||
*/ | ||
for (i = 32; i < gic_irqs; i += 4) | ||
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i); | ||
|
||
/* | ||
* Disable all interrupts. Leave the PPI and SGIs alone | ||
* as they are enabled by redistributor registers. | ||
*/ | ||
for (i = 32; i < gic_irqs; i += 32) | ||
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8); | ||
|
||
if (sync_access) | ||
sync_access(); | ||
} | ||
|
||
void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) | ||
{ | ||
int i; | ||
|
||
/* | ||
* Deal with the banked PPI and SGI interrupts - disable all | ||
* PPI interrupts, ensure all SGI interrupts are enabled. | ||
*/ | ||
writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR); | ||
writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET); | ||
|
||
/* | ||
* Set priority on PPI and SGI interrupts | ||
*/ | ||
for (i = 0; i < 32; i += 4) | ||
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); | ||
|
||
if (sync_access) | ||
sync_access(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright (C) 2002 ARM Limited, All Rights Reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef _IRQ_GIC_COMMON_H | ||
#define _IRQ_GIC_COMMON_H | ||
|
||
#include <linux/of.h> | ||
#include <linux/irqdomain.h> | ||
|
||
void gic_configure_irq(unsigned int irq, unsigned int type, | ||
void __iomem *base, void (*sync_access)(void)); | ||
void gic_dist_config(void __iomem *base, int gic_irqs, | ||
void (*sync_access)(void)); | ||
void gic_cpu_config(void __iomem *base, void (*sync_access)(void)); | ||
|
||
#endif /* _IRQ_GIC_COMMON_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters