Skip to content

Commit

Permalink
perf: arm_dsu: Support DSU ACPI devices
Browse files Browse the repository at this point in the history
Add support for probing device from ACPI node.
Each DSU ACPI node and its associated cpus are inside a cluster node.

Signed-off-by: Tuan Phan <[email protected]>
Reviewed-by: Suzuki K Poulose <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
Tuan Phan authored and willdeacon committed Sep 15, 2020
1 parent 44fdf4e commit 2b694fc
Showing 1 changed file with 57 additions and 6 deletions.
63 changes: 57 additions & 6 deletions drivers/perf/arm_dsu_pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define DRVNAME PMUNAME "_pmu"
#define pr_fmt(fmt) DRVNAME ": " fmt

#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/bug.h>
Expand Down Expand Up @@ -603,18 +604,19 @@ static struct dsu_pmu *dsu_pmu_alloc(struct platform_device *pdev)
}

/**
* dsu_pmu_dt_get_cpus: Get the list of CPUs in the cluster.
* dsu_pmu_dt_get_cpus: Get the list of CPUs in the cluster
* from device tree.
*/
static int dsu_pmu_dt_get_cpus(struct device_node *dev, cpumask_t *mask)
static int dsu_pmu_dt_get_cpus(struct device *dev, cpumask_t *mask)
{
int i = 0, n, cpu;
struct device_node *cpu_node;

n = of_count_phandle_with_args(dev, "cpus", NULL);
n = of_count_phandle_with_args(dev->of_node, "cpus", NULL);
if (n <= 0)
return -ENODEV;
for (; i < n; i++) {
cpu_node = of_parse_phandle(dev, "cpus", i);
cpu_node = of_parse_phandle(dev->of_node, "cpus", i);
if (!cpu_node)
break;
cpu = of_cpu_node_to_id(cpu_node);
Expand All @@ -631,6 +633,36 @@ static int dsu_pmu_dt_get_cpus(struct device_node *dev, cpumask_t *mask)
return 0;
}

/**
* dsu_pmu_acpi_get_cpus: Get the list of CPUs in the cluster
* from ACPI.
*/
static int dsu_pmu_acpi_get_cpus(struct device *dev, cpumask_t *mask)
{
#ifdef CONFIG_ACPI
int cpu;

/*
* A dsu pmu node is inside a cluster parent node along with cpu nodes.
* We need to find out all cpus that have the same parent with this pmu.
*/
for_each_possible_cpu(cpu) {
struct acpi_device *acpi_dev;
struct device *cpu_dev = get_cpu_device(cpu);

if (!cpu_dev)
continue;

acpi_dev = ACPI_COMPANION(cpu_dev);
if (acpi_dev &&
acpi_dev->parent == ACPI_COMPANION(dev)->parent)
cpumask_set_cpu(cpu, mask);
}
#endif

return 0;
}

/*
* dsu_pmu_probe_pmu: Probe the PMU details on a CPU in the cluster.
*/
Expand Down Expand Up @@ -676,14 +708,24 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
{
int irq, rc;
struct dsu_pmu *dsu_pmu;
struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev);
char *name;
static atomic_t pmu_idx = ATOMIC_INIT(-1);

dsu_pmu = dsu_pmu_alloc(pdev);
if (IS_ERR(dsu_pmu))
return PTR_ERR(dsu_pmu);

rc = dsu_pmu_dt_get_cpus(pdev->dev.of_node, &dsu_pmu->associated_cpus);
if (IS_ERR_OR_NULL(fwnode))
return -ENOENT;

if (is_of_node(fwnode))
rc = dsu_pmu_dt_get_cpus(&pdev->dev, &dsu_pmu->associated_cpus);
else if (is_acpi_device_node(fwnode))
rc = dsu_pmu_acpi_get_cpus(&pdev->dev, &dsu_pmu->associated_cpus);
else
return -ENOENT;

if (rc) {
dev_warn(&pdev->dev, "Failed to parse the CPUs\n");
return rc;
Expand Down Expand Up @@ -752,11 +794,21 @@ static const struct of_device_id dsu_pmu_of_match[] = {
{ .compatible = "arm,dsu-pmu", },
{},
};
MODULE_DEVICE_TABLE(of, dsu_pmu_of_match);

#ifdef CONFIG_ACPI
static const struct acpi_device_id dsu_pmu_acpi_match[] = {
{ "ARMHD500", 0},
{},
};
MODULE_DEVICE_TABLE(acpi, dsu_pmu_acpi_match);
#endif

static struct platform_driver dsu_pmu_driver = {
.driver = {
.name = DRVNAME,
.of_match_table = of_match_ptr(dsu_pmu_of_match),
.acpi_match_table = ACPI_PTR(dsu_pmu_acpi_match),
.suppress_bind_attrs = true,
},
.probe = dsu_pmu_device_probe,
Expand Down Expand Up @@ -826,7 +878,6 @@ static void __exit dsu_pmu_exit(void)
module_init(dsu_pmu_init);
module_exit(dsu_pmu_exit);

MODULE_DEVICE_TABLE(of, dsu_pmu_of_match);
MODULE_DESCRIPTION("Perf driver for ARM DynamIQ Shared Unit");
MODULE_AUTHOR("Suzuki K Poulose <[email protected]>");
MODULE_LICENSE("GPL v2");

0 comments on commit 2b694fc

Please sign in to comment.