From nobody Fri Sep 25 19:19:51 2026 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 593BC395AC5 for ; Wed, 9 Sep 2026 07:23:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938586; cv=none; b=W8iUjZOUZLplKoXlO4WflLDf74lHlSP5uCkGopBXhvRmYNkIzPdtFEg1U+i/FsVTmKUX5xa6AV7/KiyNnzV6tVGXLyz5yek9SMBEviaTU8YK96XDawSCXGapnKrOhQ4kPGdWqSC4EuIXpKJ/XWfeZ0Cman/rCAgzgdUSu491uNg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938586; c=relaxed/simple; bh=0VcYBPXxQV6RtRrACTK8F/4BNFnDJR+ms5/SgX1n4VY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IHSRn+eLoRv/nfyg8XI6vi54Kuz6Z0FXblm4tobDFodJHzFEv0Vv7+NfQt37we3X/EOAhSQ6dHogtOsNa/xSvpxXP2wLqXb+c3qwzy+zoc25BZpDdSEpXxYlYKOkeJxQpei1BALbHB2JaJ8nkJJ06byZt69xHxsRarCny2xHrnI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=D2MryZzI; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=D2MryZzI; arc=none smtp.client-ip=45.249.212.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="D2MryZzI"; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="D2MryZzI" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=X3XS6557iUVxAH+TSGS8ZcMo2fQUNDkYGZxf+WlbOjo=; b=D2MryZzIiHoAcEKb6h5By7r/KXVUi2lLThQCP7hJTO5hipbYA4J4zY/JaQu/lc3LBA21QIMCX KFEefpXcOdw+WSO2cBHRFQWMEjhxnosQRgqnnRrVKmHHiLtj4cP7Ywo30wcJAhvAzSWX0yaYZDF YoUyMFjIzL7yMU7XvpVgg8s= Received: from canpmsgout04.his.huawei.com (unknown [172.19.92.133]) by szxga01-in.huawei.com (SkyGuard) with ESMTPS id 4hfsgv4jDlz1BFqW for ; Wed, 9 Sep 2026 15:22:03 +0800 (CST) dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=X3XS6557iUVxAH+TSGS8ZcMo2fQUNDkYGZxf+WlbOjo=; b=D2MryZzIiHoAcEKb6h5By7r/KXVUi2lLThQCP7hJTO5hipbYA4J4zY/JaQu/lc3LBA21QIMCX KFEefpXcOdw+WSO2cBHRFQWMEjhxnosQRgqnnRrVKmHHiLtj4cP7Ywo30wcJAhvAzSWX0yaYZDF YoUyMFjIzL7yMU7XvpVgg8s= Received: from mail.maildlp.com (unknown [172.19.162.223]) by canpmsgout04.his.huawei.com (SkyGuard) with ESMTPS id 4hfsS36KQbz1prm3; Wed, 9 Sep 2026 15:11:47 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id A993D40575; Wed, 9 Sep 2026 15:22:43 +0800 (CST) Received: from localhost.huawei.com (10.90.31.46) by whupemo500002.china.huawei.com (7.152.185.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 9 Sep 2026 15:22:42 +0800 From: Yushan Wang To: , , , , CC: , , , , , Subject: [PATCH v5 1/3] drivers/perf: hisi: Consolidate uncore PMU cpuhp states Date: Wed, 9 Sep 2026 15:22:38 +0800 Message-ID: <20260909072240.2308808-2-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260909072240.2308808-1-wangyushan12@huawei.com> References: <20260909072240.2308808-1-wangyushan12@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To whupemo500002.china.huawei.com (7.152.185.250) Content-Type: text/plain; charset="utf-8" Every HiSilicon uncore PMU driver allocates its own static cpuhp state even though they all register identical online/offline callbacks. This wastes slots in the cpuhp state enum and needlessly fragments the hotplug state space. Move the cpuhp state setup into the shared hisi_uncore_pmu framework: register a single dynamic state (CPUHP_AP_ONLINE_DYN) at framework module init and export it for all HiSilicon uncore PMU drivers to use. Drop the now-unused static CPUHP_AP_PERF_ARM_HISI_* entries from include/linux/cpuhotplug.h. The L3C PMU driver keeps a private dynamic state because it has its own hotplug callbacks for migrating multiple per-CPU interrupt affinities, but switches from its former static slot to CPUHP_AP_ONLINE_DYN for consistency. No intended functional changes. Reviewed-by: Robin Murphy Reviewed-by: Jonathan Cameron Signed-off-by: Yushan Wang --- drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c | 34 +++--------------- drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 34 +++--------------- drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 34 +++--------------- drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 21 +++++------ drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 35 ++---------------- drivers/perf/hisilicon/hisi_uncore_noc_pmu.c | 35 ++---------------- drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 34 +++--------------- drivers/perf/hisilicon/hisi_uncore_pmu.c | 25 +++++++++++++ drivers/perf/hisilicon/hisi_uncore_pmu.h | 2 ++ drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 34 +++--------------- drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 36 ++----------------- include/linux/cpuhotplug.h | 6 ---- 12 files changed, 67 insertions(+), 263 deletions(-) diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hi= silicon/hisi_uncore_cpa_pmu.c index b879b81adfdd..83967725c51c 100644 --- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c @@ -295,7 +295,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *p= dev) =20 /* Power Management should be disabled before using CPA PMU. */ hisi_cpa_pmu_disable_pm(cpa_pmu); - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &cpa_pmu->node); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); @@ -307,7 +307,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *p= dev) if (ret) { dev_err(cpa_pmu->dev, "PMU register failed\n"); cpuhp_state_remove_instance_nocalls( - CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, &cpa_pmu->node); + hisi_uncore_pmu_cpuhp_state, &cpa_pmu->node); hisi_cpa_pmu_enable_pm(cpa_pmu); return ret; } @@ -321,7 +321,7 @@ static void hisi_cpa_pmu_remove(struct platform_device = *pdev) struct hisi_pmu *cpa_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&cpa_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &cpa_pmu->node); hisi_cpa_pmu_enable_pm(cpa_pmu); } @@ -336,33 +336,7 @@ static struct platform_driver hisi_cpa_pmu_driver =3D { .remove =3D hisi_cpa_pmu_remove, }; =20 -static int __init hisi_cpa_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, - "AP_PERF_ARM_HISI_CPA_ONLINE", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret) { - pr_err("setup hotplug failed: %d\n", ret); - return ret; - } - - ret =3D platform_driver_register(&hisi_cpa_pmu_driver); - if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE); - - return ret; -} -module_init(hisi_cpa_pmu_module_init); - -static void __exit hisi_cpa_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_cpa_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE); -} -module_exit(hisi_cpa_pmu_module_exit); +module_platform_driver(hisi_cpa_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC CPA PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/h= isilicon/hisi_uncore_ddrc_pmu.c index 21c494881ca0..e905160523ee 100644 --- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c @@ -401,7 +401,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *= pdev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &ddrc_pmu->node); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug;\n", ret); @@ -414,7 +414,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *= pdev) if (ret) { dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n"); cpuhp_state_remove_instance_nocalls( - CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node); + hisi_uncore_pmu_cpuhp_state, &ddrc_pmu->node); } =20 return ret; @@ -425,7 +425,7 @@ static void hisi_ddrc_pmu_remove(struct platform_device= *pdev) struct hisi_pmu *ddrc_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&ddrc_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &ddrc_pmu->node); } =20 @@ -501,33 +501,7 @@ static struct platform_driver hisi_ddrc_pmu_driver =3D= { .remove =3D hisi_ddrc_pmu_remove, }; =20 -static int __init hisi_ddrc_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, - "AP_PERF_ARM_HISI_DDRC_ONLINE", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret) { - pr_err("DDRC PMU: setup hotplug, ret =3D %d\n", ret); - return ret; - } - - ret =3D platform_driver_register(&hisi_ddrc_pmu_driver); - if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE); - - return ret; -} -module_init(hisi_ddrc_pmu_module_init); - -static void __exit hisi_ddrc_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_ddrc_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE); -} -module_exit(hisi_ddrc_pmu_module_exit); +module_platform_driver(hisi_ddrc_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC DDRC uncore PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hi= silicon/hisi_uncore_hha_pmu.c index 97cfaa586a87..93a250b7abb8 100644 --- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c @@ -490,7 +490,7 @@ static int hisi_hha_pmu_probe(struct platform_device *p= dev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &hha_pmu->node); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); @@ -503,7 +503,7 @@ static int hisi_hha_pmu_probe(struct platform_device *p= dev) if (ret) { dev_err(hha_pmu->dev, "HHA PMU register failed!\n"); cpuhp_state_remove_instance_nocalls( - CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node); + hisi_uncore_pmu_cpuhp_state, &hha_pmu->node); } =20 return ret; @@ -514,7 +514,7 @@ static void hisi_hha_pmu_remove(struct platform_device = *pdev) struct hisi_pmu *hha_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&hha_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &hha_pmu->node); } =20 @@ -528,33 +528,7 @@ static struct platform_driver hisi_hha_pmu_driver =3D { .remove =3D hisi_hha_pmu_remove, }; =20 -static int __init hisi_hha_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, - "AP_PERF_ARM_HISI_HHA_ONLINE", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret) { - pr_err("HHA PMU: Error setup hotplug, ret =3D %d;\n", ret); - return ret; - } - - ret =3D platform_driver_register(&hisi_hha_pmu_driver); - if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE); - - return ret; -} -module_init(hisi_hha_pmu_module_init); - -static void __exit hisi_hha_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_hha_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE); -} -module_exit(hisi_hha_pmu_module_exit); +module_platform_driver(hisi_hha_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC HHA uncore PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hi= silicon/hisi_uncore_l3c_pmu.c index 56a88fb0d3c2..e40506e09702 100644 --- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c @@ -93,6 +93,8 @@ struct hisi_l3c_pmu_ext { bool support_ext; }; =20 +static enum cpuhp_state hisi_l3c_pmu_cpuhp_state; + static bool support_ext(struct hisi_l3c_pmu *pmu) { struct hisi_l3c_pmu_ext *l3c_pmu_ext =3D pmu->l3c_pmu.dev_info->private; @@ -844,8 +846,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *p= dev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, - &l3c_pmu->node); + ret =3D cpuhp_state_add_instance(hisi_l3c_pmu_cpuhp_state, &l3c_pmu->node= ); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); return ret; @@ -857,7 +858,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *p= dev) if (ret) { dev_err(l3c_pmu->dev, "L3C PMU register failed!\n"); cpuhp_state_remove_instance_nocalls( - CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node); + hisi_l3c_pmu_cpuhp_state, &l3c_pmu->node); } =20 return ret; @@ -868,7 +869,7 @@ static void hisi_l3c_pmu_remove(struct platform_device = *pdev) struct hisi_pmu *l3c_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&l3c_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_l3c_pmu_cpuhp_state, &l3c_pmu->node); } =20 @@ -938,20 +939,20 @@ static int hisi_l3c_pmu_offline_cpu(unsigned int cpu,= struct hlist_node *node) =20 static int __init hisi_l3c_pmu_module_init(void) { - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, + int ret =3D cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "AP_PERF_ARM_HISI_L3_ONLINE", hisi_l3c_pmu_online_cpu, hisi_l3c_pmu_offline_cpu); - if (ret) { + if (ret < 0) { pr_err("L3C PMU: Error setup hotplug, ret =3D %d\n", ret); return ret; } =20 + hisi_l3c_pmu_cpuhp_state =3D ret; + ret =3D platform_driver_register(&hisi_l3c_pmu_driver); if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE); + cpuhp_remove_multi_state(hisi_l3c_pmu_cpuhp_state); =20 return ret; } @@ -960,7 +961,7 @@ module_init(hisi_l3c_pmu_module_init); static void __exit hisi_l3c_pmu_module_exit(void) { platform_driver_unregister(&hisi_l3c_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE); + cpuhp_remove_multi_state(hisi_l3c_pmu_cpuhp_state); } module_exit(hisi_l3c_pmu_module_exit); =20 diff --git a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c b/drivers/perf/his= ilicon/hisi_uncore_mn_pmu.c index 246cc0333099..ad898153ff49 100644 --- a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c @@ -13,9 +13,6 @@ =20 #include "hisi_uncore_pmu.h" =20 -/* Dynamic CPU hotplug state used by MN PMU */ -static enum cpuhp_state hisi_mn_pmu_online; - /* MN register definition */ #define HISI_MN_DYNAMIC_CTRL_REG 0x400 #define HISI_MN_DYNAMIC_CTRL_EN BIT(0) @@ -291,7 +288,7 @@ static int hisi_mn_pmu_dev_init(struct platform_device = *pdev, =20 static void hisi_mn_pmu_remove_cpuhp(void *hotplug_node) { - cpuhp_state_remove_instance_nocalls(hisi_mn_pmu_online, hotplug_node); + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, hotplug_= node); } =20 static void hisi_mn_pmu_unregister(void *pmu) @@ -320,7 +317,7 @@ static int hisi_mn_pmu_probe(struct platform_device *pd= ev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(hisi_mn_pmu_online, &mn_pmu->node); + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &mn_pmu->no= de); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to register cpu hotplug\n"= ); =20 @@ -376,33 +373,7 @@ static struct platform_driver hisi_mn_pmu_driver =3D { .probe =3D hisi_mn_pmu_probe, }; =20 -static int __init hisi_mn_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "perf/hisi/mn:online= ", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret < 0) { - pr_err("hisi_mn_pmu: Failed to setup MN PMU hotplug: %d\n", ret); - return ret; - } - hisi_mn_pmu_online =3D ret; - - ret =3D platform_driver_register(&hisi_mn_pmu_driver); - if (ret) - cpuhp_remove_multi_state(hisi_mn_pmu_online); - - return ret; -} -module_init(hisi_mn_pmu_module_init); - -static void __exit hisi_mn_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_mn_pmu_driver); - cpuhp_remove_multi_state(hisi_mn_pmu_online); -} -module_exit(hisi_mn_pmu_module_exit); +module_platform_driver(hisi_mn_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC MN uncore PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_noc_pmu.c b/drivers/perf/hi= silicon/hisi_uncore_noc_pmu.c index 616f4af57db7..abf44fa46d17 100644 --- a/drivers/perf/hisilicon/hisi_uncore_noc_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_noc_pmu.c @@ -41,9 +41,6 @@ HISI_PMU_EVENT_ATTR_EXTRACTOR(ch, config1, 2, 0); HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_en, config1, 3, 3); =20 -/* Dynamic CPU hotplug state used by this PMU driver */ -static enum cpuhp_state hisi_noc_pmu_cpuhp_state; - struct hisi_noc_pmu_regs { u32 version; u32 pmu_ctrl; @@ -324,7 +321,7 @@ static int hisi_noc_pmu_dev_init(struct platform_device= *pdev, struct hisi_pmu * =20 static void hisi_noc_pmu_remove_cpuhp_instance(void *hotplug_node) { - cpuhp_state_remove_instance_nocalls(hisi_noc_pmu_cpuhp_state, hotplug_nod= e); + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, hotplug_= node); } =20 static void hisi_noc_pmu_unregister_pmu(void *pmu) @@ -353,7 +350,7 @@ static int hisi_noc_pmu_probe(struct platform_device *p= dev) if (ret) return ret; =20 - ret =3D cpuhp_state_add_instance(hisi_noc_pmu_cpuhp_state, &noc_pmu->node= ); + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &noc_pmu->n= ode); if (ret) return dev_err_probe(dev, ret, "Fail to register cpuhp instance\n"); =20 @@ -408,33 +405,7 @@ static struct platform_driver hisi_noc_pmu_driver =3D { .probe =3D hisi_noc_pmu_probe, }; =20 -static int __init hisi_noc_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "perf/hisi/noc:onlin= e", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret < 0) { - pr_err("hisi_noc_pmu: Fail to setup cpuhp callbacks, ret =3D %d\n", ret); - return ret; - } - hisi_noc_pmu_cpuhp_state =3D ret; - - ret =3D platform_driver_register(&hisi_noc_pmu_driver); - if (ret) - cpuhp_remove_multi_state(hisi_noc_pmu_cpuhp_state); - - return ret; -} -module_init(hisi_noc_pmu_module_init); - -static void __exit hisi_noc_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_noc_pmu_driver); - cpuhp_remove_multi_state(hisi_noc_pmu_cpuhp_state); -} -module_exit(hisi_noc_pmu_module_exit); +module_platform_driver(hisi_noc_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC Uncore NoC PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/his= ilicon/hisi_uncore_pa_pmu.c index 80108c63cb60..3d1e0af64260 100644 --- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c @@ -468,7 +468,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pd= ev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &pa_pmu->node); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); @@ -479,7 +479,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pd= ev) ret =3D perf_pmu_register(&pa_pmu->pmu, name, -1); if (ret) { dev_err(pa_pmu->dev, "PMU register failed, ret =3D %d\n", ret); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &pa_pmu->node); return ret; } @@ -493,7 +493,7 @@ static void hisi_pa_pmu_remove(struct platform_device *= pdev) struct hisi_pmu *pa_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&pa_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &pa_pmu->node); } =20 @@ -515,33 +515,7 @@ static struct platform_driver hisi_pa_pmu_driver =3D { .remove =3D hisi_pa_pmu_remove, }; =20 -static int __init hisi_pa_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, - "AP_PERF_ARM_HISI_PA_ONLINE", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret) { - pr_err("PA PMU: cpuhp state setup failed, ret =3D %d\n", ret); - return ret; - } - - ret =3D platform_driver_register(&hisi_pa_pmu_driver); - if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE); - - return ret; -} -module_init(hisi_pa_pmu_module_init); - -static void __exit hisi_pa_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_pa_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE); -} -module_exit(hisi_pa_pmu_module_exit); +module_platform_driver(hisi_pa_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon Protocol Adapter uncore PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisili= con/hisi_uncore_pmu.c index 77390d033d08..346c87594614 100644 --- a/drivers/perf/hisilicon/hisi_uncore_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c @@ -23,6 +23,9 @@ =20 #define HISI_MAX_PERIOD(nr) (GENMASK_ULL((nr) - 1, 0)) =20 +enum cpuhp_state hisi_uncore_pmu_cpuhp_state; +EXPORT_SYMBOL_NS_GPL(hisi_uncore_pmu_cpuhp_state, "HISI_PMU"); + /* * PMU event attributes */ @@ -618,5 +621,27 @@ void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct m= odule *module) } EXPORT_SYMBOL_NS_GPL(hisi_pmu_init, "HISI_PMU"); =20 +static int __init hisi_uncore_pmu_init(void) +{ + int ret; + + ret =3D cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "perf/hisi/uncore:on= line", + hisi_uncore_pmu_online_cpu, + hisi_uncore_pmu_offline_cpu); + if (ret < 0) + return ret; + + hisi_uncore_pmu_cpuhp_state =3D ret; + + return 0; +} +module_init(hisi_uncore_pmu_init); + +static void __exit hisi_uncore_pmu_exit(void) +{ + cpuhp_remove_multi_state(hisi_uncore_pmu_cpuhp_state); +} +module_exit(hisi_uncore_pmu_exit); + MODULE_DESCRIPTION("HiSilicon SoC uncore Performance Monitor driver framew= ork"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisili= con/hisi_uncore_pmu.h index 3ffe6acda653..e5a4b3898865 100644 --- a/drivers/perf/hisilicon/hisi_uncore_pmu.h +++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h @@ -171,4 +171,6 @@ int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu, void hisi_uncore_pmu_init_topology(struct hisi_pmu *hisi_pmu, struct devic= e *dev); =20 void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module); + +extern enum cpuhp_state hisi_uncore_pmu_cpuhp_state; #endif /* __HISI_UNCORE_PMU_H__ */ diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/h= isilicon/hisi_uncore_sllc_pmu.c index cd32d606df05..d01340ff2e5c 100644 --- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c @@ -503,7 +503,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *= pdev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &sllc_pmu->node); if (ret) { dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); @@ -515,7 +515,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *= pdev) ret =3D perf_pmu_register(&sllc_pmu->pmu, name, -1); if (ret) { dev_err(sllc_pmu->dev, "PMU register failed, ret =3D %d\n", ret); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &sllc_pmu->node); return ret; } @@ -530,7 +530,7 @@ static void hisi_sllc_pmu_remove(struct platform_device= *pdev) struct hisi_pmu *sllc_pmu =3D platform_get_drvdata(pdev); =20 perf_pmu_unregister(&sllc_pmu->pmu); - cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, &sllc_pmu->node); } =20 @@ -551,33 +551,7 @@ static struct platform_driver hisi_sllc_pmu_driver =3D= { .remove =3D hisi_sllc_pmu_remove, }; =20 -static int __init hisi_sllc_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, - "AP_PERF_ARM_HISI_SLLC_ONLINE", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret) { - pr_err("SLLC PMU: cpuhp state setup failed, ret =3D %d\n", ret); - return ret; - } - - ret =3D platform_driver_register(&hisi_sllc_pmu_driver); - if (ret) - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE); - - return ret; -} -module_init(hisi_sllc_pmu_module_init); - -static void __exit hisi_sllc_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_sllc_pmu_driver); - cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE); -} -module_exit(hisi_sllc_pmu_module_exit); +module_platform_driver(hisi_sllc_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SLLC uncore PMU driver"); diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/his= ilicon/hisi_uncore_uc_pmu.c index e8186b6e1687..b4d017a5d688 100644 --- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c @@ -13,9 +13,6 @@ =20 #include "hisi_uncore_pmu.h" =20 -/* Dynamic CPU hotplug state used by UC PMU */ -static enum cpuhp_state hisi_uc_pmu_online; - /* UC register definition */ #define HISI_UC_INT_MASK_REG 0x0800 #define HISI_UC_INT_STS_REG 0x0808 @@ -488,7 +485,7 @@ static int hisi_uc_pmu_dev_probe(struct platform_device= *pdev, =20 static void hisi_uc_pmu_remove_cpuhp_instance(void *hotplug_node) { - cpuhp_state_remove_instance_nocalls(hisi_uc_pmu_online, hotplug_node); + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, hotplug_= node); } =20 static void hisi_uc_pmu_unregister_pmu(void *pmu) @@ -518,7 +515,7 @@ static int hisi_uc_pmu_probe(struct platform_device *pd= ev) if (!name) return -ENOMEM; =20 - ret =3D cpuhp_state_add_instance(hisi_uc_pmu_online, &uc_pmu->node); + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &uc_pmu->no= de); if (ret) return dev_err_probe(&pdev->dev, ret, "Error registering hotplug\n"); =20 @@ -559,34 +556,7 @@ static struct platform_driver hisi_uc_pmu_driver =3D { .probe =3D hisi_uc_pmu_probe, }; =20 -static int __init hisi_uc_pmu_module_init(void) -{ - int ret; - - ret =3D cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, - "perf/hisi/uc:online", - hisi_uncore_pmu_online_cpu, - hisi_uncore_pmu_offline_cpu); - if (ret < 0) { - pr_err("UC PMU: Error setup hotplug, ret =3D %d\n", ret); - return ret; - } - hisi_uc_pmu_online =3D ret; - - ret =3D platform_driver_register(&hisi_uc_pmu_driver); - if (ret) - cpuhp_remove_multi_state(hisi_uc_pmu_online); - - return ret; -} -module_init(hisi_uc_pmu_module_init); - -static void __exit hisi_uc_pmu_module_exit(void) -{ - platform_driver_unregister(&hisi_uc_pmu_driver); - cpuhp_remove_multi_state(hisi_uc_pmu_online); -} -module_exit(hisi_uc_pmu_module_exit); +module_platform_driver(hisi_uc_pmu_driver); =20 MODULE_IMPORT_NS("HISI_PMU"); MODULE_DESCRIPTION("HiSilicon SoC UC uncore PMU driver"); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index feb32949aeea..1b6dba159bb2 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -209,12 +209,6 @@ enum cpuhp_state { CPUHP_AP_PERF_S390_SF_ONLINE, CPUHP_AP_PERF_ARM_CCI_ONLINE, CPUHP_AP_PERF_ARM_CCN_ONLINE, - CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, - CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, - CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, - CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, - CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, - CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, CPUHP_AP_PERF_ARM_L2X0_ONLINE, --=20 2.33.0 From nobody Fri Sep 25 19:19:51 2026 Received: from canpmsgout07.his.huawei.com (canpmsgout07.his.huawei.com [113.46.200.222]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 178BC44A415 for ; Wed, 9 Sep 2026 07:22:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.222 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938578; cv=none; b=UGQuhLF+qhKfIA6YPeK0G92VFaRyC98tFRaA/InQ3b5eGGLvoyuSKV1HJWud2mQJSYNvdofAWJ3VI4IcTUr2T7iQ+eDE5BWUvIuX3hcL46AJ7hvFwuuZNT1juTzbu8ps+1P/B5Qbw/3+5uy717cXhayL9bPmqGrJQWrTHcjMFLQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938578; c=relaxed/simple; bh=rgnlViJZM4Xmrgjuvmp/ynrrkNE7G8XhTv0NI/2kRps=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GpeaVoDNZMREP6ciB1fTFWM8kOG6MA1z9gvWQ4OYKF7c/hcfKrerHcy2IXfkMTUNlA2w6KFAcKO4YxoAT+vhA+HmzeRyu2aH7alv/FdX2bnHfxYGqnW/yCV4v77gdYdW5HBazx6oKwbqU55TJiLKCwCh5JyL3iKlnynjcWmH9Xw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=eil0470A; arc=none smtp.client-ip=113.46.200.222 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="eil0470A" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=svET0LgVcqJC3FmaZA/n+q+MCyDmHUcu6ERDJhjBdRU=; b=eil0470AaMOErGvwRhXJ+wsya93qsNPOb2JGPGhqfuEUmdRcYz/9yvvSoJDaTWw4A0y62VXUJ oy11mlZJTBh1J8xmypqRi8I4V/QH/ngjIDUux4e/w53Oc/k2ib00GazIkQAYHSr0tpl11mSJUoA Dhs/OunYzOWmi2nVsFXR01U= Received: from mail.maildlp.com (unknown [172.19.163.214]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4hfsS63zJkzLlX8; Wed, 9 Sep 2026 15:11:50 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id C19CE4056C; Wed, 9 Sep 2026 15:22:44 +0800 (CST) Received: from localhost.huawei.com (10.90.31.46) by whupemo500002.china.huawei.com (7.152.185.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 9 Sep 2026 15:22:43 +0800 From: Yushan Wang To: , , , , CC: , , , , , Subject: [PATCH v5 2/3] drivers/perf: hisi: Add support for uncore ITS PMU Date: Wed, 9 Sep 2026 15:22:39 +0800 Message-ID: <20260909072240.2308808-3-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260909072240.2308808-1-wangyushan12@huawei.com> References: <20260909072240.2308808-1-wangyushan12@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To whupemo500002.china.huawei.com (7.152.185.250) Content-Type: text/plain; charset="utf-8" The Interrupt Translation Service (ITS) PMU counts interrupts routed to the ITS by category (LPI/SGI/PPI event counts and latencies) and also collects micro-op statistics for the ITS itself. Add a driver for the ITS PMU on the HiSilicon uncore PMU framework. Like the NoC PMU it has no overflow interrupt, so the interrupt enable/disable callbacks are empty stubs. The PMU supports filtering counters by a 32-bit interrupt id (int_id), composed of a 16-bit DeviceID/PEID in the upper half and a 16-bit EventID/IntID in the lower half. The INT_ID filter is global to the PMU instance, so only one filtered event (int_en=3D1) may run at a time; opening a second filtered event returns -EINVAL. The filter slot is reserved at event_init() time and held for the lifetime of the event via event->destroy, so concurrent event_init() callers and events that are multiplexed out cannot race to clobber the hardware filter configuration. Document the int_id and int_en format attributes in Documentation/admin-guide/perf/hisi-pmu.rst. Signed-off-by: Yushan Wang --- Documentation/admin-guide/perf/hisi-pmu.rst | 16 + drivers/perf/hisilicon/Makefile | 2 +- drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 379 +++++++++++++++++++ 3 files changed, 396 insertions(+), 1 deletion(-) create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/ad= min-guide/perf/hisi-pmu.rst index d56b2d690709..8cb4711c9c37 100644 --- a/Documentation/admin-guide/perf/hisi-pmu.rst +++ b/Documentation/admin-guide/perf/hisi-pmu.rst @@ -128,6 +128,22 @@ channel with this option. The current supported channe= ls are as follows: 7. tt_en: NoC PMU supports counting only transactions that have tracetag s= et if this option is set. See the 2nd list for more information about traceta= g. =20 +8. int_id: ITS PMU supports filtering by interrupt id, which is defined by +hardware. Interrupt id takes up to 32 bits, and can be divided into 2 part= s: + +- Upper 16 bits: DeviceID if counting LPI, PEID if counting SGI/PPI. +- Lower 16 bits: EventID if counting LPI, IntID if counting SGI/PPI. + +int_id is a global configuration for each PMU instance: the filter applies= to +all counters, so the PMU can only run events that agree on it. An unfilter= ed +event (int_en not set) cannot run concurrently with a filtered one, and two +filtered events can run concurrently only if they filter the same int_id. +perf time-multiplexes any events that cannot coexist, rather than corrupti= ng +the counts. + +9. int_en: A one-bit flag to tell if int_id is used to filter the statisti= cs. It +allows filtering 0 DeviceID and EventID. + For HiSilicon uncore PMU v3 whose identifier is 0x40, some uncore PMUs are further divided into parts for finer granularity of tracing, each part has= its own dedicated PMU, and all such PMUs together cover the monitoring job of = events diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makef= ile index 186be3d02238..5f28cfdb8a72 100644 --- a/drivers/perf/hisilicon/Makefile +++ b/drivers/perf/hisilicon/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_HISI_PMU) +=3D hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \ hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \ hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o hisi_uncore_uc_pmu.o \ - hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o + hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o hisi_uncore_its_pmu.o =20 obj-$(CONFIG_HISI_PCIE_PMU) +=3D hisi_pcie_pmu.o obj-$(CONFIG_HNS3_PMU) +=3D hns3_pmu.o diff --git a/drivers/perf/hisilicon/hisi_uncore_its_pmu.c b/drivers/perf/hi= silicon/hisi_uncore_its_pmu.c new file mode 100644 index 000000000000..f97378985aba --- /dev/null +++ b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for HiSilicon Uncore ITS PMU device + * + * Copyright (c) 2026 HiSilicon Technologies Co., Ltd. + * Author: Yushan Wang + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hisi_uncore_pmu.h" + +#define ITS_PMU_VERSION 0x21000 +#define ITS_PMU_GLOBAL_CTRL 0x21004 +#define ITS_PMU_GLOBAL_CTRL_PMU_EN BIT(0) +#define ITS_PMU_COUNTER_CTRL 0x21008 +#define ITS_PMU_EVENT_CTRL 0x2100c +#define ITS_PMU_COUNTER0 0x21010 + +#define ITS_PMU_INT_ID_MASK 0x20008 +#define ITS_PMU_INT_ID_CTRL 0x20084 + +#define ITS_PMU_NR_COUNTERS 4 + +#define ITS_PMU_EVENT_CNTRn(cntr0, n) ((cntr0) + 8 * (n)) +#define ITS_PMU_CNTR_CTRL_MASK(n) GENMASK(8 * ((n) + 1) - 1, 8 * (n)) +#define ITS_PMU_CNTR_EVENT_CFG(n, e) ((e) << ((n) * 8)) +#define ITS_PMU_EVENT_CTRL_TYPE GENMASK(12, 0) + +HISI_PMU_EVENT_ATTR_EXTRACTOR(event, config, 31, 0); +HISI_PMU_EVENT_ATTR_EXTRACTOR(int_id, config1, 31, 0); +HISI_PMU_EVENT_ATTR_EXTRACTOR(int_en, config1, 32, 32); + +struct hisi_its_pmu_regs { + u32 version; + u32 pmu_ctrl; + u32 event_ctrl0; + u32 event_cntr0; + u32 cntr_ctrl; +}; + +static void hisi_its_pmu_write_evtype(struct hisi_pmu *pmu, int idx, u32 t= ype) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + u32 reg; + + reg =3D readl(pmu->base + reg_info->event_ctrl0); + reg &=3D ~ITS_PMU_CNTR_CTRL_MASK(idx); + reg |=3D ITS_PMU_CNTR_EVENT_CFG(idx, type); + writel(reg, pmu->base + reg_info->event_ctrl0); +} + +static u64 hisi_its_pmu_read_counter(struct hisi_pmu *pmu, + struct hw_perf_event *hwc) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + + return readq(pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->= idx)); +} + +static void hisi_its_pmu_write_counter(struct hisi_pmu *pmu, + struct hw_perf_event *hwc, u64 val) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + + writeq(val, pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->i= dx)); +} + +static void hisi_its_pmu_enable_counter(struct hisi_pmu *pmu, + struct hw_perf_event *hwc) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + u32 reg; + + reg =3D readl(pmu->base + reg_info->cntr_ctrl); + reg |=3D BIT(hwc->idx); + writel(reg, pmu->base + reg_info->cntr_ctrl); +} + +static void hisi_its_pmu_disable_counter(struct hisi_pmu *pmu, + struct hw_perf_event *hwc) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + u32 reg; + + reg =3D readl(pmu->base + reg_info->cntr_ctrl); + reg &=3D ~BIT(hwc->idx); + writel(reg, pmu->base + reg_info->cntr_ctrl); +} + +static void hisi_its_pmu_enable_counter_int(struct hisi_pmu *pmu, + struct hw_perf_event *hwc) +{ + /* No overflow interrupt; counters rely on the framework's priming. */ +} + +static void hisi_its_pmu_disable_counter_int(struct hisi_pmu *pmu, + struct hw_perf_event *hwc) +{ +} + +static void hisi_its_pmu_start_counters(struct hisi_pmu *pmu) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + u32 reg; + + reg =3D readl(pmu->base + reg_info->pmu_ctrl); + reg |=3D ITS_PMU_GLOBAL_CTRL_PMU_EN; + writel(reg, pmu->base + reg_info->pmu_ctrl); +} + +static void hisi_its_pmu_stop_counters(struct hisi_pmu *pmu) +{ + struct hisi_its_pmu_regs *reg_info =3D pmu->dev_info->private; + u32 reg; + + reg =3D readl(pmu->base + reg_info->pmu_ctrl); + reg &=3D ~ITS_PMU_GLOBAL_CTRL_PMU_EN; + writel(reg, pmu->base + reg_info->pmu_ctrl); +} + +static void hisi_its_pmu_enable_filter(struct perf_event *event) +{ + struct hisi_pmu *pmu =3D to_hisi_pmu(event->pmu); + u32 int_id =3D hisi_get_int_id(event); + u32 int_en =3D hisi_get_int_en(event); + + if (!int_en) + return; + + writel(int_id, pmu->base + ITS_PMU_INT_ID_CTRL); + /* Write 0 to this register to enable filtering with int_id. */ + writel(0, pmu->base + ITS_PMU_INT_ID_MASK); +} + +static void hisi_its_pmu_disable_filter(struct perf_event *event) +{ + struct hisi_pmu *pmu =3D to_hisi_pmu(event->pmu); + u32 int_en =3D hisi_get_int_en(event); + + if (!int_en) + return; + + writel(0, pmu->base + ITS_PMU_INT_ID_CTRL); + writel(-1U, pmu->base + ITS_PMU_INT_ID_MASK); +} + +/* + * The INT_ID filter is global to the PMU. Events can coexist only if they + * agree on it: both unfiltered, or both filtering the same int_id. + */ +static bool hisi_its_pmu_check_global_filter(struct perf_event *curr, + struct perf_event *new) +{ + u32 curr_en =3D hisi_get_int_en(curr); + u32 new_en =3D hisi_get_int_en(new); + + if (curr_en !=3D new_en) + return false; + + if (curr_en) + return hisi_get_int_id(curr) =3D=3D hisi_get_int_id(new); + + return true; +} + +static int hisi_its_pmu_get_event_idx(struct perf_event *event) +{ + struct hisi_pmu *pmu =3D to_hisi_pmu(event->pmu); + struct hisi_pmu_hwevents *pmu_events =3D &pmu->pmu_events; + int cur_idx; + + cur_idx =3D find_first_bit(pmu_events->used_mask, pmu->num_counters); + if (cur_idx !=3D pmu->num_counters && + !hisi_its_pmu_check_global_filter(pmu_events->hw_events[cur_idx], eve= nt)) + return -EINVAL; + + return hisi_uncore_pmu_get_event_idx(event); +} + +static const struct hisi_uncore_ops hisi_uncore_its_ops =3D { + .write_evtype =3D hisi_its_pmu_write_evtype, + .get_event_idx =3D hisi_its_pmu_get_event_idx, + .read_counter =3D hisi_its_pmu_read_counter, + .write_counter =3D hisi_its_pmu_write_counter, + .enable_counter =3D hisi_its_pmu_enable_counter, + .disable_counter =3D hisi_its_pmu_disable_counter, + .enable_counter_int =3D hisi_its_pmu_enable_counter_int, + .disable_counter_int =3D hisi_its_pmu_disable_counter_int, + .start_counters =3D hisi_its_pmu_start_counters, + .stop_counters =3D hisi_its_pmu_stop_counters, + .enable_filter =3D hisi_its_pmu_enable_filter, + .disable_filter =3D hisi_its_pmu_disable_filter, +}; + +static struct attribute *hisi_its_pmu_format_attrs[] =3D { + HISI_PMU_FORMAT_ATTR(event, "config:0-7"), + HISI_PMU_FORMAT_ATTR(int_id, "config1:0-31"), + HISI_PMU_FORMAT_ATTR(int_en, "config1:32-32"), + NULL +}; + +static const struct attribute_group hisi_its_pmu_format_group =3D { + .name =3D "format", + .attrs =3D hisi_its_pmu_format_attrs, +}; + +static struct attribute *hisi_its_pmu_events_attrs[] =3D { + HISI_PMU_EVENT_ATTR(lpi_num, 0xc0), + HISI_PMU_EVENT_ATTR(lpi_time, 0x80), + HISI_PMU_EVENT_ATTR(sgi_num, 0xc1), + HISI_PMU_EVENT_ATTR(sgi_time, 0x81), + HISI_PMU_EVENT_ATTR(ppi_num, 0xc2), + HISI_PMU_EVENT_ATTR(ppi_time, 0x82), + HISI_PMU_EVENT_ATTR(sl3_lpi_num, 0xc3), + HISI_PMU_EVENT_ATTR(sl3_sgi_num, 0xc4), + HISI_PMU_EVENT_ATTR(sl3_ppi_num, 0xc5), + HISI_PMU_EVENT_ATTR(sl0_ddr_read, 0xc9), + HISI_PMU_EVENT_ATTR(sl0_ddr_time, 0x89), + HISI_PMU_EVENT_ATTR(sl1_ddr_read, 0xca), + HISI_PMU_EVENT_ATTR(sl1_ddr_time, 0x8a), + HISI_PMU_EVENT_ATTR(sl2_ddr_read, 0xcb), + HISI_PMU_EVENT_ATTR(sl2_ddr_time, 0x8b), + HISI_PMU_EVENT_ATTR(cycles, 0xcc), + NULL +}; + +static const struct attribute_group hisi_its_pmu_events_group =3D { + .name =3D "events", + .attrs =3D hisi_its_pmu_events_attrs, +}; + +static const struct attribute_group *hisi_its_pmu_attr_groups[] =3D { + &hisi_its_pmu_format_group, + &hisi_its_pmu_events_group, + &hisi_pmu_cpumask_attr_group, + &hisi_pmu_identifier_group, + NULL +}; + +static int hisi_its_pmu_dev_init(struct platform_device *pdev, + struct hisi_pmu *pmu) +{ + struct hisi_its_pmu_regs *reg_info; + + hisi_uncore_pmu_init_topology(pmu, &pdev->dev); + + if (pmu->topo.scl_id < 0) + return dev_err_probe(&pdev->dev, -EINVAL, "failed to get scl-id\n"); + + if (pmu->topo.index_id < 0) + return dev_err_probe(&pdev->dev, -EINVAL, "failed to get idx-id\n"); + + pmu->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pmu->base)) + return dev_err_probe(&pdev->dev, PTR_ERR(pmu->base), + "fail to remap io memory\n"); + + pmu->dev_info =3D device_get_match_data(&pdev->dev); + if (!pmu->dev_info) + return -ENODEV; + + pmu->pmu_events.attr_groups =3D pmu->dev_info->attr_groups; + pmu->counter_bits =3D pmu->dev_info->counter_bits; + pmu->check_event =3D pmu->dev_info->check_event; + pmu->num_counters =3D ITS_PMU_NR_COUNTERS; + pmu->ops =3D &hisi_uncore_its_ops; + pmu->dev =3D &pdev->dev; + pmu->on_cpu =3D -1; + + reg_info =3D pmu->dev_info->private; + pmu->identifier =3D readl(pmu->base + reg_info->version); + + /* Reset the global INT_ID filter to disabled. */ + writel(0, pmu->base + ITS_PMU_INT_ID_CTRL); + writel(-1U, pmu->base + ITS_PMU_INT_ID_MASK); + + return 0; +} + +static void hisi_its_pmu_remove_cpuhp_instance(void *hotplug_node) +{ + cpuhp_state_remove_instance_nocalls(hisi_uncore_pmu_cpuhp_state, + hotplug_node); +} + +static void hisi_its_pmu_unregister_pmu(void *pmu) +{ + perf_pmu_unregister(pmu); +} + +static int hisi_its_pmu_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct hisi_pmu *pmu; + char *name; + int ret; + + pmu =3D devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL); + if (!pmu) + return -ENOMEM; + + /* + * HiSilicon Uncore PMU framework needs to get common hisi_pmu device + * from device's drvdata. + */ + platform_set_drvdata(pdev, pmu); + + ret =3D hisi_its_pmu_dev_init(pdev, pmu); + if (ret) + return ret; + + ret =3D cpuhp_state_add_instance(hisi_uncore_pmu_cpuhp_state, &pmu->node); + if (ret) + return dev_err_probe(dev, ret, "Fail to register cpuhp instance\n"); + + ret =3D devm_add_action_or_reset(dev, hisi_its_pmu_remove_cpuhp_instance, + &pmu->node); + if (ret) + return ret; + + hisi_pmu_init(pmu, THIS_MODULE); + + name =3D devm_kasprintf(dev, GFP_KERNEL, "hisi_scl%d_its%d", + pmu->topo.scl_id, pmu->topo.index_id); + if (!name) + return -ENOMEM; + + ret =3D perf_pmu_register(&pmu->pmu, name, -1); + if (ret) + return dev_err_probe(dev, ret, "Fail to register PMU\n"); + + return devm_add_action_or_reset(dev, hisi_its_pmu_unregister_pmu, + &pmu->pmu); +} + +static struct hisi_its_pmu_regs hisi_its_v1_pmu_regs =3D { + .version =3D ITS_PMU_VERSION, + .pmu_ctrl =3D ITS_PMU_GLOBAL_CTRL, + .event_ctrl0 =3D ITS_PMU_EVENT_CTRL, + .event_cntr0 =3D ITS_PMU_COUNTER0, + .cntr_ctrl =3D ITS_PMU_COUNTER_CTRL, +}; + +static const struct hisi_pmu_dev_info hisi_its_v1 =3D { + .attr_groups =3D hisi_its_pmu_attr_groups, + .counter_bits =3D 48, + .check_event =3D ITS_PMU_EVENT_CTRL_TYPE, + .private =3D &hisi_its_v1_pmu_regs, +}; + +static const struct acpi_device_id hisi_its_pmu_ids[] =3D { + { "HISI0591", (kernel_ulong_t)&hisi_its_v1 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, hisi_its_pmu_ids); + +static struct platform_driver hisi_its_pmu_driver =3D { + .driver =3D { + .name =3D "hisi_its_pmu", + .acpi_match_table =3D hisi_its_pmu_ids, + .suppress_bind_attrs =3D true, + }, + .probe =3D hisi_its_pmu_probe, +}; + +module_platform_driver(hisi_its_pmu_driver); + +MODULE_IMPORT_NS("HISI_PMU"); +MODULE_DESCRIPTION("HiSilicon SoC Uncore ITS PMU driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yushan Wang "); --=20 2.33.0 From nobody Fri Sep 25 19:19:51 2026 Received: from canpmsgout10.his.huawei.com (canpmsgout10.his.huawei.com [113.46.200.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0B8E448BA4 for ; Wed, 9 Sep 2026 07:22:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938576; cv=none; b=Bp0KK60CFizKX3qnf/7AgIwMt9YzNcy8KJ2VKPKOb7bwyh/pgo8De14I8tJBib7s6u4VOUE8wlgUYxJkhbcEeQNLUT6ilwGrZeGQ5z7DVLIPShdGnE0ueiNgBUl95SDNKxcr/PQTAR46AiWUAFkHA2gS8spfN36nNReY2+QJatc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788938576; c=relaxed/simple; bh=MC4H6oqZIwOFAiLRbZlIIx4c5qCHZIlRcruM11fnk7s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=axwHfvhfLyeA/u60uZ3SEcDDgtlBaUPlrQIyER0qu//9K0KsySJ2RN2eWH18kIFzzOJ8bVUi3ypQyvJAMbJuCBUSr+qnMPy2yHUBJovbQvodvcP+XP0yVsZGLLgXWllLTO0MMofXUVFbX30pXhhnutEbcS1g0X5tEBTfq0uhiw4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=3jJRz0A8; arc=none smtp.client-ip=113.46.200.225 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="3jJRz0A8" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=FYAaJ/nstk18ZP+Irwr92KPlz26fv0Oh5+iqsnRCB4U=; b=3jJRz0A8YI8rCByIrw0v18w2KtrXcTmS6tpw8lCycDJ0pLP/urlLzCB6ifjAT1bQsAbwS9zm6 B+e+3AWsR+VAbq3PZJ/fSveQ2C70DWkaHsPVy1g77R77C6+AnOvMUlUqC5cfXov2ckXiLL19FoS 8wMvrSfdBGd/wtBTwJlt0d0= Received: from mail.maildlp.com (unknown [172.19.163.163]) by canpmsgout10.his.huawei.com (SkyGuard) with ESMTPS id 4hfsS71fhdz1K96s; Wed, 9 Sep 2026 15:11:51 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id A57724058D; Wed, 9 Sep 2026 15:22:45 +0800 (CST) Received: from localhost.huawei.com (10.90.31.46) by whupemo500002.china.huawei.com (7.152.185.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Wed, 9 Sep 2026 15:22:44 +0800 From: Yushan Wang To: , , , , CC: , , , , , Subject: [PATCH v5 3/3] drivers/perf: hisi: Add cycle event for HIP13 MN PMU Date: Wed, 9 Sep 2026 15:22:40 +0800 Message-ID: <20260909072240.2308808-4-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260909072240.2308808-1-wangyushan12@huawei.com> References: <20260909072240.2308808-1-wangyushan12@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To whupemo500002.china.huawei.com (7.152.185.250) Content-Type: text/plain; charset="utf-8" From: Yifan Wu The MN (Miscellaneous Node) PMU on HiSilicon HIP13 exposes a cycle counter in addition to the existing event set. Add a v2 event list that includes the cycles event (0x0F) and a new hisi_mn_v2 dev_info matched by the new ACPI id HISI0224. Rename the existing event list, attribute group and attr_groups array to *_v1 so the two MN PMU versions can coexist. Signed-off-by: Yifan Wu Signed-off-by: Yushan Wang --- drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 63 ++++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c b/drivers/perf/his= ilicon/hisi_uncore_mn_pmu.c index ad898153ff49..1ded8a6b2358 100644 --- a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c @@ -188,7 +188,7 @@ static const struct attribute_group hisi_mn_pmu_format_= group =3D { .attrs =3D hisi_mn_pmu_format_attr, }; =20 -static struct attribute *hisi_mn_pmu_events_attr[] =3D { +static struct attribute *hisi_mn_pmu_events_attr_v1[] =3D { HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00), HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01), HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02), @@ -215,14 +215,55 @@ static struct attribute *hisi_mn_pmu_events_attr[] = =3D { NULL }; =20 -static const struct attribute_group hisi_mn_pmu_events_group =3D { +static const struct attribute_group hisi_mn_pmu_events_group_v1 =3D { .name =3D "events", - .attrs =3D hisi_mn_pmu_events_attr, + .attrs =3D hisi_mn_pmu_events_attr_v1, }; =20 -static const struct attribute_group *hisi_mn_pmu_attr_groups[] =3D { +static const struct attribute_group *hisi_mn_pmu_attr_groups_v1[] =3D { &hisi_mn_pmu_format_group, - &hisi_mn_pmu_events_group, + &hisi_mn_pmu_events_group_v1, + &hisi_pmu_cpumask_attr_group, + &hisi_pmu_identifier_group, + NULL +}; + +static struct attribute *hisi_mn_pmu_events_attr_v2[] =3D { + HISI_PMU_EVENT_ATTR(req_eobarrier_num, 0x00), + HISI_PMU_EVENT_ATTR(req_ecbarrier_num, 0x01), + HISI_PMU_EVENT_ATTR(req_dvmop_num, 0x02), + HISI_PMU_EVENT_ATTR(req_dvmsync_num, 0x03), + HISI_PMU_EVENT_ATTR(req_retry_num, 0x04), + HISI_PMU_EVENT_ATTR(req_writenosnp_num, 0x05), + HISI_PMU_EVENT_ATTR(req_readnosnp_num, 0x06), + HISI_PMU_EVENT_ATTR(snp_dvm_num, 0x07), + HISI_PMU_EVENT_ATTR(snp_dvmsync_num, 0x08), + HISI_PMU_EVENT_ATTR(l3t_req_dvm_num, 0x09), + HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_num, 0x0A), + HISI_PMU_EVENT_ATTR(mn_req_dvm_num, 0x0B), + HISI_PMU_EVENT_ATTR(mn_req_dvmsync_num, 0x0C), + HISI_PMU_EVENT_ATTR(pa_req_dvm_num, 0x0D), + HISI_PMU_EVENT_ATTR(pa_req_dvmsync_num, 0x0E), + HISI_PMU_EVENT_ATTR(cycles, 0x0F), + HISI_PMU_EVENT_ATTR(snp_dvm_latency, 0x80), + HISI_PMU_EVENT_ATTR(snp_dvmsync_latency, 0x81), + HISI_PMU_EVENT_ATTR(l3t_req_dvm_latency, 0x82), + HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_latency, 0x83), + HISI_PMU_EVENT_ATTR(mn_req_dvm_latency, 0x84), + HISI_PMU_EVENT_ATTR(mn_req_dvmsync_latency, 0x85), + HISI_PMU_EVENT_ATTR(pa_req_dvm_latency, 0x86), + HISI_PMU_EVENT_ATTR(pa_req_dvmsync_latency, 0x87), + NULL +}; + +static const struct attribute_group hisi_mn_pmu_events_group_v2 =3D { + .name =3D "events", + .attrs =3D hisi_mn_pmu_events_attr_v2, +}; + +static const struct attribute_group *hisi_mn_pmu_attr_groups_v2[] =3D { + &hisi_mn_pmu_format_group, + &hisi_mn_pmu_events_group_v2, &hisi_pmu_cpumask_attr_group, &hisi_pmu_identifier_group, NULL @@ -347,14 +388,22 @@ static struct hisi_mn_pmu_regs hisi_mn_v1_pmu_regs = =3D { }; =20 static const struct hisi_pmu_dev_info hisi_mn_v1 =3D { - .attr_groups =3D hisi_mn_pmu_attr_groups, + .attr_groups =3D hisi_mn_pmu_attr_groups_v1, + .counter_bits =3D 48, + .check_event =3D HISI_MN_EVTYPE_MASK, + .private =3D &hisi_mn_v1_pmu_regs, +}; + +static const struct hisi_pmu_dev_info hisi_mn_v2 =3D { + .attr_groups =3D hisi_mn_pmu_attr_groups_v2, .counter_bits =3D 48, .check_event =3D HISI_MN_EVTYPE_MASK, .private =3D &hisi_mn_v1_pmu_regs, }; =20 static const struct acpi_device_id hisi_mn_pmu_acpi_match[] =3D { - { "HISI0222", (kernel_ulong_t) &hisi_mn_v1 }, + { "HISI0222", (kernel_ulong_t)&hisi_mn_v1 }, + { "HISI0224", (kernel_ulong_t)&hisi_mn_v2 }, { } }; MODULE_DEVICE_TABLE(acpi, hisi_mn_pmu_acpi_match); --=20 2.33.0