* Re: [PATCH v8 09/12] iommu/arm-smmu-v3: Implement pm_runtime & system sleep ops
From: Pranjal Shrivastava @ 2026-06-09 10:13 UTC (permalink / raw)
To: Daniel Mentz
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <CAE2F3rCTHZOiSx5tTVmLmubJ4SUDtXvCX6oLqsdEsPAFTKJZ4A@mail.gmail.com>
On Tue, Jun 02, 2026 at 08:27:22AM -0700, Daniel Mentz wrote:
> On Mon, Jun 1, 2026 at 2:59 PM Pranjal Shrivastava <praan@google.com> wrote:
> > +static inline u32 arm_smmu_cmdq_owner_prod_idx(struct arm_smmu_cmdq *cmdq)
> > +{
> > + return atomic_read(&cmdq->owner_prod) & CMDQ_PROD_IDX_MASK;
>
> Is this masking necessary? Can't we just use
> atomic_read(&cmdq->owner_prod) as is? The only place in
> arm_smmu_cmdq_issue_cmdlist() that writes to cmdq->owner_prod already
> applied CMDQ_PROD_IDX_MASK.
Ack. I'll drop the masking.
>
> > +}
> > +
>
> > @@ -4839,6 +4876,10 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
> > return ret;
> > }
> >
> > + /* Clear any flags from the previous life */
> > + atomic_andnot(CMDQ_PROD_STOP_FLAG, &smmu->cmdq.owner_prod);
>
> Same. I believe CMDQ_PROD_STOP_FLAG will never be set in
> smmu->cmdq.owner_prod. Hence, clearing it shouldn't be necessary.
Ack. I'll drop this.
>
> > + atomic_andnot(CMDQ_PROD_STOP_FLAG, &smmu->cmdq.q.llq.atomic.prod);
> > +
> > /* Invalidate any cached configuration */
> > arm_smmu_cmdq_issue_cmd_with_sync(smmu, arm_smmu_make_cmd_cfgi_all());
> >
> > @@ -4898,6 +4939,21 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
Thanks,
Praan
^ permalink raw reply
* [PATCH 2/3] arm64: cputype: Add C1-Premium definitions
From: Mark Rutland @ 2026-06-09 10:12 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, mark.rutland, will
In-Reply-To: <20260609101203.1512409-1-mark.rutland@arm.com>
Add cputype definitions for C1-Premium. These will be used for errata
detection in subsequent patches.
These values can be found in the C1-Premium TRM:
https://developer.arm.com/documentation/109416/0100/
... in section A.5.1 ("MIDR_EL1, Main ID Register").
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cputype.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 3e223a7781866..1b9f0cda1336d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -100,6 +100,7 @@
#define ARM_CPU_PART_C1_ULTRA 0xD8C
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define ARM_CPU_PART_C1_PRO 0xD8B
+#define ARM_CPU_PART_C1_PREMIUM 0xD90
#define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00
@@ -193,6 +194,7 @@
#define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO)
+#define MIDR_C1_PREMIUM MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PREMIUM)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
--
2.30.2
^ permalink raw reply related
* [PATCH 3/3] arm64: errata: Mitigate TLBI errata on various Arm CPUs
From: Mark Rutland @ 2026-06-09 10:12 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, mark.rutland, will
In-Reply-To: <20260609101203.1512409-1-mark.rutland@arm.com>
A number of CPUs developed by Arm suffer from errata whereby a broadcast
TLBI;DSB sequence may complete before the global observation of writes
which are translated by an affected TLB entry.
These errata ONLY affect the completion of memory accesses which have
been translated by an invalidated TLB entry, and these errata DO NOT
affect the actual invalidation of TLB entries. TLB entries are removed
correctly.
This issue has been assigned CVE ID CVE-2025-10263.
To mitigate this issue, Arm recommends that software follows any
affected TLBI;DSB sequence with an additional TLBI;DSB, which will
ensure that all memory write effects affected by the first TLBI have
been globally observed. The additional TLBI can use any operation that
is broadcast to affected CPUs, and the additional DSB can use any option
that is sufficient to complete the additional TLBI.
The ARM64_WORKAROUND_REPEAT_TLBI workaround is sufficient to mitigate
the issue. Enable this workaround for affected CPUs, and update the
silicon errata documentation accordingly.
Note that due to the manner in which Arm develops IP and tracks errata,
some CPUs share a common erratum number.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
Documentation/arch/arm64/silicon-errata.rst | 42 +++++++++++++++++++++
arch/arm64/Kconfig | 36 ++++++++++++++++++
arch/arm64/kernel/cpu_errata.c | 32 +++++++++++++++-
3 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 61c2fd7ef6441..6f4a93602abca 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -129,17 +129,29 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A76 | #4193800 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A76AE | #4193801 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #1491015 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A77 | #4193798 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A78 | #4193791 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A78AE | #4193793 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78C | #3324346, | ARM64_ERRATUM_3194386 |
| | | #3324347 | |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A78C | #4193794 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 |
@@ -148,6 +160,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-A710 | #4193788 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
@@ -160,20 +174,32 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X1 | #4193791 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X1C | #4193792 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X2 | #4193788 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X3 | #4193786 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X4 | #4118414 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Cortex-X925 | #4193781 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873, | ARM64_ERRATUM_1418040 |
| | | #1418040 | |
+----------------+-----------------+-----------------+-----------------------------+
@@ -184,6 +210,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-N1 | #4193800 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 |
@@ -192,20 +220,34 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-N2 | #4193789 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #1619801 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-V1 | #4193790 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-V2 | #4193787 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-V3 | #4193784 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3AE | #3312417 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | Neoverse-V3AE | #4193784 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM | C1-Premium | #4193780 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | C1-Pro | #4193714 | ARM64_ERRATUM_4193714 |
+----------------+-----------------+-----------------+-----------------------------+
+| ARM | C1-Ultra | #4193780 | ARM64_ERRATUM_4118414 |
++----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #562869, | ARM_SMMU_MMU_500_CPRE_ERRATA|
| | | #841119, | |
| | | #826419, | |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 62fe27f2f6981..8065b733aa8c6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1154,6 +1154,42 @@ config ARM64_ERRATUM_4193714
If unsure, say Y.
+config ARM64_ERRATUM_4118414
+ bool "Cortex-*/Neoverse-*/C1-*: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
+ default y
+ select ARM64_WORKAROUND_REPEAT_TLBI
+ help
+ This option adds a workaround for the following errata:
+
+ * ARM C1-Premium erratum 4193780
+ * ARM C1-Ultra erratum 4193780
+ * ARM Cortex-A76 erratum 4193800
+ * ARM Cortex-A76AE erratum 4193801
+ * ARM Cortex-A77 erratum 4193798
+ * ARM Cortex-A78 erratum 4193791
+ * ARM Cortex-A78AE erratum 4193793
+ * ARM Cortex-A78C erratum 4193794
+ * ARM Cortex-A710 erratum 4193788
+ * ARM Cortex-X1 erratum 4193791
+ * ARM Cortex-X1C erratum 4193792
+ * ARM Cortex-X2 erratum 4193788
+ * ARM Cortex-X3 erratum 4193786
+ * ARM Cortex-X4 erratum 4118414
+ * ARM Cortex-X925 erratum 4193781
+ * ARM Neoverse-N1 erratum 4193800
+ * ARM Neoverse-N2 erratum 4193789
+ * ARM Neoverse-V1 erratum 4193790
+ * ARM Neoverse-V2 erratum 4193787
+ * ARM Neoverse-V3 erratum 4193784
+ * ARM Neoverse-V3AE erratum 4193784
+
+ On affected cores, some memory accesses might not be completed by
+ broadcast TLB invalidation.
+
+ This issue is also known as CVE-2025-10263.
+
+ If unsure, say Y.
+
config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 310e6f120992d..95e3be145fb1e 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -340,7 +340,35 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
ERRATA_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1),
},
#endif
- {},
+#ifdef CONFIG_ARM64_ERRATUM_4118414
+ {
+ ERRATA_MIDR_RANGE_LIST(((const struct midr_range[]) {
+ MIDR_ALL_VERSIONS(MIDR_C1_PREMIUM),
+ MIDR_ALL_VERSIONS(MIDR_C1_ULTRA),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76AE),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3AE),
+ {}
+ })),
+ },
+#endif
+ {}
};
#endif
@@ -705,7 +733,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
#endif
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
{
- .desc = "Qualcomm erratum 1009, or ARM erratum 1286807, 2441009",
+ .desc = "Broken broadcast TLBI completion",
.capability = ARM64_WORKAROUND_REPEAT_TLBI,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = cpucap_multi_entry_cap_matches,
--
2.30.2
^ permalink raw reply related
* [PATCH 1/3] arm64: cputype: Add C1-Ultra definitions
From: Mark Rutland @ 2026-06-09 10:12 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, mark.rutland, will
In-Reply-To: <20260609101203.1512409-1-mark.rutland@arm.com>
Add cputype definitions for C1-Ultra. These will be used for errata
detection in subsequent patches.
These values can be found in the C1-Ultra TRM:
https://developer.arm.com/documentation/108014/0100/
... in section A.5.1 ("MIDR_EL1, Main ID Register").
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/cputype.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 7b518e81dd15b..3e223a7781866 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -97,6 +97,7 @@
#define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87
#define ARM_CPU_PART_CORTEX_A720AE 0xD89
+#define ARM_CPU_PART_C1_ULTRA 0xD8C
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define ARM_CPU_PART_C1_PRO 0xD8B
@@ -189,6 +190,7 @@
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720AE)
+#define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
--
2.30.2
^ permalink raw reply related
* [PATCH 0/3] arm64: errata: Mitigate TLBI errata on various Arm CPUs
From: Mark Rutland @ 2026-06-09 10:12 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, mark.rutland, will
A number of CPUs developed by Arm suffer from errata whereby a broadcast
TLBI;DSB sequence may complete before the global observation of writes
which are translated by an affected TLB entry.
The ARM64_WORKAROUND_REPEAT_TLBI workaround is sufficient to mitigate
the issue. This series enables the workaround on affected parts,
requiring the addition of MIDR values for C1-Ultra and C1-Premium.
I've based the series on the arm64 for-next/core branch to avoid
conflicts with the recent formatting changes to
Documentation/arch/arm64/silicon-errata.rst.
This issue has been assigned CVE ID CVE-2025-10263, and Arm have
published a security bulletin:
https://developer.arm.com/documentation/112137/latest/
This will require manual backporting, so I haven't CC'd stable
explicitly. Once this is queueud I'll push out branches with backports
to the active stable trees.
Thanks,
Mark.
Mark Rutland (3):
arm64: cputype: Add C1-Ultra definitions
arm64: cputype: Add C1-Premium definitions
arm64: errata: Mitigate TLBI errata on various Arm CPUs
Documentation/arch/arm64/silicon-errata.rst | 42 +++++++++++++++++++++
arch/arm64/Kconfig | 36 ++++++++++++++++++
arch/arm64/include/asm/cputype.h | 4 ++
arch/arm64/kernel/cpu_errata.c | 32 +++++++++++++++-
4 files changed, 112 insertions(+), 2 deletions(-)
--
2.30.2
^ permalink raw reply
* Re: [PATCH v8 09/12] iommu/arm-smmu-v3: Implement pm_runtime & system sleep ops
From: Pranjal Shrivastava @ 2026-06-09 10:12 UTC (permalink / raw)
To: Daniel Mentz
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <CAE2F3rDjFwacP0_TA8tv5_p7ZJejsXAKEb=juNaXgPcMPag+Eg@mail.gmail.com>
On Sun, Jun 07, 2026 at 02:53:24PM -0700, Daniel Mentz wrote:
> On Mon, Jun 1, 2026 at 2:59 PM Pranjal Shrivastava <praan@google.com> wrote:
> > @@ -4898,6 +4939,21 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
> > if (is_kdump_kernel())
> > enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
> >
> > + /*
> > + * While the SMMU was suspended, concurrent CPU threads may have
> > + * updated in-memory structures (such as STEs, CDs, and PTEs).
> > + * Any invalidations corresponding to those updates were safely
> > + * elided because the command queue was stopped (STOP_FLAG == 1).
> > + *
> > + * Since the reset invalidate-all commands above have fully cleared
> > + * the HW TLBs and config caches, the SMMU will fetch these descriptors
> > + * directly from RAM as soon as translation is enabled.
> > + *
> > + * Add a memory barrier to collect all prior RAM writes to ensure the
> > + * SMMU sees a consistent view of memory before translation is enabled.
> > + */
> > + smp_mb();
>
> I'm not convinced that this is necessary. I understand that the write
> to smmu->cmdq.q.llq.atomic.prod needs to be ordered before setting
> CR0_SMMUEN in ARM_SMMU_CR0. However, this ordering requirement appears
> to already be met by the dma_wmb() in arm_smmu_cmdq_issue_cmdlist.
> Could you provide an example of a scenario that might fail if this
> smp_mb() were removed?
Agreed. The first dma_wmb() in the issue_cmdlist will handle this. We
don't need this smp_mb(); I'll add a note as specified in [1]
Thanks,
Praan
[1] https://lore.kernel.org/all/aiflaI4svEJvZbsC@google.com/
^ permalink raw reply
* Re: [PATCH 23/37] drm/encoder: add drm_encoder_cleanup_from()
From: Luca Ceresoli @ 2026-06-09 10:10 UTC (permalink / raw)
To: Maxime Ripard, Luca Ceresoli
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Inki Dae, Jagan Teki,
Marek Szyprowski, Marek Vasut, Stefan Agner, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Hui Pu,
Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel, imx,
linux-arm-kernel
In-Reply-To: <20260608-mighty-woodlouse-of-reading-162bca@houat>
On Mon Jun 8, 2026 at 2:10 PM CEST, Maxime Ripard wrote:
> On Tue, May 19, 2026 at 12:37:40PM +0200, Luca Ceresoli wrote:
>> Supporting hardware whose final part of the DRM pipeline can be physically
>> removed requires the ability to detach all bridges from a given point to
>> the end of the pipeline.
>>
>> Introduce a variant of drm_encoder_cleanup() for this.
>>
>> Take care to not try detaching non-attached bridges. This is needed because
>> when two or more bridges are removed not in the backwards order,
>> drm_encoder_cleanup_from() is called more than once for bridges closer to
>> the panel.
>>
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>>
>> ---
>>
>> Note: in theory drm_encoder_cleanup() is now a superset of
>> drm_encoder_cleanup_from() and may be simplified to just call
>> drm_encoder_cleanup_from() and then do the extra actions. However the
>> common code is subtly different in terms of locking and checks, so this
>> would complicate the code in this patch and has thus been kept separate for
>> the time being to make reviewing sompler. Reimplementing
>> drm_encoder_cleanup() by using drm_encoder_cleanup_from() cvacn be done
>> later on.
>>
>> A much simpler and now obsolete version of this patch (missing locking and
>> checks) previously appeared in
>> https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-13-9d6f2c9c3058@bootlin.com/
>> ---
>> drivers/gpu/drm/drm_encoder.c | 38 ++++++++++++++++++++++++++++++++++++++
>> include/drm/drm_encoder.h | 1 +
>> 2 files changed, 39 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
>> index 0d5dbed06db4..40ece477b302 100644
>> --- a/drivers/gpu/drm/drm_encoder.c
>> +++ b/drivers/gpu/drm/drm_encoder.c
>> @@ -179,6 +179,44 @@ int drm_encoder_init(struct drm_device *dev,
>> }
>> EXPORT_SYMBOL(drm_encoder_init);
>>
>> +/**
>> + * drm_encoder_cleanup_from - remove a given bridge and all the following
>> + * @encoder: encoder whole list of bridges shall be pruned
>> + * @bridge: first bridge to remove
>> + *
>> + * Removes from an encoder all the bridges starting with a given bridge
>> + * and until the end of the chain.
>> + *
>> + * Does nothing if the bridge is not attached to an encoder chain.
>> + *
>> + * This should not be used in "normal" DRM pipelines. It is only useful for
>> + * devices whose final part of the DRM chain can be physically removed and
>> + * later reconnected (possibly with different hardware).
>> + */
>> +void drm_encoder_cleanup_from(struct drm_encoder *encoder, struct drm_bridge *bridge)
>> +{
>> + struct drm_bridge *next;
>> + LIST_HEAD(tmplist);
>> +
>> + /*
>> + * We need the bridge_chain_mutex to modify the chain, but
>> + * drm_bridge_detach() will call DRM_MODESET_LOCK_ALL_BEGIN() (in
>> + * drm_modeset_lock_fini()), resulting in a possible ABBA circular
>> + * deadlock. Avoid it by first moving all the bridges to a
>> + * temporary list holding the lock, and then calling
>> + * drm_bridge_detach() without the lock.
>> + */
>> + mutex_lock(&encoder->bridge_chain_mutex);
>> + if (!list_empty(&bridge->chain_node))
>> + list_for_each_entry_safe_from(bridge, next, &encoder->bridge_chain, chain_node)
>> + list_move_tail(&bridge->chain_node, &tmplist);
>> + mutex_unlock(&encoder->bridge_chain_mutex);
>> +
>> + while (!list_empty(&tmplist))
>> + drm_bridge_detach(list_first_entry(&tmplist, struct drm_bridge, chain_node));
>> +}
>> +EXPORT_SYMBOL(drm_encoder_cleanup_from);
>> +
>
> The name is super confusing, because it doesn't clean up anything.
> drm_encoder_cleanup is called that way because it cleans up the encoder.
> This function doesn't.
>
> Unlike what's being documented, it doesn't remove any bridge either. It
> just detaches bridge, so let's just call it that way?
Good point.
What about:
* rename to drm_bridge_detach_from()
* drop the @encoder argument (get if from bridge->encoder)
* maybe even move to drm_bridge.c?
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v8 09/12] iommu/arm-smmu-v3: Implement pm_runtime & system sleep ops
From: Pranjal Shrivastava @ 2026-06-09 10:09 UTC (permalink / raw)
To: Daniel Mentz
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <CAE2F3rC4a55Hfg+JZZora4UYxJyz9WgUV_kqBt_ejUy+9RLzYQ@mail.gmail.com>
On Sun, Jun 07, 2026 at 03:30:00PM -0700, Daniel Mentz wrote:
> On Mon, Jun 1, 2026 at 2:59 PM Pranjal Shrivastava <praan@google.com> wrote:
> > +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> > +{
> > + struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > + struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
> > + int timeout = ARM_SMMU_SUSPEND_TIMEOUT_US;
> > + u32 enables, target;
> > + int ret;
> > +
> > + /* Abort all transactions before disable to avoid spurious bypass */
> > + arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
> > +
> > + /* Disable the SMMU via CR0.EN and all queues except CMDQ */
> > + enables = CR0_CMDQEN;
> > + ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0, ARM_SMMU_CR0ACK);
> > + if (ret) {
> > + dev_err(smmu->dev, "failed to disable SMMU\n");
> > + return ret;
> > + }
> > +
> > + /*
> > + * At this point the SMMU is completely disabled and won't access
> > + * any translation/config structures, even speculative accesses
> > + * aren't performed as per the IHI0070 spec (section 6.3.9.6).
> > + */
> > +
> > + /* Mark the CMDQ to stop and get the target index before the stop */
> > + target = atomic_fetch_or_relaxed(CMDQ_PROD_STOP_FLAG, &cmdq->q.llq.atomic.prod);
>
> I'm wondering if we need the non-relaxed version of atomic_fetch_or()
> here to benefit from the barrier guarantees. Otherwise, how do you
> ensure that CMDQ_PROD_STOP_FLAG isn't set before SMMUEN is cleared?
Ack. I agree we need a non-relaxed version, I missed that the STOP_FLAG
is purely RAM & was focused on the _relaxed variants to keep things
ordered as all were MMIO. I'll drop the relaxed semantics with the
STOP_FLAG.
>
> > + target &= CMDQ_PROD_IDX_MASK;
Thanks,
Praan
^ permalink raw reply
* [soc:soc/dt] BUILD SUCCESS 7b93c5b05877bc5df662d4edd827936fa2d39fc4
From: kernel test robot @ 2026-06-09 10:07 UTC (permalink / raw)
To: Linus Walleij; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/dt
branch HEAD: 7b93c5b05877bc5df662d4edd827936fa2d39fc4 Merge tag 'socfpga_dts_updates_for_v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux into soc/dt
elapsed time: 6520m
configs tested: 85
configs skipped: 1
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig gcc-16.1.0
arm allnoconfig clang-23
arm allyesconfig gcc-16.1.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 randconfig-001-20260609 clang-23
arm64 randconfig-002-20260609 gcc-13.4.0
arm64 randconfig-003-20260609 gcc-15.2.0
arm64 randconfig-004-20260609 clang-23
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky randconfig-001-20260609 gcc-9.5.0
csky randconfig-002-20260609 gcc-11.5.0
hexagon allmodconfig clang-23
hexagon allnoconfig clang-23
hexagon randconfig-001-20260609 clang-18
hexagon randconfig-002-20260609 clang-23
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allyesconfig gcc-14
loongarch allmodconfig clang-19
loongarch allnoconfig clang-20
loongarch randconfig-001-20260609 clang-23
loongarch randconfig-002-20260609 clang-23
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig gcc-16.1.0
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig gcc-11.5.0
nios2 randconfig-001-20260609 gcc-11.5.0
nios2 randconfig-002-20260609 gcc-11.5.0
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig gcc-16.1.0
parisc allyesconfig gcc-16.1.0
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig gcc-16.1.0
riscv allmodconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig clang-23
riscv randconfig-002-20260609 clang-23
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 randconfig-001-20260609 clang-23
s390 randconfig-002-20260609 gcc-16.1.0
sh allmodconfig gcc-16.1.0
sh allnoconfig gcc-16.1.0
sh allyesconfig gcc-16.1.0
sh randconfig-001-20260609 gcc-13.4.0
sh randconfig-002-20260609 gcc-11.5.0
sparc allnoconfig gcc-16.1.0
sparc randconfig-001-20260609 gcc-16.1.0
sparc randconfig-002 gcc-11.5.0
sparc64 allmodconfig clang-20
sparc64 randconfig-001 gcc-12.5.0
um allmodconfig clang-23
um allnoconfig clang-16
um allyesconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-004-20260609 gcc-14
x86_64 buildonly-randconfig-006-20260609 gcc-14
x86_64 randconfig-001-20260609 gcc-14
x86_64 randconfig-002-20260609 clang-22
x86_64 randconfig-003-20260609 gcc-14
x86_64 randconfig-004-20260609 clang-22
x86_64 randconfig-005-20260609 clang-22
x86_64 randconfig-006-20260609 clang-22
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig gcc-16.1.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap()
From: Krzysztof Kozlowski @ 2026-06-09 10:07 UTC (permalink / raw)
To: geoffrey
Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
linux-samsung-soc, linux-kernel
In-Reply-To: <20260609095224.1706036-2-geoffreyhe2@gmail.com>
On 09/06/2026 11:52, geoffrey wrote:
> From: Weigang He <geoffreyhe2@gmail.com>
>
> exynos_get_pmu_regmap() obtains a device_node via of_find_matching_node()
> and passes it to exynos_get_pmu_regmap_by_phandle(np, NULL). With
> propname == NULL the callee uses np directly and only drops a reference
> when propname is set, so the reference taken by of_find_matching_node()
> is leaked on every call -- including on each -EPROBE_DEFER retry of the
> only in-tree caller, exynos_retention_init() in the Exynos pinctrl
> driver.
>
> Drop the reference in the function that acquired it.
>
> Found by static analysis tool CodeQL.
>
> Fixes: 76640b84bd7a ("soc: samsung: pmu: Provide global function to get PMU regmap")
> Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
> ---
> drivers/soc/samsung/exynos-pmu.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index d58376c38179b..a5da2741852b4 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -167,11 +167,17 @@ static const struct mfd_cell exynos_pmu_devs[] = {
> */
> struct regmap *exynos_get_pmu_regmap(void)
> {
> - struct device_node *np = of_find_matching_node(NULL,
> - exynos_pmu_of_device_ids);
Use __free() to make it simpler.
>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v2 2/2] crypto: atmel-ecc - clean up and improve ECDH comments
From: Thorsten Blum @ 2026-06-09 10:05 UTC (permalink / raw)
To: Thorsten Blum, Herbert Xu, David S. Miller, Nicolas Ferre,
Alexandre Belloni, Claudiu Beznea
Cc: linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260609100552.233494-3-thorsten.blum@linux.dev>
Improve the kerneldoc for struct atmel_ecdh_ctx by removing the stale
"unsupported curves" wording, since the device only supports a single
curve (P-256), and move the set_secret() constraint to the description.
In atmel_ecdh_set_secret(), clarify that the device generates the
private key, and drop the redundant "only supports NIST P256" comment.
In atmel_ecdh_done() and atmel_ecdh_generate_public_key(), clarify the
truncation comments. Also note that a P-256 public key consists of two
32-byte coordinates in atmel_ecdh_compute_shared_secret(), and remove
the unnecessary fall-through comment and other redundant comments.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
Changes in v2:
- Adjust atmel_ecdh_ctx kerneldoc formatting/indentation according to:
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#members
- v1: https://lore.kernel.org/r/20260603192708.1237715-4-thorsten.blum@linux.dev/
---
drivers/crypto/atmel-ecc.c | 38 ++++++++++++++------------------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index 0ca02995a1de..cd33d3f132cc 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -27,15 +27,14 @@ static struct atmel_ecc_driver_data driver_data;
/**
* struct atmel_ecdh_ctx - transformation context
- * @client : pointer to i2c client device
- * @fallback : used for unsupported curves or when user wants to use its own
- * private key.
- * @public_key : generated when calling set_secret(). It's the responsibility
- * of the user to not call set_secret() while
- * generate_public_key() or compute_shared_secret() are in flight.
- * @curve_id : elliptic curve id
- * @do_fallback: true when the device doesn't support the curve or when the user
- * wants to use its own private key.
+ * @client: I2C client device
+ * @fallback: ECDH fallback used for caller-provided private keys
+ * @public_key: cached public key for the device-generated private key
+ * @curve_id: elliptic curve id
+ * @do_fallback: true when ECDH operations should use @fallback
+ *
+ * The caller must not invoke set_secret() while generate_public_key()
+ * or compute_shared_secret() are in flight.
*/
struct atmel_ecdh_ctx {
struct i2c_client *client;
@@ -55,7 +54,7 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
if (status)
goto free_work_data;
- /* might want less than we've got */
+ /* copy only as much as requested, capped at 32 bytes */
n_sz = min(ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
/* copy the shared secret */
@@ -64,15 +63,15 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
if (copied != n_sz)
status = -EINVAL;
- /* fall through */
free_work_data:
kfree_sensitive(work_data);
kpp_request_complete(req, status);
}
/*
- * A random private key is generated and stored in the device. The device
- * returns the pair public key.
+ * If no private key is provided, generate one in the device and cache
+ * the corresponding public key. The generated private key never leaves
+ * the device.
*/
static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
unsigned int len)
@@ -83,9 +82,7 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
struct ecdh params;
int ret = -ENOMEM;
- /* free the old public key, if any */
kfree(ctx->public_key);
- /* make sure you don't free the old public key twice */
ctx->public_key = NULL;
if (crypto_ecdh_decode_key(buf, len, ¶ms) < 0) {
@@ -94,7 +91,6 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
}
if (params.key_size) {
- /* fallback to ecdh software implementation */
ctx->do_fallback = true;
return crypto_kpp_set_secret(ctx->fallback, buf, len);
}
@@ -103,11 +99,6 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (!cmd)
return -ENOMEM;
- /*
- * The device only supports NIST P256 ECC keys. The public key size will
- * always be the same. Use a macro for the key size to avoid unnecessary
- * computations.
- */
public_key = kmalloc(ATMEL_ECC_PUBKEY_SIZE, GFP_KERNEL);
if (!public_key)
goto free_cmd;
@@ -120,7 +111,6 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (ret)
goto free_public_key;
- /* save the public key */
memcpy(public_key, &cmd->data[RSP_DATA_IDX], ATMEL_ECC_PUBKEY_SIZE);
ctx->public_key = public_key;
@@ -149,7 +139,7 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
if (!ctx->public_key)
return -EINVAL;
- /* might want less than we've got */
+ /* copy only as much as requested, capped at 64 bytes */
nbytes = min(ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
/* public key was saved at private key generation */
@@ -175,7 +165,7 @@ static int atmel_ecdh_compute_shared_secret(struct kpp_request *req)
return crypto_kpp_compute_shared_secret(req);
}
- /* must have exactly two points to be on the curve */
+ /* A P-256 public key must contain two 32-byte coordinates */
if (req->src_len != ATMEL_ECC_PUBKEY_SIZE)
return -EINVAL;
^ permalink raw reply related
* [PATCH v2 1/2] crypto: atmel-i2c - improve comment in atmel_i2c_init_ecdh_cmd
From: Thorsten Blum @ 2026-06-09 10:05 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Nicolas Ferre, Alexandre Belloni,
Claudiu Beznea
Cc: Thorsten Blum, linux-crypto, linux-arm-kernel, linux-kernel
Clarify that a P-256 public key is encoded as two 32-byte coordinates.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
No changes in patch 1/2.
---
drivers/crypto/atmel-i2c.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/atmel-i2c.c b/drivers/crypto/atmel-i2c.c
index ff19857894d0..24bded47a32b 100644
--- a/drivers/crypto/atmel-i2c.c
+++ b/drivers/crypto/atmel-i2c.c
@@ -138,9 +138,8 @@ int atmel_i2c_init_ecdh_cmd(struct atmel_i2c_cmd *cmd,
cmd->param2 = cpu_to_le16(DATA_SLOT_2);
/*
- * The device only supports NIST P256 ECC keys. The public key size will
- * always be the same. Use a macro for the key size to avoid unnecessary
- * computations.
+ * The device only supports P-256. Its public key is encoded as
+ * two 32-byte coordinates.
*/
copied = sg_copy_to_buffer(pubkey,
sg_nents_for_len(pubkey,
base-commit: 79bbe453e5bfa6e1c6aa2e8329bfc8f152b81c9b
^ permalink raw reply related
* Re: [PATCH v8 07/12] iommu/arm-smmu-v3: Add CMDQ_PROD_STOP_FLAG to gate CMDQ submissions
From: Pranjal Shrivastava @ 2026-06-09 10:05 UTC (permalink / raw)
To: Daniel Mentz
Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
Mostafa Saleh, Nicolin Chen, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <CAE2F3rDZupDgq5tQrvpuixGi-kVs+oi-Tacqa=Rxtri03LBPHQ@mail.gmail.com>
On Mon, Jun 08, 2026 at 09:20:42PM -0700, Daniel Mentz wrote:
> On Sun, Jun 7, 2026 at 11:19 PM Pranjal Shrivastava <praan@google.com> wrote:
> > > >
> > > > static void queue_poll_init(struct arm_smmu_device *smmu,
> > > > @@ -718,8 +719,25 @@ int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
> > > > do {
> > > > u64 old;
> > > >
> > > > + /*
> > > > + * If the SMMU is suspended/suspending, any new CMDs are elided.
> > > > + * This loop is the Point of Commitment. If we haven't cmpxchg'd
> > > > + * our new indices yet, we can safely bail. Once the indices are
> > > > + * committed, we MUST write valid commands to those slots to
> > > > + * avoid indefinite polling in the drain function.
> > > > + */
> > > > + if (Q_STOP(llq.prod)) {
> > > > + local_irq_restore(flags);
> > > > + return 0;
> > >
> > > On second thought, I no longer believe that this is safe. I understand
> > > that READ_ONCE(cmdq->q.llq.val) implies no ordering guarantees with
> > > respect to any writes to translation tables. In the non-stopped case,
> > > we can rely on the call to dma_wmb() further down in this function.
> > > However, for the stopped case, I can't identify any barriers that
> > > would ensure that the STOP flag is checked only after the writes are
> > > visible to SMMU. Here is an example: Let's assume the following
> > > program order:
> > >
> > > * Write to invalidate PTE
> > > * Read from cmdq->q.llq.val, determine STOP flag is set, elide TLBI
> > >
> > > What prevents the CPU from reordering these operations as follows?
> > >
> > > * Read from cmdq->q.llq.val, determine STOP flag is set, elide TLBI
> > > * Write to invalidate PTE
>
> Now, I believe that the smp_mb() call in arm_smmu_domain_inv_range()
> actually prevents this (if we remove arm_smmu_cmdq_can_elide or move
> it to after the smp_mb() call)
>
> > >
> > > Can the following situation occur?
> >
> > Not really because:
> >
> > >
> > > * Read from cmdq->q.llq.val, determine STOP flag is set, elide TLBI
> > > * (Different CPU resumes SMMU)
> >
> > We do a full smp_mb() here to ensure all writes are seen before SMMUEN=1
> > (note that the STOP_FLAG is already unset at that point, so we stop
> > eliding commands much before the SMMU is physically able to access any
> > config/xlation structures, I've explained everything below).
> >
> > > * SMMU loads old PTE value into TLB
> > > * Write to invalidate PTE
> > > * (stale PTE remains in TLB)
> > >
> > > I propose the following: If you find the STOP flag set, run dma_mb()
> > > and check again. I'm afraid that running dma_mb() unconditionally
> > > might incur too much of a performance penalty.
> >
> > IMHO, I think this might be overcomplicating things here..
> > Here's why the current version works according to me:
> >
> > Till SMMUEN=0, the SMMU is spec-guaranteed to never access translation
> > or configuration structures (Section 6.3.9.6).
> >
> > Our runtime_suspend callback sets SMMUEN=0 before setting the STOP_FLAG.
>
> Does "before" refer to program order or the order in which other
> agents can observe the STOP_FLAG relative to when SMMUEN=0 is set?
> Your program might read "Set SMMUEN=0 then set STOP_FLAG". However, my
> question is whether other observers might see the STOP_FLAG before
> SMMUEN is cleared. I couldn't identify any barriers in
> arm_smmu_runtime_suspend() that would prevent this type of
> re-ordering.
Hmm.. that's right. I guess I was wrongly relying on the fact that
_relaxed() variants are guaranteed to be ordered amongst themselves on
the same CPU but reading the barriers documentation [1] I see:
These are similar to readX() and writeX(),
[...] but they are still guaranteed to be ordered with respect to other
accesses from the same CPU thread to the same peripheral when operating
on __iomem pointers mapped with the default I/O attributes.
Hence, it seems it is possible for RAM writes to be re-ordered
before the writeX_relaxed(MMIO).
In that case, I guess we could just use the non-relaxed version to set
the STOP_FLAG...
>
> > Even if the worker CPU reorders the PTE write after the STOP_FLAG check,
> > it is benign because the SMMU is incapable of fetching that (or any) PTE
> > while the gate is closed. Because GATE_CLOSED == SMMUEN = 0, implying no
> > access to any HW structures whatsoever.
> >
> > The real synchronization happens in the Resume Path:
> >
> > 1. arm_smmu_device_reset() clears all caches / TLBs.
> > (None of these can have entries before SMMUEN=1)
> >
> > 2. We execute a full smp_mb() before setting SMMUEN=1. (that's why we
> > need smp_mb before SMMUEN=1). This barrier ensures that any PTE
> > writes made by any thread—including those that were elided while the
> > gate was closed, are globally visible before the SMMU hardware starts
> > fetching into TLBs again. (This is why Jason suggested this in v6 [1])
>
> A barrier on one CPU has no bearing on whether writes by any other CPU
> can be observed by any particular agent in the system.
>
> Let's compare this with the long comment in
> arm_smmu_domain_inv_range() which is what I believe Jason was
> referring to. In that example, you see smp_mb() in the code path on
> CPU0 and dma_wmb() in the code path on CPU1. Hence, barriers exist on
> both sides. If you compare the runtime PM design with
> arm_smmu_domain_inv_range(), then smp_mb() belongs in the CPU thread
> that performs the translation table updates not the one that performs
> the suspend/resume operation.
>
I might be missing something here, so please bear with me. My
understanding it that's needed because the IOMMU is live & actively
caching, which is not true for our case.
[Assuming we use non-relaxed semantics & ordering for the STOP flag,
i.e. set STOP_FLAG + barrier & clear STOP_FLAG (implicit dma_wmb())]
In our case, during the resume op, we first clear the STOP_FLAG before
setting SMMUEN=1 in program order. Thus, any PTE invalidations occurring
before SMMUEN=1 are executed, i.e. EVEN when the SMMU is guaranteed not
to access any structures, we've resumed invalidations.
Let's consider a few examples:
1. SUSPEND (say CPU0 is suspending)
[CPU0] SMMUEN = 0 ==> SMMU stops accessing HW structures (ABORT NOT set)
HW structures not accessed means no TLB / CFG
cache accesses as well according to the spec.
[CPU1] ==> PTE update => Invalidate => Succeeds (although SMMUEN = 0)
[CPU0] GBPA.Abort set ==> Txns are blocked
[CPU2] => PTE update => Invalidate => Succeeds [Txns blocked + SMMUEN=0]
[CPU0] ==> SET STOP_FLAG ==> Elision begins
[CPU3] ==> PTE update ==> Invalidation ==> Elided [Txns blocked + SMMUEN=0]
Hence, the races in the suspend sequence are handled correctly.
2. RESUME (say CPU0 is resuming)
[CPU1] ==> Update PTE ==> Invalidate ==> Elided [Txns blocked + SMMUEN=0]
[CPU0] ==> Clear STOP_FLAGs [Txns still blocked + SMMUEN=0]
[CPU2] ==> Update PTE ==> Invalidate ==> Succeeds [Txns blocked + SMMUEN=0]
[CPU0] ==> Invalidate all TLB ==> Succeeds [Txns still blocked + SMMUEN=0]
[CPU0] ==> Invalidate all CFG ==> Succeeds [Txns still blocked + SMMUEN=0]
[CPU2] ==> Update PTE ==> Invalidate ==> Succeeds [Txns still blocked + SMMUEN=0]
[CPU0] ==> Set SMMUEN = 1 [SMMU can now access in memory structures]
However, the TLBs and CFG caches are clean because everything
until this point couldn't have cached anything anyway.
Hence, right after clearing the STOP_FLAG, we're taking in invalidations
as normal in the resume, much before the real caching can begin.
Thus, by resuming invalidations before SMMUEN=1, we guarantee a
consistent state before the very first translation is performed.
Apart from this, I guess I'll drop the can_elide check from all
invalidation paths.
Does that sound fine?
> Actually, now that I think of it: We could just piggy pack on the
> existing smp_mb() in arm_smmu_domain_inv_range(). For your
> arm_smmu_cmdq_can_elide() to work correctly, though, you would need to
> move it to *after* the smp_mb() call. This being said, I would prefer
> to remove arm_smmu_cmdq_can_elide() as I wrote on the other thread.
> If we do take advantage of the existing smp_mb() in
> arm_smmu_domain_inv_range(), then we should probably update that
> comment to state that the runtime PM implementation now also depends
> on it.
>
> >
> > Adding a dma_mb() to the elision path would be redundant given the
> > SMMU can't access any structures and the resume barrier. We'd be
> > needlessly injecting dma_mbs when no entity is actually accessing those
> > structures while the STOP_FLAG is set.
> > >
> > > I have the same concerns with arm_smmu_cmdq_can_elide(): That
> > > READ_ONCE in arm_smmu_cmdq_can_elide() provides no guarantees in
> > > regards to ordering relative to PTE writes.
> > >
> >
> > The same as above, No structures are accessed during SMMUEN=0 (spec) and
> > during resume before setting SMMUEN=1, we do a full smp_mb() to ensure
> > all concurrent PTE writes are acquired in our resume thread before we
> > enable SMMUEN=1
>
> I think the definition of "all concurrent PTE writes" is a bit vague.
> I don't think the architecture allows you to wait for writes performed
> by other CPUs to be observable by all other agents. The only thing you
> can do is to ensure that other agents can observe that the STOP_FLAG
> has been cleared *before* SMMUEN is set. However, this is already
> achieved by the existing dma_wmb() in arm_smmu_cmdq_issue_cmdlist().
> Hence, the extra smp_mb() is not required.
>
Right, I meant that the smp_mb was needed for the STOP_FLAG is visible to
other CPUs performing PTE writes.. but I agree that the first CFGI
invalidation's dma_wmb() would ensure the STOP_FLAG is visible to all
other CPUs, I'll drop this and add a comment explaining this.
Thanks,
Praan
^ permalink raw reply
* Re: [PATCH v3 03/17] clocksource/drivers/arm_arch_timer: Default to EL2 virtual timer when running VHE
From: Marek Szyprowski @ 2026-06-09 10:03 UTC (permalink / raw)
To: Marc Zyngier, linux-arm-kernel, linux-acpi, linux-kernel,
devicetree
Cc: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Catalin Marinas,
Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
Andreas Färber, Yu-Chun Lin [林祐君],
Heiko Stuebner, Shawn Lin, Orson Zhai, Baolin Wang, Michal Simek
In-Reply-To: <20260523140242.586031-4-maz@kernel.org>
Dear All,
On 23.05.2026 16:02, Marc Zyngier wrote:
> When running with at EL2 with VHE enabled, the architecture provides
> two EL2 timer/counters, dubbed physical and virtual. Apart from their
> names, they are strictly identical.
>
> However, they don't get virtualised the same way, specially when
> it comes to adding arbitrary offsets to the timers. When running as
> a guest, the host CNTVOFF_EL2 does apply to the guest's view of
> CNTHV*_El2. This is not true for CNTPOFF_EL2 and CNTHP*_EL2, as
> the architecture is broken past the first level of virtualisation
> (it lacks some essential mechanisms to be usable, despite what
> the ARM ARM pretends).
>
> This means that when running as a L2 guest hypervisor, using the
> physical timer results in traps to L0, which are then forwarded to
> L1 in order to emulate the offset, leading to even worse performance
> due to massive trap amplification (the combination of register and
> ERET trapping is absolutely lethal).
>
> Switch the arch timer code to using the virtual timer when running
> in VHE by default, only using the physical timer if the interrupt
> is not correctly described in the firmware tables (which seems
> to be an unfortunately common case). This comes as no impact on
> bare-metal, and slightly improves the situation in the virtualised
> case.
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
This patch landed recently in linux-next as commit d87773de9efe
("clocksource/drivers/arm_arch_timer: Default to EL2 virtual timer when
running VHE"). In my tests I found that it breaks booting of RaspberryPi5
board. Reverting it on top of linux-next fixes the issue. Here is a boot
log:
Booting Linux on physical CPU 0x0000000000 [0x414fd0b1]
Linux version 7.0.0+ (m.szyprowski@AMDC4653) (aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #16769 SMP PREEMPT Tue Jun 9 11:57:24 CEST 2026
KASLR enabled
Machine model: Raspberry Pi 5 Model B Rev 1.0
earlycon: pl11 at MMIO 0x000000107d001000 (options '115200n8')
printk: legacy bootconsole [pl11] enabled
Reserved memory: created CMA memory pool at 0x000000003bc00000, size 64 MiB
OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
OF: reserved mem: 0x000000003bc00000..0x000000003fbfffff (65536 KiB) map reusable linux,cma
OF: reserved mem: 0x0000000000000000..0x000000000007ffff (512 KiB) nomap non-reusable atf@0
NUMA: Faking a node at [mem 0x0000000000000000-0x00000001ffffffff]
NODE_DATA(0) allocated [mem 0x1fefe0480-0x1fefe313f]
psci: probing for conduit method from DT.
psci: PSCIv1.1 detected in firmware.
psci: Using standard PSCI v0.2 function IDs
psci: MIGRATE_INFO_TYPE not supported.
psci: SMC Calling Convention v1.2
Zone ranges:
DMA [mem 0x0000000000000000-0x00000000ffffffff]
DMA32 empty
Normal [mem 0x0000000100000000-0x00000001ffffffff]
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000000000000-0x000000000007ffff]
node 0: [mem 0x0000000000080000-0x000000003fbfffff]
node 0: [mem 0x0000000040000000-0x00000001ffffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x00000001ffffffff]
On node 0, zone DMA: 1024 pages in unavailable ranges
percpu: Embedded 36 pages/cpu s109456 r8192 d29808 u147456
Detected PIPT I-cache on CPU0
CPU features: detected: Virtualization Host Extensions
CPU features: detected: Spectre-v4
CPU features: detected: Spectre-BHB
CPU features: kernel page table isolation forced ON by KASLR
CPU features: detected: Kernel page table isolation (KPTI)
CPU features: detected: SSBS not fully self-synchronizing
alternatives: applying boot alternatives
Kernel command line: console=ttyAMA10,115200n8 earlycon root=PARTUUID=11111111-03 rw clk_ignore_unused rootdelay=2 retain_initrd
printk: log buffer data + meta data: 131072 + 458752 = 589824 bytes
Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
software IO TLB: area num 4.
software IO TLB: mapped [mem 0x00000000fbfff000-0x00000000fffff000] (64MB)
Fallback order for Node 0: 0
Built 1 zonelists, mobility grouping on. Total pages: 2096128
Policy zone: Normal
mem auto-init: stack:off, heap alloc:off, heap free:off
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
Running RCU self tests
Running RCU synchronous self tests
rcu: Preemptible hierarchical RCU implementation.
rcu: RCU event tracing is enabled.
rcu: RCU lockdep checking is enabled.
rcu: RCU restricting CPUs from NR_CPUS=512 to nr_cpu_ids=4.
Trampoline variant of Tasks RCU enabled.
Tracing variant of Tasks RCU enabled.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
Running RCU synchronous self tests
RCU Tasks: Setting shift to 2 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=4.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
Root IRQ handler: gic_handle_irq
GIC: Using split EOI/Deactivate mode
rcu: srcu_init: Setting srcu_struct sizes based on contention.
arch_timer: cp15 timer running at 54.00MHz (hyp-virt).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xc743ce346, max_idle_ns: 440795203123 ns
sched_clock: 56 bits at 54MHz, resolution 18ns, wraps every 4398046511102ns
Console: colour dummy device 80x25
Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
... MAX_LOCKDEP_SUBCLASSES: 8
... MAX_LOCK_DEPTH: 48
... MAX_LOCKDEP_KEYS: 8192
... CLASSHASH_SIZE: 4096
... MAX_LOCKDEP_ENTRIES: 32768
... MAX_LOCKDEP_CHAINS: 65536
... CHAINHASH_SIZE: 32768
memory used by lock dependency info: 6429 kB
memory used for stack traces: 4224 kB
per task-struct memory footprint: 1920 bytes
Calibrating delay loop (skipped), value calculated using timer frequency.. 108.00 BogoMIPS (lpj=216000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
VFS: Finished mounting rootfs on nullfs
Running RCU synchronous self tests
Running RCU synchronous self tests
(booting freezes)
> ---
> drivers/clocksource/arm_arch_timer.c | 55 +++++++++++++++++-----------
> 1 file changed, 33 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 90aeff44a2764..4adf756423de9 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -688,6 +688,7 @@ static void __arch_timer_setup(struct clock_event_device *clk)
> clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
> switch (arch_timer_uses_ppi) {
> case ARCH_TIMER_VIRT_PPI:
> + case ARCH_TIMER_HYP_VIRT_PPI:
> clk->set_state_shutdown = arch_timer_shutdown_virt;
> clk->set_state_oneshot_stopped = arch_timer_shutdown_virt;
> sne = erratum_handler(set_next_event_virt);
> @@ -879,7 +880,7 @@ static void __init arch_timer_banner(void)
> pr_info("cp15 timer running at %lu.%02luMHz (%s).\n",
> (unsigned long)arch_timer_rate / 1000000,
> (unsigned long)(arch_timer_rate / 10000) % 100,
> - (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) ? "virt" : "phys");
> + arch_timer_ppi_names[arch_timer_uses_ppi]);
> }
>
> u32 arch_timer_get_rate(void)
> @@ -912,7 +913,8 @@ static void __init arch_counter_register(void)
> int width;
>
> if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) ||
> - arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) {
> + arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI ||
> + arch_timer_uses_ppi == ARCH_TIMER_HYP_VIRT_PPI) {
> if (arch_timer_counter_has_wa()) {
> rd = arch_counter_get_cntvct_stable;
> scr = raw_counter_get_cntvct_stable;
> @@ -1023,6 +1025,7 @@ static int __init arch_timer_register(void)
> ppi = arch_timer_ppi[arch_timer_uses_ppi];
> switch (arch_timer_uses_ppi) {
> case ARCH_TIMER_VIRT_PPI:
> + case ARCH_TIMER_HYP_VIRT_PPI:
> err = request_percpu_irq(ppi, arch_timer_handler_virt,
> "arch_timer", arch_timer_evt);
> break;
> @@ -1090,25 +1093,34 @@ static int __init arch_timer_common_init(void)
> /**
> * arch_timer_select_ppi() - Select suitable PPI for the current system.
> *
> - * If HYP mode is available, we know that the physical timer
> - * has been configured to be accessible from PL1. Use it, so
> - * that a guest can use the virtual timer instead.
> + * On AArch32, if HYP mode is available, we know that the physical
> + * timer has been configured to be accessible from PL1. Use it, so
> + * that a guest can use the virtual timer instead (though KVM host
> + * support has long been removed).
> *
> - * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
> - * accesses to CNTP_*_EL1 registers are silently redirected to
> - * their CNTHP_*_EL2 counterparts, and use a different PPI
> - * number.
> + * On ARMv8.1 with FEAT_VHE, the kernel runs in EL2. Accesses to
> + * CNTV_*_EL1 registers are silently redirected to their CNTHV_*_EL2
> + * counterparts, and the timer uses a different PPI number. Similar
> + * thing happen when using the EL2 physical timer. Note that a bunch
> + * of DTs out there omit the virtual EL2 timer, so fallback gracefully
> + * on the physical timer.
> + *
> + * Without VHE, if no interrupt provided for virtual timer, we'll have
> + * to stick to the physical timer. It'd better be accessible...
> *
> - * If no interrupt provided for virtual timer, we'll have to
> - * stick to the physical timer. It'd better be accessible...
> * For arm64 we never use the secure interrupt.
> *
> * Return: a suitable PPI type for the current system.
> */
> static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void)
> {
> - if (is_kernel_in_hyp_mode())
> + if (is_kernel_in_hyp_mode()) {
> + if (arch_timer_ppi[ARCH_TIMER_HYP_VIRT_PPI])
> + return ARCH_TIMER_HYP_VIRT_PPI;
> +
> + pr_warn_once(FW_BUG "VHE-capable CPU without EL2 virtual timer interrupt\n");
> return ARCH_TIMER_HYP_PPI;
> + }
>
> if (!is_hyp_mode_available() && arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
> return ARCH_TIMER_VIRT_PPI;
> @@ -1200,14 +1212,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
> if (ret)
> return ret;
>
> - arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
> - acpi_gtdt_map_ppi(ARCH_TIMER_PHYS_NONSECURE_PPI);
> -
> - arch_timer_ppi[ARCH_TIMER_VIRT_PPI] =
> - acpi_gtdt_map_ppi(ARCH_TIMER_VIRT_PPI);
> -
> - arch_timer_ppi[ARCH_TIMER_HYP_PPI] =
> - acpi_gtdt_map_ppi(ARCH_TIMER_HYP_PPI);
> + /* The GTDT parser can't be bothered with the secure timer */
> + for (int i = ARCH_TIMER_PHYS_NONSECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
> + arch_timer_ppi[i] = acpi_gtdt_map_ppi(i);
>
> arch_timer_populate_kvm_info();
>
> @@ -1253,10 +1260,14 @@ int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *ts,
> if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY))
> return -EOPNOTSUPP;
>
> - if (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI)
> + switch (arch_timer_uses_ppi) {
> + case ARCH_TIMER_VIRT_PPI:
> + case ARCH_TIMER_HYP_VIRT_PPI:
> ptp_counter = KVM_PTP_VIRT_COUNTER;
> - else
> + break;
> + default:
> ptp_counter = KVM_PTP_PHYS_COUNTER;
> + }
>
> arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID,
> ptp_counter, &hvc_res);
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply
* Re: [PATCH v7 15/15] arm64: mm: Unmap kernel data/bss entirely from the linear map
From: Geert Uytterhoeven @ 2026-06-09 9:55 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Ard Biesheuvel, linux-arm-kernel, linux-kernel, will,
catalin.marinas, mark.rutland, Ard Biesheuvel, Ryan Roberts,
Anshuman Khandual, Kevin Brodsky, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
Jann Horn, linux-mm, linux-hardening, linuxppc-dev, linux-sh,
Linux-Renesas
In-Reply-To: <6a9c0f55-fe98-4063-864b-8f7e1f4fefd7@samsung.com>
On Tue, 9 Jun 2026 at 08:28, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> On 09.06.2026 08:22, Marek Szyprowski wrote:
> > On 29.05.2026 17:02, Ard Biesheuvel wrote:
> >> From: Ard Biesheuvel <ardb@kernel.org>
> >>
> >> The linear aliases of the kernel text and rodata are also mapped
> >> read-only in the linear map. Given that the contents of these regions
> >> are mostly identical to the version in the loadable image, mapping them
> >> read-only and leaving their contents visible is a reasonable hardening
> >> measure.
> >>
> >> Data and bss, however, are now also mapped read-only but the contents of
> >> these regions are more likely to contain data that we'd rather not leak.
> >> So let's unmap these entirely in the linear map when the kernel is
> >> running normally.
> >>
> >> When going into hibernation or waking up from it, these regions need to
> >> be mapped, so map the region initially, and toggle the valid bit so
> >> map/unmap the region as needed.
> >>
> >> Doing so is required because pages covering the kernel image are marked
> >> as PageReserved, and therefore disregarded for snapshotting by the
> >> hibernate logic unless they are mapped.
> >>
> >> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > This commit landed in yesterday's linux-next as commit 63e0b6a5b693
> > ("arm64: mm: Unmap kernel data/bss entirely from the linear map").
> > In my tests I found that it breaks booting of RaspberryPi3 and
> > RaspberryPi4 boards with the following kernel panic:
Seeing the same panic on R-Car H3 ES2.0 (Cortex A57/A53), but not
on R-Car V4M (Cortex A76).
> One more comment - reverting 63e0b6a5b693 and 53205d56212c (dependent
> change) on top of next-20260608 fixes this issue.
Confirmed, too.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 2/2] soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers
From: geoffrey @ 2026-06-09 9:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
linux-samsung-soc, linux-kernel, Weigang He
In-Reply-To: <20260609095224.1706036-1-geoffreyhe2@gmail.com>
From: Weigang He <geoffreyhe2@gmail.com>
With the of_node leak in exynos_get_pmu_regmap() now fixed, the remaining
reference handling is still awkward: exynos_get_pmu_regmap() obtains the
PMU node by passing NULL to exynos_get_pmu_regmap_by_phandle(), which then
treats its np argument as the PMU node directly.
Factor the common PMU-node lookup into a helper,
exynos_get_pmu_regmap_by_node(), which only borrows the node. Each public
function then owns and releases the node it acquired: the node from
of_find_matching_node() in exynos_get_pmu_regmap(), and the node from
of_parse_phandle() in exynos_get_pmu_regmap_by_phandle().
exynos_get_pmu_regmap_by_phandle() now rejects propname == NULL with
-EINVAL. Passing NULL was never a documented use of this interface, which
looks up a PMU node through a phandle property; the only in-tree user of
that form is exynos_get_pmu_regmap(), which no longer needs it. Document
the requirement in the kerneldoc.
No functional change for the supported callers.
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
---
drivers/soc/samsung/exynos-pmu.c | 57 ++++++++++++++++++--------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index a5da2741852b4..ab19ad265aeb1 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -157,6 +157,28 @@ static const struct mfd_cell exynos_pmu_devs[] = {
{ .name = "exynos-clkout", },
};
+/*
+ * Look up the regmap of an already-probed exynos-pmu device. The caller
+ * retains ownership of @pmu_np; this helper does not take a reference.
+ */
+static struct regmap *exynos_get_pmu_regmap_by_node(struct device_node *pmu_np)
+{
+ struct device *dev;
+
+ /*
+ * Determine if exynos-pmu device has probed and therefore regmap
+ * has been created and can be returned to the caller. Otherwise we
+ * return -EPROBE_DEFER.
+ */
+ dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver, pmu_np);
+ if (!dev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ put_device(dev);
+
+ return syscon_node_to_regmap(pmu_np);
+}
+
/**
* exynos_get_pmu_regmap() - Obtain pmureg regmap
*
@@ -174,7 +196,7 @@ struct regmap *exynos_get_pmu_regmap(void)
if (!np)
return ERR_PTR(-ENODEV);
- regmap = exynos_get_pmu_regmap_by_phandle(np, NULL);
+ regmap = exynos_get_pmu_regmap_by_node(np);
of_node_put(np);
return regmap;
@@ -184,44 +206,31 @@ EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
/**
* exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
* @np: Device node holding PMU phandle property
- * @propname: Name of property holding phandle value
+ * @propname: Name of property holding phandle value (must not be NULL)
*
* Find the pmureg regmap previously configured in probe() and return regmap
* pointer.
*
- * Return: A pointer to regmap if found or ERR_PTR error value.
+ * Return: A pointer to regmap on success or an ERR_PTR() error value;
+ * -EINVAL if @propname is NULL.
*/
struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
const char *propname)
{
struct device_node *pmu_np;
- struct device *dev;
+ struct regmap *regmap;
- if (propname)
- pmu_np = of_parse_phandle(np, propname, 0);
- else
- pmu_np = np;
+ if (!propname)
+ return ERR_PTR(-EINVAL);
+ pmu_np = of_parse_phandle(np, propname, 0);
if (!pmu_np)
return ERR_PTR(-ENODEV);
- /*
- * Determine if exynos-pmu device has probed and therefore regmap
- * has been created and can be returned to the caller. Otherwise we
- * return -EPROBE_DEFER.
- */
- dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
- (void *)pmu_np);
+ regmap = exynos_get_pmu_regmap_by_node(pmu_np);
+ of_node_put(pmu_np);
- if (propname)
- of_node_put(pmu_np);
-
- if (!dev)
- return ERR_PTR(-EPROBE_DEFER);
-
- put_device(dev);
-
- return syscon_node_to_regmap(pmu_np);
+ return regmap;
}
EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
--
2.43.0
^ permalink raw reply related
* [PATCH 0/2] soc: samsung: exynos-pmu: fix of_node leak and refactor regmap lookup
From: geoffrey @ 2026-06-09 9:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
linux-samsung-soc, linux-kernel, Weigang He
From: Weigang He <geoffreyhe2@gmail.com>
exynos_get_pmu_regmap() leaks the device_node reference taken by
of_find_matching_node(): it passes the node to
exynos_get_pmu_regmap_by_phandle(np, NULL), which with propname == NULL
uses the node directly and never drops the reference.
Patch 1 is the minimal fix: drop the reference in the function that
acquired it. It is small and safe to backport.
Patch 2 is a follow-up cleanup that factors the shared PMU-node lookup
into a helper so that each public function owns and releases only the
node it acquired, removing the need to pass NULL to the by-phandle
helper. It also makes exynos_get_pmu_regmap_by_phandle() reject
propname == NULL with -EINVAL (passing NULL was never a documented use
of that interface). It is a cleanup only and not needed for the fix.
The leak was found by the static analysis tool CodeQL. I do not have
Exynos hardware, so the series has been build-tested only (arm64);
runtime testing on real hardware would be appreciated.
Weigang He (2):
soc: samsung: exynos-pmu: fix of_node refcount leak in
exynos_get_pmu_regmap()
soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers
drivers/soc/samsung/exynos-pmu.c | 71 +++++++++++++++++++-------------
1 file changed, 43 insertions(+), 28 deletions(-)
base-commit: 0f61b1860cc3f52aef9036d7235ed1f017632193
--
2.43.0
^ permalink raw reply
* [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap()
From: geoffrey @ 2026-06-09 9:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
linux-samsung-soc, linux-kernel, Weigang He
In-Reply-To: <20260609095224.1706036-1-geoffreyhe2@gmail.com>
From: Weigang He <geoffreyhe2@gmail.com>
exynos_get_pmu_regmap() obtains a device_node via of_find_matching_node()
and passes it to exynos_get_pmu_regmap_by_phandle(np, NULL). With
propname == NULL the callee uses np directly and only drops a reference
when propname is set, so the reference taken by of_find_matching_node()
is leaked on every call -- including on each -EPROBE_DEFER retry of the
only in-tree caller, exynos_retention_init() in the Exynos pinctrl
driver.
Drop the reference in the function that acquired it.
Found by static analysis tool CodeQL.
Fixes: 76640b84bd7a ("soc: samsung: pmu: Provide global function to get PMU regmap")
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
---
drivers/soc/samsung/exynos-pmu.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index d58376c38179b..a5da2741852b4 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -167,11 +167,17 @@ static const struct mfd_cell exynos_pmu_devs[] = {
*/
struct regmap *exynos_get_pmu_regmap(void)
{
- struct device_node *np = of_find_matching_node(NULL,
- exynos_pmu_of_device_ids);
- if (np)
- return exynos_get_pmu_regmap_by_phandle(np, NULL);
- return ERR_PTR(-ENODEV);
+ struct device_node *np;
+ struct regmap *regmap;
+
+ np = of_find_matching_node(NULL, exynos_pmu_of_device_ids);
+ if (!np)
+ return ERR_PTR(-ENODEV);
+
+ regmap = exynos_get_pmu_regmap_by_phandle(np, NULL);
+ of_node_put(np);
+
+ return regmap;
}
EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
--
2.43.0
^ permalink raw reply related
* [PATCH v5 3/3] arm64: dts: imx8mp-var-dart: Add support for Variscite Sonata board
From: Stefano Radaelli @ 2026-06-09 9:51 UTC (permalink / raw)
To: linux-kernel, devicetree, imx, linux-arm-kernel
Cc: pierluigi.p, Stefano Radaelli, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, Daniel Baluta, Josua Mayer,
Dario Binacchi, Maud Spierings, Alexander Stein,
Ernest Van Hoecke, Francesco Dolcini, Hugo Villeneuve
In-Reply-To: <cover.1780998600.git.stefano.r@variscite.com>
From: Stefano Radaelli <stefano.r@variscite.com>
Add device tree support for the Variscite Sonata carrier board with the
DART-MX8M-PLUS system on module.
The Sonata board includes
- uSD Card support
- USB ports and OTG
- Additional Gigabit Ethernet interface
- Uart, SPI and I2C interfaces
- HDMI support
- GPIO Expanders
- RTC module
- TPM module
- CAN peripherals
Link: https://variscite.com/carrier-boards/sonata-board/
Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
---
v4->v5:
- Fix nodes order
v3->v4:
- Add snvs nodes
v2->v3:
-
v1->v2:
- Fixed model name
- Added new usdhc2 regulator pinctrl
- Adjusted irq edges
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../dts/freescale/imx8mp-var-dart-sonata.dts | 731 ++++++++++++++++++
2 files changed, 732 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx8mp-var-dart-sonata.dts
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 03988f0eae30..818e57f54475 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -448,6 +448,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-tx8p-ml81-moduline-display-106-av101hdt-a10.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-tx8p-ml81-moduline-display-106-av123z7m-n17.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-ultra-mach-sbc.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-var-dart-sonata.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-var-som-symphony.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw71xx-2x.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw72xx-2x.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-var-dart-sonata.dts b/arch/arm64/boot/dts/freescale/imx8mp-var-dart-sonata.dts
new file mode 100644
index 000000000000..283864b2d4b3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-var-dart-sonata.dts
@@ -0,0 +1,731 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Variscite Sonata carrier board for DART-MX8M-PLUS
+ *
+ * Link: https://variscite.com/carrier-boards/sonata-board/
+ *
+ * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+#include "imx8mp-var-dart.dtsi"
+
+/ {
+ model = "Variscite DART-MX8M-PLUS on Sonata-Board";
+ compatible = "variscite,var-dart-mx8mp-sonata",
+ "variscite,var-dart-mx8mp",
+ "fsl,imx8mp";
+
+ chosen {
+ stdout-path = &uart1;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ button-home {
+ label = "Home";
+ linux,code = <KEY_HOME>;
+ gpios = <&pca6408_1 4 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ button-up {
+ label = "Up";
+ linux,code = <KEY_UP>;
+ gpios = <&pca6408_1 5 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ button-down {
+ label = "Down";
+ linux,code = <KEY_DOWN>;
+ gpios = <&pca6408_1 6 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ button-back {
+ label = "Back";
+ linux,code = <KEY_BACK>;
+ gpios = <&pca6408_1 7 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-emmc {
+ gpios = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+ label = "eMMC";
+ linux,default-trigger = "mmc2";
+ };
+ };
+
+ native-hdmi-connector {
+ compatible = "hdmi-connector";
+ label = "HDMI OUT";
+ type = "a";
+
+ port {
+ hdmi_in: endpoint {
+ remote-endpoint = <&hdmi_tx_out>;
+ };
+ };
+ };
+
+ clk40m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <40000000>;
+ clock-output-names = "can_osc";
+ };
+
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ reg_usdhc2_vmmc: regulator-vmmc-usdhc2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_vmmc_usdhc2>;
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ startup-delay-us = <100>;
+ off-on-delay-us = <12000>;
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx-audio-hdmi";
+ model = "audio-hdmi";
+ audio-cpu = <&aud2htx>;
+ hdmi-out;
+ };
+
+ sound-xcvr {
+ compatible = "fsl,imx-audio-card";
+ model = "imx-audio-xcvr";
+
+ pri-dai-link {
+ link-name = "XCVR PCM";
+
+ cpu {
+ sound-dai = <&xcvr>;
+ };
+ };
+ };
+};
+
+&aud2htx {
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>,
+ <&gpio1 12 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ ads7846: touchscreen@0 {
+ compatible = "ti,ads7846";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_restouch>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+ spi-max-frequency = <1500000>;
+ pendown-gpio = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ ti,x-min = /bits/ 16 <125>;
+ ti,x-max = /bits/ 16 <4008>;
+ ti,y-min = /bits/ 16 <282>;
+ ti,y-max = /bits/ 16 <3864>;
+ ti,x-plate-ohms = /bits/ 16 <180>;
+ ti,pressure-max = /bits/ 16 <255>;
+ ti,debounce-max = /bits/ 16 <10>;
+ ti,debounce-tol = /bits/ 16 <3>;
+ ti,debounce-rep = /bits/ 16 <1>;
+ ti,settle-delay-usec = /bits/ 16 <150>;
+ ti,keep-vref-on;
+ wakeup-source;
+ };
+
+ can0: can@1 {
+ compatible = "microchip,mcp251xfd";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+ microchip,rx-int-gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+ clocks = <&clk40m>;
+ spi-max-frequency = <20000000>;
+ };
+};
+
+&eqos {
+ mdio {
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ reset-gpios = <&pca6408_2 0 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <20000>;
+ vddio-supply = <®_phy_vddio>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ linux,default-trigger = "netdev";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ linux,default-trigger = "netdev";
+ };
+ };
+ };
+ };
+};
+
+ðphy0 {
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_LAN;
+ linux,default-trigger = "netdev";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ linux,default-trigger = "netdev";
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ /*
+ * The required RGMII TX and RX 2ns delays are implemented directly
+ * in hardware via passive delay elements on the SOM PCB.
+ * No delay configuration is needed in software via PHY driver.
+ */
+ phy-mode = "rgmii";
+ phy-handle = <ðphy1>;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "okay";
+};
+
+&hdmi_pai {
+ status = "okay";
+};
+
+&hdmi_pvi {
+ status = "okay";
+};
+
+&hdmi_tx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ hdmi_tx_out: endpoint {
+ remote-endpoint = <&hdmi_in>;
+ };
+ };
+ };
+};
+
+&hdmi_tx_phy {
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_gpio>;
+ scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ pca9534: gpio@22 {
+ compatible = "nxp,pca9534";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ eth10g-en-hog {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "eth10g_sel";
+ };
+
+ pcie2-en-hog {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "pcie2_sel";
+ };
+
+ /* RGB_SEL */
+ lvds-brg-enable-hog {
+ gpio-hog;
+ gpios = <7 GPIO_ACTIVE_HIGH>;
+ output-low;
+ line-name = "rgb_sel";
+ };
+ };
+
+ /* Capacitive touch controller */
+ ft5x06_ts: touchscreen@38 {
+ compatible = "edt,edt-ft5206";
+ reg = <0x38>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_captouch>;
+ reset-gpios = <&pca6408_2 4 GPIO_ACTIVE_LOW>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <480>;
+ touchscreen-inverted-x;
+ touchscreen-inverted-y;
+ wakeup-source;
+ };
+
+ typec@3d {
+ compatible = "nxp,ptn5150";
+ reg = <0x3d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_extcon>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+
+ port {
+ typec_dr_sw: endpoint {
+ remote-endpoint = <&usb3_drd_sw>;
+ };
+ };
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rtc>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+ wakeup-source;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_gpio>;
+ scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_gpio>;
+ scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ pca6408_1: gpio@20 {
+ compatible = "nxp,pcal6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pca6408>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pca6408_2: gpio@21 {
+ compatible = "nxp,pcal6408";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ st33ktpm2xi2c: tpm@2e {
+ compatible = "st,st33ktpm2xi2c", "tcg,tpm-tis-i2c";
+ reg = <0x2e>;
+ label = "tpm";
+ reset-gpios = <&pca9534 0 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&lcdif3 {
+ status = "okay";
+};
+
+&pcie {
+ reset-gpios = <&pca6408_2 3 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcie_phy {
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ clocks = <&pcie0_refclk>;
+ clock-names = "ref";
+ status = "okay";
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+&snvs_rtc {
+ status = "disabled";
+};
+
+/* Console */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* Header */
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+/* Header */
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usb3_0 {
+ status = "okay";
+};
+
+&usb3_1 {
+ status = "okay";
+};
+
+&usb_dwc3_0 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ status = "okay";
+
+ port {
+ usb3_drd_sw: endpoint {
+ remote-endpoint = <&typec_dr_sw>;
+ };
+ };
+};
+
+&usb_dwc3_1 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb3_phy0 {
+ fsl,phy-tx-vref-tune-percent = <122>;
+ fsl,phy-tx-preemp-amp-tune-microamp = <1800>;
+ fsl,phy-tx-vboost-level-microvolt = <1156>;
+ fsl,phy-comp-dis-tune-percent = <115>;
+ fsl,phy-pcs-tx-deemph-3p5db-attenuation-db = <33>;
+ fsl,phy-pcs-tx-swing-full-percent = <100>;
+ status = "okay";
+};
+
+&usb3_phy1 {
+ fsl,phy-tx-preemp-amp-tune-microamp = <1800>;
+ fsl,phy-tx-vref-tune-percent = <116>;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <®_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&xcvr {
+ #sound-dai-cells = <0>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_can: cangrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x1c6
+ MX8MP_IOMUXC_SPDIF_RX__GPIO5_IO04 0x16
+ >;
+ };
+
+ pinctrl_captouch: captouchgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x16
+ >;
+ };
+
+ pinctrl_ecspi1: ecspi1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK 0x12
+ MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI 0x12
+ MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO 0x12
+ MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x12
+ MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x12
+ >;
+ };
+
+ pinctrl_extcon: extcongrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x10
+ >;
+ };
+
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x90
+ MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x90
+ MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x90
+ MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x1d0
+ MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x90
+ MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x90
+ MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x00
+ MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x00
+ MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x00
+ MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x00
+ MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x00
+ MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x00
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_RXC__CAN1_TX 0x154
+ MX8MP_IOMUXC_SAI2_TXC__CAN1_RX 0x154
+ >;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI2_MCLK__CAN2_RX 0x154
+ MX8MP_IOMUXC_SAI2_TXD0__CAN2_TX 0x154
+ >;
+ };
+
+ pinctrl_gpio_leds: ledgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0xc6
+ >;
+ };
+
+ pinctrl_hdmi: hdmigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c2
+ MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c2
+ MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x10
+ MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x10
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c2_gpio: i2c2gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1c2
+ MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1c2
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c3_gpio: i2c3gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C3_SCL__GPIO5_IO18 0x1c2
+ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x1c2
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c4_gpio: i2c4gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C4_SCL__GPIO5_IO20 0x1c2
+ MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21 0x1c2
+ >;
+ };
+
+ pinctrl_pca6408: pca6408grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x1c6
+ >;
+ };
+
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO01__PWM1_OUT 0x116
+ >;
+ };
+
+ pinctrl_restouch: restouchgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0xc0
+ >;
+ };
+
+ pinctrl_rtc: rtcgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15 0x1c0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x40
+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x40
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x40
+ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x40
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x40
+ MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x40
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d0
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x194
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d4
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x196
+ MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD 0x1d6
+ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6
+ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6
+ MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6
+ MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
+ >;
+ };
+
+ pinctrl_vmmc_usdhc2: regvmmc-usdhc2grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2-gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4
+ >;
+ };
+};
--
2.47.3
^ permalink raw reply related
* [PATCH v5 2/3] arm64: dts: freescale: Add support for Variscite DART-MX8M-PLUS
From: Stefano Radaelli @ 2026-06-09 9:51 UTC (permalink / raw)
To: linux-kernel, devicetree, imx, linux-arm-kernel
Cc: pierluigi.p, Stefano Radaelli, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, Daniel Baluta, Josua Mayer,
Dario Binacchi, Maud Spierings, Alexander Stein,
Ernest Van Hoecke, Francesco Dolcini, Hugo Villeneuve
In-Reply-To: <cover.1780998600.git.stefano.r@variscite.com>
From: Stefano Radaelli <stefano.r@variscite.com>
Add device tree support for the Variscite DART-MX8MP system on module.
This SOM is designed to be used with various carrier boards.
The module includes:
- NXP i.MX8M Plus MPU processor
- Up to 8GB of LPDDR4 memory
- Up to 128GB of eMMC storage memory
- Integrated 10/100/1000 Mbps Ethernet Transceiver
- Codec audio WM8904
- WIFI6 dual-band 802.11ax/ac/a/b/g/n with optional 802.15.4 and Bluetooth
Only SOM-specific peripherals are enabled by default. Carrier board
specific interfaces are left disabled to be enabled in the respective
carrier board device trees.
Link: https://variscite.com/system-on-module-som/i-mx-8/i-mx-8m-plus/dart-mx8m-plus/
Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
---
v4->v5:
-
v3->v4:
-
v2->v3:
- Fixed wrong som eth phy address
v1->v2:
- Fixed wrong sai peripheral reference
- Fixed wrong eqos pinctrl gpio
.../boot/dts/freescale/imx8mp-var-dart.dtsi | 476 ++++++++++++++++++
1 file changed, 476 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx8mp-var-dart.dtsi
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-var-dart.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-var-dart.dtsi
new file mode 100644
index 000000000000..a647a2e0ab94
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-var-dart.dtsi
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Common dtsi for Variscite DART-MX8M-PLUS
+ *
+ * Link: https://variscite.com/system-on-module-som/i-mx-8/i-mx-8m-plus/dart-mx8m-plus/
+ *
+ * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/
+ *
+ */
+
+/dts-v1/;
+
+#include "imx8mp.dtsi"
+
+/ {
+ model = "Variscite DART-MX8M-PLUS Module";
+ compatible = "variscite,var-dart-mx8mp", "fsl,imx8mp";
+
+ reg_audio_supply: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "wm8904-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_phy_vddio: regulator-phy-vddio {
+ compatible = "regulator-fixed";
+ regulator-name = "vddio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ sound-wm8904 {
+ compatible = "simple-audio-card";
+ simple-audio-card,bitclock-master = <&codec_dai>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&codec_dai>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,name = "wm8904-audio";
+ simple-audio-card,routing =
+ "Headphone Jack", "HPOUTL",
+ "Headphone Jack", "HPOUTR",
+ "IN2L", "Line In Jack",
+ "IN2R", "Line In Jack",
+ "IN1L", "Microphone Jack",
+ "IN1R", "Microphone Jack";
+ simple-audio-card,widgets =
+ "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack",
+ "Line", "Line In Jack";
+
+ codec_dai: simple-audio-card,codec {
+ sound-dai = <&wm8904>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&sai3>;
+ };
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <10000>;
+ reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>, /* WIFI_RESET */
+ <&gpio2 8 GPIO_ACTIVE_LOW>; /* WIFI_PWR_EN */
+ };
+};
+
+&A53_0 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_1 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_2 {
+ cpu-supply = <&buck2>;
+};
+
+&A53_3 {
+ cpu-supply = <&buck2>;
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ /*
+ * The required RGMII TX and RX 2ns delays are implemented directly
+ * in hardware via passive delay elements on the SOM PCB.
+ * No delay configuration is needed in software via PHY driver.
+ */
+ phy-mode = "rgmii";
+ phy-handle = <ðphy0>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ reset-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <100000>;
+ vddio-supply = <®_phy_vddio>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ wm8904: audio-codec@1a {
+ compatible = "wlf,wm8904";
+ reg = <0x1a>;
+ #sound-dai-cells = <0>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>;
+ clock-names = "mclk";
+ AVDD-supply = <®_audio_supply>;
+ CPVDD-supply = <®_audio_supply>;
+ DBVDD-supply = <®_audio_supply>;
+ DCVDD-supply = <®_audio_supply>;
+ MICVDD-supply = <®_audio_supply>;
+ wlf,drc-cfg-names = "default", "peaklimiter", "tradition",
+ "soft", "music";
+ /*
+ * Config registers per name, respectively:
+ * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1
+ * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1
+ * KNEE_IP = -42, KNEE_OP = -3, HI_COMP = 0, LO_COMP = 1
+ * KNEE_IP = -45, KNEE_OP = -9, HI_COMP = 1/8, LO_COMP = 1
+ * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
+ */
+ wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,
+ /bits/ 16 <0x04af 0x324b 0x0010 0x0408>,
+ /bits/ 16 <0x04af 0x324b 0x0028 0x0704>,
+ /bits/ 16 <0x04af 0x324b 0x0018 0x078c>,
+ /bits/ 16 <0x04af 0x324b 0x0010 0x050e>;
+ /* GPIO1 = DMIC_CLK, don't touch others */
+ wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>;
+ };
+
+ pca9450: pmic@25 {
+ compatible = "nxp,pca9450c";
+ reg = <0x25>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pmic>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+ regulators {
+ buck1: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck2: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ nxp,dvs-run-voltage = <950000>;
+ nxp,dvs-standby-voltage = <850000>;
+ };
+
+ buck4: BUCK4 {
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5: BUCK5 {
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo5: LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+};
+
+&mu2 {
+ status = "okay";
+};
+
+&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <11536000>;
+ clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI3_IPG>,
+ <&clk IMX8MP_CLK_DUMMY>,
+ <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1>,
+ <&clk IMX8MP_CLK_DUMMY>,
+ <&clk IMX8MP_CLK_DUMMY>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ #sound-dai-cells = <0>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
+/* BT module */
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>, <&pinctrl_bt>;
+ assigned-clocks = <&clk IMX8MP_CLK_UART4>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth_iw61x: bluetooth {
+ compatible = "nxp,88w8987-bt";
+ };
+};
+
+/* WIFI */
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wifi>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_wifi>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_wifi>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ keep-power-in-suspend;
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_bt: btgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0xc0
+ MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0xc0
+ >;
+ };
+
+ pinctrl_eqos: eqosgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2
+ MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2
+ MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90
+ MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90
+ MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90
+ MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90
+ MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90
+ MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90
+ MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16
+ MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16
+ MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16
+ MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16
+ MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16
+ MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16
+ MX8MP_IOMUXC_SD2_WP__GPIO2_IO20 0x10
+ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11 0x150
+ >;
+ };
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2
+ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2
+ >;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1c2
+ MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1c2
+ >;
+ };
+
+ pinctrl_pmic: pmicgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03 0x1c0
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6
+ MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0xd6
+ MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0xd6
+ MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0xd6
+ MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0xd6
+ MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_SAI3_RX_SYNC 0xd6
+ MX8MP_IOMUXC_SAI3_RXC__AUDIOMIX_SAI3_RX_BCLK 0xd6
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_ECSPI2_SCLK__UART4_DCE_RX 0x140
+ MX8MP_IOMUXC_ECSPI2_MOSI__UART4_DCE_TX 0x140
+ MX8MP_IOMUXC_ECSPI2_MISO__UART4_DCE_CTS 0x140
+ MX8MP_IOMUXC_ECSPI2_SS0__UART4_DCE_RTS 0x140
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x194
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d4
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d4
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d4
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d4
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x196
+ MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d6
+ MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d6
+ MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d6
+ MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d6
+ MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d0
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d0
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d0
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d0
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d0
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d0
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d0
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d0
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d0
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x194
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d4
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d4
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d4
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d4
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d4
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d4
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d4
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d4
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d4
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x196
+ MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD 0x1d6
+ MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0 0x1d6
+ MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1 0x1d6
+ MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2 0x1d6
+ MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3 0x1d6
+ MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4 0x1d6
+ MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5 0x1d6
+ MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6 0x1d6
+ MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7 0x1d6
+ MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B 0xc6
+ >;
+ };
+
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0xc0
+ MX8MP_IOMUXC_SD1_DATA6__GPIO2_IO08 0xc0
+ >;
+ };
+};
--
2.47.3
^ permalink raw reply related
* [PATCH v5 1/3] dt-bindings: arm: fsl: add Variscite DART-MX8M PLUS Boards
From: Stefano Radaelli @ 2026-06-09 9:51 UTC (permalink / raw)
To: linux-kernel, devicetree, imx, linux-arm-kernel
Cc: pierluigi.p, Stefano Radaelli, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, Daniel Baluta, Josua Mayer,
Dario Binacchi, Maud Spierings, Alexander Stein,
Ernest Van Hoecke, Francesco Dolcini, Hugo Villeneuve,
Conor Dooley
In-Reply-To: <cover.1780998600.git.stefano.r@variscite.com>
From: Stefano Radaelli <stefano.r@variscite.com>
Add DT compatible strings for Variscite DART-MX8MP SoM and Variscite
development carrier Board.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
---
v4->v5:
-
v3->v4:
-
v2->v3:
-
v1->v2:
-
Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 86876311ec59..11629b9eafc5 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1310,6 +1310,12 @@ properties:
- const: tq,imx8mp-tqma8mpql # TQ-Systems GmbH i.MX8MP TQMa8MPQL SOM
- const: fsl,imx8mp
+ - description: Variscite DART-MX8M Plus based boards
+ items:
+ - const: variscite,var-dart-mx8mp-sonata # Variscite DART-MX8MP on Sonata Development Board
+ - const: variscite,var-dart-mx8mp # Variscite DART-MX8MP SOM
+ - const: fsl,imx8mp
+
- description: Variscite VAR-SOM-MX8M Plus based boards
items:
- const: variscite,var-som-mx8mp-symphony
--
2.47.3
^ permalink raw reply related
* [PATCH v5 0/3] Add support for Variscite DART-MX8M-PLUS and Sonata board
From: Stefano Radaelli @ 2026-06-09 9:51 UTC (permalink / raw)
To: linux-kernel, devicetree, imx, linux-arm-kernel
Cc: pierluigi.p, Stefano Radaelli, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, Daniel Baluta, Josua Mayer,
Dario Binacchi, Maud Spierings, Alexander Stein,
Ernest Van Hoecke, Francesco Dolcini, Hugo Villeneuve
This patch series adds support for the Variscite DART-MX8M-PLUS
system on module and the Sonata carrier board.
The series includes:
- SOM device tree with on-module peripherals
- Sonata carrier board device tree with board-specific features
The implementation follows the standard SOM + carrier board pattern
where the SOM dtsi contains only peripherals mounted on the module,
while carrier-specific interfaces are enabled in the board dts.
v4->v5:
- Fix nodes order
v3->v4:
- Add snvs nodes
v2->v3:
- Fixed wrong som eth phy address
v1->v2:
- Fixed wrong sai peripheral reference
- Fixed wrong eqos pinctrl gpio
- Fixed model name
- Added new usdhc2 regulator pinctrl
- Adjusted irq edges
Stefano Radaelli (3):
dt-bindings: arm: fsl: add Variscite DART-MX8M PLUS Boards
arm64: dts: freescale: Add support for Variscite DART-MX8M-PLUS
arm64: dts: imx8mp-var-dart: Add support for Variscite Sonata board
.../devicetree/bindings/arm/fsl.yaml | 6 +
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../dts/freescale/imx8mp-var-dart-sonata.dts | 731 ++++++++++++++++++
.../boot/dts/freescale/imx8mp-var-dart.dtsi | 476 ++++++++++++
4 files changed, 1214 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx8mp-var-dart-sonata.dts
create mode 100644 arch/arm64/boot/dts/freescale/imx8mp-var-dart.dtsi
base-commit: be580423d3f84b84a2f549df91e66bc4f54eda02
--
2.47.3
^ permalink raw reply
* Re: [PATCH 0/2] arm64: ftrace: support DIRECT_CALLS without CALL_OPS
From: Puranjay Mohan @ 2026-06-09 9:50 UTC (permalink / raw)
To: Jose Fernandez (Anthropic)
Cc: Steven Rostedt, Masami Hiramatsu, Mark Rutland, Catalin Marinas,
Will Deacon, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
Justin Stitt, linux-kernel, linux-trace-kernel, linux-arm-kernel,
llvm, bpf, Florent Revest, Xu Kuohai
In-Reply-To: <20260609-arm64-ftrace-direct-calls-v1-0-4a46f266697f@linux.dev>
On Tue, Jun 9, 2026 at 6:19 AM Jose Fernandez (Anthropic)
<jose.fernandez@linux.dev> wrote:
>
> On arm64, HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS is currently selected
> only when DYNAMIC_FTRACE_WITH_CALL_OPS is available. CALL_OPS, in
> turn, is mutually exclusive with kCFI: the pre-function NOPs it needs
> would change the offset of the pre-function type hash (see
> baaf553d3bc3 ("arm64: Implement HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS")),
> and the compiler support needed to reconcile the two does not exist
> yet.
>
> The result is that a CONFIG_CFI=y arm64 kernel has no
> ftrace direct calls at all, so register_fentry() fails with -ENOTSUPP
> and no BPF trampoline can attach: fentry/fexit, fmod_ret and BPF LSM
> programs are all unavailable. Deployments that want both kCFI
> hardening and BPF-based security monitoring currently have to give
> one of them up. systemd's bpf-restrict-fs feature hits this today:
> https://lore.kernel.org/all/20250610232418.GA3544567@ax162/
>
> CALL_OPS is an optimization for direct calls, not a dependency.
> In-BL-range trampolines are reached by a direct branch without
> consulting the ops pointer, and out-of-range trampolines already
> fall back to ftrace_caller, where the DIRECT_CALLS machinery
> (call_direct_funcs() storing the trampoline in ftrace_regs, the
> ftrace_caller tail-call) is gated on DIRECT_CALLS alone. s390 and
> loongarch ship HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS this way,
> without having CALL_OPS at all.
>
> Patch 1 prepares ftrace_modify_call() to build without CALL_OPS by
> widening its #ifdef and using the existing ftrace_rec_update_ops()
> wrapper (no functional change for current configurations). Patch 2
> drops the CALL_OPS requirement from the DIRECT_CALLS select.
>
> Configurations that keep CALL_OPS (clang !CFI, and GCC without
> CC_OPTIMIZE_FOR_SIZE) are unchanged. We verified this: in an arm64
> clang build, every object file is byte-identical before and after
> the series except ftrace.o itself, and its disassembly is identical.
> CFI builds (and GCC -Os builds) gain working direct calls, with
> out-of-range attachments taking the ftrace_caller dispatch path
> instead of the per-callsite fast path.
>
> We tested on a 6.18.y-based kernel and on this base with clang
> kCFI builds (CONFIG_CFI=y, enforcing) under qemu (TCG, and KVM on an
> arm64 host) and on GB200-based arm64 hardware: fentry/fexit, fmod_ret
> and BPF LSM programs load, attach and execute; the ftrace-direct
> sample modules (including both modify samples, exercising
> ftrace_modify_call()) run cleanly; no CFI violations observed. The
> fentry_test, fexit_test, fentry_fexit, fexit_sleep, fexit_stress,
> modify_return, tracing_struct, lsm and trampoline_count selftests and
> the ftrace direct-call selftests (test.d/direct) pass on the new
> configuration with results identical to a CALL_OPS kernel built from
> the same tree, and a broader test_progs sweep showed no differences
> attributable to this series. Without the series, all of the above
> fail at attach time with -ENOTSUPP.
>
> riscv has the same gap (its DIRECT_CALLS select also requires
> CALL_OPS, and its CALL_OPS is likewise !CFI); if this approach is
> acceptable for arm64 we can follow up there.
>
It looks correct to me and should work.
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
^ permalink raw reply
* [PATCH v4 2/2] i2c: imx-lpi2c: reset controller in probe stage
From: carlos.song @ 2026-06-09 9:51 UTC (permalink / raw)
To: aisheng.dong, andi.shyti, Frank.Li, s.hauer, kernel, festevam
Cc: linux-i2c, imx, linux-arm-kernel, linux-kernel, Carlos Song
In-Reply-To: <20260609095119.924029-1-carlos.song@oss.nxp.com>
From: Carlos Song <carlos.song@nxp.com>
Reset I2C controller in probe stage to avoid unexpected LPI2C controller
state left from previous stages and hang system boot.
Per the LPI2C reference manual, section 7.1.4 "Controller Control (MCR)"
and 7.1.20 Target Control (SCR), the RST bit (bit 1) description states:
"The reset takes effect immediately and remains asserted until negated
by software. There is no minimum delay required before clearing the
software reset."
Therefore, it is safe to write 0 to MCR and SCR immediately after
asserting the RST bit without any additional delay.
Signed-off-by: Carlos Song <carlos.song@nxp.com>
---
drivers/i2c/busses/i2c-imx-lpi2c.c | 33 ++++++++++++++++++++----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index fbb9c0b0a99c..93f263bf27b2 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -1510,17 +1510,12 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (ret)
lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ;
- ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
- pdev->name, lpi2c_imx);
- if (ret)
- return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq);
-
i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);
platform_set_drvdata(pdev, lpi2c_imx);
ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);
if (ret)
- goto free_irq;
+ return dev_err_probe(&pdev->dev, ret, "can't get LPI2C clock\n");
/*
* Lock the parent clock rate to avoid getting parent clock upon
@@ -1550,6 +1545,22 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
+ /*
+ * Reset all internal controller registers of both Master and Target
+ * to avoid effects of previous status.
+ */
+ writel(MCR_RST, lpi2c_imx->base + LPI2C_MCR);
+ writel(SCR_RST, lpi2c_imx->base + LPI2C_SCR);
+ writel(0, lpi2c_imx->base + LPI2C_MCR);
+ writel(0, lpi2c_imx->base + LPI2C_SCR);
+
+ ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
+ pdev->name, lpi2c_imx);
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq);
+ goto rpm_disable;
+ }
+
temp = readl(lpi2c_imx->base + LPI2C_PARAM);
lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
@@ -1558,19 +1569,19 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev);
/* Give it another chance if pinctrl used is not ready yet */
if (ret == -EPROBE_DEFER)
- goto rpm_disable;
+ goto free_irq;
/* Init DMA */
ret = lpi2c_dma_init(&pdev->dev, phy_addr);
if (ret) {
if (ret == -EPROBE_DEFER)
- goto rpm_disable;
+ goto free_irq;
dev_info(&pdev->dev, "use pio mode\n");
}
ret = i2c_add_adapter(&lpi2c_imx->adapter);
if (ret)
- goto rpm_disable;
+ goto free_irq;
pm_runtime_put_autosuspend(&pdev->dev);
@@ -1578,6 +1589,8 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
return 0;
+free_irq:
+ devm_free_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx);
rpm_disable:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@@ -1585,8 +1598,6 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
clk_disable:
clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks);
-free_irq:
- devm_free_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx);
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v4 1/2] i2c: imx-lpi2c: properly unwind resources on probe failure
From: carlos.song @ 2026-06-09 9:51 UTC (permalink / raw)
To: aisheng.dong, andi.shyti, Frank.Li, s.hauer, kernel, festevam
Cc: linux-i2c, imx, linux-arm-kernel, linux-kernel, Carlos Song
In-Reply-To: <20260609095119.924029-1-carlos.song@oss.nxp.com>
From: Carlos Song <carlos.song@nxp.com>
When probe fails after clk_bulk_prepare_enable() succeeds but before
runtime PM is initialized, the enabled clocks are never disabled.
Additionally, calling pm_runtime_put_sync() in the error path can
trigger the runtime suspend callback, which may attempt to disable
clocks that have not been fully set up, leading to potential issues
during error unwinding.
Introduce two new error labels: clk_disable to explicitly invoke
clk_bulk_disable_unprepare(), and free_irq to release the IRQ via
devm_free_irq(). Replace pm_runtime_put_sync() with the sequence of
pm_runtime_disable(), pm_runtime_set_suspended() and
pm_runtime_put_noidle() to bypass the runtime suspend callback during
error recovery. Update all goto targets so that each failure site
releases only the resources acquired up to that point.
Signed-off-by: Carlos Song <carlos.song@nxp.com>
---
drivers/i2c/busses/i2c-imx-lpi2c.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
index cd4da50c4dd9..fbb9c0b0a99c 100644
--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -1520,21 +1520,25 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks);
if (ret)
- return ret;
+ goto free_irq;
/*
* Lock the parent clock rate to avoid getting parent clock upon
* each transfer
*/
ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
- if (ret)
- return dev_err_probe(&pdev->dev, ret,
- "can't lock I2C peripheral clock rate\n");
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret,
+ "can't lock I2C peripheral clock rate\n");
+ goto clk_disable;
+ }
lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
- if (!lpi2c_imx->rate_per)
- return dev_err_probe(&pdev->dev, -EINVAL,
- "can't get I2C peripheral clock rate\n");
+ if (!lpi2c_imx->rate_per) {
+ ret = dev_err_probe(&pdev->dev, -EINVAL,
+ "can't get I2C peripheral clock rate\n");
+ goto clk_disable;
+ }
if (lpi2c_imx->hwdata->need_prepare_unprepare_clk)
pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_LONG_TIMEOUT_MS);
@@ -1576,8 +1580,13 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
rpm_disable:
pm_runtime_dont_use_autosuspend(&pdev->dev);
- pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+clk_disable:
+ clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks);
+free_irq:
+ devm_free_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx);
return ret;
}
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox