Module Name: src Committed By: jmcneill Date: Sat Jun 29 12:53:05 UTC 2019
Modified Files: src/sys/arch/arm/fdt: pmu_fdt.c Log Message: Add support for multiple PMUs To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/fdt/pmu_fdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/fdt/pmu_fdt.c diff -u src/sys/arch/arm/fdt/pmu_fdt.c:1.5 src/sys/arch/arm/fdt/pmu_fdt.c:1.6 --- src/sys/arch/arm/fdt/pmu_fdt.c:1.5 Mon Jan 21 08:04:26 2019 +++ src/sys/arch/arm/fdt/pmu_fdt.c Sat Jun 29 12:53:05 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: pmu_fdt.c,v 1.5 2019/01/21 08:04:26 skrll Exp $ */ +/* $NetBSD: pmu_fdt.c,v 1.6 2019/06/29 12:53:05 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmu_fdt.c,v 1.5 2019/01/21 08:04:26 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmu_fdt.c,v 1.6 2019/06/29 12:53:05 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: pmu_fdt.c,v #include <sys/cpu.h> #include <sys/interrupt.h> #include <sys/kmem.h> +#include <sys/xcall.h> #include <dev/fdt/fdtvar.h> @@ -52,6 +53,9 @@ __KERNEL_RCSID(0, "$NetBSD: pmu_fdt.c,v #include <arm/armreg.h> +static bool pmu_fdt_uses_ppi; +static int pmu_fdt_count; + static int pmu_fdt_match(device_t, cfdata_t, void *); static void pmu_fdt_attach(device_t, device_t, void *); @@ -109,20 +113,37 @@ pmu_fdt_attach(device_t parent, device_t } static void +pmu_fdt_init_cpu(void *arg1, void *arg2) +{ + arm_pmu_init(); +} + +static void pmu_fdt_init(device_t self) { struct pmu_fdt_softc * const sc = device_private(self); const int phandle = sc->sc_phandle; char intrstr[128]; int error, n; + uint64_t xc; void **ih; - error = arm_pmu_init(); - if (error != 0) { - aprint_error_dev(self, "failed to initialize PMU\n"); + if (pmu_fdt_uses_ppi && pmu_fdt_count > 0) { + /* + * Second instance of a PMU where PPIs are used. Since the PMU + * is already initialized and the PPI interrupt handler has + * already been installed, there is nothing left to do here. + */ + if (fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) + aprint_normal_dev(self, "interrupting on %s\n", intrstr); return; } + if (pmu_fdt_count == 0) { + xc = xc_broadcast(0, pmu_fdt_init_cpu, NULL, NULL); + xc_wait(xc); + } + ih = kmem_zalloc(sizeof(void *) * ncpu, KM_SLEEP); for (n = 0; n < ncpu; n++) { @@ -158,6 +179,9 @@ pmu_fdt_init(device_t self) } } + pmu_fdt_count++; + pmu_fdt_uses_ppi = nirq == 1 && ncpu > 1; + cleanup: kmem_free(ih, sizeof(void *) * ncpu); }