aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-05-10 11:14:42 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2016-05-11 05:12:43 -0400
commitdc9722cc57eba336038b2ade111436656c5a87d0 (patch)
tree733721c1e42a0256969b0f9a33f2d21c33f9b73d /drivers/irqchip/irq-gic.c
parentc2baa2f3f42fc6ea302bb666889c5843986a19a3 (diff)
irqchip/gic: Return an error if GIC initialisation fails
If the GIC initialisation fails, then currently we do not return an error or clean-up afterwards. Although for root controllers, this failure may be fatal anyway, for secondary controllers, it may not be fatal and so return an error on failure and clean-up. Update the functions gic_cpu_init() and gic_pm_init() to return an error instead of calling BUG() and perform any necessary clean-up. For non-banked GIC controllers, make sure that we free any memory allocated if we fail to initialise the IRQ domain. Please note that free_percpu() only frees memory if the pointer passed to it is not NULL and so it is unnecessary to check if both pointers are valid or not. 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.c99
1 files changed, 73 insertions, 26 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index a8cb86bea544..7cf138286442 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -467,7 +467,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
467 writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); 467 writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
468} 468}
469 469
470static void gic_cpu_init(struct gic_chip_data *gic) 470static int gic_cpu_init(struct gic_chip_data *gic)
471{ 471{
472 void __iomem *dist_base = gic_data_dist_base(gic); 472 void __iomem *dist_base = gic_data_dist_base(gic);
473 void __iomem *base = gic_data_cpu_base(gic); 473 void __iomem *base = gic_data_cpu_base(gic);
@@ -483,7 +483,9 @@ static void gic_cpu_init(struct gic_chip_data *gic)
483 /* 483 /*
484 * Get what the GIC says our CPU mask is. 484 * Get what the GIC says our CPU mask is.
485 */ 485 */
486 BUG_ON(cpu >= NR_GIC_CPU_IF); 486 if (WARN_ON(cpu >= NR_GIC_CPU_IF))
487 return -EINVAL;
488
487 cpu_mask = gic_get_cpumask(gic); 489 cpu_mask = gic_get_cpumask(gic);
488 gic_cpu_map[cpu] = cpu_mask; 490 gic_cpu_map[cpu] = cpu_mask;
489 491
@@ -500,6 +502,8 @@ static void gic_cpu_init(struct gic_chip_data *gic)
500 502
501 writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); 503 writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
502 gic_cpu_if_up(gic); 504 gic_cpu_if_up(gic);
505
506 return 0;
503} 507}
504 508
505int gic_cpu_if_down(unsigned int gic_nr) 509int gic_cpu_if_down(unsigned int gic_nr)
@@ -713,26 +717,39 @@ static struct notifier_block gic_notifier_block = {
713 .notifier_call = gic_notifier, 717 .notifier_call = gic_notifier,
714}; 718};
715 719
716static void __init gic_pm_init(struct gic_chip_data *gic) 720static int __init gic_pm_init(struct gic_chip_data *gic)
717{ 721{
718 gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4, 722 gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
719 sizeof(u32)); 723 sizeof(u32));
720 BUG_ON(!gic->saved_ppi_enable); 724 if (WARN_ON(!gic->saved_ppi_enable))
725 return -ENOMEM;
721 726
722 gic->saved_ppi_active = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4, 727 gic->saved_ppi_active = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
723 sizeof(u32)); 728 sizeof(u32));
724 BUG_ON(!gic->saved_ppi_active); 729 if (WARN_ON(!gic->saved_ppi_active))
730 goto free_ppi_enable;
725 731
726 gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4, 732 gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
727 sizeof(u32)); 733 sizeof(u32));
728 BUG_ON(!gic->saved_ppi_conf); 734 if (WARN_ON(!gic->saved_ppi_conf))
735 goto free_ppi_active;
729 736
730 if (gic == &gic_data[0]) 737 if (gic == &gic_data[0])
731 cpu_pm_register_notifier(&gic_notifier_block); 738 cpu_pm_register_notifier(&gic_notifier_block);
739
740 return 0;
741
742free_ppi_active:
743 free_percpu(gic->saved_ppi_active);
744free_ppi_enable:
745 free_percpu(gic->saved_ppi_enable);
746
747 return -ENOMEM;
732} 748}
733#else 749#else
734static void __init gic_pm_init(struct gic_chip_data *gic) 750static int __init gic_pm_init(struct gic_chip_data *gic)
735{ 751{
752 return 0;
736} 753}
737#endif 754#endif
738 755
@@ -1005,13 +1022,13 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
1005 .unmap = gic_irq_domain_unmap, 1022 .unmap = gic_irq_domain_unmap,
1006}; 1023};
1007 1024
1008static void __init __gic_init_bases(unsigned int gic_nr, int irq_start, 1025static int __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1009 void __iomem *dist_base, void __iomem *cpu_base, 1026 void __iomem *dist_base, void __iomem *cpu_base,
1010 u32 percpu_offset, struct fwnode_handle *handle) 1027 u32 percpu_offset, struct fwnode_handle *handle)
1011{ 1028{
1012 irq_hw_number_t hwirq_base; 1029 irq_hw_number_t hwirq_base;
1013 struct gic_chip_data *gic; 1030 struct gic_chip_data *gic;
1014 int gic_irqs, irq_base, i; 1031 int gic_irqs, irq_base, i, ret;
1015 1032
1016 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR); 1033 BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
1017 1034
@@ -1026,7 +1043,7 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1026 gic->chip.irq_mask = gic_eoimode1_mask_irq; 1043 gic->chip.irq_mask = gic_eoimode1_mask_irq;
1027 gic->chip.irq_eoi = gic_eoimode1_eoi_irq; 1044 gic->chip.irq_eoi = gic_eoimode1_eoi_irq;
1028 gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity; 1045 gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity;
1029 gic->chip.name = "GICv2"; 1046 gic->chip.name = kasprintf(GFP_KERNEL, "GICv2");
1030 } else { 1047 } else {
1031 gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr); 1048 gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr);
1032 } 1049 }
@@ -1036,17 +1053,16 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1036 gic->chip.irq_set_affinity = gic_set_affinity; 1053 gic->chip.irq_set_affinity = gic_set_affinity;
1037#endif 1054#endif
1038 1055
1039#ifdef CONFIG_GIC_NON_BANKED 1056 if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && percpu_offset) {
1040 if (percpu_offset) { /* Frankein-GIC without banked registers... */ 1057 /* Frankein-GIC without banked registers... */
1041 unsigned int cpu; 1058 unsigned int cpu;
1042 1059
1043 gic->dist_base.percpu_base = alloc_percpu(void __iomem *); 1060 gic->dist_base.percpu_base = alloc_percpu(void __iomem *);
1044 gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); 1061 gic->cpu_base.percpu_base = alloc_percpu(void __iomem *);
1045 if (WARN_ON(!gic->dist_base.percpu_base || 1062 if (WARN_ON(!gic->dist_base.percpu_base ||
1046 !gic->cpu_base.percpu_base)) { 1063 !gic->cpu_base.percpu_base)) {
1047 free_percpu(gic->dist_base.percpu_base); 1064 ret = -ENOMEM;
1048 free_percpu(gic->cpu_base.percpu_base); 1065 goto error;
1049 return;
1050 } 1066 }
1051 1067
1052 for_each_possible_cpu(cpu) { 1068 for_each_possible_cpu(cpu) {
@@ -1058,9 +1074,8 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1058 } 1074 }
1059 1075
1060 gic_set_base_accessor(gic, gic_get_percpu_base); 1076 gic_set_base_accessor(gic, gic_get_percpu_base);
1061 } else 1077 } else {
1062#endif 1078 /* Normal, sane GIC... */
1063 { /* Normal, sane GIC... */
1064 WARN(percpu_offset, 1079 WARN(percpu_offset,
1065 "GIC_NON_BANKED not enabled, ignoring %08x offset!", 1080 "GIC_NON_BANKED not enabled, ignoring %08x offset!",
1066 percpu_offset); 1081 percpu_offset);
@@ -1110,8 +1125,10 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1110 hwirq_base, &gic_irq_domain_ops, gic); 1125 hwirq_base, &gic_irq_domain_ops, gic);
1111 } 1126 }
1112 1127
1113 if (WARN_ON(!gic->domain)) 1128 if (WARN_ON(!gic->domain)) {
1114 return; 1129 ret = -ENODEV;
1130 goto error;
1131 }
1115 1132
1116 if (gic_nr == 0) { 1133 if (gic_nr == 0) {
1117 /* 1134 /*
@@ -1131,8 +1148,25 @@ static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
1131 } 1148 }
1132 1149
1133 gic_dist_init(gic); 1150 gic_dist_init(gic);
1134 gic_cpu_init(gic); 1151 ret = gic_cpu_init(gic);
1135 gic_pm_init(gic); 1152 if (ret)
1153 goto error;
1154
1155 ret = gic_pm_init(gic);
1156 if (ret)
1157 goto error;
1158
1159 return 0;
1160
1161error:
1162 if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && percpu_offset) {
1163 free_percpu(gic->dist_base.percpu_base);
1164 free_percpu(gic->cpu_base.percpu_base);
1165 }
1166
1167 kfree(gic->chip.name);
1168
1169 return ret;
1136} 1170}
1137 1171
1138void __init gic_init(unsigned int gic_nr, int irq_start, 1172void __init gic_init(unsigned int gic_nr, int irq_start,
@@ -1193,7 +1227,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
1193 void __iomem *cpu_base; 1227 void __iomem *cpu_base;
1194 void __iomem *dist_base; 1228 void __iomem *dist_base;
1195 u32 percpu_offset; 1229 u32 percpu_offset;
1196 int irq; 1230 int irq, ret;
1197 1231
1198 if (WARN_ON(!node)) 1232 if (WARN_ON(!node))
1199 return -ENODEV; 1233 return -ENODEV;
@@ -1218,8 +1252,14 @@ gic_of_init(struct device_node *node, struct device_node *parent)
1218 if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) 1252 if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
1219 percpu_offset = 0; 1253 percpu_offset = 0;
1220 1254
1221 __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, 1255 ret = __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset,
1222 &node->fwnode); 1256 &node->fwnode);
1257 if (ret) {
1258 iounmap(dist_base);
1259 iounmap(cpu_base);
1260 return ret;
1261 }
1262
1223 if (!gic_cnt) 1263 if (!gic_cnt)
1224 gic_init_physaddr(node); 1264 gic_init_physaddr(node);
1225 1265
@@ -1308,7 +1348,7 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1308 struct acpi_madt_generic_distributor *dist; 1348 struct acpi_madt_generic_distributor *dist;
1309 void __iomem *cpu_base, *dist_base; 1349 void __iomem *cpu_base, *dist_base;
1310 struct fwnode_handle *domain_handle; 1350 struct fwnode_handle *domain_handle;
1311 int count; 1351 int count, ret;
1312 1352
1313 /* Collect CPU base addresses */ 1353 /* Collect CPU base addresses */
1314 count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, 1354 count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
@@ -1351,7 +1391,14 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1351 return -ENOMEM; 1391 return -ENOMEM;
1352 } 1392 }
1353 1393
1354 __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle); 1394 ret = __gic_init_bases(0, -1, dist_base, cpu_base, 0, domain_handle);
1395 if (ret) {
1396 pr_err("Failed to initialise GIC\n");
1397 irq_domain_free_fwnode(domain_handle);
1398 iounmap(cpu_base);
1399 iounmap(dist_base);
1400 return ret;
1401 }
1355 1402
1356 acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle); 1403 acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
1357 1404