1 /* 2 * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 3 * 4 * This work is licensed under the terms of the GNU LGPL, version 2. 5 */ 6 #include <devicetree.h> 7 #include <asm/gic.h> 8 #include <asm/io.h> 9 10 struct gicv2_data gicv2_data; 11 struct gicv3_data gicv3_data; 12 13 /* 14 * Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt 15 * Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt 16 */ 17 static bool 18 gic_get_dt_bases(const char *compatible, void **base1, void **base2) 19 { 20 struct dt_pbus_reg reg; 21 struct dt_device gic; 22 struct dt_bus bus; 23 int node, ret; 24 25 dt_bus_init_defaults(&bus); 26 dt_device_init(&gic, &bus, NULL); 27 28 node = dt_device_find_compatible(&gic, compatible); 29 assert(node >= 0 || node == -FDT_ERR_NOTFOUND); 30 31 if (node == -FDT_ERR_NOTFOUND) 32 return false; 33 34 dt_device_bind_node(&gic, node); 35 36 ret = dt_pbus_translate(&gic, 0, ®); 37 assert(ret == 0); 38 *base1 = ioremap(reg.addr, reg.size); 39 40 ret = dt_pbus_translate(&gic, 1, ®); 41 assert(ret == 0); 42 *base2 = ioremap(reg.addr, reg.size); 43 44 return true; 45 } 46 47 int gicv2_init(void) 48 { 49 return gic_get_dt_bases("arm,cortex-a15-gic", 50 &gicv2_data.dist_base, &gicv2_data.cpu_base); 51 } 52 53 int gicv3_init(void) 54 { 55 return gic_get_dt_bases("arm,gic-v3", &gicv3_data.dist_base, 56 &gicv3_data.redist_base[0]); 57 } 58 59 int gic_init(void) 60 { 61 if (gicv2_init()) 62 return 2; 63 else if (gicv3_init()) 64 return 3; 65 return 0; 66 } 67