irqchip: gic: kill gic_arch_extn
Subsystems (6)
cover irqchip: gic: kill gic_arch_extn
The gic_arch_extn hack that Tegra uses has been nagging me for too long. It is only there for the benefit of a single platform, and yet it impacts all GIC users. Moreover, it gives people the wrong idea ("let's use it to put some new custom hack in there"...).
But now that stacked irq domains have landed in -next, the time has come for gic_arch_extn to meet the Big Bit Bucket.
This patch series moves Tegra's legacy interrupt controller support to drivers/irqchip, implementing a stacked domain on top of the standard GIC. The GIC itself is cleaned up, and some other bits and bobs are adjusted for a good measure.
It is worth realizing that:
- I haven't been able to test this as much as I would have wanted to (suspend/resume seems to be broken on my Harmony, and I don't have another platform at hand). But I haven't seen any regression from 3.17.
- I've relaxed quite a bit of the locking in the GIC code. I believe this is safe, but someone else should give it a long hard look.
- This actively *breaks* existing setups. Once you boot a new kernel with an old DT, suspend/resume *will* be broken. Old kernels on a new DT won't even boot! You've been warned.
As for the patches, they are on top of 3.18-rc6 + tip/irq/irqdomain-arm. Patch #1 is already queued for 3.18, and only included here for completeness.
I've pushed the code to:git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/tegra-lic
Comments welcome,
M.
Marc Zyngier (9):
ARM: tegra: irq: fix buggy usage of irq_data irq field
ARM: tegra: irq: nuke leftovers from non-DT support
irqchip: tegra: add DT-based support for legacy interrupt controller
ARM: tegra: skip gic_arch_extn setup if DT has a LIC node
ARM: tegra: update DTs to expose legacy interrupt controller
DT: tegra: add binding for the legacy interrupt controller
ARM: tegra: remove old LIC support
ARM: tegra: use DT to find the GIC distributor
irqchip: gic: Drop support for gic_arch_extn
.../interrupt-controller/nvdia,tegra-ictlr.txt | 39 +++ arch/arm/boot/dts/tegra114.dtsi | 16 +- arch/arm/boot/dts/tegra124.dtsi | 16 +- arch/arm/boot/dts/tegra20.dtsi | 15 +- arch/arm/boot/dts/tegra30.dtsi | 16 +- arch/arm/mach-tegra/iomap.h | 18 -- arch/arm/mach-tegra/irq.c | 228 ++------------ arch/arm/mach-tegra/irq.h | 6 - arch/arm/mach-tegra/tegra.c | 1 - drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic.c | 46 +-- drivers/irqchip/irq-tegra.c | 335 +++++++++++++++++++++ include/linux/irqchip/arm-gic.h | 2 - 13 files changed, 461 insertions(+), 278 deletions(-) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nvdia,tegra-ictlr.txt create mode 100644 drivers/irqchip/irq-tegra.c
Signature · 1 line
2.1.3
PATCH 1/9 ARM: tegra: irq: fix buggy usage of irq_data irq field
The crazy gic_arch_extn thing that Tegra uses contains multiple references to the irq field in struct irq_data, and uses this to directly poke hardware register.
But irq is the *virtual* irq number, something that has nothing to do with the actual HW irq (stored in the hwirq field). And once we put the stacked domain code in action, the whole thing explodes, as these two values are *very* different:
root at bacon-fat:~# cat /proc/interrupts
CPU0 CPU1
16: 25801 2075 GIC 29 twd 17: 0 0 GIC 73 timer0 112: 0 0 GPIO 58 c8000600.sdhci cd 123: 0 0 GPIO 69 c8000200.sdhci cd 279: 1126 0 GIC 122 serial 281: 0 0 GIC 70 7000c000.i2c 282: 0 0 GIC 116 7000c400.i2c 283: 0 0 GIC 124 7000c500.i2c 284: 300 0 GIC 85 7000d000.i2c
[...]
Just replacing all instances of irq with hwirq fixes the issue.
--- arch/arm/mach-tegra/irq.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
arch/arm/mach-tegra/irq.c +11 -11
@@ -99,42 +99,42 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)static void tegra_mask (struct irq_data *d) { -if (d->irq <FIRST_LEGACY_IRQ ) +if (d->hwirq <FIRST_LEGACY_IRQ )return ; -tegra_irq_write_mask (d->irq,ICTLR_CPU_IER_CLR ); +tegra_irq_write_mask (d->hwirq,ICTLR_CPU_IER_CLR ); }static void tegra_unmask (struct irq_data *d) { -if (d->irq <FIRST_LEGACY_IRQ ) +if (d->hwirq <FIRST_LEGACY_IRQ )return ; -tegra_irq_write_mask (d->irq,ICTLR_CPU_IER_SET ); +tegra_irq_write_mask (d->hwirq,ICTLR_CPU_IER_SET ); }static void tegra_ack (struct irq_data *d) { -if (d->irq <FIRST_LEGACY_IRQ ) +if (d->hwirq <FIRST_LEGACY_IRQ )return ; -tegra_irq_write_mask (d->irq,ICTLR_CPU_IEP_FIR_CLR ); +tegra_irq_write_mask (d->hwirq,ICTLR_CPU_IEP_FIR_CLR ); }static void tegra_eoi (struct irq_data *d) { -if (d->irq <FIRST_LEGACY_IRQ ) +if (d->hwirq <FIRST_LEGACY_IRQ )return ; -tegra_irq_write_mask (d->irq,ICTLR_CPU_IEP_FIR_CLR ); +tegra_irq_write_mask (d->hwirq,ICTLR_CPU_IEP_FIR_CLR ); }static int tegra_retrigger (struct irq_data *d) { -if (d->irq <FIRST_LEGACY_IRQ ) +if (d->hwirq <FIRST_LEGACY_IRQ )return 0 ; -tegra_irq_write_mask (d->irq,ICTLR_CPU_IEP_FIR_SET ); +tegra_irq_write_mask (d->hwirq,ICTLR_CPU_IEP_FIR_SET );return 1 ; }
@@ -142,7 +142,7 @@ static int tegra_retrigger(struct irq_data *d)#ifdef CONFIG_PM_SLEEP static int tegra_set_wake (struct irq_data *d,unsigned int enable) { -u32 irq = d->irq; +u32 irq = d->hwirq;u32 index, mask; if (irq < FIRST_LEGACY_IRQ ||
Signature · 1 line
2.1.3
PATCH 2/9 ARM: tegra: irq: nuke leftovers from non-DT support
In reply to Marc ZyngierThe GIC is now always initialized from DT on tegra, and there is no point in keeping non-DT init code.
--- arch/arm/mach-tegra/irq.c | 8 -------- 1 file changed, 8 deletions(-)
arch/arm/mach-tegra/irq.c +0 -8
@@ -283,13 +283,5 @@ void __init tegra_init_irq(void) gic_arch_extn.irq_set_wake = tegra_set_wake; gic_arch_extn.flags =IRQCHIP_MASK_ON_SUSPEND ; -/* -* Check if there is a devicetree present, since the GIC will be -* initialized elsewhere under DT. -*/ -if (!of_have_populated_dt ()) -gic_init (0 ,29 , distbase, -IO_ADDRESS (TEGRA_ARM_PERIF_BASE +0x100 )); -tegra114_gic_cpu_pm_registration (); }
Signature · 1 line
2.1.3
PATCH 3/9 irqchip: tegra: add DT-based support for legacy interrupt controller
In reply to Marc ZyngierTegra's LIC (Legacy Interrupt Controller) has been so far only supported as a weird extension of the GIC, which is not exactly pretty.
The stacked irq domain framework fits this pretty well, and allows the LIC code to be turned into a standalone irqchip. In the process, make the driver DT aware, something that was sorely missing from the mach-tegra implementation.
--- drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-tegra.c | 335 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 336 insertions(+) create mode 100644 drivers/irqchip/irq-tegra.c
drivers/irqchip/Makefile +1 -0
@@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o obj-$(CONFIG_ARCH_MXS) += irq-mxs.o +obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o obj-$(CONFIG_METAG) += irq-metag-ext.o
drivers/irqchip/irq-tegra.c new file +335 -0
335 lines not on this page · raw message
Signature · 1 line
2.1.3
PATCH 4/9 ARM: tegra: skip gic_arch_extn setup if DT has a LIC node
In reply to Marc ZyngierIf we detect that our DT has a LIC node, don't setup gic_arch_extn, and skip tegra_legacy_irq_syscore_init as well.
This is only a temporary measure until that code is removed for good.
--- arch/arm/mach-tegra/irq.c | 11 +++++++++++ arch/arm/mach-tegra/tegra.c | 1 - 2 files changed, 11 insertions(+), 1 deletion(-)
arch/arm/mach-tegra/irq.c +11 -0
@@ -255,11 +255,21 @@ static void tegra114_gic_cpu_pm_registration(void)static void tegra114_gic_cpu_pm_registration (void ) { }#endif +static const struct of_device_id tegra_ictlr_match[]__initconst = { + { .compatible ="nvidia,tegra-ictlr" }, + { } +}; +void __init tegra_init_irq (void ) {int i;void __iomem *distbase; +if (of_find_matching_node (NULL , tegra_ictlr_match)) + goto skip_extn_setup; + +tegra_legacy_irq_syscore_init (); + distbase =IO_ADDRESS (TEGRA_ARM_INT_DIST_BASE ); num_ictlrs =readl_relaxed (distbase +GIC_DIST_CTR ) &0x1f ;
@@ -283,5 +293,6 @@ void __init tegra_init_irq(void) gic_arch_extn.irq_set_wake = tegra_set_wake; gic_arch_extn.flags =IRQCHIP_MASK_ON_SUSPEND ; +skip_extn_setup:tegra114_gic_cpu_pm_registration (); }
arch/arm/mach-tegra/tegra.c +0 -1
@@ -82,7 +82,6 @@ static void __init tegra_dt_init_irq(void) {tegra_init_irq ();irqchip_init (); -tegra_legacy_irq_syscore_init (); }static void __init tegra_dt_init (void )
Signature · 1 line
2.1.3
PATCH 5/9 ARM: tegra: update DTs to expose legacy interrupt controller
In reply to Marc ZyngierDescribe the legacy interrupt controller in every tegra DTSI files, and make it the parent of most interrupts.
--- arch/arm/boot/dts/tegra114.dtsi | 16 +++++++++++++++- arch/arm/boot/dts/tegra124.dtsi | 16 +++++++++++++++- arch/arm/boot/dts/tegra20.dtsi | 15 ++++++++++++++- arch/arm/boot/dts/tegra30.dtsi | 16 +++++++++++++++- 4 files changed, 59 insertions(+), 4 deletions(-)
arch/arm/boot/dts/tegra114.dtsi +15 -1
@@ -7,7 +7,7 @@ / { compatible = "nvidia,tegra114"; - interrupt-parent = <&gic>; + interrupt-parent = <&ictlr>; host1x at 50000000 { compatible = "nvidia,tegra114-host1x", "simple-bus";
@@ -129,6 +129,19 @@ <0x50046000 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; + }; + + ictlr: interrupt-controller at 60004000 { + compatible = "nvidia,tegra114-ictlr", "nvidia,tegra-ictlr"; + reg = <0x60004000 64>, + <0x60004100 64>, + <0x60004200 64>, + <0x60004300 64>, + <0x60004400 64>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; }; timer at 60005000 {
@@ -761,5 +774,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; };
arch/arm/boot/dts/tegra124.dtsi +15 -1
@@ -8,7 +8,7 @@ / { compatible = "nvidia,tegra124"; - interrupt-parent = <&gic>; + interrupt-parent = <&ictlr>; #address-cells = <2>; #size-cells = <2>;
@@ -167,6 +167,7 @@ <0x0 0x50046000 0x0 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupt-parent = <&gic>; }; gpu at 0,57000000 {
@@ -184,6 +185,18 @@ status = "disabled"; }; + ictlr: interrupt-controller at 60004000 { + compatible = "nvidia,tegra124-ictlr", "nvidia,tegra-ictlr"; + reg = <0x0 0x60004000 0x0 0x40>, + <0x0 0x60004100 0x0 0x40>, + <0x0 0x60004200 0x0 0x40>, + <0x0 0x60004300 0x0 0x40>, + <0x0 0x60004400 0x0 0x40>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + }; + timer at 0,60005000 { compatible = "nvidia,tegra124-timer", "nvidia,tegra20-timer"; reg = <0x0 0x60005000 0x0 0x400>;
@@ -891,5 +904,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-parent = <&gic>; }; };
arch/arm/boot/dts/tegra20.dtsi +14 -1
@@ -7,7 +7,7 @@ / { compatible = "nvidia,tegra20"; - interrupt-parent = <&intc>; + interrupt-parent = <&ictlr>; host1x at 50000000 { compatible = "nvidia,tegra20-host1x", "simple-bus";
@@ -142,6 +142,7 @@ timer at 50004600 { compatible = "arm,cortex-a9-twd-timer"; + interrupt-parent = <&intc>; reg = <0x50040600 0x20>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
@@ -154,6 +155,7 @@ 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; + interrupt-parent = <&intc>; }; cache-controller at 50043000 {
@@ -165,6 +167,17 @@ cache-level = <2>; }; + ictlr: interrupt-controller at 60004000 { + compatible = "nvidia,tegra20-ictlr", "nvidia,tegra-ictlr"; + reg = <0x60004000 64>, + <0x60004100 64>, + <0x60004200 64>, + <0x60004300 64>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + }; + timer at 60005000 { compatible = "nvidia,tegra20-timer"; reg = <0x60005000 0x60>;
arch/arm/boot/dts/tegra30.dtsi +15 -1
@@ -7,7 +7,7 @@ / { compatible = "nvidia,tegra30"; - interrupt-parent = <&intc>; + interrupt-parent = <&ictlr>; pcie-controller at 00003000 { compatible = "nvidia,tegra30-pcie";
@@ -223,6 +223,7 @@ timer at 50004600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x50040600 0x20>; + interrupt-parent = <&intc>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&tegra_car TEGRA30_CLK_TWD>;
@@ -234,6 +235,7 @@ 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; + interrupt-parent = <&intc>; }; cache-controller at 50043000 {
@@ -245,6 +247,18 @@ cache-level = <2>; }; + ictlr: interrupt-controller at 60004000 { + compatible = "nvidia,tegra30-ictlr", "nvidia,tegra-ictlr"; + reg = <0x60004000 64>, + <0x60004100 64>, + <0x60004200 64>, + <0x60004300 64>, + <0x60004400 64>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + }; + timer at 60005000 { compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; reg = <0x60005000 0x400>;
Signature · 1 line
2.1.3
PATCH 6/9 DT: tegra: add binding for the legacy interrupt controller
In reply to Marc Zyngier--- .../interrupt-controller/nvdia,tegra-ictlr.txt | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nvdia,tegra-ictlr.txt
Documentation/devicetree/bindings/interrupt-controller/nvdia,tegra-ictlr.txt new file +39 -0
@@ -0,0 +1,39 @@ +NVIDIA Legacy Interrupt Controller + +All Tegra SoCs contain a legacy interrupt controller that routes +interrupts to the GIC, and also serves as a wakeup source. It is also +refered to as "ictlr", hence the name of the binding. + +The HW block exposes a number of frames, each implementing a set of 32 +interrupts. + +Reguired properties: + +- compatible : should contain at least "nvidia,tegra-ictlr". +- reg : Specifies base physical address and size of the registers. + Each frame must be described separately. +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value must be 3. +- interrupt-parent : a phandle to the GIC these interrupts are routed + to. + +Notes: + +- Because this HW ultimately routes interrupts to the GIC, the + interrupt specifier must be that of the GIC. +- Only SPIs can use the ictlr as an interrupt parent. SGIs and PPIs + are excplicitely forbiden. + +Example: + + ictlr: interrupt-controller at 60004000 { + compatible = "nvidia,tegra20-ictlr", "nvidia,tegra-ictlr"; + reg = <0x60004000 64>, + <0x60004100 64>, + <0x60004200 64>, + <0x60004300 64>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&intc>; + };
Signature · 1 line
2.1.3
PATCH 7/9 ARM: tegra: remove old LIC support
In reply to Marc ZyngierNow that all DTs have been updated, entierely drop support for the non-DT code.
This is likely to break platforms that do not update their DT, so print a warning at boot time.
--- arch/arm/mach-tegra/iomap.h | 15 ---- arch/arm/mach-tegra/irq.c | 201 +------------------------------------------- arch/arm/mach-tegra/irq.h | 6 -- 3 files changed, 2 insertions(+), 220 deletions(-)
arch/arm/mach-tegra/iomap.h +0 -15
@@ -31,21 +31,6 @@#define TEGRA_ARM_INT_DIST_BASE 0x50041000#define TEGRA_ARM_INT_DIST_SIZE SZ_4K -#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 - -#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 - -#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 -#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 -#define TEGRA_TMR1_BASE 0x60005000#define TEGRA_TMR1_SIZE SZ_8
arch/arm/mach-tegra/irq.c +2 -199
229 lines not on this page · raw message
arch/arm/mach-tegra/irq.h +0 -6
@@ -19,10 +19,4 @@bool tegra_pending_sgi (void ); -#ifdef CONFIG_PM_SLEEP -int tegra_legacy_irq_syscore_init (void ); -#else -static inline int tegra_legacy_irq_syscore_init (void ) {return 0 ; } -#endif -#endif
Signature · 1 line
2.1.3
PATCH 7/9 ARM: tegra: remove old LIC support
Quoted 5 lines · Marc Zyngier
Now that all DTs have been updated, entierely drop support for the non-DT code.
This is likely to break platforms that do not update their DT, so print a warning at boot time.
That seems to imply that yet again we're ignoring DT-is-an-ABI...
PATCH 8/9 ARM: tegra: use DT to find the GIC distributor
In reply to Marc ZyngierTegra likes to peek at the distributor to find out if SGIs are pending. This looks odd, but I'm sure there's a good reason.
But instead of hardcoding everything, let's use the DT instead.
--- arch/arm/mach-tegra/iomap.h | 3 --- arch/arm/mach-tegra/irq.c | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-)
arch/arm/mach-tegra/iomap.h +0 -3
@@ -28,9 +28,6 @@#define TEGRA_ARM_PERIF_BASE 0x50040000#define TEGRA_ARM_PERIF_SIZE SZ_8K -#define TEGRA_ARM_INT_DIST_BASE 0x50041000 -#define TEGRA_ARM_INT_DIST_SIZE SZ_4K -#define TEGRA_TMR1_BASE 0x60005000#define TEGRA_TMR1_SIZE SZ_8
arch/arm/mach-tegra/irq.c +19 -1
@@ -36,10 +36,28 @@static void __iomem *tegra_gic_cpu_base;#endif +static const struct of_device_id dt_gic_match[]__initconst = { + { .compatible ="arm,cortex-a9-gic" }, + { .compatible ="arm,cortex-a15-gic" }, + { } +}; +bool tegra_pending_sgi (void ) {u32 pending_set; -void __iomem *distbase =IO_ADDRESS (TEGRA_ARM_INT_DIST_BASE ); +static void __iomem *distbase; + +if (unlikely (!distbase)) { +struct device_node *dn; + + dn =of_find_matching_node (NULL , dt_gic_match); +if (WARN_ONCE (!dn,"No GIC node????\n" )) +return false; + + distbase =of_iomap (dn,0 ); +if (WARN_ONCE (!distbase,"Unable to map distributor????\n" )) +return false; + } pending_set =readl_relaxed (distbase +GIC_DIST_PENDING_SET );
Signature · 1 line
2.1.3
PATCH 9/9 irqchip: gic: Drop support for gic_arch_extn
In reply to Marc ZyngierNow that the only user of gic_arch_extn has been fixed, drop the "feature" for good. This leads to the removal of some now useless locking.
--- drivers/irqchip/irq-gic.c | 46 +---------------------------------------- include/linux/irqchip/arm-gic.h | 2 -- 2 files changed, 1 insertion(+), 47 deletions(-)
drivers/irqchip/irq-gic.c +1 -45
@@ -80,19 +80,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);#define NR_GIC_CPU_IF 8static u8 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ; -/* -* Supported arch specific GIC irq extension. -* Default make them NULL. -*/ -struct irq_chip gic_arch_extn = { - .irq_eoi =NULL , - .irq_mask =NULL , - .irq_unmask =NULL , - .irq_retrigger =NULL , - .irq_set_type =NULL , - .irq_set_wake =NULL , -}; -#ifndef MAX_GIC_NR #define MAX_GIC_NR 1#endif
@@ -155,32 +142,18 @@ static void gic_mask_irq(struct irq_data *d) {u32 mask =1 << (gic_irq (d) %32 ); -raw_spin_lock (&irq_controller_lock);writel_relaxed (mask,gic_dist_base (d) +GIC_DIST_ENABLE_CLEAR + (gic_irq (d) /32 ) *4 ); -if (gic_arch_extn.irq_mask) - gic_arch_extn.irq_mask (d); -raw_spin_unlock (&irq_controller_lock); }static void gic_unmask_irq (struct irq_data *d) {u32 mask =1 << (gic_irq (d) %32 ); -raw_spin_lock (&irq_controller_lock); -if (gic_arch_extn.irq_unmask) - gic_arch_extn.irq_unmask (d);writel_relaxed (mask,gic_dist_base (d) +GIC_DIST_ENABLE_SET + (gic_irq (d) /32 ) *4 ); -raw_spin_unlock (&irq_controller_lock); }static void gic_eoi_irq (struct irq_data *d) { -if (gic_arch_extn.irq_eoi) { -raw_spin_lock (&irq_controller_lock); - gic_arch_extn.irq_eoi (d); -raw_spin_unlock (&irq_controller_lock); - } -writel_relaxed (gic_irq (d),gic_cpu_base (d) +GIC_CPU_EOI ); }
@@ -196,23 +169,13 @@ static int gic_set_type(struct irq_data *d, unsigned int type)if (type !=IRQ_TYPE_LEVEL_HIGH && type !=IRQ_TYPE_EDGE_RISING )return -EINVAL ; -raw_spin_lock (&irq_controller_lock); - -if (gic_arch_extn.irq_set_type) - gic_arch_extn.irq_set_type (d, type); -gic_configure_irq (gicirq, type, base,NULL ); -raw_spin_unlock (&irq_controller_lock); -return 0 ; }static int gic_retrigger (struct irq_data *d) { -if (gic_arch_extn.irq_retrigger) -return gic_arch_extn.irq_retrigger (d); -/* the genirq layer expects 0 if we can't retrigger in hardware */ return 0 ; }
@@ -247,14 +210,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,#ifdef CONFIG_PM static int gic_set_wake (struct irq_data *d,unsigned int on) { -int ret = -ENXIO ; - -if (gic_arch_extn.irq_set_wake) - ret = gic_arch_extn.irq_set_wake (d, on); - -return ret; +return -ENXIO ; } -#else #define gic_set_wake NULL#endif
@@ -1029,7 +986,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,set_handle_irq (gic_handle_irq); } - gic_chip.flags |= gic_arch_extn.flags;gic_dist_init (gic);gic_cpu_init (gic);gic_pm_init (gic);
include/linux/irqchip/arm-gic.h +0 -2
@@ -93,8 +93,6 @@struct device_node ; -extern struct irq_chip gic_arch_extn; -void gic_init_bases (unsigned int ,int ,void __iomem *,void __iomem *,u32 offset,struct device_node *);void gic_cascade_irq (unsigned int gic_nr,unsigned int irq);
Signature · 1 line
2.1.3
cover irqchip: gic: kill gic_arch_extn
In reply to Marc ZyngierQuoted 4 lines · Marc Zyngier
The
gic_arch_extnhack that Tegra uses has been nagging me for too long. It is only there for the benefit of a single platform, and yet it impacts all GIC users. Moreover, it gives people the wrong idea ("let's use it to put some new custom hack in there"...).
Of course, just after sending this I realised that quite a lot of platform are now using this crap:
arch/arm/mach-exynos/pm.carch/arm/mach-imx/gpc.carch/arm/mach-omap2/omap-wakeupgen.carch/arm/mach-shmobile/intc-sh73a0.carch/arm/mach-shmobile/setup-r8a7779.carch/arm/mach-ux500/cpu.carch/arm/mach-zynq/common.c
Yes, I intend to address them as well...
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...