Commit 97807325 authored by Zhou Wang's avatar Zhou Wang Committed by Will Deacon

drivers/perf: hisi: Permit modular builds of HiSilicon uncore drivers

This patch lets HiSilicon uncore PMU driver can be built as modules.
A common module and three specific uncore PMU driver modules will be built.

Export necessary functions in hisi_uncore_pmu module, and change
irq_set_affinity to irq_set_affinity_hint to pass compile.
Signed-off-by: default avatarZhou Wang <wangzhou1@hisilicon.com>
Tested-by: default avatarQi Liu <liuqi115@huawei.com>
Reviewed-by: default avatarShaokun Zhang <zhangshaokun@hisilicon.com>
Link: https://lore.kernel.org/r/1588820305-174479-1-git-send-email-wangzhou1@hisilicon.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
parent 88562f06
...@@ -79,13 +79,6 @@ config FSL_IMX8_DDR_PMU ...@@ -79,13 +79,6 @@ config FSL_IMX8_DDR_PMU
can give information about memory throughput and other related can give information about memory throughput and other related
events. events.
config HISI_PMU
bool "HiSilicon SoC PMU"
depends on ARM64 && ACPI
help
Support for HiSilicon SoC uncore performance monitoring
unit (PMU), such as: L3C, HHA and DDRC.
config QCOM_L2_PMU config QCOM_L2_PMU
bool "Qualcomm Technologies L2-cache PMU" bool "Qualcomm Technologies L2-cache PMU"
depends on ARCH_QCOM && ARM64 && ACPI depends on ARCH_QCOM && ARM64 && ACPI
...@@ -129,4 +122,6 @@ config ARM_SPE_PMU ...@@ -129,4 +122,6 @@ config ARM_SPE_PMU
Extension, which provides periodic sampling of operations in Extension, which provides periodic sampling of operations in
the CPU pipeline and reports this via the perf AUX interface. the CPU pipeline and reports this via the perf AUX interface.
source "drivers/perf/hisilicon/Kconfig"
endmenu endmenu
# SPDX-License-Identifier: GPL-2.0-only
config HISI_PMU
tristate "HiSilicon SoC PMU drivers"
depends on ARM64 && ACPI
help
Support for HiSilicon SoC L3 Cache performance monitor, Hydra Home
Agent performance monitor and DDR Controller performance monitor.
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o
...@@ -394,8 +394,9 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev) ...@@ -394,8 +394,9 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1); ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
if (ret) { if (ret) {
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n"); dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, cpuhp_state_remove_instance_nocalls(
&ddrc_pmu->node); CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node);
irq_set_affinity_hint(ddrc_pmu->irq, NULL);
} }
return ret; return ret;
...@@ -406,8 +407,9 @@ static int hisi_ddrc_pmu_remove(struct platform_device *pdev) ...@@ -406,8 +407,9 @@ static int hisi_ddrc_pmu_remove(struct platform_device *pdev)
struct hisi_pmu *ddrc_pmu = platform_get_drvdata(pdev); struct hisi_pmu *ddrc_pmu = platform_get_drvdata(pdev);
perf_pmu_unregister(&ddrc_pmu->pmu); perf_pmu_unregister(&ddrc_pmu->pmu);
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
&ddrc_pmu->node); &ddrc_pmu->node);
irq_set_affinity_hint(ddrc_pmu->irq, NULL);
return 0; return 0;
} }
......
...@@ -406,8 +406,9 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev) ...@@ -406,8 +406,9 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
ret = perf_pmu_register(&hha_pmu->pmu, name, -1); ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
if (ret) { if (ret) {
dev_err(hha_pmu->dev, "HHA PMU register failed!\n"); dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, cpuhp_state_remove_instance_nocalls(
&hha_pmu->node); CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node);
irq_set_affinity_hint(hha_pmu->irq, NULL);
} }
return ret; return ret;
...@@ -418,8 +419,9 @@ static int hisi_hha_pmu_remove(struct platform_device *pdev) ...@@ -418,8 +419,9 @@ static int hisi_hha_pmu_remove(struct platform_device *pdev)
struct hisi_pmu *hha_pmu = platform_get_drvdata(pdev); struct hisi_pmu *hha_pmu = platform_get_drvdata(pdev);
perf_pmu_unregister(&hha_pmu->pmu); perf_pmu_unregister(&hha_pmu->pmu);
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
&hha_pmu->node); &hha_pmu->node);
irq_set_affinity_hint(hha_pmu->irq, NULL);
return 0; return 0;
} }
......
...@@ -396,8 +396,9 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev) ...@@ -396,8 +396,9 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1); ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
if (ret) { if (ret) {
dev_err(l3c_pmu->dev, "L3C PMU register failed!\n"); dev_err(l3c_pmu->dev, "L3C PMU register failed!\n");
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, cpuhp_state_remove_instance_nocalls(
&l3c_pmu->node); CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node);
irq_set_affinity_hint(l3c_pmu->irq, NULL);
} }
return ret; return ret;
...@@ -408,8 +409,9 @@ static int hisi_l3c_pmu_remove(struct platform_device *pdev) ...@@ -408,8 +409,9 @@ static int hisi_l3c_pmu_remove(struct platform_device *pdev)
struct hisi_pmu *l3c_pmu = platform_get_drvdata(pdev); struct hisi_pmu *l3c_pmu = platform_get_drvdata(pdev);
perf_pmu_unregister(&l3c_pmu->pmu); perf_pmu_unregister(&l3c_pmu->pmu);
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
&l3c_pmu->node); &l3c_pmu->node);
irq_set_affinity_hint(l3c_pmu->irq, NULL);
return 0; return 0;
} }
......
...@@ -35,6 +35,7 @@ ssize_t hisi_format_sysfs_show(struct device *dev, ...@@ -35,6 +35,7 @@ ssize_t hisi_format_sysfs_show(struct device *dev,
return sprintf(buf, "%s\n", (char *)eattr->var); return sprintf(buf, "%s\n", (char *)eattr->var);
} }
EXPORT_SYMBOL_GPL(hisi_format_sysfs_show);
/* /*
* PMU event attributes * PMU event attributes
...@@ -48,6 +49,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev, ...@@ -48,6 +49,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
return sprintf(page, "config=0x%lx\n", (unsigned long)eattr->var); return sprintf(page, "config=0x%lx\n", (unsigned long)eattr->var);
} }
EXPORT_SYMBOL_GPL(hisi_event_sysfs_show);
/* /*
* sysfs cpumask attributes. For uncore PMU, we only have a single CPU to show * sysfs cpumask attributes. For uncore PMU, we only have a single CPU to show
...@@ -59,6 +61,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev, ...@@ -59,6 +61,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
return sprintf(buf, "%d\n", hisi_pmu->on_cpu); return sprintf(buf, "%d\n", hisi_pmu->on_cpu);
} }
EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show);
static bool hisi_validate_event_group(struct perf_event *event) static bool hisi_validate_event_group(struct perf_event *event)
{ {
...@@ -97,6 +100,7 @@ int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx) ...@@ -97,6 +100,7 @@ int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx)
{ {
return idx >= 0 && idx < hisi_pmu->num_counters; return idx >= 0 && idx < hisi_pmu->num_counters;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_counter_valid);
int hisi_uncore_pmu_get_event_idx(struct perf_event *event) int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
{ {
...@@ -113,6 +117,7 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event) ...@@ -113,6 +117,7 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
return idx; return idx;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx);
static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx) static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
{ {
...@@ -173,6 +178,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event) ...@@ -173,6 +178,7 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_init);
/* /*
* Set the counter to count the event that we're interested in, * Set the counter to count the event that we're interested in,
...@@ -220,6 +226,7 @@ void hisi_uncore_pmu_set_event_period(struct perf_event *event) ...@@ -220,6 +226,7 @@ void hisi_uncore_pmu_set_event_period(struct perf_event *event)
/* Write start value to the hardware event counter */ /* Write start value to the hardware event counter */
hisi_pmu->ops->write_counter(hisi_pmu, hwc, val); hisi_pmu->ops->write_counter(hisi_pmu, hwc, val);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_set_event_period);
void hisi_uncore_pmu_event_update(struct perf_event *event) void hisi_uncore_pmu_event_update(struct perf_event *event)
{ {
...@@ -240,6 +247,7 @@ void hisi_uncore_pmu_event_update(struct perf_event *event) ...@@ -240,6 +247,7 @@ void hisi_uncore_pmu_event_update(struct perf_event *event)
HISI_MAX_PERIOD(hisi_pmu->counter_bits); HISI_MAX_PERIOD(hisi_pmu->counter_bits);
local64_add(delta, &event->count); local64_add(delta, &event->count);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_update);
void hisi_uncore_pmu_start(struct perf_event *event, int flags) void hisi_uncore_pmu_start(struct perf_event *event, int flags)
{ {
...@@ -262,6 +270,7 @@ void hisi_uncore_pmu_start(struct perf_event *event, int flags) ...@@ -262,6 +270,7 @@ void hisi_uncore_pmu_start(struct perf_event *event, int flags)
hisi_uncore_pmu_enable_event(event); hisi_uncore_pmu_enable_event(event);
perf_event_update_userpage(event); perf_event_update_userpage(event);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_start);
void hisi_uncore_pmu_stop(struct perf_event *event, int flags) void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
{ {
...@@ -278,6 +287,7 @@ void hisi_uncore_pmu_stop(struct perf_event *event, int flags) ...@@ -278,6 +287,7 @@ void hisi_uncore_pmu_stop(struct perf_event *event, int flags)
hisi_uncore_pmu_event_update(event); hisi_uncore_pmu_event_update(event);
hwc->state |= PERF_HES_UPTODATE; hwc->state |= PERF_HES_UPTODATE;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_stop);
int hisi_uncore_pmu_add(struct perf_event *event, int flags) int hisi_uncore_pmu_add(struct perf_event *event, int flags)
{ {
...@@ -300,6 +310,7 @@ int hisi_uncore_pmu_add(struct perf_event *event, int flags) ...@@ -300,6 +310,7 @@ int hisi_uncore_pmu_add(struct perf_event *event, int flags)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_add);
void hisi_uncore_pmu_del(struct perf_event *event, int flags) void hisi_uncore_pmu_del(struct perf_event *event, int flags)
{ {
...@@ -311,12 +322,14 @@ void hisi_uncore_pmu_del(struct perf_event *event, int flags) ...@@ -311,12 +322,14 @@ void hisi_uncore_pmu_del(struct perf_event *event, int flags)
perf_event_update_userpage(event); perf_event_update_userpage(event);
hisi_pmu->pmu_events.hw_events[hwc->idx] = NULL; hisi_pmu->pmu_events.hw_events[hwc->idx] = NULL;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_del);
void hisi_uncore_pmu_read(struct perf_event *event) void hisi_uncore_pmu_read(struct perf_event *event)
{ {
/* Read hardware counter and update the perf counter statistics */ /* Read hardware counter and update the perf counter statistics */
hisi_uncore_pmu_event_update(event); hisi_uncore_pmu_event_update(event);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
void hisi_uncore_pmu_enable(struct pmu *pmu) void hisi_uncore_pmu_enable(struct pmu *pmu)
{ {
...@@ -329,6 +342,7 @@ void hisi_uncore_pmu_enable(struct pmu *pmu) ...@@ -329,6 +342,7 @@ void hisi_uncore_pmu_enable(struct pmu *pmu)
hisi_pmu->ops->start_counters(hisi_pmu); hisi_pmu->ops->start_counters(hisi_pmu);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_enable);
void hisi_uncore_pmu_disable(struct pmu *pmu) void hisi_uncore_pmu_disable(struct pmu *pmu)
{ {
...@@ -336,6 +350,7 @@ void hisi_uncore_pmu_disable(struct pmu *pmu) ...@@ -336,6 +350,7 @@ void hisi_uncore_pmu_disable(struct pmu *pmu)
hisi_pmu->ops->stop_counters(hisi_pmu); hisi_pmu->ops->stop_counters(hisi_pmu);
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_disable);
/* /*
...@@ -414,10 +429,11 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node) ...@@ -414,10 +429,11 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
hisi_pmu->on_cpu = cpu; hisi_pmu->on_cpu = cpu;
/* Overflow interrupt also should use the same CPU */ /* Overflow interrupt also should use the same CPU */
WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu))); WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(cpu)));
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_online_cpu);
int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node) int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
{ {
...@@ -446,7 +462,10 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node) ...@@ -446,7 +462,10 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
perf_pmu_migrate_context(&hisi_pmu->pmu, cpu, target); perf_pmu_migrate_context(&hisi_pmu->pmu, cpu, target);
/* Use this CPU for event counting */ /* Use this CPU for event counting */
hisi_pmu->on_cpu = target; hisi_pmu->on_cpu = target;
WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(target))); WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(target)));
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
MODULE_LICENSE("GPL v2");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment