diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index c574ba82b7adb4324a16dc6e756801fd5c1bf66f..b830008f1df2cf088bebbd48a66bf020a478d4cb 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -7336,7 +7336,6 @@ CONFIG_ETM4X_IMPDEF_FEATURE=y # CONFIG_CORESIGHT_CTI is not set CONFIG_CORESIGHT_TRBE=m CONFIG_ULTRASOC_SMB=m -CONFIG_ACPI_TRBE=y # end of arm64 Debugging # diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 05f0ed3ad1d86b839f22838be9a0347d41b2087f..312c164db2ed2393ccc5db551f8af0da0713c563 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o obj-$(CONFIG_ACPI) += acpi.o obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o -obj-$(CONFIG_ACPI_TRBE) += acpi_trbe.o obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_SPINLOCKS) += paravirt.o paravirt-spinlocks.o diff --git a/arch/arm64/kernel/acpi_trbe.c b/arch/arm64/kernel/acpi_trbe.c deleted file mode 100644 index 5d983ea8c8124f824e39b95cd9bf6cdc8a84b41d..0000000000000000000000000000000000000000 --- a/arch/arm64/kernel/acpi_trbe.c +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ACPI probing code for ARM Trace Buffer Extension. - * - * Copyright (C) 2022 ARM Ltd. - */ - -#include -#include -#include -#include - -static struct resource trbe_resources[] = { - { - /* irq */ - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device trbe_dev = { - .name = ARMV9_TRBE_PDEV_NAME, - .id = -1, - .resource = trbe_resources, - .num_resources = ARRAY_SIZE(trbe_resources) -}; - -static void arm_trbe_acpi_register_device(void) -{ - int cpu, hetid, irq, ret; - bool first = true; - u16 gsi = 0; - - /* - * Sanity check all the GICC tables for the same interrupt number. - * For now, we only support homogeneous 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_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_resources[0].start = irq; - ret = platform_device_register(&trbe_dev); - if (ret < 0) { - pr_warn("ACPI: TRBE: Unable to register device\n"); - acpi_unregister_gsi(gsi); - } -} - -static int arm_acpi_trbe_init(void) -{ - if (acpi_disabled) - return 0; - - arm_trbe_acpi_register_device(); - - return 0; -} -device_initcall(arm_acpi_trbe_init) diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index 70f289112a0ba71d8250a845be27e17f0435fbca..5d178ed935efd01fd3c99ed065ac652688a7eac8 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -201,7 +201,3 @@ config ULTRASOC_SMB called ultrasoc-smb. endif - -config ACPI_TRBE - depends on ARM64 && ACPI - def_bool y diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c index 79a6acb951fe298d8ecdebd915a21b3ca79f8fe2..e15592cdd20f8dab00ba615bc412ba23eef347f4 100644 --- a/drivers/hwtracing/coresight/coresight-platform.c +++ b/drivers/hwtracing/coresight/coresight-platform.c @@ -862,15 +862,15 @@ coresight_get_platform_data(struct device *dev) struct coresight_platform_data *pdata = NULL; struct fwnode_handle *fwnode = dev_fwnode(dev); + if (IS_ERR_OR_NULL(fwnode)) + goto error; + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { ret = -ENOMEM; goto error; } - if (IS_ERR_OR_NULL(fwnode)) - return pdata; - if (is_of_node(fwnode)) ret = of_get_coresight_platform_data(dev, pdata); else if (is_acpi_device_node(fwnode)) diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index b36291ce906346176c5813e6da4743dcad249dd4..6ee876db40812221a56195ab9f6388b3cac18f49 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -947,8 +947,18 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu); if (!desc.name) goto cpu_clear; - - desc.pdata = coresight_get_platform_data(dev); + /* + * TRBE coresight devices do not need regular connections + * information, as the paths get built between all percpu + * source and their respective percpu sink devices. Though + * coresight_register() expect device connections via the + * platform_data, which TRBE devices do not have. As they + * are not real ACPI devices, coresight_get_platform_data() + * ends up failing. Instead let's allocate a dummy zeroed + * coresight_platform_data structure and assign that back + * into the device for that purpose. + */ + desc.pdata = devm_kzalloc(dev, sizeof(*desc.pdata), GFP_KERNEL); if (IS_ERR(desc.pdata)) goto cpu_clear; @@ -1188,14 +1198,16 @@ static const struct of_device_id arm_trbe_of_match[] = { }; MODULE_DEVICE_TABLE(of, arm_trbe_of_match); -static const struct platform_device_id arm_trbe_match[] = { - { ARMV9_TRBE_PDEV_NAME, 0}, - {} +#ifdef CONFIG_ACPI +static const struct platform_device_id arm_trbe_acpi_match[] = { + { ARMV8_TRBE_PDEV_NAME, 0 }, + { } }; -MODULE_DEVICE_TABLE(platform, arm_trbe_match); +MODULE_DEVICE_TABLE(platform, arm_trbe_acpi_match); +#endif static struct platform_driver arm_trbe_driver = { - .id_table = arm_trbe_match, + .id_table = ACPI_PTR(arm_trbe_acpi_match), .driver = { .name = DRVNAME, .of_match_table = of_match_ptr(arm_trbe_of_match), diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h index abf3e36082f0d2355311435d783986b638525977..aebe1b505b81a3cc1ce5b8543d804117a918c6d9 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.h +++ b/drivers/hwtracing/coresight/coresight-trbe.h @@ -7,11 +7,13 @@ * * Author: Anshuman Khandual */ +#include #include #include #include #include #include +#include #include #include diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index f5c7a845cd7bf24d9aec4778d2e155d630df1b6f..0d284fda87aca86263ee382ae903547b4320e837 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -68,6 +68,62 @@ static void arm_pmu_acpi_unregister_irq(int cpu) acpi_unregister_gsi(gsi); } +static int __maybe_unused +arm_acpi_register_pmu_device(struct platform_device *pdev, u8 len, + u16 (*parse_gsi)(struct acpi_madt_generic_interrupt *)) +{ + int cpu, this_hetid, hetid, irq, ret; + u16 this_gsi = 0, gsi = 0; + + /* + * Ensure that platform device must have IORESOURCE_IRQ + * resource to hold gsi interrupt. + */ + 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, only support homogeneous ACPI machines. + */ + for_each_possible_cpu(cpu) { + struct acpi_madt_generic_interrupt *gicc; + + gicc = acpi_cpu_get_madt_gicc(cpu); + if (gicc->header.length < len) + return gsi ? -ENXIO : 0; + + this_gsi = parse_gsi(gicc); + this_hetid = find_acpi_cpu_topology_hetero_id(cpu); + if (!gsi) { + hetid = this_hetid; + gsi = this_gsi; + } else if (hetid != this_hetid || gsi != this_gsi) { + pr_warn("ACPI: %s: must be homogeneous\n", pdev->name); + return -ENXIO; + } + } + + if (!this_gsi) + return 0; + + 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) + acpi_unregister_gsi(gsi); + + return ret; +} + #if IS_ENABLED(CONFIG_ARM_SPE_PMU) static struct resource spe_resources[] = { { @@ -83,6 +139,11 @@ static struct platform_device spe_dev = { .num_resources = ARRAY_SIZE(spe_resources) }; +static u16 arm_spe_parse_gsi(struct acpi_madt_generic_interrupt *gicc) +{ + return gicc->spe_interrupt; +} + /* * For lack of a better place, hook the normal PMU MADT walk * and create a SPE device if we detect a recent MADT with @@ -90,53 +151,50 @@ static struct platform_device spe_dev = { */ static void arm_spe_acpi_register_device(void) { - int cpu, hetid, irq, ret; - bool first = true; - u16 gsi = 0; - - /* - * 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; + int ret = arm_acpi_register_pmu_device(&spe_dev, ACPI_MADT_GICC_SPE, + arm_spe_parse_gsi); + if (ret) + pr_warn("ACPI: SPE: Unable to register device\n"); +} +#else +static inline void arm_spe_acpi_register_device(void) +{ +} +#endif /* CONFIG_ARM_SPE_PMU */ - 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; - } +#if IS_ENABLED(CONFIG_CORESIGHT_TRBE) +static struct resource trbe_resources[] = { + { + /* irq */ + .flags = IORESOURCE_IRQ, } +}; - 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; - } +static struct platform_device trbe_dev = { + .name = ARMV8_TRBE_PDEV_NAME, + .id = -1, + .resource = trbe_resources, + .num_resources = ARRAY_SIZE(trbe_resources) +}; - 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); - } +static u16 arm_trbe_parse_gsi(struct acpi_madt_generic_interrupt *gicc) +{ + return gicc->trbe_interrupt; +} + +static void arm_trbe_acpi_register_device(void) +{ + int ret = arm_acpi_register_pmu_device(&trbe_dev, ACPI_MADT_GICC_TRBE, + arm_trbe_parse_gsi); + if (ret) + pr_warn("ACPI: TRBE: Unable to register device\n"); } #else -static inline void arm_spe_acpi_register_device(void) +static inline void arm_trbe_acpi_register_device(void) { + } -#endif /* CONFIG_ARM_SPE_PMU */ +#endif /* CONFIG_CORESIGHT_TRBE */ static int arm_pmu_acpi_parse_irqs(void) { @@ -344,6 +402,7 @@ static int arm_pmu_acpi_init(void) return 0; arm_spe_acpi_register_device(); + arm_trbe_acpi_register_device(); ret = arm_pmu_acpi_parse_irqs(); if (ret) diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 960452544304f04404b0f650678c4588eea84480..8970d6428d31fafaa590b0d4c6abc24f96ddd5dc 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -35,8 +35,6 @@ #define CORESIGHT_UNLOCK 0xc5acce55 -#define ARMV9_TRBE_PDEV_NAME "arm,trbe-v1" - extern struct bus_type coresight_bustype; enum coresight_dev_type { diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 505480217cf1a9b4f779b454d42bc78c464e189b..76042208eb0b54e482d139b2ad9e164a2bfc395f 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -176,5 +176,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" #endif /* __ARM_PMU_H__ */