diff options
author | Jon Hunter <jonathanh@nvidia.com> | 2016-06-07 11:12:30 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-06-13 06:53:51 -0400 |
commit | d6ce564cea0c9f8fe7e1b400026482f4e61d38ad (patch) | |
tree | 4bb9df22dfc11869a7b4796ecdfa27f41f4442e3 /drivers/irqchip/irq-gic.c | |
parent | be45beb2df6909d42a6b3b0052601b3eef878fc0 (diff) |
irqchip/gic: Isolate early GIC initialisation code
To re-use the code that initialises the GIC (found in
__gic_init_bases()), from within a platform driver, it is necessary to
move the code from the __init section so that it is always present and
not removed. Unfortunately, it is not possible to simply drop the __init
from the function declaration for __gic_init_bases() because it contains
calls to set_smp_cross_call() and set_handle_irq() which are both
located in the __init section. Fortunately, these calls are only
required for the root controller and because the initial platform driver
will only support non-root controllers that can be initialised later in
the boot process, we can move these calls to another function.
Move the bulk of the code from __gic_init_bases() to a new function
called gic_init_bases() which is not located in the __init section and
can be used by the platform driver. Update __gic_init_bases() to call
gic_init_bases() and if necessary, set_smp_cross_call() and
set_handle_irq().
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index fbc4ae2afd29..fa0dd98993fa 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -1032,14 +1032,11 @@ static const struct irq_domain_ops gic_irq_domain_ops = { | |||
1032 | .unmap = gic_irq_domain_unmap, | 1032 | .unmap = gic_irq_domain_unmap, |
1033 | }; | 1033 | }; |
1034 | 1034 | ||
1035 | static int __init __gic_init_bases(struct gic_chip_data *gic, int irq_start, | 1035 | static int gic_init_bases(struct gic_chip_data *gic, int irq_start, |
1036 | struct fwnode_handle *handle) | 1036 | struct fwnode_handle *handle) |
1037 | { | 1037 | { |
1038 | irq_hw_number_t hwirq_base; | 1038 | irq_hw_number_t hwirq_base; |
1039 | int gic_irqs, irq_base, i, ret; | 1039 | int gic_irqs, irq_base, ret; |
1040 | |||
1041 | if (WARN_ON(!gic || gic->domain)) | ||
1042 | return -EINVAL; | ||
1043 | 1040 | ||
1044 | /* Initialize irq_chip */ | 1041 | /* Initialize irq_chip */ |
1045 | gic->chip = gic_chip; | 1042 | gic->chip = gic_chip; |
@@ -1138,23 +1135,6 @@ static int __init __gic_init_bases(struct gic_chip_data *gic, int irq_start, | |||
1138 | goto error; | 1135 | goto error; |
1139 | } | 1136 | } |
1140 | 1137 | ||
1141 | if (gic == &gic_data[0]) { | ||
1142 | /* | ||
1143 | * Initialize the CPU interface map to all CPUs. | ||
1144 | * It will be refined as each CPU probes its ID. | ||
1145 | * This is only necessary for the primary GIC. | ||
1146 | */ | ||
1147 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
1148 | gic_cpu_map[i] = 0xff; | ||
1149 | #ifdef CONFIG_SMP | ||
1150 | set_smp_cross_call(gic_raise_softirq); | ||
1151 | register_cpu_notifier(&gic_cpu_notifier); | ||
1152 | #endif | ||
1153 | set_handle_irq(gic_handle_irq); | ||
1154 | if (static_key_true(&supports_deactivate)) | ||
1155 | pr_info("GIC: Using split EOI/Deactivate mode\n"); | ||
1156 | } | ||
1157 | |||
1158 | gic_dist_init(gic); | 1138 | gic_dist_init(gic); |
1159 | ret = gic_cpu_init(gic); | 1139 | ret = gic_cpu_init(gic); |
1160 | if (ret) | 1140 | if (ret) |
@@ -1177,6 +1157,35 @@ error: | |||
1177 | return ret; | 1157 | return ret; |
1178 | } | 1158 | } |
1179 | 1159 | ||
1160 | static int __init __gic_init_bases(struct gic_chip_data *gic, | ||
1161 | int irq_start, | ||
1162 | struct fwnode_handle *handle) | ||
1163 | { | ||
1164 | int i; | ||
1165 | |||
1166 | if (WARN_ON(!gic || gic->domain)) | ||
1167 | return -EINVAL; | ||
1168 | |||
1169 | if (gic == &gic_data[0]) { | ||
1170 | /* | ||
1171 | * Initialize the CPU interface map to all CPUs. | ||
1172 | * It will be refined as each CPU probes its ID. | ||
1173 | * This is only necessary for the primary GIC. | ||
1174 | */ | ||
1175 | for (i = 0; i < NR_GIC_CPU_IF; i++) | ||
1176 | gic_cpu_map[i] = 0xff; | ||
1177 | #ifdef CONFIG_SMP | ||
1178 | set_smp_cross_call(gic_raise_softirq); | ||
1179 | register_cpu_notifier(&gic_cpu_notifier); | ||
1180 | #endif | ||
1181 | set_handle_irq(gic_handle_irq); | ||
1182 | if (static_key_true(&supports_deactivate)) | ||
1183 | pr_info("GIC: Using split EOI/Deactivate mode\n"); | ||
1184 | } | ||
1185 | |||
1186 | return gic_init_bases(gic, irq_start, handle); | ||
1187 | } | ||
1188 | |||
1180 | void __init gic_init(unsigned int gic_nr, int irq_start, | 1189 | void __init gic_init(unsigned int gic_nr, int irq_start, |
1181 | void __iomem *dist_base, void __iomem *cpu_base) | 1190 | void __iomem *dist_base, void __iomem *cpu_base) |
1182 | { | 1191 | { |