From 56c408f10d674eba68fce755af895611b4ef8f62 Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 27 Oct 2021 16:15:04 +0100 Subject: [PATCH 01/25] irqchip/gic-v3-its: Give the percpu rdist struct its own flags field Later patches will require tracking some per-rdist status. Reuse the bytes "lost" to padding within the __percpu rdist struct as a flags field, and re-encode ->lpi_enabled within said flags. No change in functionality intended. Signed-off-by: Valentin Schneider Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211027151506.2085066-2-valentin.schneider@arm.com --- drivers/irqchip/irq-gic-v3-its.c | 8 +++++--- include/linux/irqchip/arm-gic-v3.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 584cbcceca..5a024f35cb 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -46,6 +46,8 @@ #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) +#define RD_LOCAL_LPI_ENABLED BIT(0) + static u32 lpi_id_bits; /* @@ -3064,7 +3066,7 @@ static void its_cpu_init_lpis(void) phys_addr_t paddr; u64 val, tmp; - if (gic_data_rdist()->lpi_enabled) + if (gic_data_rdist()->flags & RD_LOCAL_LPI_ENABLED) return; val = readl_relaxed(rbase + GICR_CTLR); @@ -3178,7 +3180,7 @@ static void its_cpu_init_lpis(void) /* Make sure the GIC has seen the above */ dsb(sy); out: - gic_data_rdist()->lpi_enabled = true; + gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED; pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", smp_processor_id(), gic_data_rdist()->pend_page ? "allocated" : "reserved", @@ -5154,7 +5156,7 @@ static int redist_disable_lpis(void) * * If running with preallocated tables, there is nothing to do. */ - if (gic_data_rdist()->lpi_enabled || + if ((gic_data_rdist()->flags & RD_LOCAL_LPI_ENABLED) || (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED)) return 0; diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index f6d092fdb9..e515c85310 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -671,7 +671,7 @@ struct rdists { void __iomem *rd_base; struct page *pend_page; phys_addr_t phys_base; - bool lpi_enabled; + u64 flags; cpumask_t *vpe_table_mask; void *vpe_l1_base; } __percpu *rdist; -- Gitee From 055eaacca08220d341efb286680d78d8e2c64053 Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 27 Oct 2021 16:15:05 +0100 Subject: [PATCH 02/25] irqchip/gic-v3-its: Postpone LPI pending table freeing and memreserve Memory used by the LPI tables have to be made persistent for kexec to have a chance to work, as explained in [1]. If they have been made persistent and we are booting into a kexec'd kernel, we also need to free the pages that were preemptively allocated by the new kernel for those tables. Both of those operations currently happen during its_cpu_init(), which happens in a _STARTING (IOW atomic) cpuhp callback for secondary CPUs. efi_mem_reserve_iomem() issues a GFP_ATOMIC allocation, which unfortunately doesn't work under PREEMPT_RT (this ends up grabbing a non-raw spinlock, which can sleep under PREEMPT_RT). Similarly, freeing the pages ends up grabbing a sleepable spinlock. Since the memreserve is only required by kexec, it doesn't have to be done so early in the secondary boot process. Issue the reservation in a new CPUHP_AP_ONLINE_DYN cpuhp callback, and piggy-back the page freeing on top of it. A CPU gets to run the body of this new callback exactly once. As kexec issues a machine_shutdown() prior to machine_kexec(), it will be serialized vs a CPU being plugged to life by the hotplug machinery - either the CPU will have been brought up and have had its redistributor's pending table memreserved, or it never went online and will have its table allocated by the new kernel. [1]: https://lore.kernel.org/lkml/20180921195954.21574-1-marc.zyngier@arm.com/ Signed-off-by: Valentin Schneider Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211027151506.2085066-3-valentin.schneider@arm.com --- drivers/irqchip/irq-gic-v3-its.c | 58 +++++++++++++++++++++++++++--- drivers/irqchip/irq-gic-v3.c | 1 + include/linux/irqchip/arm-gic-v3.h | 1 + 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 5a024f35cb..df8bdfeaf2 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -47,6 +47,8 @@ #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) #define RD_LOCAL_LPI_ENABLED BIT(0) +#define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) +#define RD_LOCAL_MEMRESERVE_DONE BIT(2) static u32 lpi_id_bits; @@ -3085,15 +3087,13 @@ static void its_cpu_init_lpis(void) paddr &= GENMASK_ULL(51, 16); WARN_ON(!gic_check_reserved_range(paddr, LPI_PENDBASE_SZ)); - its_free_pending_table(gic_data_rdist()->pend_page); - gic_data_rdist()->pend_page = NULL; + gic_data_rdist()->flags |= RD_LOCAL_PENDTABLE_PREALLOCATED; goto out; } pend_page = gic_data_rdist()->pend_page; paddr = page_to_phys(pend_page); - WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ)); /* set PROPBASE */ val = (gic_rdists->prop_table_pa | @@ -3183,7 +3183,8 @@ static void its_cpu_init_lpis(void) gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED; pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", smp_processor_id(), - gic_data_rdist()->pend_page ? "allocated" : "reserved", + gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ? + "reserved" : "allocated", &paddr); } @@ -5218,6 +5219,38 @@ int its_cpu_init(void) return 0; } +static int its_cpu_memreserve_lpi(unsigned int cpu) +{ + struct page *pend_page; + int ret = 0; + + /* This gets to run exactly once per CPU */ + if (gic_data_rdist()->flags & RD_LOCAL_MEMRESERVE_DONE) + return 0; + + pend_page = gic_data_rdist()->pend_page; + if (WARN_ON(!pend_page)) { + ret = -ENOMEM; + goto out; + } + /* + * If the pending table was pre-programmed, free the memory we + * preemptively allocated. Otherwise, reserve that memory for + * later kexecs. + */ + if (gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED) { + its_free_pending_table(pend_page); + gic_data_rdist()->pend_page = NULL; + } else { + phys_addr_t paddr = page_to_phys(pend_page); + WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ)); + } + +out: + gic_data_rdist()->flags |= RD_LOCAL_MEMRESERVE_DONE; + return ret; +} + static const struct of_device_id its_device_id[] = { { .compatible = "arm,gic-v3-its", }, {}, @@ -5403,6 +5436,23 @@ static void __init its_acpi_probe(void) static void __init its_acpi_probe(void) { } #endif +int __init its_lpi_memreserve_init(void) +{ + int state; + + if (!efi_enabled(EFI_CONFIG_TABLES)) + return 0; + + state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "irqchip/arm/gicv3/memreserve:online", + its_cpu_memreserve_lpi, + NULL); + if (state < 0) + return state; + + return 0; +} + int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, struct irq_domain *parent_domain) { diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c1f8c1be84..ae4b1dc271 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1811,6 +1811,7 @@ static int __init gic_init_bases(void __iomem *dist_base, if (gic_dist_supports_lpis()) { its_init(handle, &gic_data.rdists, gic_data.domain); its_cpu_init(); + its_lpi_memreserve_init(); } else { if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) gicv2m_init(handle, gic_data.domain); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index e515c85310..3b34132a11 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -688,6 +688,7 @@ struct rdists { struct irq_domain; struct fwnode_handle; +int __init its_lpi_memreserve_init(void); int its_cpu_init(void); int its_init(struct fwnode_handle *handle, struct rdists *rdists, struct irq_domain *domain); -- Gitee From 3c1cd201a41b41b84a7ff611038c682cfdcbfa87 Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 27 Oct 2021 16:15:06 +0100 Subject: [PATCH 03/25] irqchip/gic-v3-its: Limit memreserve cpuhp state lifetime The new memreserve cpuhp callback only needs to survive up until a point where every CPU in the system has booted once. Beyond that, it becomes a no-op and can be put in the bin. Signed-off-by: Valentin Schneider Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20211027151506.2085066-4-valentin.schneider@arm.com --- drivers/irqchip/irq-gic-v3-its.c | 16 ++++++++++++++++ include/linux/irqchip/arm-gic-v3.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index df8bdfeaf2..9723827312 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -5219,6 +5219,15 @@ int its_cpu_init(void) return 0; } +static void rdist_memreserve_cpuhp_cleanup_workfn(struct work_struct *work) +{ + cpuhp_remove_state_nocalls(gic_rdists->cpuhp_memreserve_state); + gic_rdists->cpuhp_memreserve_state = CPUHP_INVALID; +} + +static DECLARE_WORK(rdist_memreserve_cpuhp_cleanup_work, + rdist_memreserve_cpuhp_cleanup_workfn); + static int its_cpu_memreserve_lpi(unsigned int cpu) { struct page *pend_page; @@ -5247,6 +5256,10 @@ static int its_cpu_memreserve_lpi(unsigned int cpu) } out: + /* Last CPU being brought up gets to issue the cleanup */ + if (cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask)) + schedule_work(&rdist_memreserve_cpuhp_cleanup_work); + gic_data_rdist()->flags |= RD_LOCAL_MEMRESERVE_DONE; return ret; } @@ -5443,6 +5456,7 @@ int __init its_lpi_memreserve_init(void) if (!efi_enabled(EFI_CONFIG_TABLES)) return 0; + gic_rdists->cpuhp_memreserve_state = CPUHP_INVALID; state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "irqchip/arm/gicv3/memreserve:online", its_cpu_memreserve_lpi, @@ -5450,6 +5464,8 @@ int __init its_lpi_memreserve_init(void) if (state < 0) return state; + gic_rdists->cpuhp_memreserve_state = state; + return 0; } diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 3b34132a11..28c9859c2f 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -680,6 +680,7 @@ struct rdists { u64 flags; u32 gicd_typer; u32 gicd_typer2; + int cpuhp_memreserve_state; bool has_vlpis; bool has_rvpeid; bool has_direct_lpi; -- Gitee From 20b8e537fdc3796de9b7e232b593510ac31872cd Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 30 Sep 2022 12:18:42 +0100 Subject: [PATCH 04/25] arm_pmu: acpi: factor out PMU<->CPU association A subsequent patch will rework the ACPI probing of PMUs, and we'll need to associate a CPU with a PMU in two separate paths. Factor out the association logic into a helper function so that it can be reused. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Cc: Pierre Gondois Cc: Will Deacon Reviewed-and-tested-by: Pierre Gondois Link: https://lore.kernel.org/r/20220930111844.1522365-2-mark.rutland@arm.com Signed-off-by: Will Deacon --- drivers/perf/arm_pmu_acpi.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index f5c7a845cd..50b29b8a14 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -240,6 +240,22 @@ static bool pmu_irq_matches(struct arm_pmu *pmu, int irq) return true; } +static void arm_pmu_acpi_associate_pmu_cpu(struct arm_pmu *pmu, + unsigned int cpu) +{ + int irq = per_cpu(pmu_irqs, cpu); + + per_cpu(probed_pmus, cpu) = pmu; + + if (pmu_irq_matches(pmu, irq)) { + struct pmu_hw_events __percpu *hw_events; + hw_events = pmu->hw_events; + per_cpu(hw_events->irq, cpu) = irq; + } + + cpumask_set_cpu(cpu, &pmu->supported_cpus); +} + /* * This must run before the common arm_pmu hotplug logic, so that we can * associate a CPU and its interrupt before the common code tries to manage the @@ -252,27 +268,16 @@ static bool pmu_irq_matches(struct arm_pmu *pmu, int irq) static int arm_pmu_acpi_cpu_starting(unsigned int cpu) { struct arm_pmu *pmu; - struct pmu_hw_events __percpu *hw_events; - int irq; /* If we've already probed this CPU, we have nothing to do */ if (per_cpu(probed_pmus, cpu)) return 0; - irq = per_cpu(pmu_irqs, cpu); - pmu = arm_pmu_acpi_find_alloc_pmu(); if (!pmu) return -ENOMEM; - per_cpu(probed_pmus, cpu) = pmu; - - if (pmu_irq_matches(pmu, irq)) { - hw_events = pmu->hw_events; - per_cpu(hw_events->irq, cpu) = irq; - } - - cpumask_set_cpu(cpu, &pmu->supported_cpus); + arm_pmu_acpi_associate_pmu_cpu(pmu, cpu); /* * Ideally, we'd probe the PMU here when we find the first matching -- Gitee From 3fbe00933dcbf1294a5098654c098a53b6e1dcee Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 30 Sep 2022 12:18:43 +0100 Subject: [PATCH 05/25] arm_pmu: factor out PMU matching A subsequent patch will rework the ACPI probing of PMUs, and we'll need to match a CPU with a known cpuid in two separate paths. Factor out the matching logic into a helper function so that it can be reused. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Cc: Pierre Gondois Cc: Will Deacon Reviewed-and-tested-by: Pierre Gondois Link: https://lore.kernel.org/r/20220930111844.1522365-3-mark.rutland@arm.com Signed-off-by: Will Deacon --- drivers/perf/arm_pmu_acpi.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index 50b29b8a14..b90f4604b4 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -185,7 +185,7 @@ static int arm_pmu_acpi_parse_irqs(void) return err; } -static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) +static struct arm_pmu *arm_pmu_acpi_find_pmu(void) { unsigned long cpuid = read_cpuid_id(); struct arm_pmu *pmu; @@ -199,6 +199,17 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) return pmu; } + return NULL; +} + +static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) +{ + struct arm_pmu *pmu; + + pmu = arm_pmu_acpi_find_pmu(); + if (pmu) + return pmu; + pmu = armpmu_alloc_atomic(); if (!pmu) { pr_warn("Unable to allocate PMU for CPU%d\n", @@ -206,7 +217,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) return NULL; } - pmu->acpi_cpuid = cpuid; + pmu->acpi_cpuid = read_cpuid_id(); return pmu; } -- Gitee From ff9cc3fd3a4eed90c657ad51e06195bbc1ada2c8 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Fri, 30 Sep 2022 12:18:44 +0100 Subject: [PATCH 06/25] arm_pmu: rework ACPI probing The current ACPI PMU probing logic tries to associate PMUs with CPUs when the CPU is first brought online, in order to handle late hotplug, though PMUs are only registered during early boot, and so for late hotplugged CPUs this can only associate the CPU with an existing PMU. We tried to be clever and the have the arm_pmu_acpi_cpu_starting() callback allocate a struct arm_pmu when no matching instance is found, in order to avoid duplication of logic. However, as above this doesn't do anything useful for late hotplugged CPUs, and this requires us to allocate memory in an atomic context, which is especially problematic for PREEMPT_RT, as reported by Valentin and Pierre. This patch reworks the probing to detect PMUs for all online CPUs in the arm_pmu_acpi_probe() function, which is more aligned with how DT probing works. The arm_pmu_acpi_cpu_starting() callback only tries to associate CPUs with an existing arm_pmu instance, avoiding the problem of allocating in atomic context. Note that as we didn't previously register PMUs for late-hotplugged CPUs, this change doesn't result in a loss of existing functionality, though we will now warn when we cannot associate a CPU with a PMU. This change allows us to pull the hotplug callback registration into the arm_pmu_acpi_probe() function, as we no longer need the callbacks to be invoked shortly after probing the boot CPUs, and can register it without invoking the calls. For the moment the arm_pmu_acpi_init() initcall remains to register the SPE PMU, though in future this should probably be moved elsewhere (e.g. the arm64 ACPI init code), since this doesn't need to be tied to the regular CPU PMU code. Signed-off-by: Mark Rutland Reported-by: Valentin Schneider Link: https://lore.kernel.org/r/20210810134127.1394269-2-valentin.schneider@arm.com/ Reported-by: Pierre Gondois Link: https://lore.kernel.org/linux-arm-kernel/20220912155105.1443303-1-pierre.gondois@arm.com/ Cc: Pierre Gondois Cc: Valentin Schneider Cc: Will Deacon Reviewed-and-tested-by: Pierre Gondois Link: https://lore.kernel.org/r/20220930111844.1522365-4-mark.rutland@arm.com Signed-off-by: Will Deacon --- drivers/perf/arm_pmu.c | 21 ++------ drivers/perf/arm_pmu_acpi.c | 95 +++++++++++++++++++----------------- include/linux/perf/arm_pmu.h | 1 - 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 7fd11ef5cb..37ca31bfa7 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -888,18 +888,16 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) &cpu_pmu->node); } -static struct arm_pmu *__armpmu_alloc(gfp_t flags) +struct arm_pmu *armpmu_alloc(void) { struct arm_pmu *pmu; int cpu; - pmu = kzalloc(sizeof(*pmu), flags); - if (!pmu) { - pr_info("failed to allocate PMU device!\n"); + pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + if (!pmu) goto out; - } - pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags); + pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, GFP_KERNEL); if (!pmu->hw_events) { pr_info("failed to allocate per-cpu PMU data.\n"); goto out_free_pmu; @@ -945,17 +943,6 @@ static struct arm_pmu *__armpmu_alloc(gfp_t flags) return NULL; } -struct arm_pmu *armpmu_alloc(void) -{ - return __armpmu_alloc(GFP_KERNEL); -} - -struct arm_pmu *armpmu_alloc_atomic(void) -{ - return __armpmu_alloc(GFP_ATOMIC); -} - - void armpmu_free(struct arm_pmu *pmu) { free_percpu(pmu->hw_events); diff --git a/drivers/perf/arm_pmu_acpi.c b/drivers/perf/arm_pmu_acpi.c index b90f4604b4..7353eb5e3e 100644 --- a/drivers/perf/arm_pmu_acpi.c +++ b/drivers/perf/arm_pmu_acpi.c @@ -13,6 +13,7 @@ #include #include +#include #include static DEFINE_PER_CPU(struct arm_pmu *, probed_pmus); @@ -202,26 +203,6 @@ static struct arm_pmu *arm_pmu_acpi_find_pmu(void) return NULL; } -static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void) -{ - struct arm_pmu *pmu; - - pmu = arm_pmu_acpi_find_pmu(); - if (pmu) - return pmu; - - pmu = armpmu_alloc_atomic(); - if (!pmu) { - pr_warn("Unable to allocate PMU for CPU%d\n", - smp_processor_id()); - return NULL; - } - - pmu->acpi_cpuid = read_cpuid_id(); - - return pmu; -} - /* * Check whether the new IRQ is compatible with those already associated with * the PMU (e.g. we don't have mismatched PPIs). @@ -284,26 +265,45 @@ static int arm_pmu_acpi_cpu_starting(unsigned int cpu) if (per_cpu(probed_pmus, cpu)) return 0; - pmu = arm_pmu_acpi_find_alloc_pmu(); - if (!pmu) - return -ENOMEM; + pmu = arm_pmu_acpi_find_pmu(); + if (!pmu) { + pr_warn_ratelimited("Unable to associate CPU%d with a PMU\n", + cpu); + return 0; + } arm_pmu_acpi_associate_pmu_cpu(pmu, cpu); - - /* - * Ideally, we'd probe the PMU here when we find the first matching - * CPU. We can't do that for several reasons; see the comment in - * arm_pmu_acpi_init(). - * - * So for the time being, we're done. - */ return 0; } +static void arm_pmu_acpi_probe_matching_cpus(struct arm_pmu *pmu, + unsigned long cpuid) +{ + int cpu; + + for_each_online_cpu(cpu) { + unsigned long cpu_cpuid = per_cpu(cpu_data, cpu).reg_midr; + + if (cpu_cpuid == cpuid) + arm_pmu_acpi_associate_pmu_cpu(pmu, cpu); + } +} + int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { int pmu_idx = 0; - int cpu, ret; + unsigned int cpu; + int ret; + + ret = arm_pmu_acpi_parse_irqs(); + if (ret) + return ret; + + ret = cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_ACPI_STARTING, + "perf/arm/pmu_acpi:starting", + arm_pmu_acpi_cpu_starting, NULL); + if (ret) + return ret; /* * Initialise and register the set of PMUs which we know about right @@ -318,13 +318,26 @@ int arm_pmu_acpi_probe(armpmu_init_fn init_fn) * For the moment, as with the platform/DT case, we need at least one * of a PMU's CPUs to be online at probe time. */ - for_each_possible_cpu(cpu) { + for_each_online_cpu(cpu) { struct arm_pmu *pmu = per_cpu(probed_pmus, cpu); + unsigned long cpuid; char *base_name; - if (!pmu || pmu->name) + /* If we've already probed this CPU, we have nothing to do */ + if (pmu) continue; + pmu = armpmu_alloc(); + if (!pmu) { + pr_warn("Unable to allocate PMU for CPU%d\n", + cpu); + } + + cpuid = per_cpu(cpu_data, cpu).reg_midr; + pmu->acpi_cpuid = cpuid; + + arm_pmu_acpi_probe_matching_cpus(pmu, cpuid); + ret = init_fn(pmu); if (ret == -ENODEV) { /* PMU not handled by this driver, or not present */ @@ -349,26 +362,16 @@ int arm_pmu_acpi_probe(armpmu_init_fn init_fn) } } - return 0; + return ret; } static int arm_pmu_acpi_init(void) { - int ret; - if (acpi_disabled) return 0; arm_spe_acpi_register_device(); - ret = arm_pmu_acpi_parse_irqs(); - if (ret) - return ret; - - ret = cpuhp_setup_state(CPUHP_AP_PERF_ARM_ACPI_STARTING, - "perf/arm/pmu_acpi:starting", - arm_pmu_acpi_cpu_starting, NULL); - - return ret; + return 0; } subsys_initcall(arm_pmu_acpi_init) diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 505480217c..07452114fa 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -165,7 +165,6 @@ static inline int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { return 0; } /* Internal functions only for core arm_pmu code */ struct arm_pmu *armpmu_alloc(void); -struct arm_pmu *armpmu_alloc_atomic(void); void armpmu_free(struct arm_pmu *pmu); int armpmu_register(struct arm_pmu *pmu); int armpmu_request_irq(int irq, int cpu); -- Gitee From 1011c2a3b5a698a1cdb8bc3e4d0cb46bd81d05ff Mon Sep 17 00:00:00 2001 From: zuoqian Date: Thu, 26 Jun 2025 14:43:04 +0800 Subject: [PATCH 07/25] net: phytmac: fix page refcounting for XDP_REDIRECT The current page counting scheme assumes that the reference count cannot decrease until the received frame is sent to the upper layers of the networking stack. This assumption does not hold for the XDP_REDIRECT action, particularly with BPF_MAP_TYPE_XSKMAP handling, since a page (pointed out by xdp_buff) can have its reference count decreased via the xdp_do_redirect call. To work around that, now start off by a large page count and then don't allow a refcount less than two. Signed-off-by: zuoqian --- drivers/net/ethernet/phytium/phytmac_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/phytium/phytmac_main.c b/drivers/net/ethernet/phytium/phytmac_main.c index f97abb027a..ff377d954e 100644 --- a/drivers/net/ethernet/phytium/phytmac_main.c +++ b/drivers/net/ethernet/phytium/phytmac_main.c @@ -712,7 +712,8 @@ static bool phytmac_alloc_mapped_page(struct phytmac *pdata, bi->addr = dma; bi->page = page; bi->page_offset = PHYTMAC_SKB_PAD; - bi->pagecnt_bias = 1; + page_ref_add(page, USHRT_MAX - 1); + bi->pagecnt_bias = USHRT_MAX; return true; } @@ -747,8 +748,8 @@ static bool phytmac_can_reuse_rx_page(struct phytmac_rx_buffer *rx_buffer) * the pagecnt_bias and page count so that we fully restock the * number of references the driver holds. */ - if (unlikely(!pagecnt_bias)) { - page_ref_add(page, USHRT_MAX); + if (unlikely(pagecnt_bias == 1)) { + page_ref_add(page, USHRT_MAX - 1); rx_buffer->pagecnt_bias = USHRT_MAX; } -- Gitee From c0a51d454c608281c7dd06a23fb83b2eae09bd2b Mon Sep 17 00:00:00 2001 From: zuoqian Date: Mon, 7 Jul 2025 15:00:17 +0800 Subject: [PATCH 08/25] arm64: phytium_defconfig: open gpio sysfs support Signed-off-by: zuoqian --- arch/arm64/configs/phytium_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 1c13e80f9f..9d0dbb737e 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -397,6 +397,7 @@ CONFIG_SPMI=y CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MAX77620=y +CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ALTERA=m CONFIG_GPIO_DWAPB=y CONFIG_GPIO_MB86S7X=y -- Gitee From 2e5c77bc637352281a7ef486517dde074f381073 Mon Sep 17 00:00:00 2001 From: Chen Baozi Date: Fri, 14 Jul 2023 08:33:59 +0800 Subject: [PATCH 09/25] arm64: kpti: Add Phytium FTC3xx/6xx CPU cores to kpti safelist Since Phytium FTC3xx/6xx CPU cores are all meltdown safe, add them to kpti_safe_list[]. Signed-off-by: Chen Baozi Change-Id: I8db79ef0b2513c8dfd9c5f7cbf03ceabb829da16 Signed-off-by: liutianyu1250 --- arch/arm64/kernel/cpufeature.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index fccfeddbbc..2cb7bd9ef3 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1354,6 +1354,12 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC660), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC661), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_PS17064), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC663), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC664), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_GOLD), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), -- Gitee From 6bbf7d3b9a499b22651e5d70c4a04aab22919ec0 Mon Sep 17 00:00:00 2001 From: Chen Baozi Date: Fri, 14 Jul 2023 08:33:59 +0800 Subject: [PATCH 10/25] arm64: proton-pack: Add Phytium FTC310 CPU core to spectre-v2/v4 safelist FTC310 (LITTLE) CPUs are spectre-v2 and spectre-v4 safe, hence add them to the safe list. Signed-off-by: Chen Baozi Change-Id: I21b27be8d02d56f03792a0c7656b7d29437e3776 Signed-off-by: liutianyu1250 --- arch/arm64/kernel/proton-pack.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index 9c0e9d9eed..e5536f7cad 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -159,6 +159,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void) MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), @@ -486,6 +487,7 @@ static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void) MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), { /* sentinel */ }, -- Gitee From 2551e37ce5555c97fb68d51b7a3a3566f6f8d8f5 Mon Sep 17 00:00:00 2001 From: Wang Yinfeng Date: Wed, 8 May 2024 14:25:03 +0800 Subject: [PATCH 11/25] arm/arm64: Bugfix the CPU MPIDR definition of phytium FTC303 core This patch Fixed MPIDR definition to 0x303 in phytium FTC303 series core. Mainline: Open-Source Signed-off-by: Wang Yinfeng Signed-off-by: Li Mingzhe Change-Id: I013783e6774661a67726a11ea09b0413b921017e Signed-off-by: liutianyu1250 --- arch/arm64/include/asm/cputype.h | 4 ++-- arch/arm64/kernel/cpufeature.c | 2 +- arch/arm64/kernel/proton-pack.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index ef6ce5ef19..75040f267c 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -117,7 +117,7 @@ #define AMPERE_CPU_PART_AMPERE1 0xAC3 -#define PHYTIUM_CPU_PART_FTC310 0x660 +#define PHYTIUM_CPU_PART_FTC303 0x303 #define PHYTIUM_CPU_PART_FTC660 0x660 #define PHYTIUM_CPU_PART_FTC661 0x661 #define PHYTIUM_CPU_PART_FTC662 0x662 @@ -165,7 +165,7 @@ #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) -#define MIDR_PHYTIUM_FTC310 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC310) +#define MIDR_PHYTIUM_FTC303 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC303) #define MIDR_PHYTIUM_FTC660 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC660) #define MIDR_PHYTIUM_FTC661 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC661) #define MIDR_PHYTIUM_PS17064 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_FTC662) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 2cb7bd9ef3..da91bc6647 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1354,7 +1354,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL), - MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC303), MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC660), MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC661), MIDR_ALL_VERSIONS(MIDR_PHYTIUM_PS17064), diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index e5536f7cad..55d1b11ef3 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -159,7 +159,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void) MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), - MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC303), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_2XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), @@ -487,7 +487,7 @@ static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void) MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), - MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC310), + MIDR_ALL_VERSIONS(MIDR_PHYTIUM_FTC303), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_3XX_SILVER), MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_SILVER), { /* sentinel */ }, -- Gitee From ee0d7d50512af60012a76d6fccbd755818448288 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 28 Jan 2022 22:15:50 +0800 Subject: [PATCH 12/25] net: stmmac: properly handle with runtime pm in stmmac_dvr_remove() There are two issues with runtime pm handling in stmmac_dvr_remove(): 1. the mac is runtime suspended before stopping dma and rx/tx. We need to ensure the device is properly resumed back. 2. the stmmaceth clk enable/disable isn't balanced in both exit and error handling code path. Take the exit code path for example, when we unbind the driver or rmmod the driver module, the mac is runtime suspended as said above, so the stmmaceth clk is disabled, but stmmac_dvr_remove() stmmac_remove_config_dt() clk_disable_unprepare() CCF will complain this time. The error handling code path suffers from the similar situtaion. Here are kernel warnings in error handling code path on Allwinner D1 platform: [ 1.604695] ------------[ cut here ]------------ [ 1.609328] bus-emac already disabled [ 1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec [ 1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1 [ 1.627653] Hardware name: Allwinner D1 NeZha (DT) [ 1.632443] Workqueue: events_unbound deferred_probe_work_func [ 1.638286] epc : clk_core_disable+0xcc/0xec [ 1.642561] ra : clk_core_disable+0xcc/0xec [ 1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10 [ 1.654054] gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f [ 1.661272] t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00 [ 1.668489] s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8 [ 1.675707] a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002 [ 1.682924] a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29 [ 1.690141] s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80 [ 1.697358] s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff [ 1.704577] s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000 [ 1.711794] s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff [ 1.719012] t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0 [ 1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003 [ 1.732233] [] clk_core_disable+0xcc/0xec [ 1.737810] [] clk_disable+0x38/0x78 [ 1.742956] [] worker_thread+0x1a8/0x4d8 [ 1.748451] [] stmmac_remove_config_dt+0x1c/0x4c [ 1.754646] [] sun8i_dwmac_probe+0x378/0x82c [ 1.760484] [] worker_thread+0x1a8/0x4d8 [ 1.765975] [] platform_probe+0x64/0xf0 [ 1.771382] [] really_probe.part.0+0x8c/0x30c [ 1.777305] [] __driver_probe_device+0xa0/0x148 [ 1.783402] [] driver_probe_device+0x38/0x138 [ 1.789324] [] __device_attach_driver+0xd0/0x170 [ 1.795508] [] __driver_attach_async_helper+0xbc/0xc0 [ 1.802125] [] bus_for_each_drv+0x68/0xb4 [ 1.807701] [] __device_attach+0xd8/0x184 [ 1.813277] [] bus_probe_device+0x98/0xbc [ 1.818852] [] deferred_probe_work_func+0x90/0xd4 [ 1.825122] [] process_one_work+0x1e4/0x390 [ 1.830872] [] worker_thread+0x31c/0x4d8 [ 1.836362] [] kthreadd+0x94/0x188 [ 1.841335] [] kthreadd+0x94/0x188 [ 1.846304] [] process_one_work+0x38c/0x390 [ 1.852054] [] kthread+0x124/0x160 [ 1.857021] [] set_kthread_struct+0x5c/0x60 [ 1.862770] [] ret_from_syscall_rejected+0x8/0xc [ 1.868956] ---[ end trace 8d5c6046255f84a0 ]--- [ 1.873675] ------------[ cut here ]------------ [ 1.878366] bus-emac already unprepared [ 1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168 [ 1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G W 5.14.0-rc4 #1 [ 1.898674] Hardware name: Allwinner D1 NeZha (DT) [ 1.903464] Workqueue: events_unbound deferred_probe_work_func [ 1.909305] epc : clk_core_unprepare+0xe4/0x168 [ 1.913840] ra : clk_core_unprepare+0xe4/0x168 [ 1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10 [ 1.925593] gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002 [ 1.932811] t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00 [ 1.940029] s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800 [ 1.947246] a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001 [ 1.954463] a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001 [ 1.961680] s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80 [ 1.968898] s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff [ 1.976115] s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000 [ 1.983333] s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001 [ 1.990550] t5 : 0000000000000000 t6 : ffffffe001600002 [ 1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003 [ 2.003771] [] clk_core_unprepare+0xe4/0x168 [ 2.009609] [] clk_unprepare+0x24/0x3c [ 2.014929] [] stmmac_remove_config_dt+0x24/0x4c [ 2.021125] [] sun8i_dwmac_probe+0x378/0x82c [ 2.026965] [] worker_thread+0x1a8/0x4d8 [ 2.032463] [] platform_probe+0x64/0xf0 [ 2.037871] [] really_probe.part.0+0x8c/0x30c [ 2.043795] [] __driver_probe_device+0xa0/0x148 [ 2.049892] [] driver_probe_device+0x38/0x138 [ 2.055815] [] __device_attach_driver+0xd0/0x170 [ 2.061999] [] __driver_attach_async_helper+0xbc/0xc0 [ 2.068616] [] bus_for_each_drv+0x68/0xb4 [ 2.074193] [] __device_attach+0xd8/0x184 [ 2.079769] [] bus_probe_device+0x98/0xbc [ 2.085345] [] deferred_probe_work_func+0x90/0xd4 [ 2.091616] [] process_one_work+0x1e4/0x390 [ 2.097367] [] worker_thread+0x31c/0x4d8 [ 2.102858] [] kthreadd+0x94/0x188 [ 2.107830] [] kthreadd+0x94/0x188 [ 2.112800] [] process_one_work+0x38c/0x390 [ 2.118551] [] kthread+0x124/0x160 [ 2.123520] [] set_kthread_struct+0x5c/0x60 [ 2.129268] [] ret_from_syscall_rejected+0x8/0xc [ 2.135455] ---[ end trace 8d5c6046255f84a1 ]--- Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver") Signed-off-by: Jisheng Zhang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8416a186cd..6722ec3ab3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5246,6 +5246,10 @@ int stmmac_dvr_remove(struct device *dev) netdev_info(priv->dev, "%s: removing driver", __func__); + pm_runtime_get_sync(dev); + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + stmmac_stop_all_dma(priv); stmmac_mac_set(priv, priv->ioaddr, false); netif_carrier_off(ndev); @@ -5257,8 +5261,6 @@ int stmmac_dvr_remove(struct device *dev) phylink_destroy(priv->phylink); if (priv->plat->stmmac_rst) reset_control_assert(priv->plat->stmmac_rst); - pm_runtime_put(dev); - pm_runtime_disable(dev); if (priv->hw->pcs != STMMAC_PCS_TBI && priv->hw->pcs != STMMAC_PCS_RTBI) stmmac_mdio_unregister(ndev); -- Gitee From c2d1165c17c3b0b02e5b0559a6f366baa3bda064 Mon Sep 17 00:00:00 2001 From: Biao Huang Date: Thu, 14 Jul 2022 14:00:13 +0800 Subject: [PATCH 13/25] net: stmmac: fix pm runtime issue in stmmac_dvr_remove() If netif is running when stmmac_dvr_remove is invoked, the unregister_netdev will call ndo_stop(stmmac_release) and vlan_kill_rx_filter(stmmac_vlan_rx_kill_vid). Currently, stmmac_dvr_remove() will disable pm runtime before unregister_netdev. When stmmac_vlan_rx_kill_vid is invoked, pm_runtime_resume_and_get in it returns EACCESS error number, and reports: dwmac-mediatek 11021000.ethernet eth0: stmmac_dvr_remove: removing driver dwmac-mediatek 11021000.ethernet eth0: FPE workqueue stop dwmac-mediatek 11021000.ethernet eth0: failed to kill vid 0081/0 Move the pm_runtime_disable to the end of stmmac_dvr_remove to fix this issue. Fixes: 6449520391dfc ("net: stmmac: properly handle with runtime pm in stmmac_dvr_remove()") Signed-off-by: Biao Huang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6722ec3ab3..88ba76d0c3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5247,8 +5247,6 @@ int stmmac_dvr_remove(struct device *dev) netdev_info(priv->dev, "%s: removing driver", __func__); pm_runtime_get_sync(dev); - pm_runtime_disable(dev); - pm_runtime_put_noidle(dev); stmmac_stop_all_dma(priv); stmmac_mac_set(priv, priv->ioaddr, false); @@ -5267,6 +5265,9 @@ int stmmac_dvr_remove(struct device *dev) destroy_workqueue(priv->wq); mutex_destroy(&priv->lock); + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + return 0; } EXPORT_SYMBOL_GPL(stmmac_dvr_remove); -- Gitee From f5ca8592cf354726243233c7dce5eec36254baef Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Wed, 10 Sep 2025 15:07:07 +0800 Subject: [PATCH 14/25] arm64: phytium_defconfig: add some bpf config for snap Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 9d0dbb737e..db634df161 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -22,10 +22,12 @@ CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y +CONFIG_BPF_SYSCALL=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_ARCH_PHYTIUM=y -- Gitee From d05416fa46383b594ad5fad365f6511f9ae0ce7b Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Tue, 23 Sep 2025 11:09:29 +0800 Subject: [PATCH 15/25] net: phy: motorcomm: imporve yt8521 read_status Add reset phydev->speed & duplex when not link. When link is down, ethtool will show: ... Speed: Unknown! Duplex: Unknown! (255) ... rather than the old speed & duplex info at link up. Signed-off-by: liutianyu1250 --- drivers/net/phy/motorcomm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 79ea717672..6bd0460398 100755 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -1559,6 +1559,8 @@ static int yt8521_read_status(struct phy_device *phydev) ytxxxx_adjust_status(phydev, val_utp, 1); } else { link_utp = 0; + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; } if (link_utp) { -- Gitee From 616f7eb16d1fbd1fdfeb5da4da09fb9dcdb9a8bb Mon Sep 17 00:00:00 2001 From: Li Yuze Date: Mon, 29 Jul 2024 15:42:16 +0800 Subject: [PATCH 16/25] edac:phytium: Add EDAC driver version messages This patch add driver version information, which will be used to synchronize and manage driver patches in the future. Mainline: Open-Source Signed-off-by: Li Yuze Signed-off-by: Wang Yinfeng Change-Id: Ibcff6b3a006d38aea6197c15524d79c36ba4f8db --- drivers/edac/phytium_edac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/edac/phytium_edac.c b/drivers/edac/phytium_edac.c index 9201d0d703..bf4646f987 100644 --- a/drivers/edac/phytium_edac.c +++ b/drivers/edac/phytium_edac.c @@ -38,6 +38,8 @@ #define MAX_ERR_GROUP 3 +#define EDAC_DRIVER_VERSION "1.1.1" + struct phytium_edac { struct device *dev; void __iomem **ras_base; @@ -482,4 +484,4 @@ module_platform_driver(phytium_edac_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Huangjie "); -MODULE_DESCRIPTION("Phytium Pe220x EDAC driver"); +MODULE_VERSION(EDAC_DRIVER_VERSION); -- Gitee From f22d95505cc75fabcafe8c1a1180f0443349cec5 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Wed, 17 Sep 2025 17:20:24 +0800 Subject: [PATCH 17/25] drivers: edac/phytium: add support for pd2208 Signed-off-by: Huangjie --- drivers/edac/phytium_edac.c | 243 ++++++++++++++++++++++++++++++++---- 1 file changed, 221 insertions(+), 22 deletions(-) diff --git a/drivers/edac/phytium_edac.c b/drivers/edac/phytium_edac.c index bf4646f987..c563c229fa 100644 --- a/drivers/edac/phytium_edac.c +++ b/drivers/edac/phytium_edac.c @@ -14,6 +14,8 @@ #include #include #include "edac_module.h" +#include +#include #define EDAC_MOD_STR "phytium_edac" @@ -36,21 +38,21 @@ #define CORRECTED_ERROR 0 #define UNCORRECTED_ERROR 1 -#define MAX_ERR_GROUP 3 +#define EDAC_DRIVER_VERSION "1.1.2" -#define EDAC_DRIVER_VERSION "1.1.1" +struct ras_error_info { + u32 index; + u32 error_type; + const char *error_str; +}; struct phytium_edac { struct device *dev; void __iomem **ras_base; struct dentry *dfs; struct edac_device_ctl_info *edac_dev; -}; - -struct ras_error_info { - u32 index; - u32 error_type; - const char *error_str; + int num_err_group; + const struct ras_error_info **error_info; }; /* error severity definition */ @@ -128,8 +130,182 @@ static const struct ras_error_info pe220x_ras_peu_error[] = { { 5, CORRECTED_ERROR, "axi_r_rsp_error" }, }; +/* pd2208 error */ +static const struct ras_error_info pd2208_ras_err[] = { + {0, CORRECTED_ERROR, "lmu0_ras_ecc_corrected_err"}, + {1, UNCORRECTED_ERROR, "lmu0_ras_ecc_uncorrected_err"}, + {2, CORRECTED_ERROR, "lmu1_ras_ecc_corrected_err"}, + {3, UNCORRECTED_ERROR, "lmu1_ras_ecc_uncorrected_err"}, + {4, CORRECTED_ERROR, "sram_corrected_err"}, + {5, UNCORRECTED_ERROR, "sram_uncorrected_err"}, + {6, UNCORRECTED_ERROR, "qspi_ras_addr_err"}, + {7, UNCORRECTED_ERROR, "qspi_ras_pstrb_err"}, + {8, UNCORRECTED_ERROR, "intreq_err"}, + {9, UNCORRECTED_ERROR, "gic_axim_err"}, + {10, UNCORRECTED_ERROR, "gic_ecc_fatal"}, + {11, UNCORRECTED_ERROR, "lsd_lbc_ras_err"}, + {12, UNCORRECTED_ERROR, "nEXTERRIRQ_cluster0"}, + {13, UNCORRECTED_ERROR, "nINTERRIRQ_cluster0"}, + {14, UNCORRECTED_ERROR, "nEXTERRIRQ_cluster1"}, + {15, UNCORRECTED_ERROR, "nINTERRIRQ_cluster1"}, + {16, UNCORRECTED_ERROR, "nEXTERRIRQ_cluster2"}, + {17, UNCORRECTED_ERROR, "nINTERRIRQ_cluster2"}, + {18, UNCORRECTED_ERROR, "nEXTERRIRQ_cluster3"}, + {19, UNCORRECTED_ERROR, "nINTERRIRQ_cluster3"}, + {20, CORRECTED_ERROR, "lbc_ecc_corrected_err"}, + {21, UNCORRECTED_ERROR, "lbc_ecc_uncorrected_err"}, +}; + +static const struct ras_error_info pd2208_ras_sram_err[] = { + {0, CORRECTED_ERROR, "scp_sram_corrected_err"}, + {1, UNCORRECTED_ERROR, "scp_sram_uncorrected_err"}, + {2, CORRECTED_ERROR, "scp_sharemem_corrected_err"}, + {3, UNCORRECTED_ERROR, "scp_sharemem_uncorrected_err"}, + {4, CORRECTED_ERROR, "wr_cmd_buf_corrected_err"}, + {5, UNCORRECTED_ERROR, "wr_cmd_buf_uncorrected_err"}, + {6, CORRECTED_ERROR, "rd_dat_buf_corrected_err"}, + {7, UNCORRECTED_ERROR, "rd_dat_buf_uncorrected_err"}, + {8, CORRECTED_ERROR, "wr_cmd_buf_corrected_err"}, + {9, UNCORRECTED_ERROR, "wr_cmd_buf_uncorrected_err"}, + {10, CORRECTED_ERROR, "wr_dat_buf_corrected_err"}, + {11, UNCORRECTED_ERROR, "wr_dat_buf_uncorrected_err"}, + {12, CORRECTED_ERROR, "drtrch0_corrected_err"}, + {13, UNCORRECTED_ERROR, "drtrch0_uncorrected_err"}, + {14, CORRECTED_ERROR, "drtrch0_corrected_err"}, + {15, UNCORRECTED_ERROR, "drtrch0_uncorrected_err"}, + {16, CORRECTED_ERROR, "dmac_corrected_err"}, + {17, UNCORRECTED_ERROR, "dmac_uncorrected_err"}, + {18, CORRECTED_ERROR, "rmram0_corrected_err"}, + {19, UNCORRECTED_ERROR, "rmram0_uncorrected_err"}, + {20, CORRECTED_ERROR, "rmram1_corrected_err"}, + {21, UNCORRECTED_ERROR, "rmram1_uncorrected_err"}, + {22, CORRECTED_ERROR, "rmram2_corrected_err"}, + {23, UNCORRECTED_ERROR, "rmram2_uncorrected_err"}, + {24, CORRECTED_ERROR, "rmram3_corrected_err"}, + {25, UNCORRECTED_ERROR, "rmram3_uncorrected_err"}, + {26, CORRECTED_ERROR, "gmactx0_corrected_err"}, + {27, UNCORRECTED_ERROR, "gmactx0_uncorrected_err"}, + {28, CORRECTED_ERROR, "gmactx1_corrected_err"}, + {29, UNCORRECTED_ERROR, "gmactx1_uncorrected_err"}, + {30, CORRECTED_ERROR, "gmactx2_corrected_err"}, + {31, UNCORRECTED_ERROR, "gmactx2_uncorrected_err"}, + {32, CORRECTED_ERROR, "gmactx3_corrected_err"}, + {33, UNCORRECTED_ERROR, "gmactx3_uncorrected_err"}, +}; + +static const struct ras_error_info pd2208_ras_peu_sram0_err[] = { + {0, CORRECTED_ERROR, "c0p2a_corrected_err"}, + {1, UNCORRECTED_ERROR, "c0p2a_uncorrected_err"}, + {2, CORRECTED_ERROR, "c0a2p_corrected_err"}, + {3, UNCORRECTED_ERROR, "c0a2p_uncorrected_err"}, + {4, CORRECTED_ERROR, "c0rxbuf0_corrected_err"}, + {5, UNCORRECTED_ERROR, "c0rxbuf0_uncorrected_err"}, + {6, CORRECTED_ERROR, "c0rxbuf1_corrected_err"}, + {7, UNCORRECTED_ERROR, "c0rxbuf1 _uncorrected_err"}, + {8, CORRECTED_ERROR, "c0rxbuf2_corrected_err"}, + {9, UNCORRECTED_ERROR, "c0rxbuf2 _uncorrected_err"}, + {10, CORRECTED_ERROR, "c0rxbuf3_corrected_err"}, + {11, UNCORRECTED_ERROR, "c0rxbuf3 _uncorrected_err"}, + {12, CORRECTED_ERROR, "c0txbuf0_corrected_err"}, + {13, UNCORRECTED_ERROR, "c0txbuf0_uncorrected_err"}, + {14, CORRECTED_ERROR, "c0txbuf1_corrected_err"}, + {15, UNCORRECTED_ERROR, "c0txbuf1 _uncorrected_err"}, + {16, CORRECTED_ERROR, "c0txbuf2_corrected_err"}, + {17, UNCORRECTED_ERROR, "c0txbuf2 _uncorrected_err"}, + {18, CORRECTED_ERROR, "c0txbuf3_corrected_err"}, + {19, UNCORRECTED_ERROR, "c0txbuf3 _uncorrected_err"}, + {20, CORRECTED_ERROR, "c1p2a_corrected_err"}, + {21, UNCORRECTED_ERROR, "c1p2a_uncorrected_err"}, + {22, CORRECTED_ERROR, "c1a2p_corrected_err"}, + {23, UNCORRECTED_ERROR, "c1a2p_uncorrected_err"}, + {24, CORRECTED_ERROR, "c1rxbuf0_corrected_err"}, + {25, UNCORRECTED_ERROR, "c1rxbuf0_uncorrected_err"}, + {26, CORRECTED_ERROR, "c1rxbuf1_corrected_err"}, + {27, UNCORRECTED_ERROR, "c1rxbuf1 _uncorrected_err"}, + {28, CORRECTED_ERROR, "c1rxbuf2_corrected_err"}, + {29, UNCORRECTED_ERROR, "c1rxbuf2 _uncorrected_err"}, + {30, CORRECTED_ERROR, "c1rxbuf3_corrected_err"}, + {31, UNCORRECTED_ERROR, "c1rxbuf3 _uncorrected_err"}, + {32, CORRECTED_ERROR, "c1txbuf0_corrected_err"}, + {33, UNCORRECTED_ERROR, "c1txbuf0_uncorrected_err"}, + {34, CORRECTED_ERROR, "c1txbuf1_corrected_err"}, + {35, UNCORRECTED_ERROR, "c1txbuf1 _uncorrected_err"}, + {36, CORRECTED_ERROR, "c1txbuf2_corrected_err"}, + {37, UNCORRECTED_ERROR, "c1txbuf2 _uncorrected_err"}, + {38, CORRECTED_ERROR, "c1txbuf3_corrected_err"}, + {39, UNCORRECTED_ERROR, "c1txbuf3 _uncorrected_err"}, + {40, CORRECTED_ERROR, "c2p2a_corrected_err"}, + {41, UNCORRECTED_ERROR, "c2p2a_uncorrected_err"}, + {42, CORRECTED_ERROR, "c2a2p_corrected_err"}, + {43, UNCORRECTED_ERROR, "c2a2p_uncorrected_err"}, + {44, CORRECTED_ERROR, "c2rxbuf0_corrected_err"}, + {45, UNCORRECTED_ERROR, "c2rxbuf0_uncorrected_err"}, + {46, CORRECTED_ERROR, "c2rxbuf1_corrected_err"}, + {47, UNCORRECTED_ERROR, "c2rxbuf1 _uncorrected_err"}, + {48, CORRECTED_ERROR, "c2rxbuf2_corrected_err"}, + {49, UNCORRECTED_ERROR, "c2rxbuf2 _uncorrected_err"}, + {50, CORRECTED_ERROR, "c2rxbuf3_corrected_err"}, + {51, UNCORRECTED_ERROR, "c2rxbuf3 _uncorrected_err"}, + {52, CORRECTED_ERROR, "c2txbuf0_corrected_err"}, + {53, UNCORRECTED_ERROR, "c2txbuf0_uncorrected_err"}, + {54, CORRECTED_ERROR, "c2txbuf1_corrected_err"}, + {55, UNCORRECTED_ERROR, "c2txbuf1 _uncorrected_err"}, +}; + +static const struct ras_error_info pd2208_ras_peu_sram1_err[] = { + {0, CORRECTED_ERROR, "c2txbuf2_corrected_err"}, + {1, UNCORRECTED_ERROR, "c2txbuf2_uncorrected_err"}, + {2, CORRECTED_ERROR, "c2txbuf3_corrected_err"}, + {3, UNCORRECTED_ERROR, "c2txbuf3_uncorrected_err"}, + {4, CORRECTED_ERROR, "phy0_sram0_corrected_err"}, + {5, UNCORRECTED_ERROR, "phy0_sram0_uncorrected_err"}, + {6, CORRECTED_ERROR, "phy0_sram1_corrected_err"}, + {7, UNCORRECTED_ERROR, "phy0_sram1 _uncorrected_err"}, + {8, CORRECTED_ERROR, "phy0_sram2_corrected_err"}, + {9, UNCORRECTED_ERROR, "phy0_sram2 _uncorrected_err"}, + {10, CORRECTED_ERROR, "phy0_sram3_corrected_err"}, + {11, UNCORRECTED_ERROR, "phy0_sram3 _uncorrected_err"}, + {12, CORRECTED_ERROR, "phy1_sram0_corrected_err"}, + {13, UNCORRECTED_ERROR, "phy1_sram0_uncorrected_err"}, + {14, CORRECTED_ERROR, "mac0_rxdpram_corrected_err"}, + {15, UNCORRECTED_ERROR, "mac0_rxdpram _uncorrected_err"}, + {16, CORRECTED_ERROR, "mac0_txdpram_corrected_err"}, + {17, UNCORRECTED_ERROR, "mac0_txdpram _uncorrected_err"}, + {18, CORRECTED_ERROR, "mac1_rxdpram_corrected_err"}, + {19, UNCORRECTED_ERROR, "mac1_rxdpram _uncorrected_err"}, + {20, CORRECTED_ERROR, "mac1_txdpram_corrected_err"}, + {21, UNCORRECTED_ERROR, "mac1_txdpram _uncorrected_err"}, +}; + +static const struct ras_error_info pd2208_ras_peu_base_err[] = { + {0, UNCORRECTED_ERROR, "pio_rd_addr_error"}, + {1, UNCORRECTED_ERROR, "pio_rd_timeout"}, + {2, UNCORRECTED_ERROR, "pio_wr_addr_error"}, + {3, UNCORRECTED_ERROR, "pio_wr_timeout"}, + {4, CORRECTED_ERROR, "axi_b_rsp_error"}, + {5, UNCORRECTED_ERROR, "axi_r_rsp_error"}, + {6, UNCORRECTED_ERROR, "mac0_asf_trans_to_err"}, + {7, UNCORRECTED_ERROR, "mac0_asf_protocol_err"}, + {8, UNCORRECTED_ERROR, "mac0_asf_nonfatal_int"}, + {9, UNCORRECTED_ERROR, "mac0_asf_fatal_int"}, + {10, UNCORRECTED_ERROR, "mac1_asf_trans_to_err"}, + {11, UNCORRECTED_ERROR, "mac1_asf_protocol_err"}, + {12, UNCORRECTED_ERROR, "mac1_asf_nonfatal_int"}, + {13, UNCORRECTED_ERROR, "mac1_asf_fatal_int"}, +}; + static const struct ras_error_info *pe220x_ras_error[] = { - pe220x_ras_soc_error, pe220x_ras_peu_psu_error, pe220x_ras_peu_error + pe220x_ras_soc_error, + pe220x_ras_peu_psu_error, + pe220x_ras_peu_error, +}; + +static const struct ras_error_info *pd2208_ras_error[] = { + pd2208_ras_err, + pd2208_ras_sram_err, + pd2208_ras_peu_sram0_err, + pd2208_ras_peu_sram1_err, + pd2208_ras_peu_base_err, }; static inline unsigned int get_error_num(const struct phytium_edac *edac, @@ -146,11 +322,11 @@ static inline void phytium_ras_setup(const struct phytium_edac *edac) { u64 val = 0; unsigned int i = 0; + /* * enable error report and generate interrupt for corrected error event - * first error record owned by node present the node configuration */ - for (i = 0; i < MAX_ERR_GROUP; i++) { + for (i = 0; i < edac->num_err_group; i++) { val = readq(edac->ras_base[i] + ERR_CTLR(0)); val |= CTLR_ED | CTLR_UI | CTLR_CFI; writeq(val, edac->ras_base[i] + ERR_CTLR(0)); @@ -190,7 +366,7 @@ static ssize_t phytium_edac_inject_ctrl_write(struct file *filp, goto out; res = kstrtouint(tmp, 0, &error_group); - if (res || error_group >= MAX_ERR_GROUP) { + if (res || error_group >= edac->num_err_group) { dev_err(edac->dev, "invalid error group parameters"); goto out; } @@ -207,11 +383,11 @@ static ssize_t phytium_edac_inject_ctrl_write(struct file *filp, goto out; } - dev_dbg(edac->dev, "inject group%d, error_id: %d\n", + dev_dbg(edac->dev, "inject group: %d, error_id: %d\n", error_group, error_id); - if (pe220x_ras_error[error_group][error_id].error_type == - CORRECTED_ERROR) { + if (edac->error_info[error_group][error_id].error_type + == CORRECTED_ERROR) { writeq(MISC0_CEC(0xFF), edac->ras_base[error_group] + ERR_MISC0(error_id)); } @@ -295,7 +471,7 @@ static int get_error_id(struct phytium_edac *edac, int *error_id, int err_id = 0; /* Iterate over the ras node to check error status */ - for (i = 0; i < MAX_ERR_GROUP; i++) { + for (i = 0; i < edac->num_err_group; i++) { error_num = get_error_num(edac, i); error_bit = readq(edac->ras_base[i] + ERR_GSR); for (err_id = 0; err_id < error_num; err_id++) { @@ -311,7 +487,7 @@ static int get_error_id(struct phytium_edac *edac, int *error_id, } } - if (i >= MAX_ERR_GROUP) { + if (i >= edac->num_err_group) { ret = -1; dev_warn(edac->dev, "no error detect.\n"); } @@ -324,7 +500,7 @@ static void phytium_edac_error_report(struct phytium_edac *edac, const int error_group) { const struct ras_error_info *err_info = - pe220x_ras_error[error_group]; + edac->error_info[error_group]; if (err_info[error_id].error_type == UNCORRECTED_ERROR) { edac_printk(KERN_CRIT, EDAC_MOD_STR, "uncorrected error: %s\n", @@ -383,6 +559,17 @@ static irqreturn_t phytium_edac_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static inline int of_address_count(struct device_node *np) +{ + struct resource res; + int count = 0; + + while (of_address_to_resource(np, count, &res) == 0) + count++; + + return count; +} + static int phytium_edac_probe(struct platform_device *pdev) { struct phytium_edac *edac; @@ -401,14 +588,23 @@ static int phytium_edac_probe(struct platform_device *pdev) edac->dev = &pdev->dev; platform_set_drvdata(pdev, edac); - edac->ras_base = devm_kcalloc(&pdev->dev, 3, - sizeof(*edac->ras_base), GFP_KERNEL); + edac->error_info = + (const struct ras_error_info **)of_device_get_match_data(&pdev->dev); + + edac->num_err_group = of_address_count(pdev->dev.of_node); + if (edac->num_err_group <= 0) { + dev_err(&pdev->dev, "can't get error group count"); + goto out; + } + + edac->ras_base = devm_kcalloc(&pdev->dev, edac->num_err_group, + sizeof(*edac->ras_base), GFP_KERNEL); if (!edac->ras_base) { return -ENOMEM; goto out; } - for (i = 0; i < MAX_ERR_GROUP; i++) { + for (i = 0; i < edac->num_err_group; i++) { res = platform_get_resource(pdev, IORESOURCE_MEM, i); edac->ras_base[i] = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(edac->ras_base[i])) { @@ -466,7 +662,10 @@ static int phytium_edac_remove(struct platform_device *pdev) } static const struct of_device_id phytium_edac_of_match[] = { - { .compatible = "phytium,pe220x-edac" }, + { .compatible = "phytium,pe220x-edac", + .data = pe220x_ras_error }, + { .compatible = "phytium,pd2208-edac", + .data = pd2208_ras_error }, {}, }; MODULE_DEVICE_TABLE(of, phytium_edac_of_match); -- Gitee From 5bcdce61fc3f663b03cc9394d1e9bbc0f397f235 Mon Sep 17 00:00:00 2001 From: zuoqian Date: Sun, 28 Sep 2025 14:38:21 +0800 Subject: [PATCH 18/25] net: phytmac: fix fixed-link link down ethtool status Add reset pdata->speed & duplex when not link in fixed-link mode. When link is down, ethtool will show: ... Speed: Unknown! Duplex: Unknown! (255) ... rather than the old speed & duplex info at link up. Signed-off-by: zuoqian --- drivers/net/ethernet/phytium/phytmac_ethtool.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/phytium/phytmac_ethtool.c b/drivers/net/ethernet/phytium/phytmac_ethtool.c index 2cc224c96a..bdeb8ab4e0 100644 --- a/drivers/net/ethernet/phytium/phytmac_ethtool.c +++ b/drivers/net/ethernet/phytium/phytmac_ethtool.c @@ -381,8 +381,13 @@ static int phytmac_get_link_ksettings(struct net_device *ndev, if (!ndev->phydev) { kset->base.port = PORT_FIBRE; kset->base.transceiver = XCVR_INTERNAL; - kset->base.duplex = pdata->duplex; - kset->base.speed = pdata->speed; + if (netif_carrier_ok(ndev)) { + kset->base.duplex = pdata->duplex; + kset->base.speed = pdata->speed; + } else { + kset->base.duplex = DUPLEX_UNKNOWN; + kset->base.speed = SPEED_UNKNOWN; + } if (pdata->phy_interface == PHY_INTERFACE_MODE_USXGMII || pdata->phy_interface == PHY_INTERFACE_MODE_10GBASER) { -- Gitee From e98e94f9c0f60ea985c86e5df481c47613a36d77 Mon Sep 17 00:00:00 2001 From: zuoqian Date: Mon, 29 Sep 2025 14:05:20 +0800 Subject: [PATCH 19/25] net: macb: fix fixed-link link down ethtool status Signed-off-by: zuoqian --- drivers/net/ethernet/cadence/macb_main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 9c5e769927..02833e97c4 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -3620,8 +3620,13 @@ static int macb_get_link_ksettings(struct net_device *netdev, supported); ethtool_convert_legacy_u32_to_link_mode(kset->link_modes.advertising, advertising); - kset->base.speed = bp->speed; - kset->base.duplex = bp->duplex; + if (netif_carrier_ok(netdev)) { + kset->base.speed = bp->speed; + kset->base.duplex = bp->duplex; + } else { + kset->base.speed = SPEED_UNKNOWN; + kset->base.duplex = DUPLEX_UNKNOWN; + } } else { phylink_ethtool_ksettings_get(bp->phylink, kset); } -- Gitee From da8d4e08f52014b8108eb7fd56a38cb6fdc4c0f2 Mon Sep 17 00:00:00 2001 From: zuoqian Date: Mon, 29 Sep 2025 14:29:40 +0800 Subject: [PATCH 20/25] arm64: phytium_defconfig: select REALTEK_PHY as Y Signed-off-by: zuoqian --- arch/arm64/configs/phytium_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index db634df161..6744732496 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -302,7 +302,7 @@ CONFIG_MARVELL_10G_PHY=m CONFIG_MICREL_PHY=y CONFIG_MICROSEMI_PHY=y CONFIG_AT803X_PHY=y -CONFIG_REALTEK_PHY=m +CONFIG_REALTEK_PHY=y CONFIG_ROCKCHIP_PHY=y CONFIG_VITESSE_PHY=y CONFIG_MOTORCOMM_PHY=y -- Gitee From de8572b9e1d4c5eca9eebea8bcc1fee5893e7c0e Mon Sep 17 00:00:00 2001 From: zuoqian Date: Mon, 29 Sep 2025 16:10:01 +0800 Subject: [PATCH 21/25] net: macb: update bp->duplex when link up Signed-off-by: zuoqian --- drivers/net/ethernet/cadence/macb_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 02833e97c4..2b09aa48eb 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1074,6 +1074,9 @@ static void macb_mac_link_up(struct phylink_config *config, } } + bp->speed = speed; + bp->duplex = duplex; + netif_tx_wake_all_queues(ndev); } -- Gitee From 4213848c5326d5491e08b468354e98b3e1b72373 Mon Sep 17 00:00:00 2001 From: Huangjie Date: Thu, 16 Oct 2025 15:58:28 +0800 Subject: [PATCH 22/25] drivers: edac/phytium: ignore pe220x soc_err 40~43 soc_err 40-43 is for debug not open for user Signed-off-by: Huangjie --- drivers/edac/phytium_edac.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/edac/phytium_edac.c b/drivers/edac/phytium_edac.c index c563c229fa..0a15846031 100644 --- a/drivers/edac/phytium_edac.c +++ b/drivers/edac/phytium_edac.c @@ -190,7 +190,7 @@ static const struct ras_error_info pd2208_ras_sram_err[] = { {30, CORRECTED_ERROR, "gmactx2_corrected_err"}, {31, UNCORRECTED_ERROR, "gmactx2_uncorrected_err"}, {32, CORRECTED_ERROR, "gmactx3_corrected_err"}, - {33, UNCORRECTED_ERROR, "gmactx3_uncorrected_err"}, + {33, UNCORRECTED_ERROR, "gmactx3_uncorrected_err"}, }; static const struct ras_error_info pd2208_ras_peu_sram0_err[] = { @@ -502,6 +502,11 @@ static void phytium_edac_error_report(struct phytium_edac *edac, const struct ras_error_info *err_info = edac->error_info[error_group]; + /* ignore pe220x soc_err id 40~43 */ + if ((err_info == pe220x_ras_soc_error) && + (error_id >= 40) && (error_id <= 43)) + return; + if (err_info[error_id].error_type == UNCORRECTED_ERROR) { edac_printk(KERN_CRIT, EDAC_MOD_STR, "uncorrected error: %s\n", err_info[error_id].error_str); -- Gitee From a07eb6d677b2ce4014d4c033eeda80d13660f48b Mon Sep 17 00:00:00 2001 From: zuoqian Date: Thu, 16 Oct 2025 17:26:01 +0800 Subject: [PATCH 23/25] net: phytmac: support ipv6 TSO Signed-off-by: zuoqian --- drivers/net/ethernet/phytium/phytmac_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/phytium/phytmac_main.c b/drivers/net/ethernet/phytium/phytmac_main.c index ff377d954e..ee2a835bd3 100644 --- a/drivers/net/ethernet/phytium/phytmac_main.c +++ b/drivers/net/ethernet/phytium/phytmac_main.c @@ -2365,7 +2365,7 @@ static netdev_features_t phytmac_features_check(struct sk_buff *skb, hdrlen = skb_transport_offset(skb); if (!IS_ALIGNED(skb_headlen(skb) - hdrlen, PHYTMAC_TX_LEN_ALIGN)) - return features & ~NETIF_F_TSO; + return features & ~(NETIF_F_TSO | NETIF_F_TSO6); nr_frags = skb_shinfo(skb)->nr_frags; /* No need to check last fragment */ @@ -2374,7 +2374,7 @@ static netdev_features_t phytmac_features_check(struct sk_buff *skb, const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; if (!IS_ALIGNED(skb_frag_size(frag), PHYTMAC_TX_LEN_ALIGN)) - return features & ~NETIF_F_TSO; + return features & ~(NETIF_F_TSO | NETIF_F_TSO6); } return features; } @@ -2660,7 +2660,7 @@ void phytmac_default_config(struct phytmac *pdata) ndev->hw_features = NETIF_F_SG; if (pdata->capacities & PHYTMAC_CAPS_LSO) - ndev->hw_features |= NETIF_F_TSO; + ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; if (pdata->use_ncsi) { ndev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); -- Gitee From 974e1c6bdfa458979fd7508a31238d9ed4f0a5c3 Mon Sep 17 00:00:00 2001 From: zuoqian Date: Fri, 17 Oct 2025 17:17:42 +0800 Subject: [PATCH 24/25] net: macb: support ipv6 TSO Signed-off-by: zuoqian --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 2b09aa48eb..658aafa3f8 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -84,7 +84,7 @@ struct sifive_fu540_macb_mgmt { #define GEM_MAX_TX_LEN (unsigned int)(0x3FC0) #define GEM_MTU_MIN_SIZE ETH_MIN_MTU -#define MACB_NETIF_LSO NETIF_F_TSO +#define MACB_NETIF_LSO (NETIF_F_TSO | NETIF_F_TSO6) #define MACB_WOL_HAS_MAGIC_PACKET (0x1 << 0) #define MACB_WOL_ENABLED (0x1 << 1) -- Gitee From c3a614665d69c1ffef502e08896339ca4373cb60 Mon Sep 17 00:00:00 2001 From: liutianyu1250 Date: Tue, 21 Oct 2025 14:04:56 +0800 Subject: [PATCH 25/25] arm64: phytium_defconfig: default enable CIFS Signed-off-by: liutianyu1250 --- arch/arm64/configs/phytium_defconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/configs/phytium_defconfig b/arch/arm64/configs/phytium_defconfig index 6744732496..5bf947fdf4 100644 --- a/arch/arm64/configs/phytium_defconfig +++ b/arch/arm64/configs/phytium_defconfig @@ -768,13 +768,12 @@ CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_2_INTER_SSC=y CONFIG_NFSD_V4_SECURITY_LABEL=y +CONFIG_CIFS=y CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_SECURITY=y CONFIG_CRYPTO_USER=y -CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_DRBG_HASH=y -- Gitee