Message ID | 20230728112733.359620-2-anshuman.khandual@arm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp378004vqg; Fri, 28 Jul 2023 04:56:46 -0700 (PDT) X-Google-Smtp-Source: APBJJlFHjvWbAwn+Z5B7XnKywGlX2duIib+U6lbTLAIgTZB6enLbfcY24lfgj63+wN+YjazKOR2N X-Received: by 2002:aa7:da8b:0:b0:522:1d23:a1f8 with SMTP id q11-20020aa7da8b000000b005221d23a1f8mr1359561eds.26.1690545406233; Fri, 28 Jul 2023 04:56:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690545406; cv=none; d=google.com; s=arc-20160816; b=1GtOk/IjmjBha4ddJvzkN3aweuVD1UcfH9Xk6AxZVmVOwkokN+MsTkRfB6jt5dpF6R AZ9xelFqwt1rmY8gh8G7opkgljn9iFIhTLXmGYL+GO9EFrSxJo/b0TqgYnOmfAs/opq9 vaqYlpEifSHRqhT/+QTBFgF3wtDHkSY6X9NYNc226JjoflWXxzIrDRyEzNAtarKp0evw 7S/9FzajeCtAnFHPJ9BH1yGJEEOMTRgUsm2FHGSTDsq97nGz6e7IWieGQP4DbGpqjwhM jQSN9iHxLjsUvOps6XVrJJiAazK5h9HpmpLMyhdITlljyow6UKI5qQShKp3w4qyF6WYY XFmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=1OaUY9+MqlC2J+t1OhPnSjwVsmA0E9k6o/2hmx1K008=; fh=J+p7EhpAaI9pLvGhGO08nD/3D2XA+A6RPzvd+bjr8cY=; b=kBHageDe5W44YxuazlY59CWg0/0lMyGMW8d2pdPlLQlqysoT1vXnU/5av6prE4CBLN aU0xEL+653wDkXsspkFpHd7kvn6iWcIWOMkSoU22VLaOnNbq4Tx9VCq897vKKjlImuxl nSU1mP1Ta8q+vjaOALLidwIOArCPi8hbyHtBENRppu9FUWKg5HjO97UvdcIQTH/UkRe3 GmLu+/xxfVp23ankAlZXYccZH4NJGHiJuGgLMX/72NXRnAt5YjLeCZZUqy8l4LqVlCf7 5UExl3JwPqcsLPbm+eSni8CYgHc+vj/WLc2i65CTlw1JY2ynDszJ0U7or9j/93QAAe+U hvdg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r24-20020aa7cfd8000000b0051de2e74786si2344823edy.266.2023.07.28.04.56.21; Fri, 28 Jul 2023 04:56:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236236AbjG1L2H (ORCPT <rfc822;hanasaki@gmail.com> + 99 others); Fri, 28 Jul 2023 07:28:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235573AbjG1L17 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 28 Jul 2023 07:27:59 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3D2652D5B for <linux-kernel@vger.kernel.org>; Fri, 28 Jul 2023 04:27:58 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 182BED75; Fri, 28 Jul 2023 04:28:41 -0700 (PDT) Received: from a077893.blr.arm.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 68B1F3F6C4; Fri, 28 Jul 2023 04:27:55 -0700 (PDT) From: Anshuman Khandual <anshuman.khandual@arm.com> To: linux-arm-kernel@lists.infradead.org, suzuki.poulose@arm.com Cc: Anshuman Khandual <anshuman.khandual@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Mark Rutland <mark.rutland@arm.com>, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] arm_pmu: acpi: Add a representative platform device for TRBE Date: Fri, 28 Jul 2023 16:57:31 +0530 Message-Id: <20230728112733.359620-2-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230728112733.359620-1-anshuman.khandual@arm.com> References: <20230728112733.359620-1-anshuman.khandual@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772665340052020519 X-GMAIL-MSGID: 1772665340052020519 |
Series |
coresight: trbe: Enable ACPI based devices
|
|
Commit Message
Anshuman Khandual
July 28, 2023, 11:27 a.m. UTC
ACPI TRBE does not have a HID for identification which could create and add
a platform device into the platform bus. Also without a platform device, it
cannot be probed and bound to a platform driver.
This creates a dummy platform device for TRBE after ascertaining that ACPI
provides required interrupts uniformly across all cpus on the system. This
device gets created inside drivers/perf/arm_pmu_acpi.c to accommodate TRBE
being built as a module.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/arm64/include/asm/acpi.h | 3 ++
drivers/perf/arm_pmu_acpi.c | 63 +++++++++++++++++++++++++++++++++++
include/linux/perf/arm_pmu.h | 1 +
3 files changed, 67 insertions(+)
Comments
On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: > ACPI TRBE does not have a HID for identification which could create and add > a platform device into the platform bus. Also without a platform device, it > cannot be probed and bound to a platform driver. > > This creates a dummy platform device for TRBE after ascertaining that ACPI > provides required interrupts uniformly across all cpus on the system. This > device gets created inside drivers/perf/arm_pmu_acpi.c to accommodate TRBE > being built as a module. > > Cc: Catalin Marinas <catalin.marinas@arm.com> > Cc: Will Deacon <will@kernel.org> > Cc: Mark Rutland <mark.rutland@arm.com> > Cc: linux-arm-kernel@lists.infradead.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> --->8 > diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c > index 90815ad762eb..dd3df6729808 100644 > --- a/drivers/perf/arm_pmu_acpi.c > +++ b/drivers/perf/arm_pmu_acpi.c > @@ -139,6 +139,68 @@ static inline void arm_spe_acpi_register_device(void) > } > #endif /* CONFIG_ARM_SPE_PMU */ > > +#ifdef CONFIG_CORESIGHT_TRBE > +static struct resource trbe_acpi_resources[] = { > + { > + /* irq */ > + .flags = IORESOURCE_IRQ, > + } > +}; > + > +static struct platform_device trbe_acpi_dev = { > + .name = ARMV8_TRBE_PDEV_NAME, > + .id = -1, > + .resource = trbe_acpi_resources, > + .num_resources = ARRAY_SIZE(trbe_acpi_resources) > +}; > + > +static void arm_trbe_acpi_register_device(void) > +{ > + int cpu, hetid, irq, ret; > + bool first = true; > + u16 gsi = 0; > + > + for_each_possible_cpu(cpu) { > + struct acpi_madt_generic_interrupt *gicc; > + > + gicc = acpi_cpu_get_madt_gicc(cpu); > + if (gicc->header.length < ACPI_MADT_GICC_TRBE) > + return; > + > + if (first) { > + gsi = gicc->trbe_interrupt; > + if (!gsi) > + return; > + > + hetid = find_acpi_cpu_topology_hetero_id(cpu); > + first = false; > + } else if ((gsi != gicc->trbe_interrupt) || > + (hetid != find_acpi_cpu_topology_hetero_id(cpu))) { > + pr_warn("ACPI: TRBE must be homogeneous\n"); > + return; > + } > + } > + > + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); > + if (irq < 0) { > + pr_warn("ACPI: TRBE Unable to register interrupt: %d\n", gsi); > + return; > + } > + trbe_acpi_resources[0].start = irq; > + > + ret = platform_device_register(&trbe_acpi_dev); > + if (ret < 0) { > + pr_warn("ACPI: TRBE: Unable to register device\n"); > + acpi_unregister_gsi(gsi); > + } > +} > +#else > +static inline void arm_trbe_acpi_register_device(void) > +{ > + > +} > +#endif /* CONFIG_CORESIGHT_TRBE */ This looks like you ran s/spe/trbe/ over the SPE device registration code :) Please can you refactor things so we don't have all the duplication? I suspect this won't be the last device which needs the same treatement. Cheers, Will
On 7/28/23 20:10, Will Deacon wrote: > On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: >> ACPI TRBE does not have a HID for identification which could create and add >> a platform device into the platform bus. Also without a platform device, it >> cannot be probed and bound to a platform driver. >> >> This creates a dummy platform device for TRBE after ascertaining that ACPI >> provides required interrupts uniformly across all cpus on the system. This >> device gets created inside drivers/perf/arm_pmu_acpi.c to accommodate TRBE >> being built as a module. >> >> Cc: Catalin Marinas <catalin.marinas@arm.com> >> Cc: Will Deacon <will@kernel.org> >> Cc: Mark Rutland <mark.rutland@arm.com> >> Cc: linux-arm-kernel@lists.infradead.org >> Cc: linux-kernel@vger.kernel.org >> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> > > --->8 > >> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c >> index 90815ad762eb..dd3df6729808 100644 >> --- a/drivers/perf/arm_pmu_acpi.c >> +++ b/drivers/perf/arm_pmu_acpi.c >> @@ -139,6 +139,68 @@ static inline void arm_spe_acpi_register_device(void) >> } >> #endif /* CONFIG_ARM_SPE_PMU */ >> >> +#ifdef CONFIG_CORESIGHT_TRBE >> +static struct resource trbe_acpi_resources[] = { >> + { >> + /* irq */ >> + .flags = IORESOURCE_IRQ, >> + } >> +}; >> + >> +static struct platform_device trbe_acpi_dev = { >> + .name = ARMV8_TRBE_PDEV_NAME, >> + .id = -1, >> + .resource = trbe_acpi_resources, >> + .num_resources = ARRAY_SIZE(trbe_acpi_resources) >> +}; >> + >> +static void arm_trbe_acpi_register_device(void) >> +{ >> + int cpu, hetid, irq, ret; >> + bool first = true; >> + u16 gsi = 0; >> + >> + for_each_possible_cpu(cpu) { >> + struct acpi_madt_generic_interrupt *gicc; >> + >> + gicc = acpi_cpu_get_madt_gicc(cpu); >> + if (gicc->header.length < ACPI_MADT_GICC_TRBE) >> + return; >> + >> + if (first) { >> + gsi = gicc->trbe_interrupt; >> + if (!gsi) >> + return; >> + >> + hetid = find_acpi_cpu_topology_hetero_id(cpu); >> + first = false; >> + } else if ((gsi != gicc->trbe_interrupt) || >> + (hetid != find_acpi_cpu_topology_hetero_id(cpu))) { >> + pr_warn("ACPI: TRBE must be homogeneous\n"); >> + return; >> + } >> + } >> + >> + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); >> + if (irq < 0) { >> + pr_warn("ACPI: TRBE Unable to register interrupt: %d\n", gsi); >> + return; >> + } >> + trbe_acpi_resources[0].start = irq; >> + >> + ret = platform_device_register(&trbe_acpi_dev); >> + if (ret < 0) { >> + pr_warn("ACPI: TRBE: Unable to register device\n"); >> + acpi_unregister_gsi(gsi); >> + } >> +} >> +#else >> +static inline void arm_trbe_acpi_register_device(void) >> +{ >> + >> +} >> +#endif /* CONFIG_CORESIGHT_TRBE */ > > This looks like you ran s/spe/trbe/ over the SPE device registration > code :) Yeah, almost :) > > Please can you refactor things so we don't have all the duplication? I > suspect this won't be the last device which needs the same treatement. Should the refactoring just accommodate SPE, and TRBE or make it more generic to accommodate future devices as well. Something like the following enumeration. enum arm_platform_device { ARM_PLATFORM_DEVICE_SPE, ARM_PLATFORM_DEVICE_TRBE, ARM_PLATFORM_DEVICE_MAX, }; But that would require adding some helper functions to select these following elements based on the above enumeration via a common function - gicc->XXX_interrupt - ACPI_MADT_GICC_SPE/TRBE for header length comparison - static struct platform_device/resources (static objects in the file) Seems like will add much more code for a refactor. Did you have something else in mind for the refactor.
On Mon, Jul 31, 2023 at 05:38:38PM +0530, Anshuman Khandual wrote: > On 7/28/23 20:10, Will Deacon wrote: > > On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: > >> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c > >> index 90815ad762eb..dd3df6729808 100644 > >> --- a/drivers/perf/arm_pmu_acpi.c > >> +++ b/drivers/perf/arm_pmu_acpi.c [...] > >> + ret = platform_device_register(&trbe_acpi_dev); > >> + if (ret < 0) { > >> + pr_warn("ACPI: TRBE: Unable to register device\n"); > >> + acpi_unregister_gsi(gsi); > >> + } > >> +} > >> +#else > >> +static inline void arm_trbe_acpi_register_device(void) > >> +{ > >> + > >> +} > >> +#endif /* CONFIG_CORESIGHT_TRBE */ > > > > This looks like you ran s/spe/trbe/ over the SPE device registration > > code :) > > Yeah, almost :) > > > Please can you refactor things so we don't have all the duplication? I > > suspect this won't be the last device which needs the same treatement. > > Should the refactoring just accommodate SPE, and TRBE or make it more generic to > accommodate future devices as well. Something like the following enumeration. > > enum arm_platform_device { > ARM_PLATFORM_DEVICE_SPE, > ARM_PLATFORM_DEVICE_TRBE, > ARM_PLATFORM_DEVICE_MAX, > }; > > But that would require adding some helper functions to select these following > elements based on the above enumeration via a common function > > - gicc->XXX_interrupt > - ACPI_MADT_GICC_SPE/TRBE for header length comparison > - static struct platform_device/resources (static objects in the file) > > Seems like will add much more code for a refactor. Did you have something else > in mind for the refactor. All I'm saying is that we shouldn't have identical copies of the code to walk the MADT, pull out the irqs and register the device. So something like the totally untested hack below. I probably broke something, but hopefully you see what I mean. Will --->8 diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index 90815ad762eb..7f1cf36c6e69 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -69,6 +69,62 @@ static void arm_pmu_acpi_unregister_irq(int cpu) acpi_unregister_gsi(gsi); } +static int +arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, + u16 (*parse_gsi)(struct acpi_madt_generic_interrupt *)) +{ + int cpu, hetid, irq, ret; + bool matched = false; + u16 gsi = 0; + + if (pdev->num_resources != 1) + return -ENXIO; + + if (pdev->resource[0].flags != IORESOURCE_IRQ) + return -ENXIO; + + /* + * Sanity check all the GICC tables for the same interrupt number. + * For now, we only support homogeneous ACPI machines. + */ + for_each_possible_cpu(cpu) { + struct acpi_madt_generic_interrupt *gicc; + u16 this_gsi; + + gicc = acpi_cpu_get_madt_gicc(cpu); + if (gicc->header.length < len) + return matched ? -ENXIO : 0; + + this_gsi = parse_gsi(gicc); + if (!matched) { + hetid = find_acpi_cpu_topology_hetero_id(cpu); + gsi = this_gsi; + matched = true; + } else if (hetid != find_acpi_cpu_topology_hetero_id(cpu) || + gsi != this_gsi) { + pr_warn("ACPI: %s: must be homogeneous\n", pdev->name); + return -ENXIO; + } + } + + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, + ACPI_ACTIVE_HIGH); + if (irq < 0) { + pr_warn("ACPI: %s Unable to register interrupt: %d\n", + pdev->name, gsi); + return -ENXIO; + } + + pdev->resource[0].start = irq; + ret = platform_device_register(pdev); + if (ret < 0) { + pr_warn("ACPI: %s: Unable to register device\n", pdev->name); + acpi_unregister_gsi(gsi); + } + + return ret; +} + #if IS_ENABLED(CONFIG_ARM_SPE_PMU) static struct resource spe_resources[] = { { @@ -89,49 +145,18 @@ static struct platform_device spe_dev = { * and create a SPE device if we detect a recent MADT with * a homogeneous PPI mapping. */ +static u16 arm_spe_parse_gsi(struct acpi_madt_generic_interrupt *gicc) +{ + return gicc->spe_interrupt; +} + static void arm_spe_acpi_register_device(void) { - int cpu, hetid, irq, ret; - bool first = true; - u16 gsi = 0; + int err = arm_acpi_register_pmu_device(&spe_dev, ACPI_MADT_GICC_SPE, + arm_spe_parse_gsi); - /* - * Sanity check all the GICC tables for the same interrupt number. - * For now, we only support homogeneous ACPI/SPE machines. - */ - for_each_possible_cpu(cpu) { - struct acpi_madt_generic_interrupt *gicc; - - gicc = acpi_cpu_get_madt_gicc(cpu); - if (gicc->header.length < ACPI_MADT_GICC_SPE) - return; - - if (first) { - gsi = gicc->spe_interrupt; - if (!gsi) - return; - hetid = find_acpi_cpu_topology_hetero_id(cpu); - first = false; - } else if ((gsi != gicc->spe_interrupt) || - (hetid != find_acpi_cpu_topology_hetero_id(cpu))) { - pr_warn("ACPI: SPE must be homogeneous\n"); - return; - } - } - - irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, - ACPI_ACTIVE_HIGH); - if (irq < 0) { - pr_warn("ACPI: SPE Unable to register interrupt: %d\n", gsi); - return; - } - - spe_resources[0].start = irq; - ret = platform_device_register(&spe_dev); - if (ret < 0) { - pr_warn("ACPI: SPE: Unable to register device\n"); - acpi_unregister_gsi(gsi); - } + if (err) + pr_warn("ACPI: Failed to register SPE device\n"); } #else static inline void arm_spe_acpi_register_device(void)
On 7/31/23 20:29, Will Deacon wrote: > On Mon, Jul 31, 2023 at 05:38:38PM +0530, Anshuman Khandual wrote: >> On 7/28/23 20:10, Will Deacon wrote: >>> On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: >>>> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c >>>> index 90815ad762eb..dd3df6729808 100644 >>>> --- a/drivers/perf/arm_pmu_acpi.c >>>> +++ b/drivers/perf/arm_pmu_acpi.c > > [...] > >>>> + ret = platform_device_register(&trbe_acpi_dev); >>>> + if (ret < 0) { >>>> + pr_warn("ACPI: TRBE: Unable to register device\n"); >>>> + acpi_unregister_gsi(gsi); >>>> + } >>>> +} >>>> +#else >>>> +static inline void arm_trbe_acpi_register_device(void) >>>> +{ >>>> + >>>> +} >>>> +#endif /* CONFIG_CORESIGHT_TRBE */ >>> >>> This looks like you ran s/spe/trbe/ over the SPE device registration >>> code :) >> >> Yeah, almost :) >> >>> Please can you refactor things so we don't have all the duplication? I >>> suspect this won't be the last device which needs the same treatement. >> >> Should the refactoring just accommodate SPE, and TRBE or make it more generic to >> accommodate future devices as well. Something like the following enumeration. >> >> enum arm_platform_device { >> ARM_PLATFORM_DEVICE_SPE, >> ARM_PLATFORM_DEVICE_TRBE, >> ARM_PLATFORM_DEVICE_MAX, >> }; >> >> But that would require adding some helper functions to select these following >> elements based on the above enumeration via a common function >> >> - gicc->XXX_interrupt >> - ACPI_MADT_GICC_SPE/TRBE for header length comparison >> - static struct platform_device/resources (static objects in the file) >> >> Seems like will add much more code for a refactor. Did you have something else >> in mind for the refactor. > > All I'm saying is that we shouldn't have identical copies of the code to > walk the MADT, pull out the irqs and register the device. > > So something like the totally untested hack below. I probably broke > something, but hopefully you see what I mean. > > Will > > --->8 > > diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c > index 90815ad762eb..7f1cf36c6e69 100644 > --- a/drivers/perf/arm_pmu_acpi.c > +++ b/drivers/perf/arm_pmu_acpi.c > @@ -69,6 +69,62 @@ static void arm_pmu_acpi_unregister_irq(int cpu) > acpi_unregister_gsi(gsi); > } > > +static int > +arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, > + u16 (*parse_gsi)(struct acpi_madt_generic_interrupt *)) This factored out helper should be wrapped inside CONFIG_ARM_SPE_PMU and CONFIG_CORESIGHT_TRBE ? Otherwise, there will be no callers left for this helper triggering warning. drivers/perf/arm_pmu_acpi.c:73:1: warning: ‘arm_acpi_register_pmu_device’ defined but not used [-Wunused-function] 73 | arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ But in that case, we have to keep adding new configs when new devices require platform devices to be registered. Is there a better way ? > +{ > + int cpu, hetid, irq, ret; > + bool matched = false; > + u16 gsi = 0; > + > + if (pdev->num_resources != 1) > + return -ENXIO; > + > + if (pdev->resource[0].flags != IORESOURCE_IRQ) > + return -ENXIO; > + > + /* > + * Sanity check all the GICC tables for the same interrupt number. > + * For now, we only support homogeneous ACPI machines. > + */ > + for_each_possible_cpu(cpu) { > + struct acpi_madt_generic_interrupt *gicc; > + u16 this_gsi; > + > + gicc = acpi_cpu_get_madt_gicc(cpu); > + if (gicc->header.length < len) > + return matched ? -ENXIO : 0; > + > + this_gsi = parse_gsi(gicc); > + if (!matched) { > + hetid = find_acpi_cpu_topology_hetero_id(cpu); > + gsi = this_gsi; > + matched = true; > + } else if (hetid != find_acpi_cpu_topology_hetero_id(cpu) || > + gsi != this_gsi) { > + pr_warn("ACPI: %s: must be homogeneous\n", pdev->name); > + return -ENXIO; > + } > + } > + > + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, > + ACPI_ACTIVE_HIGH); > + if (irq < 0) { > + pr_warn("ACPI: %s Unable to register interrupt: %d\n", > + pdev->name, gsi); > + return -ENXIO; > + } > + > + pdev->resource[0].start = irq; > + ret = platform_device_register(pdev); > + if (ret < 0) { > + pr_warn("ACPI: %s: Unable to register device\n", pdev->name); > + acpi_unregister_gsi(gsi); > + } > + > + return ret; > +} > + > #if IS_ENABLED(CONFIG_ARM_SPE_PMU) > static struct resource spe_resources[] = { > { > @@ -89,49 +145,18 @@ static struct platform_device spe_dev = { > * and create a SPE device if we detect a recent MADT with > * a homogeneous PPI mapping. > */ > +static u16 arm_spe_parse_gsi(struct acpi_madt_generic_interrupt *gicc) > +{ > + return gicc->spe_interrupt; > +} > + > static void arm_spe_acpi_register_device(void) > { > - int cpu, hetid, irq, ret; > - bool first = true; > - u16 gsi = 0; > + int err = arm_acpi_register_pmu_device(&spe_dev, ACPI_MADT_GICC_SPE, > + arm_spe_parse_gsi); > > - /* > - * Sanity check all the GICC tables for the same interrupt number. > - * For now, we only support homogeneous ACPI/SPE machines. > - */ > - for_each_possible_cpu(cpu) { > - struct acpi_madt_generic_interrupt *gicc; > - > - gicc = acpi_cpu_get_madt_gicc(cpu); > - if (gicc->header.length < ACPI_MADT_GICC_SPE) > - return; > - > - if (first) { > - gsi = gicc->spe_interrupt; > - if (!gsi) > - return; > - hetid = find_acpi_cpu_topology_hetero_id(cpu); > - first = false; > - } else if ((gsi != gicc->spe_interrupt) || > - (hetid != find_acpi_cpu_topology_hetero_id(cpu))) { > - pr_warn("ACPI: SPE must be homogeneous\n"); > - return; > - } > - } > - > - irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, > - ACPI_ACTIVE_HIGH); > - if (irq < 0) { > - pr_warn("ACPI: SPE Unable to register interrupt: %d\n", gsi); > - return; > - } > - > - spe_resources[0].start = irq; > - ret = platform_device_register(&spe_dev); > - if (ret < 0) { > - pr_warn("ACPI: SPE: Unable to register device\n"); > - acpi_unregister_gsi(gsi); > - } > + if (err) > + pr_warn("ACPI: Failed to register SPE device\n"); > } > #else > static inline void arm_spe_acpi_register_device(void) >
On Tue, Aug 01, 2023 at 09:05:54AM +0530, Anshuman Khandual wrote: > > > On 7/31/23 20:29, Will Deacon wrote: > > On Mon, Jul 31, 2023 at 05:38:38PM +0530, Anshuman Khandual wrote: > >> On 7/28/23 20:10, Will Deacon wrote: > >>> On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: > >>>> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c > >>>> index 90815ad762eb..dd3df6729808 100644 > >>>> --- a/drivers/perf/arm_pmu_acpi.c > >>>> +++ b/drivers/perf/arm_pmu_acpi.c > > > > [...] > > > >>>> + ret = platform_device_register(&trbe_acpi_dev); > >>>> + if (ret < 0) { > >>>> + pr_warn("ACPI: TRBE: Unable to register device\n"); > >>>> + acpi_unregister_gsi(gsi); > >>>> + } > >>>> +} > >>>> +#else > >>>> +static inline void arm_trbe_acpi_register_device(void) > >>>> +{ > >>>> + > >>>> +} > >>>> +#endif /* CONFIG_CORESIGHT_TRBE */ > >>> > >>> This looks like you ran s/spe/trbe/ over the SPE device registration > >>> code :) > >> > >> Yeah, almost :) > >> > >>> Please can you refactor things so we don't have all the duplication? I > >>> suspect this won't be the last device which needs the same treatement. > >> > >> Should the refactoring just accommodate SPE, and TRBE or make it more generic to > >> accommodate future devices as well. Something like the following enumeration. > >> > >> enum arm_platform_device { > >> ARM_PLATFORM_DEVICE_SPE, > >> ARM_PLATFORM_DEVICE_TRBE, > >> ARM_PLATFORM_DEVICE_MAX, > >> }; > >> > >> But that would require adding some helper functions to select these following > >> elements based on the above enumeration via a common function > >> > >> - gicc->XXX_interrupt > >> - ACPI_MADT_GICC_SPE/TRBE for header length comparison > >> - static struct platform_device/resources (static objects in the file) > >> > >> Seems like will add much more code for a refactor. Did you have something else > >> in mind for the refactor. > > > > All I'm saying is that we shouldn't have identical copies of the code to > > walk the MADT, pull out the irqs and register the device. > > > > So something like the totally untested hack below. I probably broke > > something, but hopefully you see what I mean. > > > > Will > > > > --->8 > > > > diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c > > index 90815ad762eb..7f1cf36c6e69 100644 > > --- a/drivers/perf/arm_pmu_acpi.c > > +++ b/drivers/perf/arm_pmu_acpi.c > > @@ -69,6 +69,62 @@ static void arm_pmu_acpi_unregister_irq(int cpu) > > acpi_unregister_gsi(gsi); > > } > > > > +static int > > +arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, > > + u16 (*parse_gsi)(struct acpi_madt_generic_interrupt *)) > > This factored out helper should be wrapped inside CONFIG_ARM_SPE_PMU > and CONFIG_CORESIGHT_TRBE ? Otherwise, there will be no callers left > for this helper triggering warning. > > drivers/perf/arm_pmu_acpi.c:73:1: warning: ‘arm_acpi_register_pmu_device’ defined but not used [-Wunused-function] > 73 | arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > But in that case, we have to keep adding new configs when new devices > require platform devices to be registered. Is there a better way ? __maybe_unused? Like I said, I didn't test that thing at all, I was just trying to illustrate the sort of refactoring I had in mind. Will
On 8/1/23 13:08, Will Deacon wrote: > On Tue, Aug 01, 2023 at 09:05:54AM +0530, Anshuman Khandual wrote: >> >> >> On 7/31/23 20:29, Will Deacon wrote: >>> On Mon, Jul 31, 2023 at 05:38:38PM +0530, Anshuman Khandual wrote: >>>> On 7/28/23 20:10, Will Deacon wrote: >>>>> On Fri, Jul 28, 2023 at 04:57:31PM +0530, Anshuman Khandual wrote: >>>>>> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c >>>>>> index 90815ad762eb..dd3df6729808 100644 >>>>>> --- a/drivers/perf/arm_pmu_acpi.c >>>>>> +++ b/drivers/perf/arm_pmu_acpi.c >>> >>> [...] >>> >>>>>> + ret = platform_device_register(&trbe_acpi_dev); >>>>>> + if (ret < 0) { >>>>>> + pr_warn("ACPI: TRBE: Unable to register device\n"); >>>>>> + acpi_unregister_gsi(gsi); >>>>>> + } >>>>>> +} >>>>>> +#else >>>>>> +static inline void arm_trbe_acpi_register_device(void) >>>>>> +{ >>>>>> + >>>>>> +} >>>>>> +#endif /* CONFIG_CORESIGHT_TRBE */ >>>>> >>>>> This looks like you ran s/spe/trbe/ over the SPE device registration >>>>> code :) >>>> >>>> Yeah, almost :) >>>> >>>>> Please can you refactor things so we don't have all the duplication? I >>>>> suspect this won't be the last device which needs the same treatement. >>>> >>>> Should the refactoring just accommodate SPE, and TRBE or make it more generic to >>>> accommodate future devices as well. Something like the following enumeration. >>>> >>>> enum arm_platform_device { >>>> ARM_PLATFORM_DEVICE_SPE, >>>> ARM_PLATFORM_DEVICE_TRBE, >>>> ARM_PLATFORM_DEVICE_MAX, >>>> }; >>>> >>>> But that would require adding some helper functions to select these following >>>> elements based on the above enumeration via a common function >>>> >>>> - gicc->XXX_interrupt >>>> - ACPI_MADT_GICC_SPE/TRBE for header length comparison >>>> - static struct platform_device/resources (static objects in the file) >>>> >>>> Seems like will add much more code for a refactor. Did you have something else >>>> in mind for the refactor. >>> >>> All I'm saying is that we shouldn't have identical copies of the code to >>> walk the MADT, pull out the irqs and register the device. >>> >>> So something like the totally untested hack below. I probably broke >>> something, but hopefully you see what I mean. >>> >>> Will >>> >>> --->8 >>> >>> diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c >>> index 90815ad762eb..7f1cf36c6e69 100644 >>> --- a/drivers/perf/arm_pmu_acpi.c >>> +++ b/drivers/perf/arm_pmu_acpi.c >>> @@ -69,6 +69,62 @@ static void arm_pmu_acpi_unregister_irq(int cpu) >>> acpi_unregister_gsi(gsi); >>> } >>> >>> +static int >>> +arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, >>> + u16 (*parse_gsi)(struct acpi_madt_generic_interrupt *)) >> >> This factored out helper should be wrapped inside CONFIG_ARM_SPE_PMU >> and CONFIG_CORESIGHT_TRBE ? Otherwise, there will be no callers left >> for this helper triggering warning. >> >> drivers/perf/arm_pmu_acpi.c:73:1: warning: ‘arm_acpi_register_pmu_device’ defined but not used [-Wunused-function] >> 73 | arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, >> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> >> But in that case, we have to keep adding new configs when new devices >> require platform devices to be registered. Is there a better way ? > > __maybe_unused? > > Like I said, I didn't test that thing at all, I was just trying to > illustrate the sort of refactoring I had in mind. Sure. If it's okay, will use your Co-developed-by/Signed-off-by tags for this refactoring patch.
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index bd68e1b7f29f..4d537d56eb84 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -42,6 +42,9 @@ #define ACPI_MADT_GICC_SPE (offsetof(struct acpi_madt_generic_interrupt, \ spe_interrupt) + sizeof(u16)) +#define ACPI_MADT_GICC_TRBE (offsetof(struct acpi_madt_generic_interrupt, \ + trbe_interrupt) + sizeof(u16)) + /* Basic configuration for ACPI */ #ifdef CONFIG_ACPI pgprot_t __acpi_get_mem_attribute(phys_addr_t addr); diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index 90815ad762eb..dd3df6729808 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -139,6 +139,68 @@ static inline void arm_spe_acpi_register_device(void) } #endif /* CONFIG_ARM_SPE_PMU */ +#ifdef CONFIG_CORESIGHT_TRBE +static struct resource trbe_acpi_resources[] = { + { + /* irq */ + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device trbe_acpi_dev = { + .name = ARMV8_TRBE_PDEV_NAME, + .id = -1, + .resource = trbe_acpi_resources, + .num_resources = ARRAY_SIZE(trbe_acpi_resources) +}; + +static void arm_trbe_acpi_register_device(void) +{ + int cpu, hetid, irq, ret; + bool first = true; + u16 gsi = 0; + + for_each_possible_cpu(cpu) { + struct acpi_madt_generic_interrupt *gicc; + + gicc = acpi_cpu_get_madt_gicc(cpu); + if (gicc->header.length < ACPI_MADT_GICC_TRBE) + return; + + if (first) { + gsi = gicc->trbe_interrupt; + if (!gsi) + return; + + hetid = find_acpi_cpu_topology_hetero_id(cpu); + first = false; + } else if ((gsi != gicc->trbe_interrupt) || + (hetid != find_acpi_cpu_topology_hetero_id(cpu))) { + pr_warn("ACPI: TRBE must be homogeneous\n"); + return; + } + } + + irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); + if (irq < 0) { + pr_warn("ACPI: TRBE Unable to register interrupt: %d\n", gsi); + return; + } + trbe_acpi_resources[0].start = irq; + + ret = platform_device_register(&trbe_acpi_dev); + if (ret < 0) { + pr_warn("ACPI: TRBE: Unable to register device\n"); + acpi_unregister_gsi(gsi); + } +} +#else +static inline void arm_trbe_acpi_register_device(void) +{ + +} +#endif /* CONFIG_CORESIGHT_TRBE */ + static int arm_pmu_acpi_parse_irqs(void) { int irq, cpu, irq_cpu, err; @@ -374,6 +436,7 @@ static int arm_pmu_acpi_init(void) return 0; arm_spe_acpi_register_device(); + arm_trbe_acpi_register_device(); return 0; } diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index a0801f68762b..7ec26d21303d 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -187,5 +187,6 @@ void armpmu_free_irq(int irq, int cpu); #endif /* CONFIG_ARM_PMU */ #define ARMV8_SPE_PDEV_NAME "arm,spe-v1" +#define ARMV8_TRBE_PDEV_NAME "arm-trbe-acpi" #endif /* __ARM_PMU_H__ */