int arm_pmu_device_probe(struct platform_device *pdev, const struct of_device_id *of_table, const struct pmu_probe_info *probe_table) { const struct of_device_id *of_id; armpmu_init_fn init_fn; struct device_node *node = pdev->dev.of_node; struct arm_pmu *pmu; int ret = -ENODEV; pmu = armpmu_alloc(); if (!pmu) return -ENOMEM; pmu->plat_device = pdev; ret = pmu_parse_irqs(pmu); if (ret) goto out_free; if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { init_fn = of_id->data; pmu->secure_access = of_property_read_bool(pdev->dev.of_node, "secure-reg-access"); /* arm64 systems boot only as non-secure */ if (IS_ENABLED(CONFIG_ARM64) && pmu->secure_access) { pr_warn("ignoring \"secure-reg-access\" property for arm64\n"); pmu->secure_access = false; } ret = init_fn(pmu); } else if (probe_table) { cpumask_setall(&pmu->supported_cpus); ret = probe_current_pmu(pmu, probe_table); } if (ret) { pr_info("%pOF: failed to probe PMU!\n", node); goto out_free; } ret = armpmu_request_irqs(pmu); if (ret) goto out_free_irqs; ret = armpmu_register(pmu); if (ret) goto out_free; return 0; out_free_irqs: armpmu_free_irqs(pmu); out_free: pr_info("%pOF: failed to register PMU devices!\n", node); armpmu_free(pmu); return ret; }
static int cpu_pmu_device_probe(struct platform_device *pdev) { const struct of_device_id *of_id; const int (*init_fn)(struct arm_pmu *); struct device_node *node = pdev->dev.of_node; struct arm_pmu *pmu; int ret = -ENODEV; if (cpu_pmu) { pr_info("attempt to register multiple PMU devices!\n"); return -ENOSPC; } pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL); if (!pmu) { pr_info("failed to allocate PMU device!\n"); return -ENOMEM; } cpu_pmu = pmu; cpu_pmu->plat_device = pdev; if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) { init_fn = of_id->data; ret = of_pmu_irq_cfg(pdev); if (!ret) ret = init_fn(pmu); } else { ret = probe_current_pmu(pmu); } if (ret) { pr_info("failed to probe PMU!\n"); goto out_free; } ret = cpu_pmu_init(cpu_pmu); if (ret) goto out_free; ret = armpmu_register(cpu_pmu, -1); if (ret) goto out_destroy; return 0; out_destroy: cpu_pmu_destroy(cpu_pmu); out_free: pr_info("failed to register PMU devices!\n"); kfree(pmu); return ret; }
int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { int pmu_idx = 0; int cpu, ret; /* * Initialise and register the set of PMUs which we know about right * now. Ideally we'd do this in arm_pmu_acpi_cpu_starting() so that we * could handle late hotplug, but this may lead to deadlock since we * might try to register a hotplug notifier instance from within a * hotplug notifier. * * There's also the problem of having access to the right init_fn, * without tying this too deeply into the "real" PMU driver. * * For the moment, as with the platform/DT case, we need at least one * of a PMU's CPUs to be online at probe time. */ for_each_possible_cpu(cpu) { struct arm_pmu *pmu = per_cpu(probed_pmus, cpu); char *base_name; if (!pmu || pmu->name) continue; ret = init_fn(pmu); if (ret == -ENODEV) { /* PMU not handled by this driver, or not present */ continue; } else if (ret) { pr_warn("Unable to initialise PMU for CPU%d\n", cpu); return ret; } base_name = pmu->name; pmu->name = kasprintf(GFP_KERNEL, "%s_%d", base_name, pmu_idx++); if (!pmu->name) { pr_warn("Unable to allocate PMU name for CPU%d\n", cpu); return -ENOMEM; } ret = armpmu_register(pmu); if (ret) { pr_warn("Failed to register PMU for CPU%d\n", cpu); kfree(pmu->name); return ret; } } return 0; }
static int __devinit l2x0pmu_device_probe(struct platform_device *pdev) { u32 aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); u32 debug = readl_relaxed(l2x0_base + L2X0_DEBUG_CTRL); l2x0_pmu.plat_device = pdev; if (!(aux & (1 << L2X0_AUX_CTRL_EVENT_MONITOR_SHIFT))) { pr_err("Ev Monitor is OFF. L2 counters disabled.\n"); return -EOPNOTSUPP; } pr_info("L2CC PMU device found. DEBUG_CTRL: %x\n", debug); /* Get value of dynamically allocated PMU type. */ if (!armpmu_register(&l2x0_pmu, "msm-l2", -1)) pmu_type = l2x0_pmu.pmu.type; else { pr_err("l2x0_pmu registration failed\n"); return -EOPNOTSUPP; } return 0; }