Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm-cci: Rearrange code for splitting PMU vs driver code

No functional changes, only code re-arrangements for easier split of the
PMU code vs low level driver code. Extracts the port handling code
to cci_probe_ports().

Tested-by: Sudeep Holla <sudeep.holla@arm.com>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Acked-by: Punit Agrawal <punit.agrawal@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

Suzuki K. Poulose and committed by
Will Deacon
f6b9e83c b1862199

+163 -163
+163 -163
drivers/bus/arm-cci.c
··· 29 29 #include <asm/cacheflush.h> 30 30 #include <asm/smp_plat.h> 31 31 32 - #define DRIVER_NAME "CCI-400" 33 - #define DRIVER_NAME_PMU DRIVER_NAME " PMU" 34 - 35 - #define CCI_PORT_CTRL 0x0 36 - #define CCI_CTRL_STATUS 0xc 37 - 38 - #define CCI_ENABLE_SNOOP_REQ 0x1 39 - #define CCI_ENABLE_DVM_REQ 0x2 40 - #define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ) 32 + static void __iomem *cci_ctrl_base; 33 + static unsigned long cci_ctrl_phys; 41 34 42 35 struct cci_nb_ports { 43 36 unsigned int nb_ace; 44 37 unsigned int nb_ace_lite; 45 38 }; 46 39 47 - enum cci_ace_port_type { 48 - ACE_INVALID_PORT = 0x0, 49 - ACE_PORT, 50 - ACE_LITE_PORT, 40 + static const struct cci_nb_ports cci400_ports = { 41 + .nb_ace = 2, 42 + .nb_ace_lite = 3 51 43 }; 52 44 53 - struct cci_ace_port { 54 - void __iomem *base; 55 - unsigned long phys; 56 - enum cci_ace_port_type type; 57 - struct device_node *dn; 45 + static const struct of_device_id arm_cci_matches[] = { 46 + {.compatible = "arm,cci-400", .data = &cci400_ports }, 47 + {}, 58 48 }; 59 - 60 - static struct cci_ace_port *ports; 61 - static unsigned int nb_cci_ports; 62 - 63 - static void __iomem *cci_ctrl_base; 64 - static unsigned long cci_ctrl_phys; 65 49 66 50 #ifdef CONFIG_HW_PERF_EVENTS 51 + 52 + #define DRIVER_NAME "CCI-400" 53 + #define DRIVER_NAME_PMU DRIVER_NAME " PMU" 67 54 68 55 #define CCI_PMCR 0x0100 69 56 #define CCI_PID2 0x0fe8 ··· 61 74 62 75 #define CCI_PID2_REV_MASK 0xf0 63 76 #define CCI_PID2_REV_SHIFT 4 77 + 78 + #define CCI_PMU_EVT_SEL 0x000 79 + #define CCI_PMU_CNTR 0x004 80 + #define CCI_PMU_CNTR_CTRL 0x008 81 + #define CCI_PMU_OVRFLW 0x00c 82 + 83 + #define CCI_PMU_OVRFLW_FLAG 1 84 + 85 + #define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K) 86 + 87 + #define CCI_PMU_CNTR_MASK ((1ULL << 32) -1) 88 + 89 + #define CCI_PMU_EVENT_MASK 0xff 90 + #define CCI_PMU_EVENT_SOURCE(event) ((event >> 5) & 0x7) 91 + #define CCI_PMU_EVENT_CODE(event) (event & 0x1f) 92 + 93 + #define CCI_PMU_MAX_HW_EVENTS 5 /* CCI PMU has 4 counters + 1 cycle counter */ 94 + 95 + struct cci_pmu_hw_events { 96 + struct perf_event *events[CCI_PMU_MAX_HW_EVENTS]; 97 + unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)]; 98 + raw_spinlock_t pmu_lock; 99 + }; 100 + 101 + struct cci_pmu { 102 + void __iomem *base; 103 + struct pmu pmu; 104 + int nr_irqs; 105 + int irqs[CCI_PMU_MAX_HW_EVENTS]; 106 + unsigned long active_irqs; 107 + struct pmu_port_event_ranges *port_ranges; 108 + struct cci_pmu_hw_events hw_events; 109 + struct platform_device *plat_device; 110 + int num_events; 111 + atomic_t active_events; 112 + struct mutex reserve_mutex; 113 + cpumask_t cpus; 114 + }; 115 + static struct cci_pmu *pmu; 116 + 117 + #define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu)) 64 118 65 119 /* Port ids */ 66 120 #define CCI_PORT_S0 0 ··· 117 89 #define CCI_REV_R1 1 118 90 #define CCI_REV_R1_PX 5 119 91 120 - #define CCI_PMU_EVT_SEL 0x000 121 - #define CCI_PMU_CNTR 0x004 122 - #define CCI_PMU_CNTR_CTRL 0x008 123 - #define CCI_PMU_OVRFLW 0x00c 124 - 125 - #define CCI_PMU_OVRFLW_FLAG 1 126 - 127 - #define CCI_PMU_CNTR_BASE(idx) ((idx) * SZ_4K) 128 - 129 - #define CCI_PMU_CNTR_MASK ((1ULL << 32) -1) 130 - 131 92 /* 132 93 * Instead of an event id to monitor CCI cycles, a dedicated counter is 133 94 * provided. Use 0xff to represent CCI cycles and hope that no future revisions ··· 125 108 enum cci400_perf_events { 126 109 CCI_PMU_CYCLES = 0xff 127 110 }; 128 - 129 - #define CCI_PMU_EVENT_MASK 0xff 130 - #define CCI_PMU_EVENT_SOURCE(event) ((event >> 5) & 0x7) 131 - #define CCI_PMU_EVENT_CODE(event) (event & 0x1f) 132 - 133 - #define CCI_PMU_MAX_HW_EVENTS 5 /* CCI PMU has 4 counters + 1 cycle counter */ 134 111 135 112 #define CCI_PMU_CYCLE_CNTR_IDX 0 136 113 #define CCI_PMU_CNTR0_IDX 1 ··· 183 172 [CCI_REV_R1] = "CCI_400_r1", 184 173 }; 185 174 186 - struct cci_pmu_hw_events { 187 - struct perf_event *events[CCI_PMU_MAX_HW_EVENTS]; 188 - unsigned long used_mask[BITS_TO_LONGS(CCI_PMU_MAX_HW_EVENTS)]; 189 - raw_spinlock_t pmu_lock; 190 - }; 191 - 192 - struct cci_pmu { 193 - void __iomem *base; 194 - struct pmu pmu; 195 - int nr_irqs; 196 - int irqs[CCI_PMU_MAX_HW_EVENTS]; 197 - unsigned long active_irqs; 198 - struct pmu_port_event_ranges *port_ranges; 199 - struct cci_pmu_hw_events hw_events; 200 - struct platform_device *plat_device; 201 - int num_events; 202 - atomic_t active_events; 203 - struct mutex reserve_mutex; 204 - cpumask_t cpus; 205 - }; 206 - static struct cci_pmu *pmu; 207 - 208 - #define to_cci_pmu(c) (container_of(c, struct cci_pmu, pmu)) 209 - 210 - static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) 211 - { 212 - int i; 213 - 214 - for (i = 0; i < nr_irqs; i++) 215 - if (irq == irqs[i]) 216 - return true; 217 - 218 - return false; 219 - } 220 - 221 - static int probe_cci_revision(void) 222 - { 223 - int rev; 224 - rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK; 225 - rev >>= CCI_PID2_REV_SHIFT; 226 - 227 - if (rev < CCI_REV_R1_PX) 228 - return CCI_REV_R0; 229 - else 230 - return CCI_REV_R1; 231 - } 232 - 233 - static struct pmu_port_event_ranges *port_range_by_rev(void) 234 - { 235 - int rev = probe_cci_revision(); 236 - 237 - return &port_event_range[rev]; 238 - } 239 - 240 175 static int pmu_is_valid_slave_event(u8 ev_code) 241 176 { 242 177 return pmu->port_ranges->slave_min <= ev_code && ··· 220 263 } 221 264 222 265 return -ENOENT; 266 + } 267 + 268 + static int probe_cci_revision(void) 269 + { 270 + int rev; 271 + rev = readl_relaxed(cci_ctrl_base + CCI_PID2) & CCI_PID2_REV_MASK; 272 + rev >>= CCI_PID2_REV_SHIFT; 273 + 274 + if (rev < CCI_REV_R1_PX) 275 + return CCI_REV_R0; 276 + else 277 + return CCI_REV_R1; 278 + } 279 + 280 + static struct pmu_port_event_ranges *port_range_by_rev(void) 281 + { 282 + int rev = probe_cci_revision(); 283 + 284 + return &port_event_range[rev]; 223 285 } 224 286 225 287 static int pmu_is_valid_counter(struct cci_pmu *cci_pmu, int idx) ··· 878 902 {}, 879 903 }; 880 904 905 + static bool is_duplicate_irq(int irq, int *irqs, int nr_irqs) 906 + { 907 + int i; 908 + 909 + for (i = 0; i < nr_irqs; i++) 910 + if (irq == irqs[i]) 911 + return true; 912 + 913 + return false; 914 + } 915 + 881 916 static int cci_pmu_probe(struct platform_device *pdev) 882 917 { 883 918 struct resource *res; ··· 959 972 return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 960 973 } 961 974 975 + static struct platform_driver cci_pmu_driver = { 976 + .driver = { 977 + .name = DRIVER_NAME_PMU, 978 + .of_match_table = arm_cci_pmu_matches, 979 + }, 980 + .probe = cci_pmu_probe, 981 + }; 982 + 983 + static struct platform_driver cci_platform_driver = { 984 + .driver = { 985 + .name = DRIVER_NAME, 986 + .of_match_table = arm_cci_matches, 987 + }, 988 + .probe = cci_platform_probe, 989 + }; 990 + 991 + static int __init cci_platform_init(void) 992 + { 993 + int ret; 994 + 995 + ret = platform_driver_register(&cci_pmu_driver); 996 + if (ret) 997 + return ret; 998 + 999 + return platform_driver_register(&cci_platform_driver); 1000 + } 1001 + 1002 + #else /* !CONFIG_HW_PERF_EVENTS */ 1003 + 1004 + static int __init cci_platform_init(void) 1005 + { 1006 + return 0; 1007 + } 1008 + 962 1009 #endif /* CONFIG_HW_PERF_EVENTS */ 1010 + 1011 + #define CCI_PORT_CTRL 0x0 1012 + #define CCI_CTRL_STATUS 0xc 1013 + 1014 + #define CCI_ENABLE_SNOOP_REQ 0x1 1015 + #define CCI_ENABLE_DVM_REQ 0x2 1016 + #define CCI_ENABLE_REQ (CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ) 1017 + 1018 + enum cci_ace_port_type { 1019 + ACE_INVALID_PORT = 0x0, 1020 + ACE_PORT, 1021 + ACE_LITE_PORT, 1022 + }; 1023 + 1024 + struct cci_ace_port { 1025 + void __iomem *base; 1026 + unsigned long phys; 1027 + enum cci_ace_port_type type; 1028 + struct device_node *dn; 1029 + }; 1030 + 1031 + static struct cci_ace_port *ports; 1032 + static unsigned int nb_cci_ports; 963 1033 964 1034 struct cpu_port { 965 1035 u64 mpidr; ··· 1337 1293 } 1338 1294 EXPORT_SYMBOL_GPL(__cci_control_port_by_index); 1339 1295 1340 - static const struct cci_nb_ports cci400_ports = { 1341 - .nb_ace = 2, 1342 - .nb_ace_lite = 3 1343 - }; 1344 - 1345 - static const struct of_device_id arm_cci_matches[] = { 1346 - {.compatible = "arm,cci-400", .data = &cci400_ports }, 1347 - {}, 1348 - }; 1349 - 1350 1296 static const struct of_device_id arm_cci_ctrl_if_matches[] = { 1351 1297 {.compatible = "arm,cci-400-ctrl-if", }, 1352 1298 {}, 1353 1299 }; 1354 1300 1355 - static int cci_probe(void) 1301 + static int cci_probe_ports(struct device_node *np) 1356 1302 { 1357 1303 struct cci_nb_ports const *cci_config; 1358 1304 int ret, i, nb_ace = 0, nb_ace_lite = 0; 1359 - struct device_node *np, *cp; 1305 + struct device_node *cp; 1360 1306 struct resource res; 1361 1307 const char *match_str; 1362 1308 bool is_ace; 1363 1309 1364 - np = of_find_matching_node(NULL, arm_cci_matches); 1365 - if (!np) 1366 - return -ENODEV; 1367 - 1368 - if (!of_device_is_available(np)) 1369 - return -ENODEV; 1370 1310 1371 1311 cci_config = of_match_node(arm_cci_matches, np)->data; 1372 1312 if (!cci_config) ··· 1361 1333 ports = kcalloc(nb_cci_ports, sizeof(*ports), GFP_KERNEL); 1362 1334 if (!ports) 1363 1335 return -ENOMEM; 1364 - 1365 - ret = of_address_to_resource(np, 0, &res); 1366 - if (!ret) { 1367 - cci_ctrl_base = ioremap(res.start, resource_size(&res)); 1368 - cci_ctrl_phys = res.start; 1369 - } 1370 - if (ret || !cci_ctrl_base) { 1371 - WARN(1, "unable to ioremap CCI ctrl\n"); 1372 - ret = -ENXIO; 1373 - goto memalloc_err; 1374 - } 1375 1336 1376 1337 for_each_child_of_node(np, cp) { 1377 1338 if (!of_match_node(arm_cci_ctrl_if_matches, cp)) ··· 1421 1404 sync_cache_w(&cpu_port); 1422 1405 __sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports); 1423 1406 pr_info("ARM CCI driver probed\n"); 1407 + 1424 1408 return 0; 1409 + } 1425 1410 1426 - memalloc_err: 1411 + static int cci_probe(void) 1412 + { 1413 + int ret; 1414 + struct device_node *np; 1415 + struct resource res; 1427 1416 1428 - kfree(ports); 1429 - return ret; 1417 + np = of_find_matching_node(NULL, arm_cci_matches); 1418 + if(!np || !of_device_is_available(np)) 1419 + return -ENODEV; 1420 + 1421 + ret = of_address_to_resource(np, 0, &res); 1422 + if (!ret) { 1423 + cci_ctrl_base = ioremap(res.start, resource_size(&res)); 1424 + cci_ctrl_phys = res.start; 1425 + } 1426 + if (ret || !cci_ctrl_base) { 1427 + WARN(1, "unable to ioremap CCI ctrl\n"); 1428 + return -ENXIO; 1429 + } 1430 + 1431 + return cci_probe_ports(np); 1430 1432 } 1431 1433 1432 1434 static int cci_init_status = -EAGAIN; ··· 1463 1427 return cci_init_status; 1464 1428 } 1465 1429 1466 - #ifdef CONFIG_HW_PERF_EVENTS 1467 - static struct platform_driver cci_pmu_driver = { 1468 - .driver = { 1469 - .name = DRIVER_NAME_PMU, 1470 - .of_match_table = arm_cci_pmu_matches, 1471 - }, 1472 - .probe = cci_pmu_probe, 1473 - }; 1474 - 1475 - static struct platform_driver cci_platform_driver = { 1476 - .driver = { 1477 - .name = DRIVER_NAME, 1478 - .of_match_table = arm_cci_matches, 1479 - }, 1480 - .probe = cci_platform_probe, 1481 - }; 1482 - 1483 - static int __init cci_platform_init(void) 1484 - { 1485 - int ret; 1486 - 1487 - ret = platform_driver_register(&cci_pmu_driver); 1488 - if (ret) 1489 - return ret; 1490 - 1491 - return platform_driver_register(&cci_platform_driver); 1492 - } 1493 - 1494 - #else 1495 - 1496 - static int __init cci_platform_init(void) 1497 - { 1498 - return 0; 1499 - } 1500 - 1501 - #endif 1502 1430 /* 1503 1431 * To sort out early init calls ordering a helper function is provided to 1504 1432 * check if the CCI driver has beed initialized. Function check if the driver