aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@arm.com>2016-04-11 11:32:54 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2016-05-03 06:54:21 -0400
commit502d6df11ae394301470703fa6e485a0dc133401 (patch)
tree996904d7b5ddca66ea74ec31e3c9f29cb1ead7a1 /drivers/irqchip/irq-gic.c
parentbafa9193d00c7bfff4c4aea0d48cd2b55a6378c2 (diff)
irqchip/gic-v2: Parse and export virtual GIC information
For now, the firmware tables are parsed 2 times: once in the GIC drivers, the other timer when initializing the vGIC. It means code duplication and make more tedious to add the support for another firmware table (like ACPI). Introduce a new structure and set of helpers to get/set the virtual GIC information. Also fill up the structure for GICv2. Signed-off-by: Julien Grall <julien.grall@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7a73786596cd..3f1d9fd3a462 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -102,6 +102,8 @@ static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
102 102
103static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; 103static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly;
104 104
105static struct gic_kvm_info gic_v2_kvm_info;
106
105#ifdef CONFIG_GIC_NON_BANKED 107#ifdef CONFIG_GIC_NON_BANKED
106static void __iomem *gic_get_percpu_base(union gic_base *base) 108static void __iomem *gic_get_percpu_base(union gic_base *base)
107{ 109{
@@ -1189,6 +1191,29 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
1189 return true; 1191 return true;
1190} 1192}
1191 1193
1194static void __init gic_of_setup_kvm_info(struct device_node *node)
1195{
1196 int ret;
1197 struct resource *vctrl_res = &gic_v2_kvm_info.vctrl;
1198 struct resource *vcpu_res = &gic_v2_kvm_info.vcpu;
1199
1200 gic_v2_kvm_info.type = GIC_V2;
1201
1202 gic_v2_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
1203 if (!gic_v2_kvm_info.maint_irq)
1204 return;
1205
1206 ret = of_address_to_resource(node, 2, vctrl_res);
1207 if (ret)
1208 return;
1209
1210 ret = of_address_to_resource(node, 3, vcpu_res);
1211 if (ret)
1212 return;
1213
1214 gic_set_kvm_info(&gic_v2_kvm_info);
1215}
1216
1192int __init 1217int __init
1193gic_of_init(struct device_node *node, struct device_node *parent) 1218gic_of_init(struct device_node *node, struct device_node *parent)
1194{ 1219{
@@ -1218,8 +1243,10 @@ gic_of_init(struct device_node *node, struct device_node *parent)
1218 1243
1219 __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, 1244 __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset,
1220 &node->fwnode); 1245 &node->fwnode);
1221 if (!gic_cnt) 1246 if (!gic_cnt) {
1222 gic_init_physaddr(node); 1247 gic_init_physaddr(node);
1248 gic_of_setup_kvm_info(node);
1249 }
1223 1250
1224 if (parent) { 1251 if (parent) {
1225 irq = irq_of_parse_and_map(node, 0); 1252 irq = irq_of_parse_and_map(node, 0);
@@ -1248,6 +1275,10 @@ IRQCHIP_DECLARE(pl390, "arm,pl390", gic_of_init);
1248static struct 1275static struct
1249{ 1276{
1250 phys_addr_t cpu_phys_base; 1277 phys_addr_t cpu_phys_base;
1278 u32 maint_irq;
1279 int maint_irq_mode;
1280 phys_addr_t vctrl_base;
1281 phys_addr_t vcpu_base;
1251} acpi_data __initdata; 1282} acpi_data __initdata;
1252 1283
1253static int __init 1284static int __init
@@ -1272,6 +1303,12 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
1272 return -EINVAL; 1303 return -EINVAL;
1273 1304
1274 acpi_data.cpu_phys_base = gic_cpu_base; 1305 acpi_data.cpu_phys_base = gic_cpu_base;
1306 acpi_data.maint_irq = processor->vgic_interrupt;
1307 acpi_data.maint_irq_mode = (processor->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
1308 ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
1309 acpi_data.vctrl_base = processor->gich_base_address;
1310 acpi_data.vcpu_base = processor->gicv_base_address;
1311
1275 cpu_base_assigned = 1; 1312 cpu_base_assigned = 1;
1276 return 0; 1313 return 0;
1277} 1314}
@@ -1302,6 +1339,41 @@ static bool __init gic_validate_dist(struct acpi_subtable_header *header,
1302 1339
1303#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) 1340#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K)
1304#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) 1341#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K)
1342#define ACPI_GICV2_VCTRL_MEM_SIZE (SZ_4K)
1343#define ACPI_GICV2_VCPU_MEM_SIZE (SZ_8K)
1344
1345static void __init gic_acpi_setup_kvm_info(void)
1346{
1347 int irq;
1348 struct resource *vctrl_res = &gic_v2_kvm_info.vctrl;
1349 struct resource *vcpu_res = &gic_v2_kvm_info.vcpu;
1350
1351 gic_v2_kvm_info.type = GIC_V2;
1352
1353 if (!acpi_data.vctrl_base)
1354 return;
1355
1356 vctrl_res->flags = IORESOURCE_MEM;
1357 vctrl_res->start = acpi_data.vctrl_base;
1358 vctrl_res->end = vctrl_res->start + ACPI_GICV2_VCTRL_MEM_SIZE - 1;
1359
1360 if (!acpi_data.vcpu_base)
1361 return;
1362
1363 vcpu_res->flags = IORESOURCE_MEM;
1364 vcpu_res->start = acpi_data.vcpu_base;
1365 vcpu_res->end = vcpu_res->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
1366
1367 irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
1368 acpi_data.maint_irq_mode,
1369 ACPI_ACTIVE_HIGH);
1370 if (irq <= 0)
1371 return;
1372
1373 gic_v2_kvm_info.maint_irq = irq;
1374
1375 gic_set_kvm_info(&gic_v2_kvm_info);
1376}
1305 1377
1306static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, 1378static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1307 const unsigned long end) 1379 const unsigned long end)
@@ -1359,6 +1431,8 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1359 if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) 1431 if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
1360 gicv2m_init(NULL, gic_data[0].domain); 1432 gicv2m_init(NULL, gic_data[0].domain);
1361 1433
1434 gic_acpi_setup_kvm_info();
1435
1362 return 0; 1436 return 0;
1363} 1437}
1364IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 1438IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,