perf/arm_cspmu: Fixes and cleanups
Subsystems (3)
cover perf/arm_cspmu: Fixes and cleanups
Hi all,
I've been working on adding support for the 64-bit extension and devicetree probing[1], which I'm not posting yet since it's still untested and may need a bit more work. However I think these preparatory patches stand up well enough on their own so could land sooner.
Thanks,
Robin.
[1] https://gitlab.arm.com/linux-arm/linux-rm/-/commits/cspmu-dev/
Robin Murphy (4):
perf/arm_cspmu: Fix event attribute type
ACPI/APMT: Don't register invalid resource
perf/arm_cspmu: Clean up ACPI dependency
perf/arm_cspmu: Decouple APMT dependency
drivers/acpi/arm64/apmt.c | 10 +++-- drivers/perf/arm_cspmu/Kconfig | 3 +- drivers/perf/arm_cspmu/arm_cspmu.c | 70 +++++++++++++----------------- drivers/perf/arm_cspmu/arm_cspmu.h | 4 +- 4 files changed, 39 insertions(+), 48 deletions(-)
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
PATCH 1/4 perf/arm_cspmu: Fix event attribute type
ARM_CSPMU_EVENT_ATTR() defines a struct perf_pmu_events_attr, so arm_cspmu_sysfs_event_show() should not be interpreting it as struct dev_ext_attribute.
--- drivers/perf/arm_cspmu/arm_cspmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/perf/arm_cspmu/arm_cspmu.c +4 -4
@@ -189,10 +189,10 @@ static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu)ssize_t arm_cspmu_sysfs_event_show (struct device *dev,struct device_attribute *attr,char *buf) { -struct dev_ext_attribute *eattr = - container_of(attr, struct dev_ext_attribute, attr); -return sysfs_emit (buf,"event=0x%llx\n" , - (unsigned long long )eattr->var); +struct perf_pmu_events_attr *pmu_attr; + + pmu_attr =container_of (attr,typeof (*pmu_attr), attr); +return sysfs_emit (buf,"event=0x%llx\n" , pmu_attr->id); }EXPORT_SYMBOL_GPL (arm_cspmu_sysfs_event_show);
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 1/4] perf/arm_cspmu: Fix event attribute type
Quoted 17 lines · Robin Murphy
ARM_CSPMU_EVENT_ATTR()defines a structperf_pmu_events_attr, soarm_cspmu_sysfs_event_show()should not be interpreting it as structdev_ext_attribute.Fixes e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver")Signed-off-by Robin Murphy <[email protected]>--- drivers/perf/arm_cspmu/arm_cspmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)drivers/perf/arm_cspmu/arm_cspmu.c +0
-0@@ -189,10 +189,10 @@ static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu)ssize_t arm_cspmu_sysfs_event_show (struct device *dev,struct device_attribute *attr,char *buf)
drivers/perf/arm_cspmu/arm_cspmu.c static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu) · line 196
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +4
-4{ -struct dev_ext_attribute *eattr = - container_of(attr, struct dev_ext_attribute, attr); -return sysfs_emit (buf,"event=0x%llx\n" , - (unsigned long long )eattr->var); +struct perf_pmu_events_attr *pmu_attr; + + pmu_attr =container_of (attr,typeof (*pmu_attr), attr); +return sysfs_emit (buf,"event=0x%llx\n" , pmu_attr->id); }
Thanks for catching this ! The other option would be to, which was the original intention.
drivers/perf/arm_cspmu/arm_cspmu.h +0 -0
@@ -32,7 +32,7 @@ ARM_CSPMU_EXT_ATTR(_name, arm_cspmu_sysfs_format_show, (char
*)_config)
#define ARM_CSPMU_EVENT_ATTR(_name, _config) \
- PMU_EVENT_ATTR_ID(_name, arm_cspmu_sysfs_event_show, _config)
+ ARM_CSPMU_EXT_ATTR(_name, arm_cspmu_sysfs_event_show, (void*)(unsigned long)_config)
/* Default event id mask */
Either way,
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 1/4] perf/arm_cspmu: Fix event attribute type
In reply to Robin MurphyQuoted 6 lines · Robin Murphy
ARM_CSPMU_EVENT_ATTR()defines a structperf_pmu_events_attr, soarm_cspmu_sysfs_event_show()should not be interpreting it as structdev_ext_attribute.Fixes e37dfd65731d ("perf: arm_cspmu: Add support for ARM CoreSight PMU driver")Signed-off-by Robin Murphy <[email protected]>
Quoted 27 lines
---
drivers/perf/arm_cspmu/arm_cspmu.c| 8 ++++----1 file changed, 4 insertions(+), 4 deletions(-)drivers/perf/arm_cspmu/arm_cspmu.c +4
-4@@ -189,10 +189,10 @@ static inline bool use_64b_counter_reg(const struct arm_cspmu *cspmu)ssize_t arm_cspmu_sysfs_event_show (struct device *dev,struct device_attribute *attr,char *buf) { -struct dev_ext_attribute *eattr = - container_of(attr, struct dev_ext_attribute, attr); -return sysfs_emit (buf,"event=0x%llx\n" , - (unsigned long long )eattr->var); +struct perf_pmu_events_attr *pmu_attr; + + pmu_attr =container_of (attr,typeof (*pmu_attr), attr); +return sysfs_emit (buf,"event=0x%llx\n" , pmu_attr->id); }EXPORT_SYMBOL_GPL (arm_cspmu_sysfs_event_show);Signature · 1 line
2.39.2.101.g768bb238c484.dirty
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 2/4 ACPI/APMT: Don't register invalid resource
In reply to Robin MurphyDon't register a resource for the second page unless the dual-page extension flag is actually present to say it's valid.
---
Not a critical fix, since the driver currently works around this itself, but patch #4 would like to clean that up.
drivers/acpi/arm64/apmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/acpi/arm64/apmt.c +6 -4
@@ -35,11 +35,13 @@ static int __init apmt_init_resources(struct resource *res, num_res++; - res[num_res].start = node->base_address1; - res[num_res].end = node->base_address1 +SZ_4K -1 ; - res[num_res].flags =IORESOURCE_MEM ; +if (node->flags &ACPI_APMT_FLAGS_DUAL_PAGE ) { + res[num_res].start = node->base_address1; + res[num_res].end = node->base_address1 +SZ_4K -1 ; + res[num_res].flags =IORESOURCE_MEM ; - num_res++; + num_res++; + }if (node->ovflw_irq !=0 ) { trigger = (node->ovflw_irq_flags &ACPI_APMT_OVFLW_IRQ_FLAGS_MODE );
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 2/4] ACPI/APMT: Don't register invalid resource
Quoted 27 lines · Robin Murphy
Don't register a resource for the second page unless the dual-page extension flag is actually present to say it's valid.
CC Lorenzo Pieralisi <[email protected]>CC Hanjun Guo <[email protected]>CC Sudeep Holla <[email protected]>Signed-off-by Robin Murphy <[email protected]>---
Not a critical fix, since the driver currently works around this itself, but patch #4 would like to clean that up.
drivers/acpi/arm64/apmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)drivers/acpi/arm64/apmt.c +1
-3@@ -35,11 +35,13 @@ static int __init apmt_init_resources(struct resource *res, num_res++; - res[num_res].start = node->base_address1; - res[num_res].end = node->base_address1 +SZ_4K -1 ; - res[num_res].flags =IORESOURCE_MEM ; +if (node->flags &ACPI_APMT_FLAGS_DUAL_PAGE ) {
drivers/acpi/arm64/apmt.c static int __init apmt_init_resources(struct resource *res, · line 47
Quoted 10 lines
drivers/acpi/arm64/apmt.c +5
-1+ res[num_res].start = node->base_address1; + res[num_res].end = node->base_address1 +SZ_4K -1 ; + res[num_res].flags =IORESOURCE_MEM ; - num_res++; + num_res++; + }if (node->ovflw_irq !=0 ) { trigger = (node->ovflw_irq_flags &ACPI_APMT_OVFLW_IRQ_FLAGS_MODE );
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 2/4] ACPI/APMT: Don't register invalid resource
In reply to Robin MurphyQuoted 27 lines · Robin Murphy
Don't register a resource for the second page unless the dual-page extension flag is actually present to say it's valid.
CC Lorenzo Pieralisi <[email protected]>CC Hanjun Guo <[email protected]>CC Sudeep Holla <[email protected]>Signed-off-by Robin Murphy <[email protected]>---
Not a critical fix, since the driver currently works around this itself, but patch #4 would like to clean that up.
drivers/acpi/arm64/apmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)drivers/acpi/arm64/apmt.c +1
-3@@ -35,11 +35,13 @@ static int __init apmt_init_resources(struct resource *res, num_res++; - res[num_res].start = node->base_address1; - res[num_res].end = node->base_address1 +SZ_4K -1 ; - res[num_res].flags =IORESOURCE_MEM ; +if (node->flags &ACPI_APMT_FLAGS_DUAL_PAGE ) {
drivers/acpi/arm64/apmt.c static int __init apmt_init_resources(struct resource *res, · line 47
Quoted 10 lines
drivers/acpi/arm64/apmt.c +5
-1+ res[num_res].start = node->base_address1; + res[num_res].end = node->base_address1 +SZ_4K -1 ; + res[num_res].flags =IORESOURCE_MEM ; - num_res++; + num_res++; + }if (node->ovflw_irq !=0 ) { trigger = (node->ovflw_irq_flags &ACPI_APMT_OVFLW_IRQ_FLAGS_MODE );
Good catch,
Re: [PATCH 2/4] ACPI/APMT: Don't register invalid resource
In reply to Robin MurphyQuoted 7 lines · Robin Murphy
Don't register a resource for the second page unless the dual-page extension flag is actually present to say it's valid.
CC Lorenzo Pieralisi <[email protected]>CC Hanjun Guo <[email protected]>CC Sudeep Holla <[email protected]>Signed-off-by Robin Murphy <[email protected]>
Quoted 34 lines
---
Not a critical fix, since the driver currently works around this itself, but patch #4 would like to clean that up.
drivers/acpi/arm64/apmt.c| 10 ++++++----1 file changed, 6 insertions(+), 4 deletions(-)drivers/acpi/arm64/apmt.c +6
-4@@ -35,11 +35,13 @@ static int __init apmt_init_resources(struct resource *res, num_res++; - res[num_res].start = node->base_address1; - res[num_res].end = node->base_address1 +SZ_4K -1 ; - res[num_res].flags =IORESOURCE_MEM ; +if (node->flags &ACPI_APMT_FLAGS_DUAL_PAGE ) { + res[num_res].start = node->base_address1; + res[num_res].end = node->base_address1 +SZ_4K -1 ; + res[num_res].flags =IORESOURCE_MEM ; - num_res++; + num_res++; + }if (node->ovflw_irq !=0 ) { trigger = (node->ovflw_irq_flags &ACPI_APMT_OVFLW_IRQ_FLAGS_MODE );Signature · 1 line
2.39.2.101.g768bb238c484.dirty
PATCH 3/4 perf/arm_cspmu: Clean up ACPI dependency
In reply to Robin MurphyBuild-wise, the ACPI dependency consists of only a couple of things which could probably stand being factored out into ACPI helpers anyway. However for the immediate concern of working towards Devicetree support here, it's easy enough to make a few tweaks to contain the affected code locally, such that we can relax the Kconfig dependency.
--- drivers/perf/arm_cspmu/Kconfig | 3 +-- drivers/perf/arm_cspmu/arm_cspmu.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-)
drivers/perf/arm_cspmu/Kconfig +1 -2
@@ -4,8 +4,7 @@ config ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU tristate "ARM Coresight Architecture PMU" - depends on ARM64 && ACPI - depends on ACPI_APMT || COMPILE_TEST + depends on ARM64 || COMPILE_TEST help Provides support for performance monitoring unit (PMU) devices based on ARM CoreSight PMU architecture. Note that this PMU
drivers/perf/arm_cspmu/arm_cspmu.c +15 -2
@@ -28,7 +28,6 @@#include <linux/module.h> #include <linux/perf_event.h> #include <linux/platform_device.h> -#include <acpi/processor.h> #include "arm_cspmu.h" #include "nvidia_cspmu.h"
@@ -1075,6 +1074,9 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)return 0 ; } +#if defined(CONFIG_ACPI ) && defined(CONFIG_ARM64 ) +#include <acpi/processor.h> +static inline int arm_cspmu_find_cpu_container (int cpu,u32 container_uid) {u32 acpi_uid;
@@ -1099,7 +1101,7 @@ static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid)return -ENODEV ; } -static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) {struct device *dev;struct acpi_apmt_node *apmt_node;
@@ -1135,6 +1137,17 @@ static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu) return 0; } +#else +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) +{ +return -ENODEV ; +} +#endif + +static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +{ +return arm_cspmu_acpi_get_cpus (cspmu); +}static int arm_cspmu_register_pmu (struct arm_cspmu *cspmu) {
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 3/4] perf/arm_cspmu: Clean up ACPI dependency
Quoted 65 lines · Robin Murphy
Build-wise, the ACPI dependency consists of only a couple of things which could probably stand being factored out into ACPI helpers anyway. However for the immediate concern of working towards Devicetree support here, it's easy enough to make a few tweaks to contain the affected code locally, such that we can relax the
Kconfigdependency.Signed-off-by Robin Murphy <[email protected]>--- drivers/perf/arm_cspmu/Kconfig | 3 +-- drivers/perf/arm_cspmu/arm_cspmu.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-)drivers/perf/arm_cspmu/Kconfig +1
-2@@ -4,8 +4,7 @@ config ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU tristate "ARM Coresight Architecture PMU" - depends on ARM64 && ACPI - depends on ACPI_APMT || COMPILE_TEST + depends on ARM64 || COMPILE_TEST help Provides support for performance monitoring unit (PMU) devices based on ARM CoreSight PMU architecture. Note that this PMUdrivers/perf/arm_cspmu/arm_cspmu.c +8
-2@@ -28,7 +28,6 @@#include <linux/module.h> #include <linux/perf_event.h> #include <linux/platform_device.h> -#include <acpi/processor.h> #include "arm_cspmu.h" #include "nvidia_cspmu.h" @@ -1075,6 +1074,9 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)return 0 ; } +#if defined(CONFIG_ACPI ) && defined(CONFIG_ARM64 ) +#include <acpi/processor.h> +static inline int arm_cspmu_find_cpu_container (int cpu,u32 container_uid) {u32 acpi_uid;@@ -1099,7 +1101,7 @@ static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid)return -ENODEV ; } -static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) {struct device *dev;struct acpi_apmt_node *apmt_node;@@ -1135,6 +1137,17 @@ static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu) return 0; } +#else +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) +{ +return -ENODEV ;
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu) · line 1153
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +7
-0+} +#endif + +static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +{ +return arm_cspmu_acpi_get_cpus (cspmu); +}static int arm_cspmu_register_pmu (struct arm_cspmu *cspmu) {
Re: [PATCH 3/4] perf/arm_cspmu: Clean up ACPI dependency
In reply to Robin MurphyQuoted 7 lines · Robin Murphy
Build-wise, the ACPI dependency consists of only a couple of things which could probably stand being factored out into ACPI helpers anyway. However for the immediate concern of working towards Devicetree support here, it's easy enough to make a few tweaks to contain the affected code locally, such that we can relax the
Kconfigdependency.Signed-off-by Robin Murphy <[email protected]>
Quoted 72 lines
---
drivers/perf/arm_cspmu/Kconfig| 3 +--drivers/perf/arm_cspmu/arm_cspmu.c| 17 +++++++++++++++--2 files changed, 16 insertions(+), 4 deletions(-)drivers/perf/arm_cspmu/Kconfig +0
-0@@ -4,8 +4,7 @@config
ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU
tristate "ARM Coresight Architecture PMU"drivers/perf/arm_cspmu/Kconfig +1
-2- depends on ARM64 && ACPI - depends on ACPI_APMT || COMPILE_TEST + depends on ARM64 || COMPILE_TESThelp
Provides support for performance monitoring unit (PMU) devices based on ARM CoreSight PMU architecture. Note that this PMUdrivers/perf/arm_cspmu/arm_cspmu.c +15
-2@@ -28,7 +28,6 @@#include <linux/module.h> #include <linux/perf_event.h> #include <linux/platform_device.h> -#include <acpi/processor.h> #include "arm_cspmu.h" #include "nvidia_cspmu.h" @@ -1075,6 +1074,9 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)return 0 ; } +#if defined(CONFIG_ACPI ) && defined(CONFIG_ARM64 ) +#include <acpi/processor.h> +static inline int arm_cspmu_find_cpu_container (int cpu,u32 container_uid) {u32 acpi_uid;@@ -1099,7 +1101,7 @@ static inline int arm_cspmu_find_cpu_container(int cpu, u32 container_uid)return -ENODEV ; } -static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) {struct device *dev;struct acpi_apmt_node *apmt_node;@@ -1135,6 +1137,17 @@ static int arm_cspmu_get_cpus(struct arm_cspmu *cspmu) return 0; } +#else +static int arm_cspmu_acpi_get_cpus (struct arm_cspmu *cspmu) +{ +return -ENODEV ; +} +#endif + +static int arm_cspmu_get_cpus (struct arm_cspmu *cspmu) +{ +return arm_cspmu_acpi_get_cpus (cspmu); +}static int arm_cspmu_register_pmu (struct arm_cspmu *cspmu) {Signature · 1 line
2.39.2.101.g768bb238c484.dirty
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 4/4 perf/arm_cspmu: Decouple APMT dependency
In reply to Robin MurphyThe functional paths of the driver need not care about ACPI, so abstract the property of atomic doubleword access as its own flag (repacking the structure for a better fit). We also do not need to go poking directly at the APMT for standard resources which the ACPI layer has already dealt with, so deal with the optional MMIO page and interrupt in the normal firmware-agnostic manner. The few remaining portions of probing that *are* APMT-specific can still easily retrieve the APMT pointer as needed without us having to carry a duplicate copy around everywhere.
--- drivers/perf/arm_cspmu/arm_cspmu.c | 45 ++++++++---------------------- drivers/perf/arm_cspmu/arm_cspmu.h | 4 +-- 2 files changed, 13 insertions(+), 36 deletions(-)
drivers/perf/arm_cspmu/arm_cspmu.c +11 -34
@@ -100,10 +100,6 @@#define ARM_CSPMU_ACTIVE_CPU_MASK 0x0#define ARM_CSPMU_ASSOCIATED_CPU_MASK 0x1 -/* Check if field f in flags is set with value v */ -#define CHECK_APMT_FLAG (flags, f, v) \ - ((flags & (ACPI_APMT_FLAGS_ ## f)) == (ACPI_APMT_FLAGS_ ## f ## _ ## v)) -/* Check and use default if implementer doesn't provide attribute callback */ #define CHECK_DEFAULT_IMPL_OPS (ops, callback) \ do { \
@@ -155,12 +151,6 @@ static u64 read_reg64_hilohi(const void __iomem *addr, u32 max_poll_count)return val; } -/* Check if PMU supports 64-bit single copy atomic. */ -static inline bool supports_64bit_atomics (const struct arm_cspmu *cspmu) -{ -return CHECK_APMT_FLAG (cspmu->apmt_node->flags,ATOMIC ,SUPP ); -} -/* Check if cycle counter is supported. */ static inline bool supports_cycle_counter (const struct arm_cspmu *cspmu) {
@@ -319,7 +309,7 @@ static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu)static atomic_t pmu_idx[ACPI_APMT_NODE_TYPE_COUNT ] = {0 }; dev = cspmu->dev; - apmt_node = cspmu->apmt_node; + apmt_node =dev_get_platdata (dev); pmu_type = apmt_node->type;if (pmu_type >=ACPI_APMT_NODE_TYPE_COUNT ) {
@@ -396,8 +386,8 @@ static const struct impl_match impl_match[] = {static int arm_cspmu_init_impl_ops (struct arm_cspmu *cspmu) {int ret; -struct acpi_apmt_node *apmt_node = cspmu->apmt_node;struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops; +struct acpi_apmt_node *apmt_node =dev_get_platdata (cspmu->dev);const struct impl_match *match = impl_match;/*
@@ -719,7 +709,7 @@ static u64 arm_cspmu_read_counter(struct perf_event *event) offset =counter_offset (sizeof (u64), event->hw.idx); counter_addr = cspmu->base1 + offset; -return supports_64bit_atomics (cspmu) ? +return cspmu->has_atomic_dword ?readq (counter_addr) :read_reg64_hilohi (counter_addr,HILOHI_MAX_POLL ); }
@@ -910,24 +900,18 @@ static struct arm_cspmu *arm_cspmu_alloc(struct platform_device *pdev) {struct acpi_apmt_node *apmt_node;struct arm_cspmu *cspmu; -struct device *dev; - - dev = &pdev->dev; - apmt_node = *(struct acpi_apmt_node **)dev_get_platdata (dev); -if (!apmt_node) { -dev_err (dev,"failed to get APMT node\n" ); -return NULL ; - } +struct device *dev = &pdev->dev; cspmu =devm_kzalloc (dev,sizeof (*cspmu),GFP_KERNEL );if (!cspmu)return NULL ; cspmu->dev = dev; - cspmu->apmt_node = apmt_node; -platform_set_drvdata (pdev, cspmu); + apmt_node =dev_get_platdata (dev); + cspmu->has_atomic_dword = apmt_node->flags &ACPI_APMT_FLAGS_ATOMIC ; +return cspmu; }
@@ -935,11 +919,9 @@ static int arm_cspmu_init_mmio(struct arm_cspmu *cspmu) {struct device *dev;struct platform_device *pdev; -struct acpi_apmt_node *apmt_node; dev = cspmu->dev; pdev =to_platform_device (dev); - apmt_node = cspmu->apmt_node;/* Base address for page 0. */ cspmu->base0 =devm_platform_ioremap_resource (pdev,0 );
@@ -950,7 +932,7 @@ static int arm_cspmu_init_mmio(struct arm_cspmu *cspmu)/* Base address for page 1 if supported. Otherwise point to page 0. */ cspmu->base1 = cspmu->base0; -if (CHECK_APMT_FLAG (apmt_node->flags,DUAL_PAGE ,SUPP )) { +if (platform_get_resource (pdev,IORESOURCE_MEM ,1 )) { cspmu->base1 =devm_platform_ioremap_resource (pdev,1 );if (IS_ERR (cspmu->base1)) {dev_err (dev,"ioremap failed for page-1 resource\n" );
@@ -1047,19 +1029,14 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)int irq, ret;struct device *dev;struct platform_device *pdev; -struct acpi_apmt_node *apmt_node; dev = cspmu->dev; pdev =to_platform_device (dev); - apmt_node = cspmu->apmt_node;/* Skip IRQ request if the PMU does not support overflow interrupt. */ -if (apmt_node->ovflw_irq ==0 ) -return 0 ; - - irq =platform_get_irq (pdev,0 ); + irq =platform_get_irq_optional (pdev,0 );if (irq <0 ) -return irq; +return irq == -ENXIO ?0 : irq; ret = devm_request_irq(dev, irq, arm_cspmu_handle_irq, IRQF_NOBALANCING | IRQF_NO_THREAD, dev_name(dev),
@@ -1109,7 +1086,7 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)int cpu; dev = cspmu->pmu.dev; - apmt_node = cspmu->apmt_node; + apmt_node =dev_get_platdata (dev); affinity_flag = apmt_node->flags &ACPI_APMT_FLAGS_AFFINITY ;if (affinity_flag ==ACPI_APMT_FLAGS_AFFINITY_PROC ) {
drivers/perf/arm_cspmu/arm_cspmu.h +2 -2
@@ -118,16 +118,16 @@ struct arm_cspmu_impl {struct arm_cspmu {struct pmu pmu;struct device *dev; -struct acpi_apmt_node *apmt_node;const char *name;const char *identifier;void __iomem *base0;void __iomem *base1; -int irq;cpumask_t associated_cpus;cpumask_t active_cpu;struct hlist_node cpuhp_node; +int irq; +bool has_atomic_dword;u32 pmcfgr;u32 num_logical_ctrs;u32 num_set_clr_reg;
Signature · 1 line
2.39.2.101.g768bb238c484.dirty
Re: [PATCH 4/4] perf/arm_cspmu: Decouple APMT dependency
Quoted 10 lines · Robin Murphy
The functional paths of the driver need not care about ACPI, so abstract the property of atomic doubleword access as its own flag (repacking the structure for a better fit). We also do not need to go poking directly at the APMT for standard resources which the ACPI layer has already dealt with, so deal with the optional MMIO page and interrupt in the normal firmware-agnostic manner. The few remaining portions of probing that *are* APMT-specific can still easily retrieve the APMT pointer as needed without us having to carry a duplicate copy around everywhere.
Signed-off-by Robin Murphy <[email protected]>
Re: [PATCH 4/4] perf/arm_cspmu: Decouple APMT dependency
In reply to Robin MurphyHi Robin,
I have a couple of comments below
Quoted 19 lines · Robin Murphy
The functional paths of the driver need not care about ACPI, so abstract the property of atomic doubleword access as its own flag (repacking the structure for a better fit). We also do not need to go poking directly at the APMT for standard resources which the ACPI layer has already dealt with, so deal with the optional MMIO page and interrupt in the normal firmware-agnostic manner. The few remaining portions of probing that *are* APMT-specific can still easily retrieve the APMT pointer as needed without us having to carry a duplicate copy around everywhere.
Signed-off-by Robin Murphy <[email protected]>---
drivers/perf/arm_cspmu/arm_cspmu.c| 45 ++++++++----------------------drivers/perf/arm_cspmu/arm_cspmu.h| 4 +--2 files changed, 13 insertions(+), 36 deletions(-)drivers/perf/arm_cspmu/arm_cspmu.c +0
-0
...
drivers/perf/arm_cspmu/arm_cspmu.c static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu) · line 312
Quoted 6 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-1@@ -319,7 +309,7 @@ static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu)static atomic_t pmu_idx[ACPI_APMT_NODE_TYPE_COUNT ] = {0 }; dev = cspmu->dev; - apmt_node = cspmu->apmt_node; + apmt_node =dev_get_platdata (dev);
Was platdata changed too? If not, I think this should be
apmt_node = *(struct acpi_apmt_node **) dev_get_platdata(dev);
drivers/perf/arm_cspmu/arm_cspmu.c static const struct impl_match impl_match[] = { · line 390
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-1pmu_type = apmt_node->type;if (pmu_type >=ACPI_APMT_NODE_TYPE_COUNT ) {@@ -396,8 +386,8 @@ static const struct impl_match impl_match[] = {static int arm_cspmu_init_impl_ops (struct arm_cspmu *cspmu) {int ret; -struct acpi_apmt_node *apmt_node = cspmu->apmt_node;struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops; +struct acpi_apmt_node *apmt_node =dev_get_platdata (cspmu->dev);
Ditto
Quoted 3 lines
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0const struct impl_match *match = impl_match;/*
...
Quoted 14 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-8@@ -910,24 +900,18 @@ static struct arm_cspmu *arm_cspmu_alloc(struct platform_device *pdev) {struct acpi_apmt_node *apmt_node;struct arm_cspmu *cspmu; -struct device *dev; - - dev = &pdev->dev; - apmt_node = *(struct acpi_apmt_node **)dev_get_platdata (dev); -if (!apmt_node) { -dev_err (dev,"failed to get APMT node\n" ); -return NULL ; - } +struct device *dev = &pdev->dev;
drivers/perf/arm_cspmu/arm_cspmu.c static struct arm_cspmu *arm_cspmu_alloc(struct platform_device *pdev) · line 912
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-2cspmu =devm_kzalloc (dev,sizeof (*cspmu),GFP_KERNEL );if (!cspmu)return NULL ; cspmu->dev = dev; - cspmu->apmt_node = apmt_node; -platform_set_drvdata (pdev, cspmu); + apmt_node =dev_get_platdata (dev);
Ditto
Quoted 4 lines
drivers/perf/arm_cspmu/arm_cspmu.c +2
-0+ cspmu->has_atomic_dword = apmt_node->flags &ACPI_APMT_FLAGS_ATOMIC ; +return cspmu; }
...
Quoted 23 lines
drivers/perf/arm_cspmu/arm_cspmu.c +2
-7@@ -1047,19 +1029,14 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu)int irq, ret;struct device *dev;struct platform_device *pdev; -struct acpi_apmt_node *apmt_node; dev = cspmu->dev; pdev =to_platform_device (dev); - apmt_node = cspmu->apmt_node;/* Skip IRQ request if the PMU does not support overflow interrupt. */ -if (apmt_node->ovflw_irq ==0 ) -return 0 ; - - irq =platform_get_irq (pdev,0 ); + irq =platform_get_irq_optional (pdev,0 );if (irq <0 ) -return irq; +return irq == -ENXIO ?0 : irq; ret = devm_request_irq(dev, irq, arm_cspmu_handle_irq, IRQF_NOBALANCING | IRQF_NO_THREAD, dev_name(dev),
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) · line 1088
Quoted 3 lines
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0@@ -1109,7 +1086,7 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu)int cpu; dev = cspmu->pmu.dev;
You didn't touch this one but shouldn't this be
dev = cspmu->dev;
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) · line 1089
Quoted 2 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-1- apmt_node = cspmu->apmt_node; + apmt_node =dev_get_platdata (dev);
Ditto
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) · line 1090
Quoted 1 line
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0affinity_flag = apmt_node->flags &ACPI_APMT_FLAGS_AFFINITY ;
Otherwise the patch looks good to me.
Cheers, Ilkka
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH 4/4] perf/arm_cspmu: Decouple APMT dependency
Quoted 32 lines · Ilkka Koskinen
Hi Robin,
I have a couple of comments below
Quoted 19 lines · Robin Murphy
The functional paths of the driver need not care about ACPI, so abstract the property of atomic doubleword access as its own flag (repacking the structure for a better fit). We also do not need to go poking directly at the APMT for standard resources which the ACPI layer has already dealt with, so deal with the optional MMIO page and interrupt in the normal firmware-agnostic manner. The few remaining portions of probing that *are* APMT-specific can still easily retrieve the APMT pointer as needed without us having to carry a duplicate copy around everywhere.
Signed-off-by Robin Murphy <[email protected]>---
drivers/perf/arm_cspmu/arm_cspmu.c| 45 ++++++++----------------------drivers/perf/arm_cspmu/arm_cspmu.h| 4 +--2 files changed, 13 insertions(+), 36 deletions(-)drivers/perf/arm_cspmu/arm_cspmu.c +0
-0...
Quoted 4 lines
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0@@ -319,7 +309,7 @@ static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu) static atomic_t pmu_idx[ACPI_APMT_NODE_TYPE_COUNT] = { 0 };
Quoted 7 lines
drivers/perf/arm_cspmu/arm_cspmu.c static const char *arm_cspmu_get_name(const struct arm_cspmu *cspmu) · line 312
Quoted 3 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-1dev = cspmu->dev; - apmt_node = cspmu->apmt_node; + apmt_node = dev_get_platdata(dev);Was platdata changed too? If not, I think this should be
apmt_node = *(struct
acpi_apmt_node**)dev_get_platdata(dev);
Oof, indeed it looks like I got the wrong thing into my head at the critical moment :(
Clearly this deserves a nice helpful wrapper so we only have to think about the nasty casting once...
Quoted 81 lines
drivers/perf/arm_cspmu/arm_cspmu.c static const struct impl_match impl_match[] = { · line 390
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0pmu_type = apmt_node->type;if (
pmu_type>=ACPI_APMT_NODE_TYPE_COUNT) {drivers/perf/arm_cspmu/arm_cspmu.c +1
-1@@ -396,8 +386,8 @@ static const struct impl_match impl_match[] = {static int arm_cspmu_init_impl_ops (struct arm_cspmu *cspmu) { int ret; - struct acpi_apmt_node *apmt_node = cspmu->apmt_node; struct arm_cspmu_impl_ops *impl_ops = &cspmu->impl.ops; + struct acpi_apmt_node *apmt_node = dev_get_platdata(cspmu->dev);Ditto
Quoted 3 lines
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0const struct impl_match *match = impl_match; /*...
Quoted 15 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-8@@ -910,24 +900,18 @@ static struct arm_cspmu *arm_cspmu_alloc(struct platform_device *pdev) { struct acpi_apmt_node *apmt_node; struct arm_cspmu *cspmu; - struct device *dev; - - dev = &pdev->dev; - apmt_node = *(struct acpi_apmt_node **)dev_get_platdata(dev); - if (!apmt_node) { - dev_err(dev, "failed to get APMT node\n"); - return NULL; - } + struct device *dev = &pdev->dev;drivers/perf/arm_cspmu/arm_cspmu.c static struct arm_cspmu *arm_cspmu_alloc(struct · line 913
Quoted 10 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-2cspmu = devm_kzalloc(dev, sizeof(*cspmu), GFP_KERNEL); if (!cspmu) return NULL; cspmu->dev = dev; - cspmu->apmt_node = apmt_node; - platform_set_drvdata(pdev, cspmu); + apmt_node = dev_get_platdata(dev);Ditto
Quoted 4 lines
drivers/perf/arm_cspmu/arm_cspmu.c +2
-0+ cspmu->has_atomic_dword = apmt_node->flags & ACPI_APMT_FLAGS_ATOMIC; + return cspmu; }...
Quoted 27 lines
drivers/perf/arm_cspmu/arm_cspmu.c +2
-7@@ -1047,19 +1029,14 @@ static int arm_cspmu_request_irq(struct arm_cspmu *cspmu) int irq, ret; struct device *dev; struct platform_device *pdev; - struct acpi_apmt_node *apmt_node; dev = cspmu->dev; pdev = to_platform_device(dev); - apmt_node = cspmu->apmt_node; /* Skip IRQ request if the PMU does not support overflow interrupt. */ - if (apmt_node->ovflw_irq == 0) - return 0; - - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq < 0) - return irq; + return irq == -ENXIO ? 0 : irq; ret = devm_request_irq(dev, irq, arm_cspmu_handle_irq,
IRQF_NOBALANCING|IRQF_NO_THREAD,dev_name(dev),drivers/perf/arm_cspmu/arm_cspmu.c +0
-0@@ -1109,7 +1086,7 @@ static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) int cpu;
Quoted 5 lines
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) · line 1088
Quoted 1 line
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0dev = cspmu->pmu.dev;You didn't touch this one but shouldn't this be
dev =
cspmu->dev;
Good catch - attributing the error message to the wrong device doesn't matter too much currently, but this change does then need it to be right. Will fix that too.
Thanks!
Robin.
Quoted 12 lines
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct · line 1090
Quoted 3 lines
drivers/perf/arm_cspmu/arm_cspmu.c +1
-1- apmt_node = cspmu->apmt_node; + apmt_node = dev_get_platdata(dev);Ditto
drivers/perf/arm_cspmu/arm_cspmu.c static int arm_cspmu_acpi_get_cpus(struct arm_cspmu *cspmu) · line 1090
Quoted 1 line
drivers/perf/arm_cspmu/arm_cspmu.c +0
-0affinity_flag = apmt_node->flags & ACPI_APMT_FLAGS_AFFINITY;Otherwise the patch looks good to me.
Cheers, Ilkka