perf: arm_dsu: Support DSU ACPI devices
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 <tuanphan@os.amperecomputing.com> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/1600106656-9542-1-git-send-email-tuanphan@os.amperecomputing.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
44fdf4ed26
commit
2b694fc92a
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -676,6 +708,7 @@ 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);
|
||||
|
||||
|
@ -683,7 +716,16 @@ static int dsu_pmu_device_probe(struct platform_device *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;
|
||||
|
@ -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,
|
||||
|
@ -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 <suzuki.poulose@arm.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
Loading…
Reference in New Issue