From nobody Fri Jul 24 04:54:16 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 1DAFB3242BA for ; Fri, 24 Jul 2026 02:52:57 +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=1784861588; cv=none; b=ky/RIOevV6tZpLkwhC69Y3Up30BRwi8qq5Vq4LjtBiE9DoNkRiYgiDLy7ELu8wwlPf5MJRjY6brTb72i9dx44CPcCo0Sx9c64h3cLna+5TzDVscfAz61jm02ceqHQuSMvW2M0xI5n7+YzNO7ouhXwtLHO4NqTafvHid0cXFmsnc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784861588; c=relaxed/simple; bh=ItixZQZvC0eYsrhcCDzZi7NSIz4GYhZ11z+u30yoGJ0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QnxMWVacF7bmys9JHRCK7zyL2ZdKP9mc+fBB0XN1FXv4ud5dQIbbBz1ToNpZlH30OzxKM2eZs7EmMyC3e2wicabnpeVNw/mGjzx88XjkQxI3RPylhHSXFdcxfo/B6s2ld9U/Coq5yULNSQYGdu+3XKcB9jKSsUNrBhwvhmpHJvE= 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=pZs1iaDY; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=pZs1iaDY; 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="pZs1iaDY"; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="pZs1iaDY" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=/IpJEiOUH4DJzbGd9fz4lOa2BHwwOv8RfGxwewsxz+Y=; b=pZs1iaDYB/E68hme+hXUYObVc63x3BO6j1ou3dEq7XuPojAU5+zK1Z35NosFp7Bb9bT8C2Tzl xoOSjFXu1Z/EWCveNmRQbZh1ve3yq7C5ytn1yCg3GlW8XhgpOpsybLv2Yj3KVFu43mjaOMNZOkp LHiC/a/UxK8ETRiowenQI7g= Received: from canpmsgout01.his.huawei.com (unknown [172.19.92.178]) by szxga01-in.huawei.com (SkyGuard) with ESMTPS id 4h5swP4Db1z1BFqL for ; Fri, 24 Jul 2026 10:52:21 +0800 (CST) dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=/IpJEiOUH4DJzbGd9fz4lOa2BHwwOv8RfGxwewsxz+Y=; b=pZs1iaDYB/E68hme+hXUYObVc63x3BO6j1ou3dEq7XuPojAU5+zK1Z35NosFp7Bb9bT8C2Tzl xoOSjFXu1Z/EWCveNmRQbZh1ve3yq7C5ytn1yCg3GlW8XhgpOpsybLv2Yj3KVFu43mjaOMNZOkp LHiC/a/UxK8ETRiowenQI7g= Received: from mail.maildlp.com (unknown [172.19.163.0]) by canpmsgout01.his.huawei.com (SkyGuard) with ESMTPS id 4h5sjz1kxdz1T4Hh; Fri, 24 Jul 2026 10:43:19 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id 36EC040561; Fri, 24 Jul 2026 10:52:42 +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.1544.11; Fri, 24 Jul 2026 10:52:41 +0800 From: Yushan Wang To: , , , , CC: , , , , , , Subject: [PATCH 1/3] drivers/perf: hisi: Consolidate uncore PMU cpuhp states Date: Fri, 24 Jul 2026 10:52:36 +0800 Message-ID: <20260724025238.3411328-2-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260724025238.3411328-1-wangyushan12@huawei.com> References: <20260724025238.3411328-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: kwepems100002.china.huawei.com (7.221.188.206) 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. 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 f963e4f9e552..0b78a0e094dd 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; @@ -845,8 +847,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; @@ -858,7 +859,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; @@ -869,7 +870,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 @@ -939,20 +940,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; } @@ -961,7 +962,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 de71dcf11653..276785a79ae9 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 */ @@ -621,5 +624,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 0fb3a2a62eb0..965d6ce02a29 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -210,12 +210,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 Jul 24 04:54:16 2026 Received: from canpmsgout06.his.huawei.com (canpmsgout06.his.huawei.com [113.46.200.221]) (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 6A42B36164D for ; Fri, 24 Jul 2026 02:52:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784861581; cv=none; b=ZC16ytsXY7ddhut3wHmjj92brb+lPXGxhHmSRnlVJIHbtEJMBspHFqeLOmjWlKwnoOS0MzE7LLvrupq+Rob/Kbesi3TPosyA2PGqETYD85F2bbRo3U8C/X6y2tjGxkgdUIbFqFIEQpklGTh0dc+cfq9s9SECaQo4TRp8w1b4beY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784861581; c=relaxed/simple; bh=gUeabhdxuH2MP2thOb0uc+FRcVXVawlC40EDc6cl5L4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HSyPs+CF3Akh9VVhO9weP/f7WT8leRBIRwwT94sNTq0qVNoo+c/4S8eoknsoK++Em7r2ZnfQmMXKh++Or9qQ7+Umtn7DFOW3EUjr9EB2qGaMtzxsDVi4voykz3bc1jZqESqj48B8GKHU5a9R7F77mugcX/rugPNe/lxOGjPYUvY= 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=pnbjXGYi; arc=none smtp.client-ip=113.46.200.221 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="pnbjXGYi" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=Y6lujL6k2eUl07bSgb0Y3AJCYCYahY5tscRwHuoS6lY=; b=pnbjXGYiaZAYC6e41iAZ/NB7NLJ4hkcAmeaECFWvDOdDUaNnylTZXM1opjnJoqmGXMM9jVlXy Q1bxXues8LGHs5k53XZLA1hUbPO5s8ybVuzRTB1cAw6hZHzHYE9N4W0YClndVmZYNxjDWSo8Jbd Uc4ItJvu253f/6gpMucNr34= Received: from mail.maildlp.com (unknown [172.19.163.0]) by canpmsgout06.his.huawei.com (SkyGuard) with ESMTPS id 4h5sk04SwZzRhQy; Fri, 24 Jul 2026 10:43:20 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id 1D9D240561; Fri, 24 Jul 2026 10:52: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.1544.11; Fri, 24 Jul 2026 10:52:41 +0800 From: Yushan Wang To: , , , , CC: , , , , , , Subject: [PATCH 2/3] drivers/perf: hisi: Add support for uncore ITS PMU Date: Fri, 24 Jul 2026 10:52:37 +0800 Message-ID: <20260724025238.3411328-3-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260724025238.3411328-1-wangyushan12@huawei.com> References: <20260724025238.3411328-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: kwepems100002.china.huawei.com (7.221.188.206) 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 | 13 + drivers/perf/hisilicon/Makefile | 2 +- drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 400 +++++++++++++++++++ 3 files changed, 414 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..b69931e4be4e 100644 --- a/Documentation/admin-guide/perf/hisi-pmu.rst +++ b/Documentation/admin-guide/perf/hisi-pmu.rst @@ -128,6 +128,19 @@ 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. Only one filtered +event (with int_en set) can run at a time; if a filtered event is already +running, new filtered events will be refused. + +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..375a14f20ee2 --- /dev/null +++ b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c @@ -0,0 +1,400 @@ +// 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(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; +}; + +struct hisi_its_pmu { + struct hisi_pmu pmu; + /* Protects filter_busy and the global INT_ID filter config. */ + spinlock_t filter_lock; + /* Reserved by a filtered event for its whole lifetime. */ + bool filter_busy; +}; + +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) +{ + /* We don't support interrupt, so a stub here. */ +} + +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); +} + +/* Release the filter slot reserved in check_filter(). */ +static void hisi_its_pmu_destroy_event(struct perf_event *event) +{ + struct hisi_pmu *pmu =3D to_hisi_pmu(event->pmu); + struct hisi_its_pmu *its_pmu =3D container_of(pmu, struct hisi_its_pmu, p= mu); + u32 int_en =3D hisi_get_int_en(event); + + if (!int_en) + return; + + spin_lock(&its_pmu->filter_lock); + its_pmu->filter_busy =3D false; + spin_unlock(&its_pmu->filter_lock); +} + +static int hisi_its_pmu_check_filter(struct perf_event *event) +{ + struct hisi_pmu *pmu =3D to_hisi_pmu(event->pmu); + struct hisi_its_pmu *its_pmu =3D container_of(pmu, struct hisi_its_pmu, p= mu); + u32 int_en =3D hisi_get_int_en(event); + + if (!int_en) + return 0; + + /* + * The INT_ID filter is global to the PMU instance: when set, all + * counters only count traffic matching int_id. Reserve the slot + * at event_init() time and hold it for the lifetime of the event + * so a concurrent or multiplexed event cannot clobber the hardware + * state. The slot is released by event->destroy(), which the perf + * core calls on both the event_init() error path and final free. + */ + spin_lock(&its_pmu->filter_lock); + if (its_pmu->filter_busy) { + spin_unlock(&its_pmu->filter_lock); + return -EINVAL; + } + its_pmu->filter_busy =3D true; + spin_unlock(&its_pmu->filter_lock); + + event->destroy =3D hisi_its_pmu_destroy_event; + return 0; +} + +static const struct hisi_uncore_ops hisi_uncore_its_ops =3D { + .write_evtype =3D hisi_its_pmu_write_evtype, + .get_event_idx =3D hisi_uncore_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, + .check_filter =3D hisi_its_pmu_check_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_its_pmu *its_pmu) +{ + struct hisi_its_pmu_regs *reg_info; + struct hisi_pmu *pmu =3D &its_pmu->pmu; + + 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); + + 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_its_pmu *its_pmu; + struct hisi_pmu *pmu; + char *name; + int ret; + + its_pmu =3D devm_kzalloc(dev, sizeof(*its_pmu), GFP_KERNEL); + if (!its_pmu) + return -ENOMEM; + + spin_lock_init(&its_pmu->filter_lock); + + pmu =3D &its_pmu->pmu; + + /* + * HiSilicon Uncore PMU framework needs to get common hisi_pmu device + * from device's drvdata. + */ + platform_set_drvdata(pdev, its_pmu); + + ret =3D hisi_its_pmu_dev_init(pdev, its_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 Jul 24 04:54:16 2026 Received: from canpmsgout02.his.huawei.com (canpmsgout02.his.huawei.com [113.46.200.217]) (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 4500F369203 for ; Fri, 24 Jul 2026 02:52:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.217 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784861577; cv=none; b=BJSGYG81GeZpjGgXcWVgVpM+/hJaG05yfGzS1OGX+E1H6c9CcuMyj8go7iXqMx02fMwig8aRCtBo/2cNf3v2u/Vq6WOvIUgUpvkKIFDK6TvCyOdOsQJ2e/S0qxFPvBO/+cyItC82LpftNsR+m7UqIVKNMQTHzqf5LLRm0S5FA6U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784861577; c=relaxed/simple; bh=MC4H6oqZIwOFAiLRbZlIIx4c5qCHZIlRcruM11fnk7s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HPXyR/CUpnM3WCvWib84zH7xYoPeqtqkE7gXHEjblZT6hi0qLRD75eLitSGD8xepGZynwwgwSk/+7N0/i6nZz97Un6z37zvxJWSsA45rkDNic6ZugHMigvqGgQWAT6KwUAETIGvZBLEtmhI/CAV4kY8hOQDJmSvc1omBzBGy2UA= 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.217 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.162.140]) by canpmsgout02.his.huawei.com (SkyGuard) with ESMTPS id 4h5sjr0GX4zcb0f; Fri, 24 Jul 2026 10:43:12 +0800 (CST) Received: from whupemo500002.china.huawei.com (unknown [7.152.185.250]) by mail.maildlp.com (Postfix) with ESMTPS id EDD7C2025F; Fri, 24 Jul 2026 10:52: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.1544.11; Fri, 24 Jul 2026 10:52:42 +0800 From: Yushan Wang To: , , , , CC: , , , , , , Subject: [PATCH 3/3] drivers/perf: hisi: Add cycle event for HIP13 MN PMU Date: Fri, 24 Jul 2026 10:52:38 +0800 Message-ID: <20260724025238.3411328-4-wangyushan12@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260724025238.3411328-1-wangyushan12@huawei.com> References: <20260724025238.3411328-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: kwepems100002.china.huawei.com (7.221.188.206) 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