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: Zhou Wang <wangzhou1@hisilicon.com> Tested-by: Qi Liu <liuqi115@huawei.com> Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com> Link: https://lore.kernel.org/r/1588820305-174479-1-git-send-email-wangzhou1@hisilicon.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
88562f06eb
commit
97807325a0
|
@ -79,13 +79,6 @@ config FSL_IMX8_DDR_PMU
|
|||
can give information about memory throughput and other related
|
||||
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
|
||||
bool "Qualcomm Technologies L2-cache PMU"
|
||||
depends on ARCH_QCOM && ARM64 && ACPI
|
||||
|
@ -129,4 +122,6 @@ config ARM_SPE_PMU
|
|||
Extension, which provides periodic sampling of operations in
|
||||
the CPU pipeline and reports this via the perf AUX interface.
|
||||
|
||||
source "drivers/perf/hisilicon/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# 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.
|
|
@ -1,2 +1,3 @@
|
|||
# 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)
|
|||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
&ddrc_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node);
|
||||
irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -406,8 +407,9 @@ static int hisi_ddrc_pmu_remove(struct platform_device *pdev)
|
|||
struct hisi_pmu *ddrc_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&ddrc_pmu->pmu);
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
&ddrc_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
&ddrc_pmu->node);
|
||||
irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -406,8 +406,9 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
&hha_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node);
|
||||
irq_set_affinity_hint(hha_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -418,8 +419,9 @@ static int hisi_hha_pmu_remove(struct platform_device *pdev)
|
|||
struct hisi_pmu *hha_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&hha_pmu->pmu);
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
&hha_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
&hha_pmu->node);
|
||||
irq_set_affinity_hint(hha_pmu->irq, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -396,8 +396,9 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(l3c_pmu->dev, "L3C PMU register failed!\n");
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
&l3c_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node);
|
||||
irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -408,8 +409,9 @@ static int hisi_l3c_pmu_remove(struct platform_device *pdev)
|
|||
struct hisi_pmu *l3c_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&l3c_pmu->pmu);
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
&l3c_pmu->node);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
&l3c_pmu->node);
|
||||
irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ ssize_t hisi_format_sysfs_show(struct device *dev,
|
|||
|
||||
return sprintf(buf, "%s\n", (char *)eattr->var);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_format_sysfs_show);
|
||||
|
||||
/*
|
||||
* PMU event attributes
|
||||
|
@ -48,6 +49,7 @@ ssize_t hisi_event_sysfs_show(struct device *dev,
|
|||
|
||||
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
|
||||
|
@ -59,6 +61,7 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_counter_valid);
|
||||
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_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)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_init);
|
||||
|
||||
/*
|
||||
* 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)
|
|||
/* Write start value to the hardware event counter */
|
||||
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)
|
||||
{
|
||||
|
@ -240,6 +247,7 @@ void hisi_uncore_pmu_event_update(struct perf_event *event)
|
|||
HISI_MAX_PERIOD(hisi_pmu->counter_bits);
|
||||
local64_add(delta, &event->count);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_update);
|
||||
|
||||
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);
|
||||
perf_event_update_userpage(event);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_start);
|
||||
|
||||
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);
|
||||
hwc->state |= PERF_HES_UPTODATE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_stop);
|
||||
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_add);
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
/* Read hardware counter and update the perf counter statistics */
|
||||
hisi_uncore_pmu_event_update(event);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
|
||||
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_enable);
|
||||
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_disable);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -414,10 +429,11 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
|
|||
hisi_pmu->on_cpu = 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_online_cpu);
|
||||
|
||||
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);
|
||||
/* Use this CPU for event counting */
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
Loading…
Reference in New Issue