* Re: [PATCH v6 20/20] swiotlb: remove unused SWIOTLB_FORCE flag
From: Petr Tesarik @ 2026-06-09 13:44 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260604083959.1265923-21-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:59 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> SWIOTLB_FORCE has no remaining in-tree users. Forced bouncing is now
> controlled through the swiotlb=force command line option via
> swiotlb_force_bounce.
>
> Remove the unused flag and simplify the force_bounce initialization.
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> include/linux/swiotlb.h | 1 -
> kernel/dma/swiotlb.c | 3 +--
> 2 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 526f82e9da45..af88ca7182f4 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -15,7 +15,6 @@ struct page;
> struct scatterlist;
>
> #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */
> -#define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */
> #define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */
These constants are kernel-internal, so let's not leave a hole in the
bitmask... I mean, what about changing SWIOTLB_ANY to (1 << 1) after
you remove SWIOTLB_FORCE?
Other than that, LGTM.
I consider this whole series a big step towards saner handling of
encrypted/decrypted memory for DMA buffers. Thank you for your effort!
Petr T
>
> /*
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index e4bd8c9eaeda..81cc4928e949 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -400,8 +400,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
> if (swiotlb_force_disable)
> return;
>
> - io_tlb_default_mem.force_bounce =
> - swiotlb_force_bounce || (flags & SWIOTLB_FORCE);
> + io_tlb_default_mem.force_bounce = swiotlb_force_bounce;
>
> #ifdef CONFIG_SWIOTLB_DYNAMIC
> if (!remap)
^ permalink raw reply
* Re: [PATCH v6 01/20] s390: Expose protected virtualization through cc_platform_has()
From: Catalin Marinas @ 2026-06-09 13:44 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Halil Pasic,
Matthew Rosato, Jaehoon Kim
In-Reply-To: <20260604083959.1265923-2-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:40PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Protected virtualization guests use memory encryption, so advertise that to
> the rest of the kernel through cc_platform_has(CC_ATTR_MEM_ENCRYPT).
>
> s390 already forces DMA mappings to be unencrypted for protected
> virtualization guests through force_dma_unencrypted(). Add
> ARCH_HAS_CC_PLATFORM and provide the matching cc_platform_has()
> implementation
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
Nit: just drop the --- line if you did intend to cc those people.
Nothing wrong for them to end up in the commit log (proof that they've
been cc'ed if they did not reply ;)).
--
Catalin
^ permalink raw reply
* Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Catalin Marinas @ 2026-06-09 13:43 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260604083959.1265923-1-aneesh.kumar@kernel.org>
On Thu, Jun 04, 2026 at 02:09:39PM +0530, Aneesh Kumar K.V (Arm) wrote:
> This series propagates DMA_ATTR_CC_SHARED through the dma-direct,
> dma-pool, and swiotlb paths so that encrypted and decrypted DMA buffers
> are handled consistently.
>
> Today, the direct DMA path mostly relies on force_dma_unencrypted() for
> shared/decrypted buffer handling. This series consolidates the
> force_dma_unencrypted() checks in the top-level functions and ensures
> that the remaining DMA interfaces use DMA attributes to make the correct
> decisions.
Please check Sashiko's reports, it has some good points:
https://sashiko.dev/#/patchset/20260604083959.1265923-1-aneesh.kumar@kernel.org
I think the main one is the swiotlb_tbl_map_single() changes which break
AMD SME host support. There cc_platform_has(CC_ATTR_MEM_ENCRYPT) is true
but force_dma_unencrypted() is false. Normally you'd not end up on this
path but you can have swiotlb=force.
> Aneesh Kumar K.V (Arm) (20):
> s390: Expose protected virtualization through cc_platform_has()
> dma-direct: swiotlb: handle swiotlb alloc/free outside
> __dma_direct_alloc_pages
> dma-direct: use DMA_ATTR_CC_SHARED in alloc/free paths
> dma-pool: track decrypted atomic pools and select them via attrs
> dma: swiotlb: pass mapping attributes by reference
> dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED
> dma-mapping: make dma_pgprot() honor DMA_ATTR_CC_SHARED
> dma-direct: pass attrs to dma_capable() for DMA_ATTR_CC_SHARED checks
> dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED
> dma-direct: set decrypted flag for remapped DMA allocations
Patch 10 above...
> dma-direct: select DMA address encoding from DMA_ATTR_CC_SHARED
> dma-pool: fix page leak in atomic_pool_expand() cleanup
Patch 12...
> dma-direct: rename ret to cpu_addr in alloc helpers
> dma-direct: return struct page from dma_direct_alloc_from_pool()
> iommu/dma: Check atomic pool allocation result directly
and I think patches 14, 15 are independent fixes. Some of them even have
Fixes: tags and Cc: stable. Please move them to the beginning of the
series to avoid inadvertent dependencies and make them harder to
backport. It's also easier to follow the series without random fixes for
mainline in the middle.
> dma: swiotlb: free dynamic pools from process context
> dma: swiotlb: handle set_memory_decrypted() failures
> dma: free atomic pool pages by physical address
> swiotlb: Preserve allocation virtual address for dynamic pools
> swiotlb: remove unused SWIOTLB_FORCE flag
--
Catalin
^ permalink raw reply
* Re: [PATCH v6 19/20] swiotlb: Preserve allocation virtual address for dynamic pools
From: Petr Tesarik @ 2026-06-09 13:40 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-20-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:58 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> swiotlb_alloc_tlb() can allocate from the DMA atomic pool when a decrypted
> pool is needed from atomic context. With CONFIG_DMA_DIRECT_REMAP, the
> atomic pool is backed by remapped virtual addresses, which are not the same
> as the direct-map addresses returned by phys_to_virt().
>
> swiotlb_init_io_tlb_pool() currently reconstructs the pool virtual address
> from the physical start address. For atomic-pool backed allocations this
> stores the wrong address in pool->vaddr. Later, swiotlb_free_tlb() passes
> that address to dma_free_from_pool(), which will fail to recognize the
> chunk
>
> Pass the virtual address returned by the allocation path into
> swiotlb_init_io_tlb_pool(), and store that address in pool->vaddr. This
> keeps the pool free path using the same virtual address as the allocator.
>
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Hm, so the old code was broken; you may want to add:
Fixes: 79636caad361 ("swiotlb: if swiotlb is full, fall back to a transient memory pool")
And of course:
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Thank you!
Petr T
> ---
> kernel/dma/swiotlb.c | 32 +++++++++++++++++++-------------
> 1 file changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 14d834ca298b..e4bd8c9eaeda 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -302,9 +302,9 @@ void __init swiotlb_update_mem_attributes(void)
> }
>
> static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> - unsigned long nslabs, bool late_alloc, unsigned int nareas)
> + void *vaddr, unsigned long nslabs, bool late_alloc,
> + unsigned int nareas)
> {
> - void *vaddr = phys_to_virt(start);
> unsigned long bytes = nslabs << IO_TLB_SHIFT, i;
>
> mem->nslabs = nslabs;
> @@ -445,7 +445,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
> return;
> }
>
> - swiotlb_init_io_tlb_pool(mem, __pa(tlb), nslabs, false, nareas);
> + swiotlb_init_io_tlb_pool(mem, __pa(tlb), tlb, nslabs, false, nareas);
> add_mem_pool(&io_tlb_default_mem, mem);
>
> if (flags & SWIOTLB_VERBOSE)
> @@ -553,7 +553,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> }
> }
>
> - swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), nslabs, true,
> + swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), vstart, nslabs, true,
> nareas);
> add_mem_pool(&io_tlb_default_mem, mem);
>
> @@ -664,25 +664,26 @@ static struct page *alloc_dma_pages(gfp_t gfp, size_t bytes,
> * @phys_limit: Maximum allowed physical address of the buffer.
> * @attrs: DMA attributes for the allocation.
> * @gfp: GFP flags for the allocation.
> + * @vaddr: Receives the virtual address for the allocated buffer.
> *
> * Return: Allocated pages, or %NULL on allocation failure.
> */
> static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
> - u64 phys_limit, unsigned long attrs, gfp_t gfp)
> + u64 phys_limit, unsigned long attrs, gfp_t gfp, void **vaddr)
> {
> struct page *page;
>
> + *vaddr = NULL;
> +
> /*
> * Allocate from the atomic pools if memory is encrypted and
> * the allocation is atomic, because decrypting may block.
> */
> if (!gfpflags_allow_blocking(gfp) && (attrs & DMA_ATTR_CC_SHARED)) {
> - void *vaddr;
> -
> if (!IS_ENABLED(CONFIG_DMA_COHERENT_POOL))
> return NULL;
>
> - return dma_alloc_from_pool(dev, bytes, &vaddr, gfp,
> + return dma_alloc_from_pool(dev, bytes, vaddr, gfp,
> attrs, dma_coherent_ok);
> }
>
> @@ -705,6 +706,8 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
> return NULL;
> }
>
> + if (page)
> + *vaddr = phys_to_virt(page_to_phys(page));
> return page;
> }
>
> @@ -750,6 +753,7 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> {
> struct io_tlb_pool *pool;
> unsigned int slot_order;
> + void *tlb_vaddr;
> struct page *tlb;
> size_t pool_size;
> size_t tlb_size;
> @@ -767,7 +771,8 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> pool->unencrypted = !!(attrs & DMA_ATTR_CC_SHARED);
>
> tlb_size = nslabs << IO_TLB_SHIFT;
> - while (!(tlb = swiotlb_alloc_tlb(dev, tlb_size, phys_limit, attrs, gfp))) {
> + while (!(tlb = swiotlb_alloc_tlb(dev, tlb_size, phys_limit, attrs, gfp,
> + &tlb_vaddr))) {
> if (nslabs <= minslabs)
> goto error_tlb;
> nslabs = ALIGN(nslabs >> 1, IO_TLB_SEGSIZE);
> @@ -781,12 +786,12 @@ static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
> if (!pool->slots)
> goto error_slots;
>
> - swiotlb_init_io_tlb_pool(pool, page_to_phys(tlb), nslabs, true, nareas);
> + swiotlb_init_io_tlb_pool(pool, page_to_phys(tlb), tlb_vaddr, nslabs,
> + true, nareas);
> return pool;
>
> error_slots:
> - swiotlb_free_tlb(page_address(tlb), tlb_size,
> - !!(attrs & DMA_ATTR_CC_SHARED));
> + swiotlb_free_tlb(tlb_vaddr, tlb_size, !!(attrs & DMA_ATTR_CC_SHARED));
> error_tlb:
> kfree(pool);
> error:
> @@ -1995,7 +2000,8 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
> mem->unencrypted = false;
> }
>
> - swiotlb_init_io_tlb_pool(pool, rmem->base, nslabs,
> + swiotlb_init_io_tlb_pool(pool, rmem->base, phys_to_virt(rmem->base),
> + nslabs,
> false, nareas);
> mem->force_bounce = true;
> mem->for_alloc = true;
^ permalink raw reply
* [PATCH v2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap()
From: Weigang He @ 2026-06-09 13:33 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
linux-samsung-soc, linux-kernel, Weigang He
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 does not drop a
reference, 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.
Annotate np with the __free(device_node) cleanup attribute so the
reference is released when the function returns.
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>
---
v2:
- Use the __free(device_node) cleanup attribute instead of an explicit
of_node_put(), as suggested by Krzysztof Kozlowski.
- Drop the former patch 2/2 (regmap lookup helper refactor); with
__free() the leak is fixed in place and the refactor is no longer
needed.
v1: https://lore.kernel.org/linux-samsung-soc/ (<<FILL IN v1 Message-ID link>>)
drivers/soc/samsung/exynos-pmu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index d58376c38179b..265a095316079 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -167,11 +167,13 @@ 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 __free(device_node) =
+ of_find_matching_node(NULL, exynos_pmu_of_device_ids);
+
+ if (!np)
+ return ERR_PTR(-ENODEV);
+
+ return exynos_get_pmu_regmap_by_phandle(np, NULL);
}
EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
base-commit: 0f61b1860cc3f52aef9036d7235ed1f017632193
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 0/2] soc: aspeed: Add BMC and host driver for PCIe BMC device
From: Grégoire Layet @ 2026-06-09 13:34 UTC (permalink / raw)
To: Andrew Lunn
Cc: joel, andrew, jacky_chou, yh_chung, ninad, linux-aspeed,
linux-arm-kernel, linux-kernel
In-Reply-To: <63654bb5-c246-41c4-bb7e-5bfa23e59f2e@lunn.ch>
> From the replies i got the host can access anything on the LPC bus of the
> aspeed.
The PCI-to-LPC bridge only decodes some addresses.
In fact, only the following are accessible over PCIe :
- LPC Channel 4, which only supports the KCS protocol
- The 2 VUARTs
- SuperIO-style Mailbox
Regarding the KCS interface over the LPC channel 4,
the BMC driver in this series does not set this up.
It just needs to be activated in the DTS.
Then the host can just start the ipmi_si driver with the correct address.
This is the intended usage for IPMI management and is part of the normal
trust model of a BMC-managed system.
Here is a summary dump of the PCI BAR1 from the host.
The BAR0 is only used to expose a BMC DRAM region for shared memory access.
This v2 removed the memory mapping so BAR0 is not exposed to userspace.
The BAR1 is used for the PCI-to-LPC bridge.
Offset Size Contents
-------- -------- ------------------------------------
0x0000-0x00B7 184 B Blank (0xFF)
0x00B8-0x00BF 8 B SuperIO Index/Data port, mailbox config only
0x00C0-0x0E87 3528 B Blank (some no decode 0xFF and some reading 0x00)
0x0E88-0x0E8F 8 B LPC KCS4
0x0E90-0x0FDF 336 B Blank (0xFF)
0x0FE0-0x0FFF 32 B VUART1
0x1000-0x2FFFF 188 KiB Blank (some no decode 0xFF and some reading 0x00)
0x30000-0x3FFFF 64 KiB Inert region: 256 times repeating reset-default
values, not affected by mailbox activation,
not accessed by this driver
The datasheet doesn't explain what this is.
So, the host does not have arbitrary LPC bus access,
it can only access a small subset of it.
The relevant peripherals must be explicitly enabled the PCI bridge
to be activated on the BMC to be accessed over PCIe.
Only the specific interfaces listed above are exposed,
and each one must be enabled by the BMC.
The security implications are limited.
The host side attack surface is bounded by what the BMC chooses to expose.
> TPMs are often there, but does a BMC have a TPM?
The AST2600 chip doesn't have a TPM.
The Asus IPMI card doesn't have a TPM module either.
If a similar PCIe add-in IPMI card has a TPM module,
it will be accessible to the BMC via the LPC bus.
But this will not be bridged to BAR1 by default
as only the above-listed interfaces are exposed.
However, the host could access the TPM with some specific BMC side
configuration of the PCIe BMC Device (PBMC).
That would be a deliberate BMC side firmware decision or bug.
This driver doesn't expose a BMC TPM.
^ permalink raw reply
* Re: [PATCH v6 17/20] dma: swiotlb: handle set_memory_decrypted() failures
From: Petr Tesarik @ 2026-06-09 13:32 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-18-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:56 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> Check the return value when converting swiotlb pools between encrypted and
> decrypted mappings. If the default pool cannot be decrypted after early
> initialization, mark the pool fully used so it cannot satisfy future bounce
> allocations.
>
> For late initialization, return the `set_memory_decrypted()` failure. For
> restricted DMA pools, fail device initialization if the reserved pool
> cannot be decrypted.
>
> This prevents swiotlb from using pools whose encryption attributes do not
> match their metadata, and avoids returning pages with uncertain encryption
> state back to the allocator.
This works fine, but instead of effectively leaking the memory, we
could return it to the buddy allocator and reset nslabs to zero as if
SWIOTLB was not even initialized.
OTOH I don't want to overthink this, because the system is probably not
too useful after such a boot-time failure, so unless you _want_ to
improve the error path, you can simply add:
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> kernel/dma/swiotlb.c | 80 +++++++++++++++++++++++++++++++++++---------
> 1 file changed, 65 insertions(+), 15 deletions(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 4c56f64602ea..14d834ca298b 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -248,6 +248,23 @@ static inline unsigned long nr_slots(u64 val)
> return DIV_ROUND_UP(val, IO_TLB_SIZE);
> }
>
> +static void swiotlb_mark_pool_used(struct io_tlb_pool *pool)
> +{
> + unsigned long i;
> +
> + for (i = 0; i < pool->nareas; i++) {
> + pool->areas[i].index = 0;
> + pool->areas[i].used = pool->area_nslabs;
> + }
> +
> + for (i = 0; i < pool->nslabs; i++) {
> + pool->slots[i].list = 0;
> + pool->slots[i].orig_addr = INVALID_PHYS_ADDR;
> + pool->slots[i].alloc_size = 0;
> + pool->slots[i].pad_slots = 0;
> + }
> +}
> +
> /*
> * Early SWIOTLB allocation may be too early to allow an architecture to
> * perform the desired operations. This function allows the architecture to
> @@ -272,8 +289,16 @@ void __init swiotlb_update_mem_attributes(void)
> return;
> bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_decrypted((unsigned long)mem->vaddr, bytes >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + int ret;
> +
> + ret = set_memory_decrypted((unsigned long)mem->vaddr,
> + bytes >> PAGE_SHIFT);
> + if (ret) {
> + pr_warn("Failed to decrypt default memory pool, disabling it\n");
> + swiotlb_mark_pool_used(mem);
> + }
> + }
> }
>
> static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> @@ -442,9 +467,10 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> {
> struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
> unsigned long nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
> + unsigned int order, area_order, slot_order;
> + bool leak_pages = false;
> unsigned int nareas;
> unsigned char *vstart = NULL;
> - unsigned int order, area_order;
> bool retried = false;
> int rc = 0;
>
> @@ -504,6 +530,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> (PAGE_SIZE << order) >> 20);
> }
>
> + rc = -ENOMEM;
> nareas = limit_nareas(default_nareas, nslabs);
> area_order = get_order(array_size(sizeof(*mem->areas), nareas));
> mem->areas = (struct io_tlb_area *)
> @@ -511,14 +538,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> if (!mem->areas)
> goto error_area;
>
> + slot_order = get_order(array_size(sizeof(*mem->slots), nslabs));
> mem->slots = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> - get_order(array_size(sizeof(*mem->slots), nslabs)));
> + slot_order);
> if (!mem->slots)
> goto error_slots;
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_decrypted((unsigned long)vstart,
> - (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + rc = set_memory_decrypted((unsigned long)vstart,
> + (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> + if (rc) {
> + leak_pages = true;
> + goto error_decrypt;
> + }
> + }
>
> swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), nslabs, true,
> nareas);
> @@ -527,16 +560,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
> swiotlb_print_info();
> return 0;
>
> +error_decrypt:
> + free_pages((unsigned long)mem->slots, slot_order);
> error_slots:
> free_pages((unsigned long)mem->areas, area_order);
> error_area:
> - free_pages((unsigned long)vstart, order);
> - return -ENOMEM;
> + if (!leak_pages)
> + free_pages((unsigned long)vstart, order);
> + return rc;
> }
>
> void __init swiotlb_exit(void)
> {
> struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
> + bool leak_pages = false;
> unsigned long tbl_vaddr;
> size_t tbl_size, slots_size;
> unsigned int area_order;
> @@ -552,19 +589,23 @@ void __init swiotlb_exit(void)
> tbl_size = PAGE_ALIGN(mem->end - mem->start);
> slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs));
>
> - if (io_tlb_default_mem.unencrypted)
> - set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT);
> + if (io_tlb_default_mem.unencrypted) {
> + if (set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT))
> + leak_pages = true;
> + }
>
> if (mem->late_alloc) {
> area_order = get_order(array_size(sizeof(*mem->areas),
> mem->nareas));
> free_pages((unsigned long)mem->areas, area_order);
> - free_pages(tbl_vaddr, get_order(tbl_size));
> + if (!leak_pages)
> + free_pages(tbl_vaddr, get_order(tbl_size));
> free_pages((unsigned long)mem->slots, get_order(slots_size));
> } else {
> memblock_free(mem->areas,
> array_size(sizeof(*mem->areas), mem->nareas));
> - memblock_phys_free(mem->start, tbl_size);
> + if (!leak_pages)
> + memblock_phys_free(mem->start, tbl_size);
> memblock_free(mem->slots, slots_size);
> }
>
> @@ -1938,9 +1979,18 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
> * restricted mem pool is decrypted by default
> */
> if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
> + int ret;
> +
> mem->unencrypted = true;
> - set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> - rmem->size >> PAGE_SHIFT);
> + ret = set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> + rmem->size >> PAGE_SHIFT);
> + if (ret) {
> + dev_err(dev, "Failed to decrypt restricted DMA pool\n");
> + kfree(pool->areas);
> + kfree(pool->slots);
> + kfree(mem);
> + return ret;
> + }
> } else {
> mem->unencrypted = false;
> }
^ permalink raw reply
* [PATCH v2 3/4] mfd: mt6397-core: add mt6323 AUXADC support
From: Roman Vivchar via B4 Relay @ 2026-06-09 13:32 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
In-Reply-To: <20260609-mt6323-adc-v2-0-aa93a22309f9@protonmail.com>
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 PMIC includes an AUXADC. Register the AUXADC in the mt6323
devices array to allow the corresponding driver to probe using compatible
string.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/mfd/mt6397-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 3e58d0764c7e..013b0857fb54 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -125,6 +125,9 @@ static const struct resource mt6323_pwrc_resources[] = {
static const struct mfd_cell mt6323_devs[] = {
{
+ .name = "mt6323-auxadc",
+ .of_compatible = "mediatek,mt6323-auxadc",
+ }, {
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
.resources = mt6323_rtc_resources,
--
2.54.0
^ permalink raw reply related
* [PATCH v2 0/4] AUXADC driver for the MediaTek mt6323 PMIC
From: Roman Vivchar via B4 Relay @ 2026-06-09 13:31 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
This series adds support for the 15-bit AUXADC hardware block found on
the MediaTek mt6323 PMIC.
The previous version of the series for all AUXADC, EFUSE and thermal
drivers was split after Krzysztof's comment [1].
Tested on the MediaTek mt6572 and mt8163 SoCs (Ben), both paired with a
mt6323.
The other parts (EFUSE and thermal) will probably be sent this week.
[1]: https://lore.kernel.org/linux-mediatek/20260504-mt6323-v1-0-799b58b355ff@protonmail.com/T/#med30fad67a090be35f549231336b2dec295233f6
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
Changes in v2:
- AUXADC driver:
- Drop channel type from the MTK_PMIC_IIO_CHAN macro (Nuno)
- Drop kerneldoc for the mt6323_auxadc struct (Nuno)
- Add channel release to save power (Sashiko, Jonathan)
- Drop 'reg' variable in the mt6323_auxadc_read (Jonathan)
- Sort variables in the mt6323_auxadc_probe (Jonathan)
- Maintainers:
- Drop linux-mediatek list (Andy)
- Split between dt-bindings and driver to avoid missing file (Nuno)
- Link to v1: https://patch.msgid.link/20260602-mt6323-adc-v1-0-68ec737508ee@protonmail.com
Changes after split:
- dt-bindings: Change 'MT63xx' to 'MT6350 series and similar' (Jonathan)
- AUXADC driver:
- Add missing headers (Andy)
- Fix AUXADC_TRIM_CH* values (Andy)
- Rename masks to include their register name (Jonathan)
- Fix formatting (Andy, Jonathan)
- Replace channel address with actual register value (Jonathan), align the table
- Replace IIO_TEMP with IIO_VOLTAGE, since the actual output is still mV, not mC
- Rename constants to match their registers (Jonathan)
- Remove 'if/else if/else' in the mt6323_auxadc_read_raw (Andy)
- Add comments for fsleep, ADC range and resolution (Andy, Jonathan)
- Remove useless error messages (Andy)
- Maintainers:
- Explicitly include mt6323 in the name (Jonathan)
- Squash with AUXADC driver commit (Krzysztof)
- Set status back to 'Maintained'
- Link to a previous series: https://patch.msgid.link/20260512-mt6323-v2-0-3efcba579e88@protonmail.com
---
Roman Vivchar (4):
dt-bindings: iio: adc: mediatek,mt6359-auxadc: add mt6323 PMIC AUXADC
iio: adc: mt6323-auxadc: add mt6323 PMIC AUXADC driver
mfd: mt6397-core: add mt6323 AUXADC support
ARM: dts: mediatek: mt6323: add AUXADC support
.../bindings/iio/adc/mediatek,mt6359-auxadc.yaml | 3 +-
MAINTAINERS | 7 +
arch/arm/boot/dts/mediatek/mt6323.dtsi | 5 +
drivers/iio/adc/Kconfig | 11 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6323-auxadc.c | 305 +++++++++++++++++++++
drivers/mfd/mt6397-core.c | 3 +
.../dt-bindings/iio/adc/mediatek,mt6323-auxadc.h | 24 ++
8 files changed, 358 insertions(+), 1 deletion(-)
---
base-commit: 028ef9c96e96197026887c0f092424679298aae8
change-id: 20260525-mt6323-adc-3befce36cbf2
Best regards,
--
Roman Vivchar <rva333@protonmail.com>
^ permalink raw reply
* [PATCH v2 1/4] dt-bindings: iio: adc: mediatek,mt6359-auxadc: add mt6323 PMIC AUXADC
From: Roman Vivchar via B4 Relay @ 2026-06-09 13:31 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
In-Reply-To: <20260609-mt6323-adc-v2-0-aa93a22309f9@protonmail.com>
From: Roman Vivchar <rva333@protonmail.com>
The MediaTek mt6323 PMIC includes an AUXADC used for battery voltage,
temperature, and other internal measurements.
Add the devicetree binding documentation and the associated header file
defining the ADC channel constants.
Also change the description to 'MT6350 series and similar' because
the binding already includes more than mt635x series PMICs.
Finally, add the MAINTAINERS entry for the header with ADC constants.
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
.../bindings/iio/adc/mediatek,mt6359-auxadc.yaml | 3 ++-
MAINTAINERS | 6 ++++++
.../dt-bindings/iio/adc/mediatek,mt6323-auxadc.h | 24 ++++++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
index 5d4ab701f51a..852eb7336a5a 100644
--- a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/iio/adc/mediatek,mt6359-auxadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: MediaTek MT6350 series PMIC AUXADC
+title: MediaTek MT6350 series and similar PMIC AUXADC
maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
@@ -19,6 +19,7 @@ description:
properties:
compatible:
enum:
+ - mediatek,mt6323-auxadc
- mediatek,mt6357-auxadc
- mediatek,mt6358-auxadc
- mediatek,mt6359-auxadc
diff --git a/MAINTAINERS b/MAINTAINERS
index d1cc0e12fe1f..2551c8cd9e9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16256,6 +16256,12 @@ S: Maintained
F: Documentation/devicetree/bindings/mmc/mtk-sd.yaml
F: drivers/mmc/host/mtk-sd.c
+MEDIATEK MT6323 PMIC AUXADC DRIVER
+M: Roman Vivchar <rva333@protonmail.com>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
+
MEDIATEK MT6735 CLOCK & RESET DRIVERS
M: Yassine Oudjana <y.oudjana@protonmail.com>
L: linux-clk@vger.kernel.org
diff --git a/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h b/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
new file mode 100644
index 000000000000..6ee9a9ecffc1
--- /dev/null
+++ b/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_MEDIATEK_MT6323_AUXADC_H
+#define _DT_BINDINGS_MEDIATEK_MT6323_AUXADC_H
+
+#define MT6323_AUXADC_BATON2 0
+#define MT6323_AUXADC_CH6 1
+#define MT6323_AUXADC_BAT_TEMP 2
+#define MT6323_AUXADC_CHIP_TEMP 3
+#define MT6323_AUXADC_VCDT 4
+#define MT6323_AUXADC_BATON1 5
+#define MT6323_AUXADC_ISENSE 6
+#define MT6323_AUXADC_BATSNS 7
+#define MT6323_AUXADC_ACCDET 8
+#define MT6323_AUXADC_AUDIO0 9
+#define MT6323_AUXADC_AUDIO1 10
+#define MT6323_AUXADC_AUDIO2 11
+#define MT6323_AUXADC_AUDIO3 12
+#define MT6323_AUXADC_AUDIO4 13
+#define MT6323_AUXADC_AUDIO5 14
+#define MT6323_AUXADC_AUDIO6 15
+#define MT6323_AUXADC_AUDIO7 16
+
+#endif
--
2.54.0
^ permalink raw reply related
* [PATCH v2 4/4] ARM: dts: mediatek: mt6323: add AUXADC support
From: Roman Vivchar via B4 Relay @ 2026-06-09 13:32 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
In-Reply-To: <20260609-mt6323-adc-v2-0-aa93a22309f9@protonmail.com>
From: Roman Vivchar <rva333@protonmail.com>
Add the devicetree node for the mt6323 AUXADC.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
arch/arm/boot/dts/mediatek/mt6323.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi
index c230c865116d..c070f4b0936c 100644
--- a/arch/arm/boot/dts/mediatek/mt6323.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi
@@ -14,6 +14,11 @@ pmic: mt6323 {
interrupt-controller;
#interrupt-cells = <2>;
+ mt6323_adc: adc {
+ compatible = "mediatek,mt6323-auxadc";
+ #io-channel-cells = <1>;
+ };
+
mt6323_leds: leds {
compatible = "mediatek,mt6323-led";
#address-cells = <1>;
--
2.54.0
^ permalink raw reply related
* [PATCH v2 2/4] iio: adc: mt6323-auxadc: add mt6323 PMIC AUXADC driver
From: Roman Vivchar via B4 Relay @ 2026-06-09 13:31 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
In-Reply-To: <20260609-mt6323-adc-v2-0-aa93a22309f9@protonmail.com>
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
provides support for reading various channels including battery and
charger voltages, battery and chip temperature, current sensing and
accessory detection.
Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
MAINTAINERS | 1 +
drivers/iio/adc/Kconfig | 11 ++
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6323-auxadc.c | 305 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 318 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2551c8cd9e9d..fb40128451dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16260,6 +16260,7 @@ MEDIATEK MT6323 PMIC AUXADC DRIVER
M: Roman Vivchar <rva333@protonmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
+F: drivers/iio/adc/mt6323-auxadc.c
F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
MEDIATEK MT6735 CLOCK & RESET DRIVERS
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 60038ae8dfc4..a03614b46041 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1137,6 +1137,17 @@ config MCP3911
This driver can also be built as a module. If so, the module will be
called mcp3911.
+config MEDIATEK_MT6323_AUXADC
+ tristate "MediaTek MT6323 PMIC AUXADC driver"
+ depends on MFD_MT6397
+ help
+ Say yes here to enable support for MediaTek MT6323 PMIC Auxiliary ADC.
+ This driver provides multiple channels for system monitoring,
+ such as battery voltage, PMIC temperature, and others.
+
+ This driver can also be built as a module. If so, the module will be
+ called mt6323-auxadc.
+
config MEDIATEK_MT6359_AUXADC
tristate "MediaTek MT6359 PMIC AUXADC driver"
depends on MFD_MT6397
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index c76550415ff1..58161750d6e3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MCP3564) += mcp3564.o
obj-$(CONFIG_MCP3911) += mcp3911.o
+obj-$(CONFIG_MEDIATEK_MT6323_AUXADC) += mt6323-auxadc.o
obj-$(CONFIG_MEDIATEK_MT6359_AUXADC) += mt6359-auxadc.o
obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o
obj-$(CONFIG_MEDIATEK_MT6370_ADC) += mt6370-adc.o
diff --git a/drivers/iio/adc/mt6323-auxadc.c b/drivers/iio/adc/mt6323-auxadc.c
new file mode 100644
index 000000000000..f2cef989d3ce
--- /dev/null
+++ b/drivers/iio/adc/mt6323-auxadc.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Roman Vivchar <rva333@protonmail.com>
+ *
+ * Based on drivers/iio/adc/mt6359-auxadc.c
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/stringify.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <linux/mfd/mt6323/registers.h>
+
+#include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
+
+#define AUXADC_STRUP_CON10_RSTB_SEL BIT(7)
+#define AUXADC_STRUP_CON10_RSTB_SW BIT(5)
+
+#define AUXADC_TOP_CKPDN2_CTL_CK BIT(5)
+
+#define AUXADC_TRIM_CH2_MASK GENMASK(11, 10)
+#define AUXADC_TRIM_CH4_MASK GENMASK(9, 8)
+#define AUXADC_TRIM_CH5_MASK GENMASK(5, 4)
+#define AUXADC_TRIM_CH6_MASK GENMASK(3, 2)
+
+#define AUXADC_CON27_VREF18_ENB_MD BIT(15)
+#define AUXADC_CON27_MD_STATUS BIT(0)
+
+#define AUXADC_CON19_GPS_STATUS BIT(1)
+
+#define AUXADC_CON26_VREF18_SELB BIT(1)
+#define AUXADC_CON26_DECI_GDLY_SEL BIT(0)
+
+#define AUXADC_CON11_VBUF_EN BIT(4)
+
+#define AUXADC_CON19_DECI_GDLY_MASK GENMASK(15, 14)
+#define AUXADC_ADC19_BUSY_MASK GENMASK(15, 1)
+#define AUXADC_READY_MASK BIT(15)
+#define AUXADC_DATA_MASK GENMASK(14, 0)
+
+#define AUXADC_CON9_OSR_MASK GENMASK(12, 10)
+#define AUXADC_DEFAULT_OSR 3
+
+#define MTK_PMIC_IIO_CHAN(_name, _chan, _addr) \
+{ \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = _chan, \
+ .address = _addr, \
+ .datasheet_name = __stringify(_name), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec mt6323_auxadc_channels[] = {
+ MTK_PMIC_IIO_CHAN(baton2, MT6323_AUXADC_BATON2, MT6323_AUXADC_ADC6),
+ MTK_PMIC_IIO_CHAN(ch6, MT6323_AUXADC_CH6, MT6323_AUXADC_ADC11),
+ MTK_PMIC_IIO_CHAN(bat_temp, MT6323_AUXADC_BAT_TEMP, MT6323_AUXADC_ADC5),
+ MTK_PMIC_IIO_CHAN(chip_temp, MT6323_AUXADC_CHIP_TEMP, MT6323_AUXADC_ADC4),
+ MTK_PMIC_IIO_CHAN(vcdt, MT6323_AUXADC_VCDT, MT6323_AUXADC_ADC2),
+ MTK_PMIC_IIO_CHAN(baton1, MT6323_AUXADC_BATON1, MT6323_AUXADC_ADC3),
+ MTK_PMIC_IIO_CHAN(isense, MT6323_AUXADC_ISENSE, MT6323_AUXADC_ADC1),
+ MTK_PMIC_IIO_CHAN(batsns, MT6323_AUXADC_BATSNS, MT6323_AUXADC_ADC0),
+ MTK_PMIC_IIO_CHAN(accdet, MT6323_AUXADC_ACCDET, MT6323_AUXADC_ADC7),
+};
+
+/*
+ * The MediaTek MT6323 (as well as a lot of other PMICs) has the following hierarchy:
+ * PMIC AUXADC <- PMIC MFD <- SoC PWRAP (wrapper for PWRAP FSM)
+ *
+ * Therefore, PWRAP regmap should be obtained using dev->parent->parent.
+ */
+struct mt6323_auxadc {
+ struct regmap *regmap;
+ struct mutex lock;
+};
+
+static int mt6323_auxadc_prepare_channel(struct mt6323_auxadc *auxadc)
+{
+ struct regmap *map = auxadc->regmap;
+ u32 val;
+ int ret;
+
+ ret = regmap_read(map, MT6323_AUXADC_CON19, &val);
+ if (ret)
+ return ret;
+
+ /* The ADC is idle. */
+ if (!(val & AUXADC_CON19_DECI_GDLY_MASK))
+ return 0;
+
+ ret = regmap_read_poll_timeout(map, MT6323_AUXADC_ADC19, val,
+ !(val & AUXADC_ADC19_BUSY_MASK),
+ 10, 500);
+ if (ret)
+ return ret;
+
+ return regmap_clear_bits(map, MT6323_AUXADC_CON19,
+ AUXADC_CON19_DECI_GDLY_MASK);
+}
+
+static int mt6323_auxadc_request(struct mt6323_auxadc *auxadc,
+ unsigned long channel)
+{
+ struct regmap *map = auxadc->regmap;
+ int ret;
+
+ ret = regmap_set_bits(map, MT6323_AUXADC_CON11, AUXADC_CON11_VBUF_EN);
+ if (ret)
+ return ret;
+
+ return regmap_set_bits(map, MT6323_AUXADC_CON22, BIT(channel));
+}
+
+static int mt6323_auxadc_release(struct mt6323_auxadc *auxadc,
+ unsigned long channel)
+{
+ struct regmap *map = auxadc->regmap;
+ int ret;
+
+ ret = regmap_clear_bits(map, MT6323_AUXADC_CON22, BIT(channel));
+ if (ret)
+ return ret;
+
+ return regmap_clear_bits(map, MT6323_AUXADC_CON11, AUXADC_CON11_VBUF_EN);
+}
+
+static int mt6323_auxadc_read(struct mt6323_auxadc *auxadc,
+ const struct iio_chan_spec *chan, int *out)
+{
+ struct regmap *map = auxadc->regmap;
+ u32 val;
+ int ret;
+
+ ret = regmap_read_poll_timeout(map, chan->address, val, (val & AUXADC_READY_MASK),
+ 1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC);
+ if (ret)
+ return ret;
+
+ *out = FIELD_GET(AUXADC_DATA_MASK, val);
+
+ return 0;
+}
+
+static int mt6323_auxadc_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct mt6323_auxadc *auxadc = iio_priv(indio_dev);
+ int ret, mult;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ if (chan->channel == MT6323_AUXADC_ISENSE ||
+ chan->channel == MT6323_AUXADC_BATSNS)
+ mult = 4;
+ else
+ mult = 1;
+
+ /* 1800mV full range with 15-bit resolution. */
+ *val = mult * 1800;
+ *val2 = 15;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_RAW:
+ scoped_guard(mutex, &auxadc->lock) {
+ ret = mt6323_auxadc_prepare_channel(auxadc);
+ if (ret)
+ return ret;
+
+ ret = mt6323_auxadc_request(auxadc, chan->channel);
+ if (ret)
+ return ret;
+
+ /* Hardware limitation: the AUXADC needs a delay to become ready. */
+ fsleep(300);
+
+ ret = mt6323_auxadc_read(auxadc, chan, val);
+
+ if (mt6323_auxadc_release(auxadc, chan->channel))
+ dev_err(&indio_dev->dev,
+ "failed to release channel %d\n", chan->channel);
+
+ if (ret)
+ return ret;
+ }
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mt6323_auxadc_init(struct mt6323_auxadc *auxadc)
+{
+ struct regmap *map = auxadc->regmap;
+ int ret;
+
+ ret = regmap_set_bits(map, MT6323_STRUP_CON10,
+ AUXADC_STRUP_CON10_RSTB_SW |
+ AUXADC_STRUP_CON10_RSTB_SEL);
+ if (ret)
+ return ret;
+
+ ret = regmap_set_bits(map, MT6323_TOP_CKPDN2, AUXADC_TOP_CKPDN2_CTL_CK);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(map, MT6323_AUXADC_CON10,
+ AUXADC_TRIM_CH2_MASK | AUXADC_TRIM_CH4_MASK |
+ AUXADC_TRIM_CH5_MASK | AUXADC_TRIM_CH6_MASK,
+ FIELD_PREP(AUXADC_TRIM_CH2_MASK, 1) |
+ FIELD_PREP(AUXADC_TRIM_CH4_MASK, 1) |
+ FIELD_PREP(AUXADC_TRIM_CH5_MASK, 1) |
+ FIELD_PREP(AUXADC_TRIM_CH6_MASK, 1));
+ if (ret)
+ return ret;
+
+ ret = regmap_set_bits(map, MT6323_AUXADC_CON27,
+ AUXADC_CON27_VREF18_ENB_MD |
+ AUXADC_CON27_MD_STATUS);
+ if (ret)
+ return ret;
+
+ ret = regmap_set_bits(map, MT6323_AUXADC_CON19, AUXADC_CON19_GPS_STATUS);
+ if (ret)
+ return ret;
+
+ ret = regmap_set_bits(map, MT6323_AUXADC_CON26,
+ AUXADC_CON26_VREF18_SELB |
+ AUXADC_CON26_DECI_GDLY_SEL);
+ if (ret)
+ return ret;
+
+ return regmap_update_bits(map, MT6323_AUXADC_CON9, AUXADC_CON9_OSR_MASK,
+ FIELD_PREP(AUXADC_CON9_OSR_MASK, AUXADC_DEFAULT_OSR));
+}
+
+static const struct iio_info mt6323_auxadc_iio_info = {
+ .read_raw = mt6323_auxadc_read_raw,
+};
+
+static int mt6323_auxadc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mt6323_auxadc *auxadc;
+ struct regmap *regmap;
+ struct iio_dev *iio;
+ int ret;
+
+ regmap = dev_get_regmap(dev->parent->parent, NULL);
+ if (!regmap)
+ return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
+
+ iio = devm_iio_device_alloc(dev, sizeof(*auxadc));
+ if (!iio)
+ return -ENOMEM;
+
+ auxadc = iio_priv(iio);
+ auxadc->regmap = regmap;
+
+ ret = devm_mutex_init(dev, &auxadc->lock);
+ if (ret)
+ return ret;
+
+ ret = mt6323_auxadc_init(auxadc);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to initialize auxadc\n");
+
+ iio->name = "mt6323-auxadc";
+ iio->info = &mt6323_auxadc_iio_info;
+ iio->modes = INDIO_DIRECT_MODE;
+ iio->channels = mt6323_auxadc_channels;
+ iio->num_channels = ARRAY_SIZE(mt6323_auxadc_channels);
+
+ return devm_iio_device_register(dev, iio);
+}
+
+static const struct of_device_id mt6323_auxadc_of_match[] = {
+ { .compatible = "mediatek,mt6323-auxadc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mt6323_auxadc_of_match);
+
+static struct platform_driver mt6323_auxadc_driver = {
+ .driver = {
+ .name = "mt6323-auxadc",
+ .of_match_table = mt6323_auxadc_of_match,
+ },
+ .probe = mt6323_auxadc_probe,
+};
+module_platform_driver(mt6323_auxadc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek MT6323 PMIC AUXADC Driver");
--
2.54.0
^ permalink raw reply related
* Re: [PATCH 2/3] iio: adc: add Axiado SARADC driver
From: Andy Shevchenko @ 2026-06-09 13:26 UTC (permalink / raw)
To: Petar Stepanovic
Cc: Akhila Kavi, Prasad Bolisetty, Jonathan Cameron, David Lechner,
Nuno Sá, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Harshit Shah, linux-iio, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <1e2f4756-e944-473a-b4d7-a5692f2b609f@axiado.com>
On Tue, Jun 09, 2026 at 11:09:32AM +0200, Petar Stepanovic wrote:
> On 6/5/2026 8:26 PM, Andy Shevchenko wrote:
...
> >> + info->clk = devm_clk_get_enabled(&pdev->dev, NULL);
> > Why no name? It will make harder for the next generations of HW in case they
> > want more than one clock to be used.
>
> This IP block currently has only one clock input, so I used the unnamed clock.
> Since there is no ambiguity for the current hardware, I would prefer to keep
> the binding simple unless a named clock is required.
Again, it doesn't matter. What matters is the potential future. Hence it's
recommended to use named clocks even for a single case as we don't know if
the next generation will use more clocks or not. In any case, it will be
your decision and up to the maintainers.
Note, I have not checked statistics of how many of those which started with
a NULL clock become more complicated in the future, but for sure there are
more than a single case in the kernel.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v6 15/20] iommu/dma: Check atomic pool allocation result directly
From: Petr Tesarik @ 2026-06-09 13:13 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-16-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:54 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> The non-blocking, non-coherent allocation path uses dma_alloc_from_pool(),
> which returns the allocated page and fills cpu_addr only on success.
>
> Do not rely on cpu_addr to detect allocation failure in this path. Check
> the returned page directly before using it for the IOMMU mapping.
>
> Fixes: 9420139f516d ("dma-pool: fix coherent pool allocations for IOMMU mappings")
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> ---
> drivers/iommu/dma-iommu.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 725c7adb0a8d..52c599f4472c 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -1671,13 +1671,16 @@ void *iommu_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
> }
>
> if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> - !gfpflags_allow_blocking(gfp) && !coherent)
> + !gfpflags_allow_blocking(gfp) && !coherent) {
> page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
> gfp, attrs, NULL);
> - else
> + if (!page)
> + return NULL;
> + } else {
> cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs);
> - if (!cpu_addr)
> - return NULL;
> + if (!cpu_addr)
> + return NULL;
> + }
>
> *handle = __iommu_dma_map(dev, page_to_phys(page), size, ioprot,
> dev->coherent_dma_mask);
^ permalink raw reply
* Re: [GIT PULL] Allwinner DT Changes for 7.2
From: Chen-Yu Tsai @ 2026-06-09 13:26 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: soc, Jernej Skrabec, Samuel Holland, linux-sunxi,
linux-arm-kernel, Paul Kocialkowski
In-Reply-To: <e2bf1f8b-677e-4184-b752-26e987f29121@kernel.org>
On Tue, Jun 9, 2026 at 10:18 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 09/06/2026 14:38, Chen-Yu Tsai wrote:
> > On Tue, Jun 9, 2026 at 8:51 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >>
> >> On 09/06/2026 13:48, Chen-Yu Tsai wrote:
> >>> On Tue, Jun 9, 2026 at 8:43 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >>>>
> >>>> On Tue, Jun 02, 2026 at 03:09:52AM +0800, Chen-Yu Tsai wrote:
> >>>>> The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
> >>>>>
> >>>>> Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
> >>>>>
> >>>>> are available in the Git repository at:
> >>>>>
> >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-dt-for-7.2
> >>>>>
> >>>>> for you to fetch changes up to 44cf19e41c769720750dbb8752aca75c247e565f:
> >>>>>
> >>>>> arm64: dts: allwinner: a523: add gpadc node (2026-05-25 05:02:58 +0800)
> >>>>>
> >>>>>
> >>>>> As mentioned in the tag, this pull request contains a change that should
> >>>>> be shared between the soc and clk trees. However since I don't have any
> >>>>> clk changes to send this cycle, I think it can just go through the soc
> >>>>> tree without any issues.
> >>>>
> >>>> But the clock driver change cannot be in the DTS branch. This should go
> >>>> via clock tree even if it is one change. And definitely not via DTS
> >>>> branch.
> >>>
> >>> It is a shared change, because it moves two symbols from the driver's
> >>> private header to the public DT binding header. I don't see how this
> >>> can go through just the clk tree when one of the subsequent patches
> >>> uses those new symbols.
> >>>
> >>> "clk: sunxi-ng: v3s: Export MBUS and DRAM clocks to the public header"
> >>> is needed by "ARM: dts: sun8i: v3s: Add mbus node to represent the
> >>> interconnect".
> >>>
> >>> The other way to go about this is to use raw numbers first, then
> >>> another patch in the next cycle to switch the numbers to actual
> >>> macros. IMHO not worth the churn and headache.
> >>
> >> You can have a duplicated define.
> >
> > I honestly did not know that it worked.
> >
> > However, splitting what is effectively one logical change (*move*
> > something) into two patches just to be able to merge them through two
> > separate trees still seems wrong to me.
>
> It is not really one logical change. Defining a new ABI (binding header
> define) is considered one change. Merging binding change into driver
> commit breaks rule of splitting bindings from implementation.
>
> Second rule is that DTS branch CANNOT take driver changes. So if you do
> not want to adhere to the above rule you still cannot combine it into
> DTS branch.
Very well. I will drop the two changes and send a revised pull request.
Paul, can you redo the clk changes as requested in the next cycle?
Thanks
ChenYu
^ permalink raw reply
* Re: [PATCH v6 16/20] dma: swiotlb: free dynamic pools from process context
From: Petr Tesarik @ 2026-06-09 13:23 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-17-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:55 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> swiotlb_dyn_free() is used after removing a dynamic swiotlb pool from
> RCU-protected lists. It can call swiotlb_free_tlb(), which may need to
> restore the encryption state of an unencrypted pool with
> set_memory_encrypted() before freeing the pages.
>
> RCU callbacks run in atomic context, but set_memory_encrypted() is not
> guaranteed to be atomic-safe on all architectures. For example, page
> attribute updates may allocate page tables or take sleeping locks.
Good catch!
> Use queue_rcu_work() for dynamic pool freeing instead. This keeps the RCU
> grace period before freeing a published pool, while running the actual pool
> teardown from workqueue context. Use the same helper for the transient-pool
> error path, since that path may also be reached from atomic DMA mapping
> context.
Strictly speaking, it's not necessary, because this is in the error
path just after allocating a transient pool. There are only two
possible scenarios:
a. The transient buffer was allocated from a sleeping context, and then
it's also OK to decrypt memory.
b. The transient buffer was allocated in atomic context, but then it was
allocated from a coherent pool and it is returned to that pool
rather than decrypted.
However, it's also fine to queue an RCU work. The logic is definitely
cleaner and easier to maintain.
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> ---
> include/linux/swiotlb.h | 4 ++--
> kernel/dma/swiotlb.c | 19 +++++++++++--------
> 2 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 4dcbf3931be1..526f82e9da45 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -64,7 +64,7 @@ extern void __init swiotlb_update_mem_attributes(void);
> * @areas: Array of memory area descriptors.
> * @slots: Array of slot descriptors.
> * @node: Member of the IO TLB memory pool list.
> - * @rcu: RCU head for swiotlb_dyn_free().
> + * @dyn_free: RCU work item used to free the pool from process context.
> * @transient: %true if transient memory pool.
> */
> struct io_tlb_pool {
> @@ -79,7 +79,7 @@ struct io_tlb_pool {
> struct io_tlb_slot *slots;
> #ifdef CONFIG_SWIOTLB_DYNAMIC
> struct list_head node;
> - struct rcu_head rcu;
> + struct rcu_work dyn_free;
> bool transient;
> bool unencrypted;
> #endif
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index f4e8b241a1c4..4c56f64602ea 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -774,13 +774,10 @@ static void swiotlb_dyn_alloc(struct work_struct *work)
> add_mem_pool(mem, pool);
> }
>
> -/**
> - * swiotlb_dyn_free() - RCU callback to free a memory pool
> - * @rcu: RCU head in the corresponding struct io_tlb_pool.
> - */
> -static void swiotlb_dyn_free(struct rcu_head *rcu)
> +static void swiotlb_dyn_free_work(struct work_struct *work)
> {
> - struct io_tlb_pool *pool = container_of(rcu, struct io_tlb_pool, rcu);
> + struct io_tlb_pool *pool =
> + container_of(to_rcu_work(work), struct io_tlb_pool, dyn_free);
> size_t slots_size = array_size(sizeof(*pool->slots), pool->nslabs);
> size_t tlb_size = pool->end - pool->start;
>
> @@ -789,6 +786,12 @@ static void swiotlb_dyn_free(struct rcu_head *rcu)
> kfree(pool);
> }
>
> +static void swiotlb_schedule_dyn_free(struct io_tlb_pool *pool)
> +{
> + INIT_RCU_WORK(&pool->dyn_free, swiotlb_dyn_free_work);
> + queue_rcu_work(system_wq, &pool->dyn_free);
> +}
> +
> /**
> * __swiotlb_find_pool() - find the IO TLB pool for a physical address
> * @dev: Device which has mapped the DMA buffer.
> @@ -835,7 +838,7 @@ static void swiotlb_del_pool(struct device *dev, struct io_tlb_pool *pool)
> list_del_rcu(&pool->node);
> spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags);
>
> - call_rcu(&pool->rcu, swiotlb_dyn_free);
> + swiotlb_schedule_dyn_free(pool);
> }
>
> #endif /* CONFIG_SWIOTLB_DYNAMIC */
> @@ -1276,7 +1279,7 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr,
> index = swiotlb_search_pool_area(dev, pool, 0, orig_addr, tbl_dma_addr,
> alloc_size, alloc_align_mask);
> if (index < 0) {
> - swiotlb_dyn_free(&pool->rcu);
> + swiotlb_schedule_dyn_free(pool);
> return -1;
> }
>
^ permalink raw reply
* Re: [GIT PULL] arm64: BST C1200 eMMC DTS + defconfig for v7.2
From: Arnd Bergmann @ 2026-06-09 13:24 UTC (permalink / raw)
To: gordon.ge, soc; +Cc: yangzh0906@thundersoft.com, linux-arm-kernel, bst-upstream
In-Reply-To: <20260603.193147-gordon.ge@bst.ai>
On Wed, Jun 3, 2026, at 13:31, gordon.ge@bst.ai wrote:
> The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
> arm64: BST C1200 eMMC DTS + defconfig for v7.2
>
> Black Sesame Technologies:
>
> Enable eMMC controller on BST C1200 CDCU1.0 board:
> - Add mmc0 node in bstc1200.dtsi (DWCMSHC SDHCI controller)
> - Add fixed clock definition and reserved SRAM bounce buffer
> - Enable mmc0 with 8-bit bus on CDCU1.0 ADAS 4C2G board
> - Enable CONFIG_MMC_SDHCI_BST=y in arm64 defconfig
>
> The MMC driver was merged via mmc-next in v7.1-rc1.
> These are the remaining DTS and defconfig pieces.
Hi Gordon,
There are two more formal mistakes here in your
pull request, please fix:
- keep the defconfig patch separate from the devicetree changes,
as we will merge them separately.
- on each patch, make sure there is at least a 'Signed-off-by'
tag from the committer (plus author, if different), and
ideally any 'Reviewed-by', 'Acked-by' or 'Tested-by' tags
you have received.
Arnd
^ permalink raw reply
* Re: [PATCH v4 1/8] drm/connector: report out-of-band IRQ_HPD events
From: Maxime Ripard @ 2026-06-09 13:20 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini, dri-devel,
linux-kernel, linux-usb, intel-gfx, intel-xe, linux-amlogic,
linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260608-hpd-irq-events-v4-1-30b62b335487@oss.qualcomm.com>
[-- Attachment #1: Type: text/plain, Size: 3144 bytes --]
Hi,
On Mon, Jun 08, 2026 at 12:33:02AM +0300, Dmitry Baryshkov wrote:
> The DisplayPort standard defines a special kind of events called IRQ.
> These events are used to notify DP Source about the events on the Sink
> side. It is extremely important for DP MST handling, where the MST
> events are reported through this IRQ.
>
> In case of the USB-C DP AltMode there is no actual HPD pulse, but the
> events are reported through the bits in the AltMode VDOs.
>
> Rename drm_connector_oob_hotplug_event() to drm_connector_dp_oob_status()
> and extend its interface to report IRQ events to the DisplayPort Sink
> drivers.
>
> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
> drivers/gpu/drm/drm_connector.c | 20 ++++++++++++--------
> drivers/usb/typec/altmodes/displayport.c | 23 +++++++++++++++--------
> include/drm/drm_connector.h | 21 +++++++++++++++++++--
> 3 files changed, 46 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 3fa4d2082cd7..bb128dd0263a 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -3502,20 +3502,24 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> }
>
> /**
> - * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
> + * drm_connector_dp_oob_status - Report out-of-band hotplug event to DisplayPort connector
> * @connector_fwnode: fwnode_handle to report the event on
> * @status: hot plug detect logical state
> + * @extra_status: additional information provided by the sink without changing
> + * the HPD state (or in addition to such a change).
> *
> - * On some hardware a hotplug event notification may come from outside the display
> - * driver / device. An example of this is some USB Type-C setups where the hardware
> - * muxes the DisplayPort data and aux-lines but does not pass the altmode HPD
> - * status bit to the GPU's DP HPD pin.
> + * In some cases when DisplayPort signals are being routed through the USB
> + * Type-C port the hotplug event notifications come from outside of the display
> + * driver / device. In this case hardware muxes the DisplayPort data and
> + * AUX-lines but does not pass the altmode HPD status bit to the GPU's DP HPD
> + * pin.
> *
> * This function can be used to report these out-of-band events after obtaining
> * a drm_connector reference through calling drm_connector_find_by_fwnode().
> */
> -void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> - enum drm_connector_status status)
> +void drm_connector_dp_oob_status(struct fwnode_handle *connector_fwnode,
> + enum drm_connector_status status,
> + enum drm_connector_status_extra extra_status)
Thanks for the renaming, but I think we can also rename
drm_connector_status_extra to something a bit more descriptive now?
drm_connector_dp_oob_event? status?
The rest looks good.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* Re: [GIT PULL] Allwinner DT Changes for 7.2
From: Krzysztof Kozlowski @ 2026-06-09 13:18 UTC (permalink / raw)
To: wens, Stephen Boyd
Cc: soc, Jernej Skrabec, Samuel Holland, linux-sunxi,
linux-arm-kernel
In-Reply-To: <CAGb2v64o+tgnLqK_xDoauB4ThF_0979_5XPB38KiZHYyh1BnVQ@mail.gmail.com>
On 09/06/2026 14:38, Chen-Yu Tsai wrote:
> On Tue, Jun 9, 2026 at 8:51 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>> On 09/06/2026 13:48, Chen-Yu Tsai wrote:
>>> On Tue, Jun 9, 2026 at 8:43 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>>>
>>>> On Tue, Jun 02, 2026 at 03:09:52AM +0800, Chen-Yu Tsai wrote:
>>>>> The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
>>>>>
>>>>> Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
>>>>>
>>>>> are available in the Git repository at:
>>>>>
>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git tags/sunxi-dt-for-7.2
>>>>>
>>>>> for you to fetch changes up to 44cf19e41c769720750dbb8752aca75c247e565f:
>>>>>
>>>>> arm64: dts: allwinner: a523: add gpadc node (2026-05-25 05:02:58 +0800)
>>>>>
>>>>>
>>>>> As mentioned in the tag, this pull request contains a change that should
>>>>> be shared between the soc and clk trees. However since I don't have any
>>>>> clk changes to send this cycle, I think it can just go through the soc
>>>>> tree without any issues.
>>>>
>>>> But the clock driver change cannot be in the DTS branch. This should go
>>>> via clock tree even if it is one change. And definitely not via DTS
>>>> branch.
>>>
>>> It is a shared change, because it moves two symbols from the driver's
>>> private header to the public DT binding header. I don't see how this
>>> can go through just the clk tree when one of the subsequent patches
>>> uses those new symbols.
>>>
>>> "clk: sunxi-ng: v3s: Export MBUS and DRAM clocks to the public header"
>>> is needed by "ARM: dts: sun8i: v3s: Add mbus node to represent the
>>> interconnect".
>>>
>>> The other way to go about this is to use raw numbers first, then
>>> another patch in the next cycle to switch the numbers to actual
>>> macros. IMHO not worth the churn and headache.
>>
>> You can have a duplicated define.
>
> I honestly did not know that it worked.
>
> However, splitting what is effectively one logical change (*move*
> something) into two patches just to be able to merge them through two
> separate trees still seems wrong to me.
It is not really one logical change. Defining a new ABI (binding header
define) is considered one change. Merging binding change into driver
commit breaks rule of splitting bindings from implementation.
Second rule is that DTS branch CANNOT take driver changes. So if you do
not want to adhere to the above rule you still cannot combine it into
DTS branch.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2] virt: arm-cca-guest: use raw variant of smp_processor_id() in arm_cca_report_new()
From: Kohei Enju @ 2026-06-09 13:16 UTC (permalink / raw)
To: Will Deacon
Cc: Suzuki K Poulose, Catalin Marinas, Sami Mujawar, Gavin Shan,
Steven Price, linux-arm-kernel, linux-kernel
In-Reply-To: <aiAUceqBREjwXk_V@willie-the-truck>
On 06/03 12:48, Will Deacon wrote:
> On Tue, Jun 02, 2026 at 04:48:43PM +0100, Suzuki K Poulose wrote:
> > On 02/06/2026 12:01, Will Deacon wrote:
> > > On Tue, May 19, 2026 at 07:12:08PM +0900, Kohei Enju wrote:
> > > > With CONFIG_DEBUG_PREEMPT=y, smp_processor_id() becomes an alias of
> > > > debug_smp_processor_id(). This debug function complains when certain
> > > > conditions that ensure CPU ID stability are not met, specifically when
> > > > it's called from a preemptible context.
> > > >
> > > > In arm_cca_report_new(), which runs in a preemptible context,
> > > > smp_processor_id() triggers a splat [0] due to this.
> > > >
> > > > However, the CPU ID obtained here is used as the target CPU for
> > > > smp_call_function_single() to designate a specific CPU for subsequent
> > > > operations, not to assert that the current thread will continue to
> > > > execute on the same CPU. Therefore, snapshotting the CPU ID itself is
> > > > correct, and thus there's no actual harm except for the splat.
> > > >
> > > > Use raw_smp_processor_id() instead, to directly retrieve the current CPU
> > > > ID without the debug checks, avoiding the unnecessary warning message
> > > > while preserving the correct functional behavior.
> > >
> > > That's pretty disgusting imo so I'd like to see some more justification
> > > for this approach.
> > >
> > > > Note that while migrate_disable() would pin the task to the current CPU,
> > > > this path should not block CPU hotplug events. Therefore, we snapshot
> > > > the current CPU ID and accept that smp_call_function_single() may fail
> > > > if the CPU goes offline.
> > >
> > > Why shouldn't it block CPU hotplug events? What happens if the CPU goes
> > > offline and comes back online again during the loop of continue calls?
> >
> > It need not. It can continue the calls. The RMM keeps track of the internal
> > progress in the "REC" object for this "VCPU". Hotplug ON/OFF
> > doesn't change the REC object in CCA Guest. So, a REC can come back and
> > execute it. But the Linux could fail the operation if the CPU isn't
> > available for fetching the report, after we do a RSI_ATTEST_TOKEN_INIT.
>
> I couldn't really shake that out of the RMM spec tbh:
> RSI_ATTESTATION_TOKEN_CONTINUE is allowed to return RSI_ERROR_UNKNOWN
> and I couldn't find anything about hotplug.
>
> But my main point, really, is why are we not using migrate_disable()
> here? I can't see the justification.
Hi Will,
Sorry for the late reply.
I agree that using migrate_disable() makes this path simpler and
clearer.
I've reviewed the discussion where the original commit was introduced:
https://lore.kernel.org/linux-arm-kernel/7a83461d-40fd-4e61-8833-5dae2abaf82b@arm.com/
but I couldn't find a strong reason why we shouldn't block CPU hotplug
or use migrate_disable(), even though I can see the current design was
intentional.
So I'm happy to rework the patch to use migrate_disable() and remove
the smp_call_function_single() calls if there are no objections.
>
> Will
>
^ permalink raw reply
* [PATCH v2] arm64/hw_breakpoint: reject unaligned watchpoints that would truncate BAS
From: Breno Leitao @ 2026-06-09 13:15 UTC (permalink / raw)
To: Will Deacon, Mark Rutland, Catalin Marinas, Pratyush Anand
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, clm, leo.bras,
kernel-team, Breno Leitao
hw_breakpoint_arch_parse() positions the BAS bit pattern in
hw->ctrl.len with
offset = hw->address & alignment_mask; /* 0..7 */
hw->ctrl.len <<= offset;
ctrl.len is an 8-bit bitfield (struct arch_hw_breakpoint_ctrl::len is
u32 :8), so the shift silently drops any bits past bit 7. For
non-compat AArch64 watchpoints the offset is unbounded relative to
ctrl.len: a perf_event_open(PERF_TYPE_BREAKPOINT) caller asking for
HW_BREAKPOINT_W with bp_addr=page+1 and bp_len=HW_BREAKPOINT_LEN_8
ends up with 0xff << 1 = 0x1fe, stored as 0xfe. The kernel programs
WCR.BAS=0xfe and the hardware watches bytes [1..7] instead of the
requested [1..8] -- the eighth byte is silently dropped. The
syscall still returns success, leaving userspace to discover the
gap by empirical probing.
The same class affects HW_BREAKPOINT_LEN_{2,4} when offset pushes the
high BAS bit past bit 7 (e.g. LEN_4 with offset=5 yields 0xe0
instead of 0x1e0). No memory-safety impact -- the value is masked
into 8 bits before encoding -- but debuggers and perf users observe
missed events on bytes they thought they were watching.
The AArch32 branch immediately above already rejects unrepresentable
(offset, len) combinations via an explicit switch. Mirror that for
the non-compat branch by checking that the shifted pattern fits in
the BAS field, returning -EINVAL when it does not.
GDB and similar debuggers are unaffected by the stricter check.
aarch64_linux_set_debug_regs() already treats EINVAL on
NT_ARM_HW_WATCH as a downgrade signal: it clears
kernel_supports_any_contiguous_range, calls aarch64_downgrade_regs()
to round the BAS up to a legacy 0x01/03/0f/ff mask with an aligned
base, and retries -- the same fallback path that PR-20207 introduced.
The new -EINVAL is therefore reachable only from a raw
perf_event_open() that pairs an unaligned base with an oversized
bp_len, which is precisely the bug.
Reproducer:
struct perf_event_attr a = {
.type = PERF_TYPE_BREAKPOINT, .size = sizeof(a),
.bp_type = HW_BREAKPOINT_W,
.bp_addr = (uintptr_t)(buf + 1),
.bp_len = HW_BREAKPOINT_LEN_8,
.exclude_kernel = 1, .exclude_hv = 1,
};
int fd = perf_event_open(&a, 0, -1, -1, 0);
/* before this fix: succeeds, watches 7 bytes (buf+1..buf+7) */
/* after this fix: fails with EINVAL */
Fixes: b08fb180bb88 ("arm64: Allow hw watchpoint at varied offset from base address")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v2:
- Use ARM_BREAKPOINT_LEN_8 instead of the 0xff magic number (Will).
- Checked and Expand the commit log to explain why GDB and similar
debuggers are unaffected by the new -EINVAL
- Link to v1: https://patch.msgid.link/20260430-arm64_bas-v1-1-c6ab2b15aec0@debian.org
---
arch/arm64/kernel/hw_breakpoint.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index ab76b36dce82..73cce8ac8368 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -559,6 +559,15 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
else
alignment_mask = 0x7;
offset = hw->address & alignment_mask;
+
+ /*
+ * BAS is an 8-bit field in WCR/BCR; the shift below would
+ * silently drop the high bits of ctrl.len when offset + len
+ * exceeds 8, programming hardware to watch fewer bytes than
+ * the user requested.
+ */
+ if (((u32)hw->ctrl.len << offset) > ARM_BREAKPOINT_LEN_8)
+ return -EINVAL;
}
hw->address &= ~alignment_mask;
---
base-commit: 0787c45ea08a13b5482e701fabc741877cf681f6
change-id: 20260430-arm64_bas-77e37d830226
Best regards,
--
Breno Leitao <leitao@debian.org>
^ permalink raw reply related
* Re: [PATCH v6 14/20] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Petr Tesarik @ 2026-06-09 13:12 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley
In-Reply-To: <20260604083959.1265923-15-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:53 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
>
> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> again, and pass the CPU address back through an out-parameter for the
> dma_direct_alloc() caller.
>
> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> Cc: stable@vger.kernel.org
While I totally agree with the reasoning and the fix, it's interesting
that this bug has been apparently present in the kernel for 5+ years
without anybody hitting nasty memory corruption bugs.
How can it be? Is the buggy code path never actually used in practice?
Does it hint at a missed opportunity to simplify the code?
Anyway, these these thoughts are intended for a possible future
cleanup. For now, let's apply the fix as is, of course.
Petr T
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> kernel/dma/direct.c | 21 ++++++++++++---------
> 1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 4e446aa4130e..e0ab9ff3f1d6 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -157,24 +157,24 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
> return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
> }
>
> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> - dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> + dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp,
> + unsigned long attrs)
> {
> struct page *page;
> u64 phys_limit;
> - void *ret;
>
> if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
> return NULL;
>
> gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
> - page = dma_alloc_from_pool(dev, size, &ret, gfp, attrs,
> + page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, attrs,
> dma_coherent_ok);
> if (!page)
> return NULL;
> *dma_handle = phys_to_dma_direct(dev, page_to_phys(page),
> !!(attrs & DMA_ATTR_CC_SHARED));
> - return ret;
> + return page;
> }
>
> static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
> @@ -270,9 +270,12 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> * the atomic pools instead if we aren't allowed block.
> */
> if ((remap || (attrs & DMA_ATTR_CC_SHARED)) &&
> - dma_direct_use_pool(dev, gfp))
> - return dma_direct_alloc_from_pool(dev, size, dma_handle,
> - gfp, attrs);
> + dma_direct_use_pool(dev, gfp)) {
> + page = dma_direct_alloc_from_pool(dev, size,
> + dma_handle, &cpu_addr,
> + gfp, attrs);
> + return page ? cpu_addr : NULL;
> + }
>
> if (is_swiotlb_for_alloc(dev)) {
> page = dma_direct_alloc_swiotlb(dev, size, attrs);
> @@ -445,7 +448,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
>
> if ((attrs & DMA_ATTR_CC_SHARED) && dma_direct_use_pool(dev, gfp))
> return dma_direct_alloc_from_pool(dev, size, dma_handle,
> - gfp, attrs);
> + &cpu_addr, gfp, attrs);
>
> if (is_swiotlb_for_alloc(dev)) {
> page = dma_direct_alloc_swiotlb(dev, size, attrs);
^ 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 11:32 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, linux-acpi, linux-kernel, devicetree,
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,
Florian Fainelli
In-Reply-To: <86ecigt2hq.wl-maz@kernel.org>
On 09.06.2026 12:46, Marc Zyngier wrote:
> On Tue, 09 Jun 2026 11:35:24 +0100,
> Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>> On 09.06.2026 12:21, Marc Zyngier wrote:
>>> On Tue, 09 Jun 2026 11:03:21 +0100,
>>> Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>>> 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:
>>> Huh.
>>>
>>> [...]
>>>
>>>> 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
>>> The interrupt appears to be advertised in the DT, but doesn't seem to
>>> fire. That's obviously not going to end well. My suspicion is that
>>> either the interrupt isn't wired (that'd be hilariously abd), or is
>>> left as Group-0 by the firmware (copy-paste from RPi4).
>>>
>>> Can you try the following hack and let me know if the kernel shouts at
>>> you?
>>>
>>> Thanks,
>>>
>>> M.
>>>
>>> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
>>> index ec70c84e9f91d..d05791e6cc0db 100644
>>> --- a/drivers/irqchip/irq-gic.c
>>> +++ b/drivers/irqchip/irq-gic.c
>>> @@ -213,6 +213,7 @@ static void gic_eoimode1_mask_irq(struct irq_data *d)
>>> static void gic_unmask_irq(struct irq_data *d)
>>> {
>>> gic_poke_irq(d, GIC_DIST_ENABLE_SET);
>>> + WARN_ON(!gic_peek_irq(d, GIC_DIST_ENABLE_SET));
>>> }
>>>
>>> static void gic_eoi_irq(struct irq_data *d)
>> I've applied this change, but it doesn't trigger any warning in the boot log.
> [+ Florian]
>
> Huh. So that really points at the timer not being wired into the GIC,
> Samsung style... Can you confirm that removing the EL2 virtual timer
> from the DT results in a booting machine?
With the following diff the board boots again:
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
index 761c59d90ffc..09ff5e9959d3 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -678,8 +678,6 @@ IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>,
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(4) |
IRQ_TYPE_LEVEL_LOW)>;
};
> Florian, can you please check whether PPI12 is actually the EL2
> virtual timer on the RPI5 SoC?
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply related
* Re: [PATCH] gpio: zynq: fix runtime PM leak on remove
From: Pandey, Radhey Shyam @ 2026-06-09 13:00 UTC (permalink / raw)
To: Ruoyu Wang, Shubhrajyoti Datta, Srinivas Neeli, Michal Simek,
Linus Walleij, Bartosz Golaszewski
Cc: Harini Katakam, Soren Brinkmann, linux-gpio, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260609073313.5-1-ruoyuw560@gmail.com>
> pm_runtime_get_sync() increments the runtime PM usage counter even when it
> returns an error. zynq_gpio_remove() uses it to keep the controller active
> while removing the GPIO chip, but never drops the usage counter again.
>
> Balance the get with pm_runtime_put_noidle() after disabling runtime PM.
>
> Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Thanks!
> ---
> drivers/gpio/gpio-zynq.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
> index 571e366624d2a..fafca91128b2e 100644
> --- a/drivers/gpio/gpio-zynq.c
> +++ b/drivers/gpio/gpio-zynq.c
> @@ -1014,6 +1014,7 @@ static void zynq_gpio_remove(struct platform_device *pdev)
> gpiochip_remove(&gpio->chip);
> device_set_wakeup_capable(&pdev->dev, 0);
> pm_runtime_disable(&pdev->dev);
> + pm_runtime_put_noidle(&pdev->dev);
> }
>
> static struct platform_driver zynq_gpio_driver = {
^ permalink raw reply
* Re: [PATCH v6 13/20] dma-direct: rename ret to cpu_addr in alloc helpers
From: Petr Tesarik @ 2026-06-09 12:54 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Jason Gunthorpe,
Mostafa Saleh, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Michael Kelley
In-Reply-To: <20260604083959.1265923-14-aneesh.kumar@kernel.org>
On Thu, 4 Jun 2026 14:09:52 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> ret in dma_direct_alloc() and dma_direct_alloc_pages() holds the returned
> CPU mapping, not a generic return value. Rename it to cpu_addr and update
> the remaining uses to match.
>
> This makes the allocation paths easier to follow and keeps the local naming
> consistent with what the variable actually represents.
>
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
I wondered if cpu_addr is descriptive enough (a CPU address could
theoretically be virtual or physical), but I can see that a few other
places already use cpu_addr to hold virtual addresses, so yeah, let's
keep this name.
Reviewed-by: Petr Tesarik <ptesarik@suse.com>
Petr T
> ---
> kernel/dma/direct.c | 31 +++++++++++++++----------------
> 1 file changed, 15 insertions(+), 16 deletions(-)
>
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index aa3489aa10a0..4e446aa4130e 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -204,7 +204,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> bool mark_mem_decrypt = false;
> bool allow_highmem = true;
> struct page *page;
> - void *ret;
> + void *cpu_addr;
>
> /*
> * DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
> @@ -318,34 +318,33 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> arch_dma_prep_coherent(page, size);
>
> /* create a coherent mapping */
> - ret = dma_common_contiguous_remap(page, size, prot,
> - __builtin_return_address(0));
> - if (!ret)
> + cpu_addr = dma_common_contiguous_remap(page, size, prot,
> + __builtin_return_address(0));
> + if (!cpu_addr)
> goto out_encrypt_pages;
> } else {
> - ret = page_address(page);
> + cpu_addr = page_address(page);
> }
>
> - memset(ret, 0, size);
> + memset(cpu_addr, 0, size);
>
> if (set_uncached) {
> void *uncached_cpu_addr;
>
> arch_dma_prep_coherent(page, size);
> - uncached_cpu_addr = arch_dma_set_uncached(ret, size);
> + uncached_cpu_addr = arch_dma_set_uncached(cpu_addr, size);
> if (IS_ERR(uncached_cpu_addr))
> goto out_free_remap_pages;
> - ret = uncached_cpu_addr;
> + cpu_addr = uncached_cpu_addr;
> }
>
> *dma_handle = phys_to_dma_direct(dev, page_to_phys(page),
> !!(attrs & DMA_ATTR_CC_SHARED));
> - return ret;
> -
> + return cpu_addr;
>
> out_free_remap_pages:
> if (remap)
> - dma_common_free_remap(ret, size);
> + dma_common_free_remap(cpu_addr, size);
>
> out_encrypt_pages:
> if (mark_mem_decrypt &&
> @@ -439,7 +438,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
> {
> unsigned long attrs = 0;
> struct page *page;
> - void *ret;
> + void *cpu_addr;
>
> if (force_dma_unencrypted(dev))
> attrs |= DMA_ATTR_CC_SHARED;
> @@ -453,7 +452,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
> if (!page)
> return NULL;
>
> - ret = page_address(page);
> + cpu_addr = page_address(page);
> goto setup_page;
> }
>
> @@ -461,11 +460,11 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
> if (!page)
> return NULL;
>
> - ret = page_address(page);
> - if ((attrs & DMA_ATTR_CC_SHARED) && dma_set_decrypted(dev, ret, size))
> + cpu_addr = page_address(page);
> + if ((attrs & DMA_ATTR_CC_SHARED) && dma_set_decrypted(dev, cpu_addr, size))
> goto out_leak_pages;
> setup_page:
> - memset(ret, 0, size);
> + memset(cpu_addr, 0, size);
> *dma_handle = phys_to_dma_direct(dev, page_to_phys(page),
> !!(attrs & DMA_ATTR_CC_SHARED));
> return page;
^ permalink raw reply
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