mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-18 04:54:52 +00:00
irqchip core changes for v3.18 (round 2)
- atmel - Add sama5d4 support - Correct # irqs for sama5d3 - broadcom - Add bcm7120 l2 interrupt controller and DT binding - gic-v3 - Add CPU PM notifier - Add enable/disable support to gic_enable_redist -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJULVIxAAoJEP45WPkGe8ZnXlEP/RYlWcdxz+0l0zsksR2r+IC3 bSTi+rM4vOVHoz+pP37ody6qEAfXcgopfU5AABEa/In0XuSVdUoNlQKAZm8hS8OS q1jgPlKnVGAXDgdmLjx+ThUjl7yDaQMZjaJEj/1kWod0D9FjkjfJynMreYBqz1n+ xb9fgDRBZYq+5c5IFmX3ME+HWIWgiNEyMOy8AcLU4xeqXCIhNjLnplptzQU8/ZRN NUuhs5hTeA/jbs3Gq2WEoOV5QSVpX5Q55ykvDWDFTA3Ukcq349mnbDo18MmhE0fz f+tDEq+TZoS73DJRD5TDykq+3WSmPgjX4u4Xvve82Jobw1Wi9GPK7pxOW/GU1TPQ hmyedlvkNXmclJyz/uYkehE44Sx/FJG74fmCQSNYEZIruT7cI39u0zGiuHhllRbx bJ7I/A6B3jiWM/2cJKDKpNoqjd+1DWprd40bs987JR72FZ792YRFZwm3ICrBnIrR XsptvZubOy0o4qdV00ZNsmRPI2wA7DoLq3ac+1ReMGOC4Al5HmX6KRUPNjaV6kAw +gbm/x8Pgsm5qC4k/kKwtQUpaWkGSMeW1tVR8lNiP82RpXasWrwCUWo38nLHD4Wd 7u1BeU5BPJAW220AkvX9BFgUs4J/rfNEfMmHFd9aRteSI68fo+gnquDGxX6rAyVx p9tLvS4O4GabaXNsZwQc =0Tcp -----END PGP SIGNATURE----- Merge tag 'irqchip-core-3.18-2' of git://git.infradead.org/users/jcooper/linux into irq/core irqchip core changes for v3.18 (round 2) from Jason Cooper * atmel: - Add sama5d4 support - Correct # irqs for sama5d3 * broadcom: - Add bcm7120 l2 interrupt controller and DT binding * gic-v3: - Add CPU PM notifier - Add enable/disable support to gic_enable_redist
This commit is contained in:
commit
2828c9cdb8
6 changed files with 386 additions and 25 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
Required properties:
|
||||
- compatible: Should be "atmel,<chip>-aic"
|
||||
<chip> can be "at91rm9200" or "sama5d3"
|
||||
<chip> can be "at91rm9200", "sama5d3" or "sama5d4"
|
||||
- interrupt-controller: Identifies the node as an interrupt controller.
|
||||
- interrupt-parent: For single AIC system, it is an empty property.
|
||||
- #interrupt-cells: The number of cells to define the interrupts. It should be 3.
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
Broadcom BCM7120-style Level 2 interrupt controller
|
||||
|
||||
This interrupt controller hardware is a second level interrupt controller that
|
||||
is hooked to a parent interrupt controller: e.g: ARM GIC for ARM-based
|
||||
platforms. It can be found on BCM7xxx products starting with BCM7120.
|
||||
|
||||
Such an interrupt controller has the following hardware design:
|
||||
|
||||
- outputs multiple interrupts signals towards its interrupt controller parent
|
||||
|
||||
- controls how some of the interrupts will be flowing, whether they will
|
||||
directly output an interrupt signal towards the interrupt controller parent,
|
||||
or if they will output an interrupt signal at this 2nd level interrupt
|
||||
controller, in particular for UARTs
|
||||
|
||||
- not all 32-bits within the interrupt controller actually map to an interrupt
|
||||
|
||||
The typical hardware layout for this controller is represented below:
|
||||
|
||||
2nd level interrupt line Outputs for the parent controller (e.g: ARM GIC)
|
||||
|
||||
0 -----[ MUX ] ------------|==========> GIC interrupt 75
|
||||
\-----------\
|
||||
|
|
||||
1 -----[ MUX ] --------)---|==========> GIC interrupt 76
|
||||
\------------|
|
||||
|
|
||||
2 -----[ MUX ] --------)---|==========> GIC interrupt 77
|
||||
\------------|
|
||||
|
|
||||
3 ---------------------|
|
||||
4 ---------------------|
|
||||
5 ---------------------|
|
||||
7 ---------------------|---|===========> GIC interrupt 66
|
||||
9 ---------------------|
|
||||
10 --------------------|
|
||||
11 --------------------/
|
||||
|
||||
6 ------------------------\
|
||||
|===========> GIC interrupt 64
|
||||
8 ------------------------/
|
||||
|
||||
12 ........................ X
|
||||
13 ........................ X (not connected)
|
||||
..
|
||||
31 ........................ X
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: should be "brcm,bcm7120-l2-intc"
|
||||
- reg: specifies the base physical address and size of the registers
|
||||
- interrupt-controller: identifies the node as an interrupt controller
|
||||
- #interrupt-cells: specifies the number of cells needed to encode an interrupt
|
||||
source, should be 1.
|
||||
- interrupt-parent: specifies the phandle to the parent interrupt controller
|
||||
this one is cascaded from
|
||||
- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
|
||||
node, valid values depend on the type of parent interrupt controller
|
||||
- brcm,int-map-mask: 32-bits bit mask describing how many and which interrupts
|
||||
are wired to this 2nd level interrupt controller, and how they match their
|
||||
respective interrupt parents. Should match exactly the number of interrupts
|
||||
specified in the 'interrupts' property.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- brcm,irq-can-wake: if present, this means the L2 controller can be used as a
|
||||
wakeup source for system suspend/resume.
|
||||
|
||||
- brcm,int-fwd-mask: if present, a 32-bits bit mask to configure for the
|
||||
interrupts which have a mux gate, typically UARTs. Setting these bits will
|
||||
make their respective interrupts outputs bypass this 2nd level interrupt
|
||||
controller completely, it completely transparent for the interrupt controller
|
||||
parent
|
||||
|
||||
Example:
|
||||
|
||||
irq0_intc: interrupt-controller@f0406800 {
|
||||
compatible = "brcm,bcm7120-l2-intc";
|
||||
interrupt-parent = <&intc>;
|
||||
#interrupt-cells = <1>;
|
||||
reg = <0xf0406800 0x8>;
|
||||
interrupt-controller;
|
||||
interrupts = <0x0 0x42 0x0>, <0x0 0x40 0x0>;
|
||||
brcm,int-map-mask = <0xeb8>, <0x140>;
|
||||
brcm,int-fwd-mask = <0x7>;
|
||||
};
|
|
@ -34,5 +34,6 @@ obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o
|
|||
obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o
|
||||
obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o
|
||||
obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o
|
||||
obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
|
||||
obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o \
|
||||
irq-bcm7120-l2.o
|
||||
obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
|
||||
|
|
|
@ -295,6 +295,7 @@ static void __init sama5d3_aic_irq_fixup(struct device_node *root)
|
|||
|
||||
static const struct of_device_id __initdata aic5_irq_fixups[] = {
|
||||
{ .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
|
||||
{ .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -341,7 +342,7 @@ static int __init aic5_of_init(struct device_node *node,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define NR_SAMA5D3_IRQS 50
|
||||
#define NR_SAMA5D3_IRQS 48
|
||||
|
||||
static int __init sama5d3_aic5_of_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
|
@ -349,3 +350,12 @@ static int __init sama5d3_aic5_of_init(struct device_node *node,
|
|||
return aic5_of_init(node, parent, NR_SAMA5D3_IRQS);
|
||||
}
|
||||
IRQCHIP_DECLARE(sama5d3_aic5, "atmel,sama5d3-aic", sama5d3_aic5_of_init);
|
||||
|
||||
#define NR_SAMA5D4_IRQS 68
|
||||
|
||||
static int __init sama5d4_aic5_of_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
{
|
||||
return aic5_of_init(node, parent, NR_SAMA5D4_IRQS);
|
||||
}
|
||||
IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init);
|
||||
|
|
219
drivers/irqchip/irq-bcm7120-l2.c
Normal file
219
drivers/irqchip/irq-bcm7120-l2.c
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Broadcom BCM7120 style Level 2 interrupt controller driver
|
||||
*
|
||||
* Copyright (C) 2014 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
|
||||
#include "irqchip.h"
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
/* Register offset in the L2 interrupt controller */
|
||||
#define IRQEN 0x00
|
||||
#define IRQSTAT 0x04
|
||||
|
||||
struct bcm7120_l2_intc_data {
|
||||
void __iomem *base;
|
||||
struct irq_domain *domain;
|
||||
bool can_wake;
|
||||
u32 irq_fwd_mask;
|
||||
u32 irq_map_mask;
|
||||
u32 saved_mask;
|
||||
};
|
||||
|
||||
static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct bcm7120_l2_intc_data *b = irq_desc_get_handler_data(desc);
|
||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||
u32 status;
|
||||
|
||||
chained_irq_enter(chip, desc);
|
||||
|
||||
status = __raw_readl(b->base + IRQSTAT);
|
||||
|
||||
if (status == 0) {
|
||||
do_bad_IRQ(irq, desc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
irq = ffs(status) - 1;
|
||||
status &= ~(1 << irq);
|
||||
generic_handle_irq(irq_find_mapping(b->domain, irq));
|
||||
} while (status);
|
||||
|
||||
out:
|
||||
chained_irq_exit(chip, desc);
|
||||
}
|
||||
|
||||
static void bcm7120_l2_intc_suspend(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct bcm7120_l2_intc_data *b = gc->private;
|
||||
u32 reg;
|
||||
|
||||
irq_gc_lock(gc);
|
||||
/* Save the current mask and the interrupt forward mask */
|
||||
b->saved_mask = __raw_readl(b->base) | b->irq_fwd_mask;
|
||||
if (b->can_wake) {
|
||||
reg = b->saved_mask | gc->wake_active;
|
||||
__raw_writel(reg, b->base);
|
||||
}
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
static void bcm7120_l2_intc_resume(struct irq_data *d)
|
||||
{
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct bcm7120_l2_intc_data *b = gc->private;
|
||||
|
||||
/* Restore the saved mask */
|
||||
irq_gc_lock(gc);
|
||||
__raw_writel(b->saved_mask, b->base);
|
||||
irq_gc_unlock(gc);
|
||||
}
|
||||
|
||||
static int bcm7120_l2_intc_init_one(struct device_node *dn,
|
||||
struct bcm7120_l2_intc_data *data,
|
||||
int irq, const __be32 *map_mask)
|
||||
{
|
||||
int parent_irq;
|
||||
|
||||
parent_irq = irq_of_parse_and_map(dn, irq);
|
||||
if (parent_irq < 0) {
|
||||
pr_err("failed to map interrupt %d\n", irq);
|
||||
return parent_irq;
|
||||
}
|
||||
|
||||
data->irq_map_mask |= be32_to_cpup(map_mask + irq);
|
||||
|
||||
irq_set_handler_data(parent_irq, data);
|
||||
irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init bcm7120_l2_intc_of_init(struct device_node *dn,
|
||||
struct device_node *parent)
|
||||
{
|
||||
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
|
||||
struct bcm7120_l2_intc_data *data;
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
const __be32 *map_mask;
|
||||
int num_parent_irqs;
|
||||
int ret = 0, len, irq;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->base = of_iomap(dn, 0);
|
||||
if (!data->base) {
|
||||
pr_err("failed to remap intc L2 registers\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dn, "brcm,int-fwd-mask", &data->irq_fwd_mask))
|
||||
data->irq_fwd_mask = 0;
|
||||
|
||||
/* Enable all interrupt specified in the interrupt forward mask and have
|
||||
* the other disabled
|
||||
*/
|
||||
__raw_writel(data->irq_fwd_mask, data->base + IRQEN);
|
||||
|
||||
num_parent_irqs = of_irq_count(dn);
|
||||
if (num_parent_irqs <= 0) {
|
||||
pr_err("invalid number of parent interrupts\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
map_mask = of_get_property(dn, "brcm,int-map-mask", &len);
|
||||
if (!map_mask || (len != (sizeof(*map_mask) * num_parent_irqs))) {
|
||||
pr_err("invalid brcm,int-map-mask property\n");
|
||||
ret = -EINVAL;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
for (irq = 0; irq < num_parent_irqs; irq++) {
|
||||
ret = bcm7120_l2_intc_init_one(dn, data, irq, map_mask);
|
||||
if (ret)
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
data->domain = irq_domain_add_linear(dn, 32,
|
||||
&irq_generic_chip_ops, NULL);
|
||||
if (!data->domain) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
|
||||
dn->full_name, handle_level_irq, clr, 0,
|
||||
IRQ_GC_INIT_MASK_CACHE);
|
||||
if (ret) {
|
||||
pr_err("failed to allocate generic irq chip\n");
|
||||
goto out_free_domain;
|
||||
}
|
||||
|
||||
gc = irq_get_domain_generic_chip(data->domain, 0);
|
||||
gc->unused = 0xfffffff & ~data->irq_map_mask;
|
||||
gc->reg_base = data->base;
|
||||
gc->private = data;
|
||||
ct = gc->chip_types;
|
||||
|
||||
ct->regs.mask = IRQEN;
|
||||
ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_ack = irq_gc_noop;
|
||||
ct->chip.irq_suspend = bcm7120_l2_intc_suspend;
|
||||
ct->chip.irq_resume = bcm7120_l2_intc_resume;
|
||||
|
||||
if (of_property_read_bool(dn, "brcm,irq-can-wake")) {
|
||||
data->can_wake = true;
|
||||
/* This IRQ chip can wake the system, set all relevant child
|
||||
* interupts in wake_enabled mask
|
||||
*/
|
||||
gc->wake_enabled = 0xffffffff;
|
||||
gc->wake_enabled &= ~gc->unused;
|
||||
ct->chip.irq_set_wake = irq_gc_set_wake;
|
||||
}
|
||||
|
||||
pr_info("registered BCM7120 L2 intc (mem: 0x%p, parent IRQ(s): %d)\n",
|
||||
data->base, num_parent_irqs);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_domain:
|
||||
irq_domain_remove(data->domain);
|
||||
out_unmap:
|
||||
iounmap(data->base);
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
IRQCHIP_DECLARE(brcmstb_l2_intc, "brcm,bcm7120-l2-intc",
|
||||
bcm7120_l2_intc_of_init);
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -155,7 +156,7 @@ static void gic_enable_sre(void)
|
|||
pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
|
||||
}
|
||||
|
||||
static void gic_enable_redist(void)
|
||||
static void gic_enable_redist(bool enable)
|
||||
{
|
||||
void __iomem *rbase;
|
||||
u32 count = 1000000; /* 1s! */
|
||||
|
@ -163,20 +164,30 @@ static void gic_enable_redist(void)
|
|||
|
||||
rbase = gic_data_rdist_rd_base();
|
||||
|
||||
/* Wake up this CPU redistributor */
|
||||
val = readl_relaxed(rbase + GICR_WAKER);
|
||||
val &= ~GICR_WAKER_ProcessorSleep;
|
||||
if (enable)
|
||||
/* Wake up this CPU redistributor */
|
||||
val &= ~GICR_WAKER_ProcessorSleep;
|
||||
else
|
||||
val |= GICR_WAKER_ProcessorSleep;
|
||||
writel_relaxed(val, rbase + GICR_WAKER);
|
||||
|
||||
while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) {
|
||||
count--;
|
||||
if (!count) {
|
||||
pr_err_ratelimited("redist didn't wake up...\n");
|
||||
return;
|
||||
}
|
||||
if (!enable) { /* Check that GICR_WAKER is writeable */
|
||||
val = readl_relaxed(rbase + GICR_WAKER);
|
||||
if (!(val & GICR_WAKER_ProcessorSleep))
|
||||
return; /* No PM support in this redistributor */
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
val = readl_relaxed(rbase + GICR_WAKER);
|
||||
if (enable ^ (val & GICR_WAKER_ChildrenAsleep))
|
||||
break;
|
||||
cpu_relax();
|
||||
udelay(1);
|
||||
};
|
||||
if (!count)
|
||||
pr_err_ratelimited("redistributor failed to %s...\n",
|
||||
enable ? "wakeup" : "sleep");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -372,20 +383,8 @@ static int gic_populate_rdist(void)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void gic_cpu_init(void)
|
||||
static void gic_cpu_sys_reg_init(void)
|
||||
{
|
||||
void __iomem *rbase;
|
||||
|
||||
/* Register ourselves with the rest of the world */
|
||||
if (gic_populate_rdist())
|
||||
return;
|
||||
|
||||
gic_enable_redist();
|
||||
|
||||
rbase = gic_data_rdist_sgi_base();
|
||||
|
||||
gic_cpu_config(rbase, gic_redist_wait_for_rwp);
|
||||
|
||||
/* Enable system registers */
|
||||
gic_enable_sre();
|
||||
|
||||
|
@ -399,6 +398,24 @@ static void gic_cpu_init(void)
|
|||
gic_write_grpen1(1);
|
||||
}
|
||||
|
||||
static void gic_cpu_init(void)
|
||||
{
|
||||
void __iomem *rbase;
|
||||
|
||||
/* Register ourselves with the rest of the world */
|
||||
if (gic_populate_rdist())
|
||||
return;
|
||||
|
||||
gic_enable_redist(true);
|
||||
|
||||
rbase = gic_data_rdist_sgi_base();
|
||||
|
||||
gic_cpu_config(rbase, gic_redist_wait_for_rwp);
|
||||
|
||||
/* initialise system registers */
|
||||
gic_cpu_sys_reg_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int gic_secondary_init(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
|
@ -532,6 +549,33 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
|
|||
#define gic_smp_init() do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_PM
|
||||
static int gic_cpu_pm_notifier(struct notifier_block *self,
|
||||
unsigned long cmd, void *v)
|
||||
{
|
||||
if (cmd == CPU_PM_EXIT) {
|
||||
gic_enable_redist(true);
|
||||
gic_cpu_sys_reg_init();
|
||||
} else if (cmd == CPU_PM_ENTER) {
|
||||
gic_write_grpen1(0);
|
||||
gic_enable_redist(false);
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block gic_cpu_pm_notifier_block = {
|
||||
.notifier_call = gic_cpu_pm_notifier,
|
||||
};
|
||||
|
||||
static void gic_cpu_pm_init(void)
|
||||
{
|
||||
cpu_pm_register_notifier(&gic_cpu_pm_notifier_block);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void gic_cpu_pm_init(void) { }
|
||||
#endif /* CONFIG_CPU_PM */
|
||||
|
||||
static struct irq_chip gic_chip = {
|
||||
.name = "GICv3",
|
||||
.irq_mask = gic_mask_irq,
|
||||
|
@ -671,6 +715,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
|
|||
gic_smp_init();
|
||||
gic_dist_init();
|
||||
gic_cpu_init();
|
||||
gic_cpu_pm_init();
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue