]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drivers/perf: hisi: Add a common function to retrieve topology from firmware
authorYicong Yang <yangyicong@hisilicon.com>
Tue, 10 Dec 2024 14:15:21 +0000 (22:15 +0800)
committerWill Deacon <will@kernel.org>
Tue, 10 Dec 2024 15:57:24 +0000 (15:57 +0000)
Currently each type of uncore PMU driver uses almost the same routine
and the same firmware interface (or properties) to retrieve the topology
information, then reset the unused IDs to -1. Extract the common parts
to the framework in hisi_uncore_pmu_init_topology().

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/20241210141525.37788-7-yangyicong@huawei.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
drivers/perf/hisilicon/hisi_uncore_pmu.c
drivers/perf/hisilicon/hisi_uncore_pmu.h
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
drivers/perf/hisilicon/hisi_uncore_uc_pmu.c

index 1a5c3fc26493118b166b93e6213e8c74fcf3a427..e3a619ea68313e9dfde805c119749c3feba36ff9 100644 (file)
@@ -180,20 +180,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_cpa_pmu_acpi_match);
 static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
                                  struct hisi_pmu *cpa_pmu)
 {
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &cpa_pmu->topo.sicl_id)) {
+       hisi_uncore_pmu_init_topology(cpa_pmu, &pdev->dev);
+
+       if (cpa_pmu->topo.sicl_id < 0) {
                dev_err(&pdev->dev, "Can not read sicl-id\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-                                    &cpa_pmu->topo.index_id)) {
+       if (cpa_pmu->topo.index_id < 0) {
                dev_err(&pdev->dev, "Cannot read idx-id\n");
                return -EINVAL;
        }
 
-       cpa_pmu->topo.ccl_id = -1;
-       cpa_pmu->topo.sccl_id = -1;
        cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(cpa_pmu->base))
                return PTR_ERR(cpa_pmu->base);
index 01aab39c0c66f53de589942a12789184acc904e3..1d12384fef8f44ff3b4d776e829bfb434ec61fe3 100644 (file)
@@ -297,6 +297,8 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
 static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
                                   struct hisi_pmu *ddrc_pmu)
 {
+       hisi_uncore_pmu_init_topology(ddrc_pmu, &pdev->dev);
+
        /*
         * Use the SCCL_ID and DDRC channel ID to identify the
         * DDRC PMU, while SCCL_ID is in MPIDR[aff2].
@@ -307,13 +309,10 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &ddrc_pmu->topo.sccl_id)) {
+       if (ddrc_pmu->topo.sccl_id < 0) {
                dev_err(&pdev->dev, "Can not read ddrc sccl-id!\n");
                return -EINVAL;
        }
-       /* DDRC PMUs only share the same SCCL */
-       ddrc_pmu->topo.ccl_id = -1;
 
        ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(ddrc_pmu->base)) {
@@ -323,8 +322,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
 
        ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
        if (ddrc_pmu->identifier >= HISI_PMU_V2) {
-               if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-                                            &ddrc_pmu->topo.sub_id)) {
+               if (ddrc_pmu->topo.sub_id < 0) {
                        dev_err(&pdev->dev, "Can not read sub-id!\n");
                        return -EINVAL;
                }
index c96fcc919e3d4812fa61092e01d00cc4ca882488..a2b9629a60816c483aecb76bd6ba7765d4d41b0d 100644 (file)
@@ -295,12 +295,13 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
        unsigned long long id;
        acpi_status status;
 
+       hisi_uncore_pmu_init_topology(hha_pmu, &pdev->dev);
+
        /*
         * Use SCCL_ID and UID to identify the HHA PMU, while
         * SCCL_ID is in MPIDR[aff2].
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &hha_pmu->topo.sccl_id)) {
+       if (hha_pmu->topo.sccl_id < 0) {
                dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
                return -EINVAL;
        }
@@ -309,8 +310,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
         * Early versions of BIOS support _UID by mistake, so we support
         * both "hisilicon, idx-id" as preference, if available.
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-                                    &hha_pmu->topo.index_id)) {
+       if (hha_pmu->topo.index_id < 0) {
                status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
                                               "_UID", NULL, &id);
                if (ACPI_FAILURE(status)) {
@@ -320,8 +320,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
 
                hha_pmu->topo.index_id = id;
        }
-       /* HHA PMUs only share the same SCCL */
-       hha_pmu->topo.ccl_id = -1;
 
        hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hha_pmu->base)) {
index d9773edf542a84cdd3a0f7f5d13e86e83bbf2bda..5ba49e902535b4207dcd1957be1fcbd989ebf165 100644 (file)
@@ -355,18 +355,18 @@ MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
 static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
                                  struct hisi_pmu *l3c_pmu)
 {
+       hisi_uncore_pmu_init_topology(l3c_pmu, &pdev->dev);
+
        /*
         * Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
         * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &l3c_pmu->topo.sccl_id)) {
+       if (l3c_pmu->topo.sccl_id < 0) {
                dev_err(&pdev->dev, "Can not read l3c sccl-id!\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-                                    &l3c_pmu->topo.ccl_id)) {
+       if (l3c_pmu->topo.ccl_id < 0) {
                dev_err(&pdev->dev, "Can not read l3c ccl-id!\n");
                return -EINVAL;
        }
index 648de8355b3f38f5851d168bdc1c7f0a1cfc285b..48c5357666d06ee12401c858abde64d022812311 100644 (file)
@@ -269,25 +269,22 @@ static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
 static int hisi_pa_pmu_init_data(struct platform_device *pdev,
                                   struct hisi_pmu *pa_pmu)
 {
+       hisi_uncore_pmu_init_topology(pa_pmu, &pdev->dev);
+
        /*
         * As PA PMU is in a SICL, use the SICL_ID and the index ID
         * to identify the PA PMU.
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &pa_pmu->topo.sicl_id)) {
+       if (pa_pmu->topo.sicl_id < 0) {
                dev_err(&pdev->dev, "Cannot read sicl-id!\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-                                    &pa_pmu->topo.index_id)) {
+       if (pa_pmu->topo.index_id < 0) {
                dev_err(&pdev->dev, "Cannot read idx-id!\n");
                return -EINVAL;
        }
 
-       pa_pmu->topo.ccl_id = -1;
-       pa_pmu->topo.sccl_id = -1;
-
        pa_pmu->dev_info = device_get_match_data(&pdev->dev);
        if (!pa_pmu->dev_info)
                return -ENODEV;
index b01852a710ada2d959aa85adfae2cdb24f704f01..5f581327a71f646cbcd18f692167e28c3642351c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/property.h>
 
 #include <asm/cputype.h>
 #include <asm/local64.h>
@@ -530,6 +531,35 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
 }
 EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_offline_cpu, "HISI_PMU");
 
+/*
+ * Retrieve the topology information from the firmware for the hisi_pmu device.
+ * The topology ID will be -1 if we cannot initialize it, it may either due to
+ * the PMU doesn't locate on this certain topology or the firmware needs to be
+ * fixed.
+ */
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev)
+{
+       struct hisi_pmu_topology *topo = &hisi_pmu->topo;
+
+       topo->sccl_id = -1;
+       topo->ccl_id = -1;
+       topo->index_id = -1;
+       topo->sub_id = -1;
+
+       if (device_property_read_u32(dev, "hisilicon,scl-id", &topo->sccl_id))
+               dev_dbg(dev, "no scl-id present\n");
+
+       if (device_property_read_u32(dev, "hisilicon,ccl-id", &topo->ccl_id))
+               dev_dbg(dev, "no ccl-id present\n");
+
+       if (device_property_read_u32(dev, "hisilicon,idx-id", &topo->index_id))
+               dev_dbg(dev, "no idx-id present\n");
+
+       if (device_property_read_u32(dev, "hisilicon,sub-id", &topo->sub_id))
+               dev_dbg(dev, "no sub-id present\n");
+}
+EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_init_topology, "HISI_PMU");
+
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
 {
        struct pmu *pmu = &hisi_pmu->pmu;
index f162a1b6c6d1dbc082acdedb2c1f327a860cd63d..53b1331b8565e25a03fe5316e49d3ed479798d95 100644 (file)
@@ -160,6 +160,7 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
                                             char *page);
 int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
                             struct platform_device *pdev);
+void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct device *dev);
 
 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
 #endif /* __HISI_UNCORE_PMU_H__ */
index 32cb23a7cf5d748fa1a13a65fbe71a2321ca7630..ba6af0d3cb2252ea6205bd7e85cd07bfe8b3978f 100644 (file)
@@ -288,25 +288,22 @@ MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
 static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
                                   struct hisi_pmu *sllc_pmu)
 {
+       hisi_uncore_pmu_init_topology(sllc_pmu, &pdev->dev);
+
        /*
         * Use the SCCL_ID and the index ID to identify the SLLC PMU,
         * while SCCL_ID is from MPIDR_EL1 by CPU.
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &sllc_pmu->topo.sccl_id)) {
+       if (sllc_pmu->topo.sccl_id < 0) {
                dev_err(&pdev->dev, "Cannot read sccl-id!\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
-                                    &sllc_pmu->topo.index_id)) {
+       if (sllc_pmu->topo.index_id < 0) {
                dev_err(&pdev->dev, "Cannot read idx-id!\n");
                return -EINVAL;
        }
 
-       /* SLLC PMUs only share the same SCCL */
-       sllc_pmu->topo.ccl_id = -1;
-
        sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sllc_pmu->base)) {
                dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
index bc51d45c8ef9acdce184d6560419d401bc8996b1..ba35c9476340d5717b79e52790fb5ce207560346 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
-#include <linux/property.h>
 
 #include "hisi_uncore_pmu.h"
 
@@ -366,25 +365,24 @@ static void hisi_uc_pmu_clear_int_status(struct hisi_pmu *uc_pmu, int idx)
 static int hisi_uc_pmu_init_data(struct platform_device *pdev,
                                 struct hisi_pmu *uc_pmu)
 {
+       hisi_uncore_pmu_init_topology(uc_pmu, &pdev->dev);
+
        /*
         * Use SCCL (Super CPU Cluster) ID and CCL (CPU Cluster) ID to
         * identify the topology information of UC PMU devices in the chip.
         * They have some CCLs per SCCL and then 4 UC PMU per CCL.
         */
-       if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
-                                    &uc_pmu->topo.sccl_id)) {
+       if (uc_pmu->topo.sccl_id < 0) {
                dev_err(&pdev->dev, "Can not read uc sccl-id!\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
-                                    &uc_pmu->topo.ccl_id)) {
+       if (uc_pmu->topo.ccl_id < 0) {
                dev_err(&pdev->dev, "Can not read uc ccl-id!\n");
                return -EINVAL;
        }
 
-       if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
-                                    &uc_pmu->topo.sub_id)) {
+       if (uc_pmu->topo.sub_id < 0) {
                dev_err(&pdev->dev, "Can not read sub-id!\n");
                return -EINVAL;
        }