Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v5] soc: aspeed: lpc-snoop: Fix usercopy overflow in snoop_file_read
From: Andrew Jeffery @ 2026-06-12  0:39 UTC (permalink / raw)
  To: karthikeyan K S
  Cc: joel, andrew, Kees Cook, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-hardening, stable
In-Reply-To: <CAP_JKPu9MTpMUZmg9BY3sxGhmBzgR0E6HnvAT7sQjVUpQp0dSQ@mail.gmail.com>

On Thu, 2026-06-11 at 23:01 +0530, karthikeyan K S wrote:
> Thanks Andrew. The __guarded_by annotation and context analysis integration
> look good, I wasn't aware of that infrastructure.
> Thanks for applying those changes on top.

Sorry, on reflection I chose my words poorly there. I applied that
patch I pasted on top as an experiment on my end. I haven't yet added
your patch to the fixes branch.

Do you mind integrating that rework, testing, and then sending the
result?

Cheers,

Andrew


^ permalink raw reply

* Re: [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Shanker Donthineni @ 2026-06-12  1:13 UTC (permalink / raw)
  To: Will Deacon
  Cc: Catalin Marinas, Vladimir Murzin, Jason Gunthorpe,
	linux-arm-kernel@lists.infradead.org, Mark Rutland,
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	Vikram Sethi, Jason Sequeira, Shanker Donthineni
In-Reply-To: <IA1PR12MB6089049028A73A2078FC6831C71B2@IA1PR12MB6089.namprd12.prod.outlook.com>

Hi Will,

On 6/11/2026 8:39 AM, sdonthineni@nvidia.com wrote:
>
> -----Original Message-----
> From: Will Deacon <will@kernel.org>
> Sent: Thursday, June 11, 2026 8:34 AM
> To: Shanker Donthineni <sdonthineni@nvidia.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>; Vladimir Murzin <vladimir.murzin@arm.com>; Jason Gunthorpe <jgg@nvidia.com>; linux-arm-kernel@lists.infradead.org; Mark Rutland <mark.rutland@arm.com>; linux-kernel@vger.kernel.org; linux-doc@vger.kernel.org; Vikram Sethi <vsethi@nvidia.com>; Jason Sequeira <jsequeira@nvidia.com>
> Subject: Re: [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
>
> External email: Use caution opening links or attachments
>
>
> On Wed, Jun 10, 2026 at 11:48:22AM -0500, Shanker Donthineni wrote:
>> On systems with NVIDIA Olympus cores, a Device-nGnR* load can be
>> observed by a peripheral before an older, non-overlapping Device-nGnR*
>> store to the same peripheral. This breaks the program-order guarantee
>> that software expects for Device-nGnR* accesses and can leave a
>> peripheral in an incorrect state, as a load is observed before an
>> earlier store takes effect.
>>
>> The erratum can occur only when all of the following apply:
>>
>>    - A PE executes a Device-nGnR* store followed by a younger
>>      Device-nGnR* load.
>>    - The store is not a store-release.
>>    - The accesses target the same peripheral and do not overlap in bytes.
>>    - There is at most one intervening Device-nGnR* store in program
>>      order, and there are no intervening Device-nGnR* loads.
>>    - There is no DSB, and no DMB that orders loads, between the store and
>>      the load.
>>    - Specific micro-architectural and timing conditions occur.
>>
>> Promote the raw MMIO store helpers (__raw_writeb/w/l/q) from plain
>> str* to stlr* (Store-Release), which removes the "store is not a
>> store-release" condition for every device write the kernel issues.
>> Because writel() and writel_relaxed() are both built on __raw_writel()
>> in asm-generic/io.h, patching the raw variants covers both the
>> non-relaxed and relaxed APIs without touching the higher layers. Note
>> that writel()'s own barrier sits before the store, so it does not
>> order the store against a subsequent readl(); the store-release
>> promotion is what provides that ordering.
>>
>> Like ARM64_ERRATUM_832075 on the load side, the change is gated on a
>> new ARM64_WORKAROUND_DEVICE_STORE_RELEASE capability and only
>> activated on parts that match MIDR_NVIDIA_OLYMPUS, so unaffected CPUs
>> continue to use the plain str* sequence.
>>
>> Note: stlr* only supports base-register addressing, so affected CPUs
>> use a base-register stlr* path. Unaffected CPUs keep the original
>> offset-addressed str* sequence introduced by commit d044d6ba6f02
>> ("arm64: io: permit offset addressing").
>>
>> The __const_memcpy_toio_aligned32() and
>> __const_memcpy_toio_aligned64() helpers are left unchanged. These
>> helpers are intended for write-combining mappings, which are Normal-NC
>> on arm64. Replacing their contiguous str* groups would defeat the
>> write-combining behavior used to improve store performance.
>>
>> Co-developed-by: Vikram Sethi <vsethi@nvidia.com>
>> Signed-off-by: Vikram Sethi <vsethi@nvidia.com>
>> Signed-off-by: Shanker Donthineni <sdonthineni@nvidia.com>
>> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>> Changes since v2:
>>    - Reworked the raw MMIO write helpers so unaffected CPUs keep the
>>      existing offset-addressed STR sequence, while affected CPUs use the
>>      base-register STLR path.
>>    - Updated the commit message to match the code changes.
>>    - Rebased on top of the arm64 for-next/errata branch:
>>      
>> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h
>> =for-next/errata
>>
>> Changes since v1:
>>    - Updated the commit message based on feedback from Vladimir Murzin.
>>
>>   Documentation/arch/arm64/silicon-errata.rst |  2 ++
>>   arch/arm64/Kconfig                          | 23 ++++++++++++++++
>>   arch/arm64/include/asm/io.h                 | 30 +++++++++++++++++++++
>>   arch/arm64/kernel/cpu_errata.c              |  8 ++++++
>>   arch/arm64/tools/cpucaps                    |  1 +
>>   5 files changed, 64 insertions(+)
>>
>> diff --git a/Documentation/arch/arm64/silicon-errata.rst
>> b/Documentation/arch/arm64/silicon-errata.rst
>> index ad09bbb10da80..fc45125dc2f80 100644
>> --- a/Documentation/arch/arm64/silicon-errata.rst
>> +++ b/Documentation/arch/arm64/silicon-errata.rst
>> @@ -298,6 +298,8 @@ stable kernels.
>>   +----------------+-----------------+-----------------+-----------------------------+
>>   | NVIDIA         | Carmel Core     | N/A             | NVIDIA_CARMEL_CNP_ERRATUM   |
>>   
>> +----------------+-----------------+-----------------+----------------
>> -------------+
>> +| NVIDIA         | Olympus core    | T410-OLY-1027   | NVIDIA_OLYMPUS_1027_ERRATUM |
>> ++----------------+-----------------+-----------------+-----------------------------+
>>   | NVIDIA         | Olympus core    | T410-OLY-1029   | ARM64_ERRATUM_4118414       |
>>   +----------------+-----------------+-----------------+-----------------------------+
>>   | NVIDIA         | T241 GICv3/4.x  | T241-FABRIC-4   | N/A                         |
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index
>> c65cef81be86a..d633eb70de1ac 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -564,6 +564,29 @@ config ARM64_ERRATUM_832075
>>
>>          If unsure, say Y.
>>
>> +config NVIDIA_OLYMPUS_1027_ERRATUM
>> +     bool "NVIDIA Olympus: device store/load ordering erratum"
>> +     default y
>> +     help
>> +       This option adds an alternative code sequence to work around an
>> +       NVIDIA Olympus core erratum where a Device-nGnR* store can be
>> +       observed by a peripheral after a younger Device-nGnR* load to the
>> +       same peripheral. This breaks the program order that drivers rely
>> +       on for MMIO and can leave a device in an incorrect state.
>> +
>> +       The workaround promotes the raw MMIO store helpers
>> +       (__raw_writeb/w/l/q) to Store-Release (STLR), which restores the
>> +       required ordering. Because writel() and writel_relaxed() are built
>> +       on __raw_writel(), both are covered without changes to the higher
>> +       layers.
>> +
>> +       The fix is applied through the alternatives framework, so enabling
>> +       this option does not by itself activate the workaround: it is
>> +       patched in only when an affected CPU is detected, and is a no-op on
>> +       unaffected CPUs.
>> +
>> +       If unsure, say Y.
>> +
>>   config ARM64_ERRATUM_834220
>>        bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
>>        depends on KVM
>> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
>> index 8cbd1e96fd50b..801223e754c90 100644
>> --- a/arch/arm64/include/asm/io.h
>> +++ b/arch/arm64/include/asm/io.h
>> @@ -22,10 +22,22 @@
>>   /*
>>    * Generic IO read/write.  These perform native-endian accesses.
>>    */
>> +static __always_inline bool arm64_needs_device_store_release(void)
>> +{
>> +     return alternative_has_cap_unlikely(
>> +                             ARM64_WORKAROUND_DEVICE_STORE_RELEASE);
>> +}
>> +
>>   #define __raw_writeb __raw_writeb
>>   static __always_inline void __raw_writeb(u8 val, volatile void
>> __iomem *addr)  {
>>        volatile u8 __iomem *ptr = addr;
>> +
>> +     if (arm64_needs_device_store_release()) {
>> +             asm volatile("stlrb %w0, [%1]" : : "rZ" (val), "r" (addr));
>> +             return;
>> +     }
>> +
>>        asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));  }
> Use an 'else' clause instead of the early return? (similarly for the other changes).
>
> I still reckon you should do something with the memcpy-to-io routines.
> A simple option could be to make dgh() a dmb on parts with the erratum?
> That at least moves the barrier out of the loop.

Thanks Will. I looked again at both the arm64 comments and the generic iomap_copy.c
contract, and I’m not convinced that making dgh() a dmb is the right fit for this
path. Based on the documented comments, callers should not assume ordering from
these helpers; if ordering is required around a memcpy, the call site should already
be providing the necessary barriers.

Related data point in generic lib/iomap_copy.c:

/**
  * __iowrite32_copy - copy data to MMIO space, in 32-bit units
  * @to: destination, in MMIO space (must be 32-bit aligned)
  * @from: source (must be 32-bit aligned)
  * @count: number of 32-bit quantities to copy
  *
  * Copy data from kernel space to MMIO space, in units of 32 bits at a
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
#ifndef __iowrite32_copy
void __iowrite32_copy(void __iomem *to, const void *from, size_t count)

/**
  * __iowrite64_copy - copy data to MMIO space, in 64-bit or 32-bit units
  * @to: destination, in MMIO space (must be 64-bit aligned)
  * @from: source (must be 64-bit aligned)
  * @count: number of 64-bit quantities to copy
  *
  * Copy data from kernel space to MMIO space, in units of 32 or 64 bits at a
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
#ifndef __iowrite64_copy
void __iowrite64_copy(void __iomem *to, const void *from, size_t count)

/**
  * __iowrite32_copy - copy data to MMIO space, in 32-bit units
  * @to: destination, in MMIO space (must be 32-bit aligned)
  * @from: source (must be 32-bit aligned)
  * @count: number of 32-bit quantities to copy
  *
  * Copy data from kernel space to MMIO space, in units of 32 bits at a
  * time.  Order of access is not guaranteed, nor is a memory barrier
  * performed afterwards.
  */
#ifndef __iowrite32_copy
void __iowrite32_copy(void __iomem *to, const void *from, size_t count)


The arm64 comment says in arch/arm64/asm/io.h:

/*
  * The ARM64 iowrite implementation is intended to support drivers that want to
  * use write combining. For instance PCI drivers using write combining with a 64
  * byte __iowrite64_copy() expect to get a 64 byte MemWr TLP on the PCIe bus.
  *
  * Newer ARM core have sensitive write combining buffers, it is important that
  * the stores be contiguous blocks of store instructions. Normal memcpy
  * approaches have a very low chance to generate write combining.
  *
  * Since this is the only API on ARM64 that should be used with write combining
  * it also integrates the DGH hint which is supposed to lower the latency to
  * emit the large TLP from the CPU.
  */

So my reading is that dgh() in the arm64 implementation is there for the
write-combining/gathering behavior. Replacing it with dmb would make this
path stronger than the generic API contract and could penalize performance
of the WC use case.

For the scalar MMIO helpers, the workaround promotes the raw writes to
store-release on affected CPUs as v1/v2 shown below. For the memcpy-toIO
helpers, could you please clarify the specific reason for adding a dmb despite
the documented no-ordering contract? Is the concern that some drivers may
be relying on ordering across memcpy_toio_*() today even though the API
does not guarantee it, and that we should cover those cases defensively?

Would prefer to avoid replacing DGH() with DMB unless there is a strong
reason to do so. Please let me know if I can post the v4 patch with
the change below, while keeping DGH() as-is in the memcpy-toIO path.

  #define __raw_writeb __raw_writeb
  static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
  {
-       volatile u8 __iomem *ptr = addr;
-       asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));
+       asm volatile(ALTERNATIVE("strb %w0, [%1]",
+                                "stlrb %w0, [%1]",
+                                ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
+                    : : "rZ" (val), "r" (addr));
  }

  #define __raw_writew __raw_writew
  static __always_inline void __raw_writew(u16 val, volatile void __iomem *addr)
  {
-       volatile u16 __iomem *ptr = addr;
-       asm volatile("strh %w0, %1" : : "rZ" (val), "Qo" (*ptr));
+       asm volatile(ALTERNATIVE("strh %w0, [%1]",
+                                "stlrh %w0, [%1]",
+                                ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
+                    : : "rZ" (val), "r" (addr));
  }

  #define __raw_writel __raw_writel
  static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr)
  {
-       volatile u32 __iomem *ptr = addr;
-       asm volatile("str %w0, %1" : : "rZ" (val), "Qo" (*ptr));
+       asm volatile(ALTERNATIVE("str %w0, [%1]",
+                                "stlr %w0, [%1]",
+                                ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
+                    : : "rZ" (val), "r" (addr));
  }

  #define __raw_writeq __raw_writeq
  static __always_inline void __raw_writeq(u64 val, volatile void __iomem *addr)
  {
-       volatile u64 __iomem *ptr = addr;
-       asm volatile("str %x0, %1" : : "rZ" (val), "Qo" (*ptr));
+       asm volatile(ALTERNATIVE("str %x0, [%1]",
+                                "stlr %x0, [%1]",
+                                ARM64_WORKAROUND_DEVICE_STORE_RELEASE)
+                    : : "rZ" (val), "r" (addr));
  }


-Shanker



^ permalink raw reply

* Re: [PATCH v2 1/2] iommu/arm-smmu-v3: Manage teardown with devm
From: Nicolin Chen @ 2026-06-12  1:15 UTC (permalink / raw)
  To: Shameer Kolothum
  Cc: iommu, linux-kernel, linux-arm-kernel, jgg, joro, will,
	robin.murphy, nathanc, mochs
In-Reply-To: <20260611084205.686559-2-skolothumtho@nvidia.com>

On Thu, Jun 11, 2026 at 09:42:04AM +0100, Shameer Kolothum wrote:
> arm_smmu_device_remove() manually frees the IOPF queue, destroys the
> vmid_map and disables the device, while the IRQs and queues are devm
> managed. devm unwinds only after remove() returns, so the cleanup runs
> in the wrong order. The IOPF queue is freed before the event-queue IRQ
> whose handler uses it.
> 
> Manage all of it with devm so the unwind order is correct. Free the IOPF
> queue and vmid_map via devm actions, and disable the device from one
> registered after arm_smmu_device_reset().
> 
> This is also a prerequisite for fixing a Tegra241 CMDQV CMD_SYNC
> use-after-free in the subsequent patch.
> 
> Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>

Given that the PATCH-2 adds new code to arm_smmu_disable_action()
which is introduced here, should this patch also cc stable tree?

> +static void arm_smmu_free_iopf_action(void *data)
> +{
> +	iopf_queue_free(data);
> +}
> +
> +static void arm_smmu_destroy_vmid_map(void *data)
> +{
> +	ida_destroy(data);
> +}
[...]
> +static void arm_smmu_disable_action(void *data)
> +{
> +	arm_smmu_device_disable(data);
> +}

Jason prefers casting.

Otherwise,

Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>


^ permalink raw reply

* Re: [PATCH v7 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-06-12  1:19 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel
In-Reply-To: <843dc0ff-a504-4237-b0f4-d92be07e2465@lunn.ch>

On Thu, Jun 11, 2026 at 11:57 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > +     /* Marvell 88E6393X EEPROM */
> > +     eeprom@50 {
> > +             compatible = "atmel,24c64";
> > +             reg = <0x50>;
> > +     };
>
> How is this on both a host I2C bus, and the switches I2C bus? Are you
> using multi-master? Is there a GPIO to hold the switch in reset while
> the host access the EEPROM?
>
>       Andrew
Hi Andrew,

Thanks for taking a look at this.

To answer your questions: No, we are not using multi-master.
The EEPROM is physically isolated by a hardware I2C multiplexer.
By default, the mux connects the EEPROM directly to the Marvell switch
for its routine operation and configuration loading. The BMC's I2C bus is
physically disconnected from the EEPROM during this time.

The BMC only gains access to this EEPROM for out-of-band firmware updates.
When an update is required, the BMC or CPLD asserts a reset to the switch,
toggles the I2C mux to route the EEPROM to the BMC, performs the flash,
and then restores the original routing before releasing the switch from reset.

Therefore, there is no runtime concurrent access or multi-master scenario
between the host and the switch.

Would you recommend adding a comment in the device tree to clarify this
hardware isolation, or is this explanation sufficient?

Best regards,
Kyle Hsieh


^ permalink raw reply

* [PATCH RESEND v2 1/2] dt-bindings: i2c: cadence: Add Axiado AX3000
From: Swark Yang @ 2026-06-12  1:37 UTC (permalink / raw)
  To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
	Swark Yang, Conor Dooley
In-Reply-To: <20260611-axiado-ax3000-cadence-i2c-support-v2-0-cfdad0534afa@axiado.com>

The Axiado AX3000 SoC integrates the Cadence I2C controller.
Add a specific compatible string "axiado,ax3000-i2c" to support
its hardware features, including SMBus Quick command capability.

Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Swark Yang <syang@axiado.com>
---
 Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
index 9f1d35ce1fe8..de2110376a3f 100644
--- a/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
+++ b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
@@ -14,9 +14,13 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - cdns,i2c-r1p10 # cadence i2c controller version 1.0
-      - cdns,i2c-r1p14 # cadence i2c controller version 1.4
+    oneOf:
+      - items:
+          - const: axiado,ax3000-i2c
+          - const: cdns,i2c-r1p14
+      - enum:
+          - cdns,i2c-r1p10 # cadence i2c controller version 1.0
+          - cdns,i2c-r1p14 # cadence i2c controller version 1.4
 
   reg:
     maxItems: 1

-- 
2.34.1



^ permalink raw reply related

* [PATCH RESEND v2 2/2] i2c: cadence: Add support for Axiado AX3000
From: Swark Yang @ 2026-06-12  1:37 UTC (permalink / raw)
  To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
	Swark Yang
In-Reply-To: <20260611-axiado-ax3000-cadence-i2c-support-v2-0-cfdad0534afa@axiado.com>

The Axiado AX3000 SoC integrates a Cadence I2C controller
that supports SMBus Quick commands.

Introduce the "axiado,ax3000-i2c" compatible string and
add a new quirk CDNS_I2C_QUIRK_SMBUS_QUICK to enable
this functionality. This allows the controller to support
I2C_FUNC_SMBUS_QUICK, enabling features such as bus scanning
via quick write commands.

Signed-off-by: Swark Yang <syang@axiado.com>
---
 drivers/i2c/busses/i2c-cadence.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 0fb728ade92e..8079c045f936 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -128,6 +128,7 @@
 #define CDNS_I2C_TIMEOUT_MAX	0xFF
 
 #define CDNS_I2C_BROKEN_HOLD_BIT	BIT(0)
+#define CDNS_I2C_QUIRKS_ENABLE_SMBUS_QUICK_CFG BIT(1)
 #define CDNS_I2C_POLL_US	100000
 #define CDNS_I2C_POLL_US_ATOMIC	10
 #define CDNS_I2C_TIMEOUT_US	500000
@@ -1175,10 +1176,14 @@ static int cdns_i2c_master_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg
  */
 static u32 cdns_i2c_func(struct i2c_adapter *adap)
 {
+	struct cdns_i2c *id = adap->algo_data;
 	u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
 			(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
 			I2C_FUNC_SMBUS_BLOCK_DATA;
 
+	if (id->quirks & CDNS_I2C_QUIRKS_ENABLE_SMBUS_QUICK_CFG)
+		func |= I2C_FUNC_SMBUS_QUICK;
+
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
 	func |= I2C_FUNC_SLAVE;
 #endif
@@ -1442,9 +1447,14 @@ static const struct cdns_platform_data r1p10_i2c_def = {
 	.quirks = CDNS_I2C_BROKEN_HOLD_BIT,
 };
 
+static const struct cdns_platform_data ax3000_i2c_def = {
+	.quirks = CDNS_I2C_QUIRKS_ENABLE_SMBUS_QUICK_CFG,
+};
+
 static const struct of_device_id cdns_i2c_of_match[] = {
 	{ .compatible = "cdns,i2c-r1p10", .data = &r1p10_i2c_def },
 	{ .compatible = "cdns,i2c-r1p14",},
+	{ .compatible = "axiado,ax3000-i2c", .data = &ax3000_i2c_def },
 	{ /* end of table */ }
 };
 MODULE_DEVICE_TABLE(of, cdns_i2c_of_match);

-- 
2.34.1



^ permalink raw reply related

* [PATCH RESEND v2 0/2] i2c: cadence: Add support for Axiado AX3000
From: Swark Yang @ 2026-06-12  1:37 UTC (permalink / raw)
  To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
	Swark Yang, Conor Dooley

This patch series adds support for the Cadence I2C controller
integrated into the Axiado AX3000 SoC and enables SMBus Quick
command functionality.

The Axiado AX3000 utilizes the Cadence I2C IP core (version r1p14).
While it is largely compatible with the existing i2c-cadence
driver logic, the AX3000 hardware specifically supports SMBus Quick
commands. This feature is currently disabled by default in the
i2c-cadence driver (masked out from I2C_FUNC_SMBUS_EMUL).

To enable this functionality, this series introduces a new
platform-specific quirk (CDNS_I2C_QUIRK_SMBUS_QUICK) and uses driver
match data for the "axiado,ax3000-i2c" compatible string. This allows
tools like 'i2cdetect' to properly scan the bus using quick write
commands.

The DT binding update follows the recommended fallback structure,
referencing the 'cdns,i2c-r1p14' fallback to ensure compatibility with
older kernels while allowing the new quirk to be enabled on AX3000.

Changes in RESEND:
- Resending as the original submission seems to have slipped through the cracks.
- No code changes since the original submission.
- Collected Conor Dooley's Acked-by for Patch 1.

Patch breakdown:

Patch 1: dt-bindings: i2c: cadence: Add Axiado AX3000
Patch 2: i2c: cadence: Add support for Axiado AX3000

These patches are expected to go via the I2C subsystem tree.

Feedback is welcome.

Signed-off-by: Swark Yang <syang@axiado.com>
---
Changes in v2:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v1: https://lore.kernel.org/r/20260504-axiado-ax3000-cadence-i2c-support-v1-0-97ed2fdc0b7b@axiado.com

---
Swark Yang (2):
      dt-bindings: i2c: cadence: Add Axiado AX3000
      i2c: cadence: Add support for Axiado AX3000

 Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml | 10 +++++++---
 drivers/i2c/busses/i2c-cadence.c                          | 10 ++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)
---
base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
change-id: 20260111-axiado-ax3000-cadence-i2c-support-53ec117bb074

Best regards,
-- 
Swark Yang <syang@axiado.com>



^ permalink raw reply

* Re: [PATCH v2 2/2] iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown
From: Nicolin Chen @ 2026-06-12  1:10 UTC (permalink / raw)
  To: Shameer Kolothum
  Cc: iommu, linux-kernel, linux-arm-kernel, jgg, joro, will,
	robin.murphy, nathanc, mochs
In-Reply-To: <20260611084205.686559-3-skolothumtho@nvidia.com>

On Thu, Jun 11, 2026 at 09:42:05AM +0100, Shameer Kolothum wrote:
> arm_smmu_impl_remove() is registered as a devres action in
> arm_smmu_impl_probe(), before arm_smmu_init_queues() allocates
> smmu->cmdq.q.base. On a devres unwind, whether a failed probe or an
> unbind, the queue is freed first and arm_smmu_impl_remove() then runs
> tegra241_cmdqv_remove_vintf(), whose VINTF deinit issues a CMD_SYNC on
> the freed memory.
> 
> Observed during testing with a QEMU hack that makes the VCMDQ fail to
> enable, so the impl reset fails and probe aborts into the devres unwind:
> 
>  platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: failed to enable, STATUS=0x00000000
>  platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: GERRORN=0x0, GERROR=0x4, CONS=0x0
>  platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: uncleared error detected, resetting
>  arm-smmu-v3 arm-smmu-v3.0.auto: failed to reset impl
>  arm-smmu-v3 arm-smmu-v3.0.auto: probe with driver arm-smmu-v3 failed with error -110
>  Unable to handle kernel paging request at virtual address ffff8000891e0098
>  ...
>  Internal error: Oops: 0000000096000047 [#1] SMP
>  ...
>  Call trace:
>   arm_smmu_cmdq_issue_cmdlist+0x320/0x6fc (P)
>   tegra241_vcmdq_hw_deinit+0x98/0x168
>   tegra241_vintf_hw_deinit+0x5c/0x1b0
>   tegra241_cmdqv_remove_vintf+0x34/0xec
>   tegra241_cmdqv_remove+0x40/0x9c
>   arm_smmu_impl_remove+0x20/0x30
>   devm_action_release+0x14/0x20
>   devres_release_all+0xa8/0x110
>   device_unbind_cleanup+0x18/0x84
>   really_probe+0x1f0/0x29c
> 
> Drop the VINTF deinit from tegra241_cmdqv_remove_vintf() so the unwind no
> longer touches the freed queue. Quiesce the VINTFs earlier instead. Add a
> device_disable() impl op and run it from arm_smmu_disable_action() while
> the CMDQ is still up. That handles a live unbind. A failed reset is already
> handled because tegra241_vintf_hw_init() deinits the VINTF on its own error
> path. tegra241_cmdqv_remove_vintf() is also used by the iommufd viommu
> destroy path, so quiesce there too.
> 
> Fixes: 4dc0d12474f9 ("iommu/tegra241-cmdqv: Add user-space use support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>

Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>


^ permalink raw reply

* RE: [PATCH v3] arm64: dts: imx94: Add Root Port node and PERST property
From: Sherry Sun @ 2026-06-12  1:57 UTC (permalink / raw)
  To: Hongxing Zhu (OSS), robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, Frank Li, s.hauer@pengutronix.de,
	festevam@gmail.com
  Cc: kernel@pengutronix.de, devicetree@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Hongxing Zhu
In-Reply-To: <20260611075057.2892593-1-hongxing.zhu@oss.nxp.com>

> 
> From: Richard Zhu <hongxing.zhu@nxp.com>
> 
> Since describing the PCIe PERST# property under Host Bridge node is now
> deprecated, it is recommended to add it to the Root Port node, so creating the
> Root Port node and add the reset-gpios property in Root Port.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> Reviewed-by: Sherry Sun <sherry.sun@nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx94.dtsi     | 11 +++++++++++
>  arch/arm64/boot/dts/freescale/imx943-evk.dts | 14 ++++++++++----
>  arch/arm64/boot/dts/freescale/imx943.dtsi    | 11 +++++++++++
>  3 files changed, 32 insertions(+), 4 deletions(-)
> ---
> Changes in v3:
> - Move the regulator to Root Port node as well, 

Hi Richard, please also add this info into the commit message.
Others look good to me.

Best Regards
Sherry
> since [2] had been
>   settled.
> - Collect Reviewed-by tag issued by Sherry.
> 
> Changes in v2:
> - Delete reset-gpio properties in PCIe bridge node.
> - Correct the "reset-gpio" property to "reset-gpios".
> 
> Since the patch-set [1] issued by Sherry had been landed. Add according
> changes on i.MX943 board too.
> [1] https://lkml.org/lkml/2026/6/1/1461
> [2] https://lore.kernel.org/imx/20260520084904.2424253-1-
> sherry.sun@oss.nxp.com/
> 
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx94.dtsi
> b/arch/arm64/boot/dts/freescale/imx94.dtsi
> index 1f9035e6cf159..dfbb73603cb24 100644
> --- a/arch/arm64/boot/dts/freescale/imx94.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx94.dtsi
> @@ -1411,6 +1411,17 @@ pcie0: pcie@4c300000 {
>  			power-domains = <&scmi_devpd
> IMX94_PD_HSIO_TOP>;
>  			fsl,max-link-speed = <3>;
>  			status = "disabled";
> +
> +			pcie0_port0: pcie@0 {
> +				compatible = "pciclass,0604";
> +				device_type = "pci";
> +				reg = <0x0 0x0 0x0 0x0 0x0>;
> +				bus-range = <0x01 0xff>;
> +
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				ranges;
> +			};
>  		};
> 
>  		pcie0_ep: pcie-ep@4c300000 {
> diff --git a/arch/arm64/boot/dts/freescale/imx943-evk.dts
> b/arch/arm64/boot/dts/freescale/imx943-evk.dts
> index 7cfd424689507..674410e541cba 100644
> --- a/arch/arm64/boot/dts/freescale/imx943-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx943-evk.dts
> @@ -1034,12 +1034,15 @@ &pcie0 {
>  		 <&pcie_ref_clk>;
>  	clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
>  		      "ref", "extref";
> -	reset-gpio = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>;
> -	vpcie3v3aux-supply = <&reg_m2_wlan>;
>  	supports-clkreq;
>  	status = "okay";
>  };
> 
> +&pcie0_port0 {
> +	reset-gpios = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>;
> +	vpcie3v3aux-supply = <&reg_m2_wlan>;
> +};
> +
>  &pcie0_ep {
>  	pinctrl-0 = <&pinctrl_pcie0>;
>  	pinctrl-names = "default";
> @@ -1058,12 +1061,15 @@ &pcie1 {
>  		 <&pcie_ref_clk>;
>  	clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux",
>  		      "ref", "extref";
> -	reset-gpio = <&pcal6416_i2c3_u46 1 GPIO_ACTIVE_LOW>;
> -	vpcie3v3aux-supply = <&reg_slot_pwr>;
>  	supports-clkreq;
>  	status = "okay";
>  };
> 
> +&pcie1_port0 {
> +	reset-gpios = <&pcal6416_i2c3_u46 1 GPIO_ACTIVE_LOW>;
> +	vpcie3v3aux-supply = <&reg_slot_pwr>;
> +};
> +
>  &pcie1_ep {
>  	pinctrl-0 = <&pinctrl_pcie1>;
>  	pinctrl-names = "default";
> diff --git a/arch/arm64/boot/dts/freescale/imx943.dtsi
> b/arch/arm64/boot/dts/freescale/imx943.dtsi
> index cf5b3dbb47ff7..01152fd0efa5e 100644
> --- a/arch/arm64/boot/dts/freescale/imx943.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx943.dtsi
> @@ -255,6 +255,17 @@ pcie1: pcie@4c380000 {
>  			power-domains = <&scmi_devpd
> IMX94_PD_HSIO_TOP>;
>  			fsl,max-link-speed = <3>;
>  			status = "disabled";
> +
> +			pcie1_port0: pcie@0 {
> +				compatible = "pciclass,0604";
> +				device_type = "pci";
> +				reg = <0x0 0x0 0x0 0x0 0x0>;
> +				bus-range = <0x01 0xff>;
> +
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				ranges;
> +			};
>  		};
> 
>  		pcie1_ep: pcie-ep@4c380000 {
> --
> 2.34.1



^ permalink raw reply

* Re: [PATCH 0/4] Xilinx TRNG fix and simplification
From: Herbert Xu @ 2026-06-12  1:58 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-crypto, linux-kernel, Mounika Botcha, Harsh Jain,
	Olivia Mackall, Michal Simek, linux-arm-kernel
In-Reply-To: <20260611204702.GB1747@quark>

On Thu, Jun 11, 2026 at 01:47:02PM -0700, Eric Biggers wrote:
>
> Can you re-add the following to "hwrng: xilinx - Move xilinx-rng into
> drivers/char/hw_random/"?  It seems you applied this before the qcom-rng
> series, then dropped the drivers/char/hw_random/Makefile change rather
> than resolve it.
> 
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 3e655d6e116b..95b5adb49560 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -51,5 +51,6 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphera-trng.o
>  obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
>  obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
>  obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
>  obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
>  obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
> +obj-$(CONFIG_HW_RANDOM_XILINX) += xilinx-trng.o

Thanks for checking.  It should be fixed now.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply

* [PATCH] ASoC: meson: Use dev_err_probe() for device reset failures
From: phucduc.bui @ 2026-06-12  2:01 UTC (permalink / raw)
  To: Mark Brown, Jerome Brunet
  Cc: Liam Girdwood, Neil Armstrong, Kevin Hilman, Martin Blumenstingl,
	Jaroslav Kysela, Takashi Iwai, linux-sound, linux-arm-kernel,
	linux-amlogic, linux-kernel, bui duc phuc

From: bui duc phuc <phucduc.bui@gmail.com>

device_reset() may return -EPROBE_DEFER. Switch to dev_err_probe() so
probe failures are reported consistently and deferred probing is handled
properly.
This matches the existing pattern used in aiu_probe().
No functional change intended.

Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
 sound/soc/meson/g12a-toacodec.c | 2 +-
 sound/soc/meson/g12a-tohdmitx.c | 2 +-
 sound/soc/meson/t9015.c         | 6 ++----
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c
index a95375b53f0a..21941ee552c5 100644
--- a/sound/soc/meson/g12a-toacodec.c
+++ b/sound/soc/meson/g12a-toacodec.c
@@ -312,7 +312,7 @@ static int g12a_toacodec_probe(struct platform_device *pdev)
 
 	ret = device_reset(dev);
 	if (ret)
-		return ret;
+		return dev_err_probe(dev, ret, "failed to reset device\n");
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
index d541ca4acfaf..967109ca2b57 100644
--- a/sound/soc/meson/g12a-tohdmitx.c
+++ b/sound/soc/meson/g12a-tohdmitx.c
@@ -251,7 +251,7 @@ static int g12a_tohdmitx_probe(struct platform_device *pdev)
 
 	ret = device_reset(dev);
 	if (ret)
-		return ret;
+		return dev_err_probe(dev, ret, "failed to reset device\n");
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
index da1a93946d67..f0b55aee5241 100644
--- a/sound/soc/meson/t9015.c
+++ b/sound/soc/meson/t9015.c
@@ -265,10 +265,8 @@ static int t9015_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(priv->avdd), "failed to AVDD\n");
 
 	ret = device_reset(dev);
-	if (ret) {
-		dev_err(dev, "reset failed\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to reset device\n");
 
 	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs)) {
-- 
2.43.0



^ permalink raw reply related

* [PATCH] arm64: defconfig: enable BST SDHCI controller
From: gordon.ge @ 2026-06-12  0:42 UTC (permalink / raw)
  To: arnd; +Cc: soc, linux-arm-kernel, yangzh0906
In-Reply-To: <178123037729.455092.8454252669856079676@bst.ai>

Enable CONFIG_MMC_SDHCI_BST to support eMMC on Black Sesame
Technologies C1200 boards.

Signed-off-by: Albert Yang <yangzh0906@thundersoft.com>
Acked-by: Gordon Ge <gordon.ge@bst.ai>
Signed-off-by: Gordon Ge <gordon.ge@bst.ai>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d905a0777f93..304e12c80af9 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1292,6 +1292,7 @@ CONFIG_MMC_SDHCI_OF_SPARX5=y
 CONFIG_MMC_SDHCI_CADENCE=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_MMC_SDHCI_BST=y
 CONFIG_MMC_SDHCI_F_SDH30=y
 CONFIG_MMC_MESON_GX=y
 CONFIG_MMC_SDHCI_MSM=y
-- 
2.50.1

^ permalink raw reply related

* [PATCH] arm64: dts: bst: enable eMMC controller in C1200
From: gordon.ge @ 2026-06-12  0:40 UTC (permalink / raw)
  To: arnd; +Cc: soc, linux-arm-kernel, yangzh0906

Add mmc0 node for the DWCMSHC SDHCI controller with basic configuration
(disabled by default) and fixed clock definition in bstc1200.dtsi.

Enable mmc0 with board-specific configuration including 8-bit bus
width and reserved SRAM bounce buffer on the CDCU1.0 ADAS 4C2G board.

The bounce buffer in reserved SRAM addresses hardware constraints
where the eMMC controller cannot access main system memory through
SMMU due to a hardware bug, and all DRAM is located outside the
4GB boundary.

Signed-off-by: Albert Yang <yangzh0906@thundersoft.com>
Acked-by: Gordon Ge <gordon.ge@bst.ai>
Signed-off-by: Gordon Ge <gordon.ge@bst.ai>
---
 .../dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts    | 19 +++++++++++++++++++
 arch/arm64/boot/dts/bst/bstc1200.dtsi         | 18 ++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts b/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts
index 5eb9ef369d8c..178ad4bf4f0a 100644
--- a/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts
+++ b/arch/arm64/boot/dts/bst/bstc1200-cdcu1.0-adas_4c2g.dts
@@ -17,6 +17,25 @@ memory@810000000 {
 		      <0x8 0xc0000000 0x1 0x0>,
 		      <0xc 0x00000000 0x0 0x40000000>;
 	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mmc0_reserved: mmc0-reserved@5160000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x5160000 0x0 0x10000>;
+			no-map;
+		};
+	};
+};
+
+&mmc0 {
+	bus-width = <8>;
+	memory-region = <&mmc0_reserved>;
+	non-removable;
+	status = "okay";
 };
 
 &uart0 {
diff --git a/arch/arm64/boot/dts/bst/bstc1200.dtsi b/arch/arm64/boot/dts/bst/bstc1200.dtsi
index dd13c6bfc3c8..9660d8396e27 100644
--- a/arch/arm64/boot/dts/bst/bstc1200.dtsi
+++ b/arch/arm64/boot/dts/bst/bstc1200.dtsi
@@ -7,6 +7,12 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	clk_mmc: clock-4000000 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <4000000>;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -72,6 +78,18 @@ uart0: serial@20008000 {
 			status = "disabled";
 		};
 
+		mmc0: mmc@22200000 {
+			compatible = "bst,c1200-sdhci";
+			reg = <0x0 0x22200000 0x0 0x1000>,
+			      <0x0 0x23006000 0x0 0x1000>;
+			clocks = <&clk_mmc>;
+			clock-names = "core";
+			dma-coherent;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <200000000>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller@32800000 {
 			compatible = "arm,gic-v3";
 			reg = <0x0 0x32800000 0x0 0x10000>,
-- 
2.50.1

^ permalink raw reply related

* Re: [PATCH] media: bcm2835-unicam: Fix querycap multiple caps
From: kernel test robot @ 2026-06-12  2:14 UTC (permalink / raw)
  To: Eugen Hristev, Raspberry Pi Kernel Maintenance,
	Mauro Carvalho Chehab, Florian Fainelli, Ray Jui, Scott Branden,
	Broadcom internal kernel review list, Sakari Ailus,
	Dave Stevenson, Laurent Pinchart, Jean-Michel Hautbois,
	Naushir Patuck
  Cc: llvm, oe-kbuild-all, linux-media, Hans Verkuil, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel, Eugen Hristev
In-Reply-To: <20260611-bcmpiqcap-v1-1-10cf7fb438df@kernel.org>

Hi Eugen,

kernel test robot noticed the following build errors:

[auto build test ERROR on a87737435cfa134f9cdcc696ba3080759d04cf72]

url:    https://github.com/intel-lab-lkp/linux/commits/Eugen-Hristev/media-bcm2835-unicam-Fix-querycap-multiple-caps/20260611-141320
base:   a87737435cfa134f9cdcc696ba3080759d04cf72
patch link:    https://lore.kernel.org/r/20260611-bcmpiqcap-v1-1-10cf7fb438df%40kernel.org
patch subject: [PATCH] media: bcm2835-unicam: Fix querycap multiple caps
config: um-allmodconfig (https://download.01.org/0day-ci/archive/20260612/202606121013.RsnqIwho-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260612/202606121013.RsnqIwho-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606121013.RsnqIwho-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/media/platform/broadcom/bcm2835-unicam.c:33:
   In file included from include/linux/dma-mapping.h:8:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:1209:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
    1209 |         return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
         |                                                   ~~~~~~~~~~ ^
>> drivers/media/platform/broadcom/bcm2835-unicam.c:1836:20: error: use of undeclared identifier 'node'
    1836 |         if (is_image_node(node))
         |                           ^
   1 warning and 1 error generated.


vim +/node +1836 drivers/media/platform/broadcom/bcm2835-unicam.c

  1825	
  1826	/* -----------------------------------------------------------------------------
  1827	 *  V4L2 video device operations
  1828	 */
  1829	
  1830	static int unicam_querycap(struct file *file, void *priv,
  1831				   struct v4l2_capability *cap)
  1832	{
  1833		strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
  1834		strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
  1835	
> 1836		if (is_image_node(node))
  1837			cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE;
  1838		else
  1839			cap->capabilities |= V4L2_CAP_META_CAPTURE;
  1840	
  1841		return 0;
  1842	}
  1843	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* Re: [PATCH] KVM: arm64: vgic: Check the interrupt is still ours before migrating it
From: Hyunwoo Kim @ 2026-06-12  2:22 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Oliver Upton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
	catalin.marinas, will, Sascha.Bischoff, jic23, timothy.hayes,
	andre.przywara, linux-arm-kernel, kvmarm, imv4bel
In-Reply-To: <865x3qtmg6.wl-maz@kernel.org>

On Wed, Jun 10, 2026 at 05:00:25PM +0100, Marc Zyngier wrote:
> On Wed, 10 Jun 2026 14:52:10 +0100,
> Hyunwoo Kim <imv4bel@gmail.com> wrote:
> > 
> > On Fri, Jun 05, 2026 at 01:43:32AM -0700, Oliver Upton wrote:
> > > On Fri, Jun 05, 2026 at 08:42:52AM +0100, Marc Zyngier wrote:
> > > > On Fri, 05 Jun 2026 07:00:37 +0100,
> > > > Oliver Upton <oupton@kernel.org> wrote:
> > > > > 
> > > > > On Fri, Jun 05, 2026 at 05:59:15AM +0900, Hyunwoo Kim wrote:
> > > > > > vgic_prune_ap_list() drops both ap_list_lock and irq_lock while migrating
> > > > > > an interrupt to another vCPU. After reacquiring the locks it only checks
> > > > > > that the affinity is unchanged (target_vcpu == vgic_target_oracle(irq))
> > > > > > before moving the interrupt, which assumes that an interrupt whose affinity
> > > > > > is preserved is still queued on this vCPU's ap_list.
> > > > > > 
> > > > > > That assumption no longer holds if the interrupt is taken off the ap_list
> > > > > > while the locks are dropped. vgic_flush_pending_lpis() removes the
> > > > > > interrupt from the list and sets irq->vcpu to NULL, but leaves
> > > > > > enabled/pending/target_vcpu untouched. As the interrupt is still enabled
> > > > > > and pending, vgic_target_oracle() returns the same target_vcpu, so the
> > > > > > affinity check passes and list_del() is run a second time on an entry that
> > > > > > has already been removed.
> > > > > > 
> > > > > > Also check that the interrupt is still assigned to this vCPU
> > > > > > (irq->vcpu == vcpu) before moving it.
> > > > > > 
> > > > > > Fixes: 0919e84c0fc1 ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
> > > > > > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
> > > > > 
> > > > > Looking at this and the other VGIC patch you sent (which should've been
> > > > > a combined series), are you trying to deal with a vCPU writing to
> > > > > another vCPU's redistributor? I.e. vCPU B setting GICR_CTLR.EnableLPIs=0
> > > > > behind the back of vCPU A?
> > > > > 
> > > > > That is extremely relevant information as the off-the-cuff reaction is
> > > > > that no race exists. But since the GIC architecture is awesome and
> > > > > allows for this sort of insanity, it obviously does....
> > > > > 
> > > > > Anyway, for LPIs resident on a particular RD, there's zero expectation
> > > > > that the pending state is preserved when EnableLPIs=0. So I'd rather
> > > > > vgic_flush_pending_lpis() just invalidate the pending state.
> > > > 
> > > > Just clearing the pending state introduces a potential problem as we
> > > > now have an interrupt that is neither active nor pending on the AP
> > > > list. It is not impossible to solve (we now have similar behaviours
> > > > with SPI deactivation from another vcpu), but that requires posting a
> > > > KVM_REQ_VGIC_PROCESS_UPDATE to the target vcpu.
> > > 
> > > Right, I was suggesting that in addition to deleting the LPI from the AP
> > > list we actually invalidate the pending state so that someone sitting on
> > > a pointer to a to-be-freed LPI sees vgic_target_oracle() returning
> > > NULL
> > > 
> > > > > Beyond that, I see two other fixes for lifetime issues around the
> > > > > vgic_irq in the middle of migration. I'd like to see explicit RCU
> > > > > protection around the release && reacquire of the ap_list_lock rather
> > > > > than depending on the precondition that IRQs are disabled.
> > > > 
> > > > I'm not sure I follow. Are you suggesting turning the AP list into an
> > > > RCU protected list?
> > > 
> > > No, sorry, I should expand a little.
> > > 
> > > We store a reference on the vgic_irq struct in the AP list, which is
> > > stable so long as the ap_list_lock is held. It should be possible for
> > > the refcount to drop to 0 between releasing the ap_list_lock and
> > > reacquiring it.
> > > 
> > > So either vgic_prune_ap_list() takes an additional reference on the
> > > vgic_irq before dropping the ap_list_lock or rely on RCU to protect
> > > vgic_irq structs observed with a non-zero refcount.
> > 
> > What are your thoughts on this approach?
> > 
> > 
> > Best regards,
> > Hyunwoo Kim
> > 
> > ---
> > 
> > diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> > index 933983bb2005..7fb871c3ccd8 100644
> > --- a/arch/arm64/kvm/vgic/vgic-init.c
> > +++ b/arch/arm64/kvm/vgic/vgic-init.c
> > @@ -523,7 +523,7 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
> >  	 * Retire all pending LPIs on this vcpu anyway as we're
> >  	 * going to destroy it.
> >  	 */
> > -	vgic_flush_pending_lpis(vcpu);
> > +	vgic_flush_pending_lpis(vcpu, true);
> > 
> >  	INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
> >  	kfree(vgic_cpu->private_irqs);
> > diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> > index 5913a20d8301..f85d63f17af0 100644
> > --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> > +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> > @@ -303,7 +303,7 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu,
> >  		if (ctlr != GICR_CTLR_ENABLE_LPIS)
> >  			return;
> > 
> > -		vgic_flush_pending_lpis(vcpu);
> > +		vgic_flush_pending_lpis(vcpu, false);
> >  		vgic_its_invalidate_all_caches(vcpu->kvm);
> >  		atomic_set_release(&vgic_cpu->ctlr, 0);
> >  	} else {
> > diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
> > index 1e9fe8764584..09629a38fc0a 100644
> > --- a/arch/arm64/kvm/vgic/vgic.c
> > +++ b/arch/arm64/kvm/vgic/vgic.c
> > @@ -192,7 +192,7 @@ static void vgic_release_deleted_lpis(struct kvm *kvm)
> >  	xa_unlock_irqrestore(&dist->lpi_xa, flags);
> >  }
> > 
> > -void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
> > +void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu, bool destroy)
> >  {
> >  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> >  	struct vgic_irq *irq, *tmp;
> > @@ -204,6 +204,13 @@ void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
> >  	list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
> >  		if (irq_is_lpi(vcpu->kvm, irq->intid)) {
> >  			raw_spin_lock(&irq->irq_lock);
> > +			/* Leave interrupts pending a migration for prune. */
> > +			if (!destroy && irq->vcpu != vgic_target_oracle(irq)) {
> > +				raw_spin_unlock(&irq->irq_lock);
> > +				continue;
> > +			}
> 
> It's rather unclear to me what the semantics of this are.
> 
> If vcpu-a decides to nuke the LPIs of vcpu-b and the LPI had in the
> meantime been migrated to vcpu-c, but obviously not observed by vcpu-c
> yet as the LPI is still on vcpu-b's AP-list, then I don't see the
> point in keeping this state.
> 
> Am I missing something obvious?

I looked a bit more into Oliver's review, the one suggesting that pending 
be cleared only for resident LPIs while the ones being migrated are left 
in place.

What the leave preserves is the pending edge of a single LPI whose target 
is already vcpu-c but which is still on vcpu-b's ap_list. This edge is 
always lost when we just clear it, but for a device that fires again a 
later INT reaches vcpu-c through the oracle, so it is mostly harmless. The 
exception is a software LPI that never fires again(irq->hw == false): 
that edge is then lost with no way to recover it, because 
its_sync_lpi_pending_table only re-syncs the LPIs whose target_vcpu matches, 
and the disable path does no pending writeback. I am not entirely sure about 
this part, though.

Since this does not look like the common case, if it does not need to be 
covered I will send v2 keeping only the pending clear and the ref hold in 
vgic_prune_ap_list(). What do you think?

> 
> > +			/* Pending state is not preserved across EnableLPIs=0. */
> > +			irq->pending_latch = false;
> 
> That part I agree with.
> 
> >  			list_del(&irq->ap_list);
> >  			irq->vcpu = NULL;
> >  			raw_spin_unlock(&irq->irq_lock);
> > @@ -797,6 +804,9 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
> > 
> >  		/* This interrupt looks like it has to be migrated. */
> > 
> > +		/* Keep the interrupt alive while the locks are dropped. */
> > +		vgic_get_irq_ref(irq);
> > +
> >  		raw_spin_unlock(&irq->irq_lock);
> >  		raw_spin_unlock(&vgic_cpu->ap_list_lock);
> > 
> > @@ -839,6 +849,8 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
> >  		raw_spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
> >  		raw_spin_unlock(&vcpuA->arch.vgic_cpu.ap_list_lock);
> > 
> > +		deleted_lpis |= vgic_put_irq_norelease(vcpu->kvm, irq);
> > +
> >  		if (target_vcpu_needs_kick) {
> >  			kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
> >  			kvm_vcpu_kick(target_vcpu);
> > diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
> > index 9d941241c8a2..c1ac24ede899 100644
> > --- a/arch/arm64/kvm/vgic/vgic.h
> > +++ b/arch/arm64/kvm/vgic/vgic.h
> > @@ -341,7 +341,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu);
> >  bool vgic_has_its(struct kvm *kvm);
> >  int kvm_vgic_register_its_device(void);
> >  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
> > -void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu);
> > +void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu, bool destroy);
> >  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> >  int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr);
> >  int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> > 
> 
> I reckon this would work just as well with just the pending state
> being removed in vgic_flush_pending_lpis(), and the reference holding
> hack in gvgic_prune_ap_list().
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


Best regards,
Hyunwoo Kim


^ permalink raw reply

* Re: [PATCH] ASoC: meson: axg-tdm-formatter: Use guard() for mutex locks
From: Bui Duc Phuc @ 2026-06-12  2:36 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: Mark Brown, Liam Girdwood, Neil Armstrong, Kevin Hilman,
	Martin Blumenstingl, Jaroslav Kysela, Takashi Iwai, linux-sound,
	linux-arm-kernel, linux-amlogic, linux-kernel
In-Reply-To: <1jo6hhebus.fsf@starbuckisacylon.baylibre.com>

Hi Jerome,

Thank you for the review and for the Reviewed-by tag.

>
> The code is not better or worse with the change but you went through the
> trouble of doing so, if Mark is fine with it, let's have it
>
> Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
>

Regarding the point about whether the change makes the code better or worse,
I have sent an additional patch to address related cleanup in the same area:

https://lore.kernel.org/all/20260612020113.9557-1-phucduc.bui@gmail.com/

Would appreciate your review on that as well.

While looking into the Meson ASoC probe paths,
I noticed a few consistency issues that seem to appear across multiple drivers:

1. Mixed usage of dev_err_probe() and dev_err() in probe error paths.

2. Inconsistent error message formatting: some messages start with lowercase
   ("failed to init..."), while others start with uppercase ("Failed
to register...").

3. In aiu_probe(), error paths for IRQ retrieval do not provide
additional context,
    making it harder to identify which resource failed:

   aiu->i2s.irq = platform_get_irq_byname(pdev, "i2s");
   if (aiu->i2s.irq < 0)
           return aiu->i2s.irq;

   aiu->spdif.irq = platform_get_irq_byname(pdev, "spdif");
   if (aiu->spdif.irq < 0)
           return aiu->spdif.irq;

4 ......

Do you think addressing these issues would improve readability and
maintainability of the Meson codebase over time?
Or is it generally preferred to leave these kinds of consistency
improvements untouched unless a functional bug is being fixed?

Best regards,
Phuc


^ permalink raw reply

* [soc:sunxi/dt-2] BUILD SUCCESS 6b81aa0c8a4f038712fa549e4d44d8279eeb0440
From: kernel test robot @ 2026-06-12  2:48 UTC (permalink / raw)
  To: Chen-Yu Tsai; +Cc: linux-arm-kernel, arm

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git sunxi/dt-2
branch HEAD: 6b81aa0c8a4f038712fa549e4d44d8279eeb0440  arm64: dts: allwinner: a523: Add missing GPIO interrupt

elapsed time: 767m

configs tested: 191
configs skipped: 2

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
alpha                               defconfig    gcc-16.1.0
arc                              allmodconfig    clang-23
arc                              allmodconfig    gcc-16.1.0
arc                               allnoconfig    gcc-16.1.0
arc                              allyesconfig    clang-23
arc                              allyesconfig    gcc-16.1.0
arc                                 defconfig    gcc-16.1.0
arc                            randconfig-001    gcc-13.4.0
arc                   randconfig-001-20260612    gcc-13.4.0
arc                            randconfig-002    gcc-13.4.0
arc                   randconfig-002-20260612    gcc-13.4.0
arm                               allnoconfig    gcc-16.1.0
arm                              allyesconfig    clang-23
arm                              allyesconfig    gcc-16.1.0
arm                         at91_dt_defconfig    clang-17
arm                                 defconfig    gcc-16.1.0
arm                            randconfig-001    gcc-13.4.0
arm                   randconfig-001-20260612    gcc-13.4.0
arm                            randconfig-002    gcc-13.4.0
arm                   randconfig-002-20260612    gcc-13.4.0
arm                            randconfig-003    gcc-13.4.0
arm                   randconfig-003-20260612    gcc-13.4.0
arm                            randconfig-004    gcc-13.4.0
arm                   randconfig-004-20260612    gcc-13.4.0
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-16.1.0
arm64                               defconfig    gcc-16.1.0
arm64                 randconfig-001-20260612    gcc-13.4.0
arm64                 randconfig-002-20260612    gcc-13.4.0
arm64                 randconfig-003-20260612    gcc-13.4.0
arm64                 randconfig-004-20260612    gcc-13.4.0
csky                             allmodconfig    gcc-16.1.0
csky                              allnoconfig    gcc-16.1.0
csky                                defconfig    gcc-16.1.0
csky                  randconfig-001-20260612    gcc-13.4.0
csky                  randconfig-002-20260612    gcc-13.4.0
hexagon                          allmodconfig    gcc-16.1.0
hexagon                           allnoconfig    gcc-16.1.0
hexagon                             defconfig    gcc-16.1.0
hexagon               randconfig-001-20260612    clang-23
hexagon               randconfig-002-20260612    clang-23
i386                             allmodconfig    clang-22
i386                              allnoconfig    gcc-16.1.0
i386                             allyesconfig    clang-22
i386        buildonly-randconfig-001-20260612    gcc-14
i386        buildonly-randconfig-002-20260612    gcc-14
i386        buildonly-randconfig-003-20260612    gcc-14
i386        buildonly-randconfig-004-20260612    gcc-14
i386        buildonly-randconfig-005-20260612    gcc-14
i386        buildonly-randconfig-006-20260612    gcc-14
i386                                defconfig    gcc-16.1.0
i386                  randconfig-001-20260612    clang-22
i386                  randconfig-002-20260612    clang-22
i386                  randconfig-003-20260612    clang-22
i386                  randconfig-004-20260612    clang-22
i386                  randconfig-005-20260612    clang-22
i386                  randconfig-006-20260612    clang-22
i386                  randconfig-007-20260612    clang-22
i386                  randconfig-011-20260612    clang-22
i386                  randconfig-012-20260612    clang-22
i386                  randconfig-013-20260612    clang-22
i386                  randconfig-014-20260612    clang-22
i386                  randconfig-015-20260612    clang-22
i386                  randconfig-016-20260612    clang-22
i386                  randconfig-017-20260612    clang-22
loongarch                        allmodconfig    clang-19
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    gcc-16.1.0
loongarch                           defconfig    clang-23
loongarch             randconfig-001-20260612    clang-23
loongarch             randconfig-002-20260612    clang-23
m68k                             allmodconfig    gcc-16.1.0
m68k                              allnoconfig    gcc-16.1.0
m68k                             allyesconfig    clang-23
m68k                             allyesconfig    gcc-16.1.0
m68k                                defconfig    clang-23
m68k                        m5272c3_defconfig    gcc-16.1.0
microblaze                        allnoconfig    gcc-16.1.0
microblaze                       allyesconfig    gcc-16.1.0
microblaze                          defconfig    clang-23
mips                             allmodconfig    gcc-16.1.0
mips                              allnoconfig    gcc-16.1.0
mips                             allyesconfig    gcc-16.1.0
mips                           ci20_defconfig    clang-23
nios2                            allmodconfig    clang-20
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-23
nios2                 randconfig-001-20260612    clang-23
nios2                 randconfig-002-20260612    clang-23
openrisc                         allmodconfig    clang-20
openrisc                         allmodconfig    gcc-16.1.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-16.1.0
openrisc                            defconfig    gcc-16.1.0
parisc                           allmodconfig    gcc-16.1.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-16.1.0
parisc                           allyesconfig    clang-17
parisc                           allyesconfig    gcc-16.1.0
parisc                              defconfig    gcc-16.1.0
parisc64                            defconfig    clang-23
powerpc                          allmodconfig    gcc-16.1.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-16.1.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-16.1.0
riscv                            allyesconfig    clang-23
riscv                               defconfig    gcc-16.1.0
riscv                 randconfig-001-20260612    gcc-11.5.0
riscv                 randconfig-002-20260612    gcc-11.5.0
s390                             allmodconfig    clang-17
s390                             allmodconfig    clang-23
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-16.1.0
s390                                defconfig    gcc-16.1.0
s390                  randconfig-001-20260612    gcc-11.5.0
s390                  randconfig-002-20260612    gcc-11.5.0
sh                               allmodconfig    gcc-16.1.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-16.1.0
sh                               allyesconfig    clang-17
sh                               allyesconfig    gcc-16.1.0
sh                                  defconfig    gcc-14
sh                    randconfig-001-20260612    gcc-11.5.0
sh                    randconfig-002-20260612    gcc-11.5.0
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-16.1.0
sparc                               defconfig    gcc-16.1.0
sparc                 randconfig-001-20260612    gcc-8.5.0
sparc                 randconfig-002-20260612    gcc-8.5.0
sparc64                          allmodconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260612    gcc-8.5.0
sparc64               randconfig-002-20260612    gcc-8.5.0
um                               allmodconfig    clang-17
um                                allnoconfig    clang-16
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-16.1.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260612    gcc-8.5.0
um                    randconfig-002-20260612    gcc-8.5.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-22
x86_64                            allnoconfig    clang-22
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-22
x86_64      buildonly-randconfig-001-20260612    gcc-14
x86_64      buildonly-randconfig-002-20260612    gcc-14
x86_64      buildonly-randconfig-003-20260612    gcc-14
x86_64      buildonly-randconfig-004-20260612    gcc-14
x86_64      buildonly-randconfig-005-20260612    gcc-14
x86_64      buildonly-randconfig-006-20260612    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-22
x86_64                randconfig-001-20260612    clang-22
x86_64                randconfig-002-20260612    clang-22
x86_64                randconfig-003-20260612    clang-22
x86_64                randconfig-004-20260612    clang-22
x86_64                randconfig-005-20260612    clang-22
x86_64                randconfig-006-20260612    clang-22
x86_64                randconfig-011-20260612    clang-22
x86_64                randconfig-012-20260612    clang-22
x86_64                randconfig-013-20260612    clang-22
x86_64                randconfig-014-20260612    clang-22
x86_64                randconfig-015-20260612    clang-22
x86_64                randconfig-016-20260612    clang-22
x86_64                randconfig-071-20260612    gcc-14
x86_64                randconfig-072-20260612    gcc-14
x86_64                randconfig-073-20260612    gcc-14
x86_64                randconfig-074-20260612    gcc-14
x86_64                randconfig-075-20260612    gcc-14
x86_64                randconfig-076-20260612    gcc-14
x86_64                               rhel-9.4    clang-22
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-22
x86_64                    rhel-9.4-kselftests    clang-22
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-22
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-16.1.0
xtensa                           allyesconfig    clang-20
xtensa                           allyesconfig    gcc-16.1.0
xtensa                randconfig-001-20260612    gcc-8.5.0
xtensa                randconfig-002-20260612    gcc-8.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* RE: Re: Re: [PATCH v2] PCI: host-common: Request bus reassignment when not probe-only
From: Ratheesh Kannoth @ 2026-06-12  4:03 UTC (permalink / raw)
  To: bjorn@helgaas.com
  Cc: Bjorn Helgaas, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, bhelgaas@google.com,
	will@kernel.org, lpieralisi@kernel.org, kwilczynski@kernel.org,
	mani@kernel.org, robh@kernel.org, vidyas@nvidia.com
In-Reply-To: <MN0PR18MB5847913D9E15805B85A0AAD2D33F2@MN0PR18MB5847.namprd18.prod.outlook.com>


> >From: Bjorn Helgaas <bjorn.helgaas@gmail.com>
> >Sent: Tuesday, May 5, 2026 8:55 PM
> 
> >I don't have access to that bug report.  If there's nothing secret in
> >it, can you make it public?
> Apologies for the access issue. I am still familiarizing myself with the
> platform's privacy settings, but I certainly intended for this to be a public
> report.
> I'll explore the settings now to make it generic/public and will get back to you
> 
> >I assume this is the same issue you mentioned at
> >https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_al
> >l_abkqm-5FLCd9zAM8cW-40rkannoth-2DOptiPlex-2D7090_-
> 3F&d=DwIFaQ&c=nKjWec
> >2b6R0mOyPaz7xtfQ&r=aekcsyBCH00_LewrEDcQBzsRw8KCpUR0vZb_auTHk4
> M&m=yH7EeB
> >e9HwRllD8K-
> >PFNS2CMFSlcaBHU6o3DYa1xndJvwVSHI4aPWi98uDKPRIJI&s=BK4_NvmXa
> >qyszkMVHWAPTa9MeaX-26Ka3xT6NKSXwFQ&e=
> Yes. I believe, we can ignore Bugzilla report as per
> https://www.kernel.org/doc/html/v4.19/admin-guide/reporting-bugs.html ?
> "Once you know the subsystem that is causing the issue, you should send a
> bug report. Some maintainers prefer bugs to be reported via bugzilla
> (https://bugzilla.kernel.org), while others prefer that bugs be reported via the
> subsystem mailing list."
> 
> >Your email response was HTML, so the mailing lists rejected it, which
> >is why your response doesn't appear here:
> >https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_al
> >l_20260414081730.3864372-2D1-2Drkannoth-40marvell.com_t_-
> 23u&d=DwIFaQ&c
> >=nKjWec2b6R0mOyPaz7xtfQ&r=aekcsyBCH00_LewrEDcQBzsRw8KCpUR0vZb
> _auTHk4M&m
> >=yH7EeBe9HwRllD8K-
> >PFNS2CMFSlcaBHU6o3DYa1xndJvwVSHI4aPWi98uDKPRIJI&s=7X
> >f3ikUPZpTjbnX3B0zimpsHFMgJx8guRkyGAl7GXz8&e=
> Sorry about that. My mail client (Outlook) defaulted to HTML formatting. Will
> be more careful in future.
Kindly advise if there are any outstanding action items required from my side. I see that the patch is not available in net-next yet
 or backported to stable versions. I want to ensure I haven't missed a step, so please excuse my impatience if it is simply a matter 
of the usual release cycle.

^ permalink raw reply

* Re: [PATCH v2 2/2] KVM: arm64: nv: Expose shadow page tables in debugfs
From: Itaru Kitayama @ 2026-06-12  4:06 UTC (permalink / raw)
  To: Wei-Lin Chang
  Cc: linux-arm-kernel, kvmarm, linux-kernel, Marc Zyngier,
	Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon
In-Reply-To: <20260317182638.1592507-3-weilin.chang@arm.com>

Hi Wei Lin,
On Tue, Mar 17, 2026 at 06:26:38PM +0000, Wei-Lin Chang wrote:
> Exposing shadow page tables in debugfs improves the debugability and
> testability of NV. With this patch a new directory "nested" is created
> for each VM created if the host is NV capable. Within the directory each
> valid s2 mmu will have its shadow page table exposed as a readable file
> with the file name formatted as 0x<vttbr>-0x<vtcr>-s2-{en,dis}abled. The
> creation and removal of the files happen at the points when an s2 mmu
> becomes valid, or the context it represents change. In the future the
> "nested" directory can also hold other NV related information.
> 
> This is gated behind CONFIG_PTDUMP_STAGE2_DEBUGFS.
> 
> Suggested-by: Marc Zyngier <maz@kernel.org>
> Reviewed-by: Sebastian Ene <sebastianene@google.com>
> Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |  9 +++++++++
>  arch/arm64/include/asm/kvm_mmu.h  |  4 ++++
>  arch/arm64/kvm/nested.c           |  6 +++++-
>  arch/arm64/kvm/ptdump.c           | 27 +++++++++++++++++++++++++++
>  4 files changed, 45 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 5d5a3bbdb95e..52977c9a11c3 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -217,6 +217,10 @@ struct kvm_s2_mmu {
>  	 */
>  	bool	nested_stage2_enabled;
>  
> +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> +	struct dentry *shadow_pt_debugfs_dentry;
> +#endif
> +
>  	/*
>  	 * true when this MMU needs to be unmapped before being used for a new
>  	 * purpose.
> @@ -405,6 +409,11 @@ struct kvm_arch {
>  	 * the associated pKVM instance in the hypervisor.
>  	 */
>  	struct kvm_protected_vm pkvm;
> +
> +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> +	/* Nested virtualization info */
> +	struct dentry *debugfs_nv_dentry;
> +#endif
>  };
>  
>  struct kvm_vcpu_fault_info {
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index d968aca0461a..01e9c72d6aa7 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -393,8 +393,12 @@ static inline bool kvm_supports_cacheable_pfnmap(void)
>  
>  #ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
>  void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
> +void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu);
> +void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu);
>  #else
>  static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
> +static inline void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu) {}
> +static inline void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu) {}
>  #endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
>  
>  #endif /* __ASSEMBLER__ */
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index eeea5e692370..31d74ed8449e 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -730,8 +730,10 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
>  	kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
>  
>  	/* Make sure we don't forget to do the laundry */
> -	if (kvm_s2_mmu_valid(s2_mmu))
> +	if (kvm_s2_mmu_valid(s2_mmu)) {
> +		kvm_nested_s2_ptdump_remove_debugfs(s2_mmu);
>  		s2_mmu->pending_unmap = true;
> +	}
>  
>  	/*
>  	 * The virtual VMID (modulo CnP) will be used as a key when matching
> @@ -745,6 +747,8 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
>  	s2_mmu->tlb_vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
>  	s2_mmu->nested_stage2_enabled = vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_VM;
>  
> +	kvm_nested_s2_ptdump_create_debugfs(s2_mmu);
> +

This function can sleep, so I get while running your shadow stage 2 KVM
selftest a messge:

[ 4408.411009] BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1624
[ 4408.411075] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 164, name: shadow_stage2
[ 4408.411136] preempt_count: 2, expected: 0
[ 4408.411172] RCU nest depth: 0, expected: 0
[ 4408.411228] CPU: 1 UID: 0 PID: 164 Comm: shadow_stage2 Tainted: G        W           7.1.0-rc2+ #48 PREEMPT(full)
[ 4408.411336] Tainted: [W]=WARN
[ 4408.411368] Hardware name:  , BIOS
[ 4408.411403] Call trace:
[ 4408.411427]  show_stack+0x24/0x50 (C)
[ 4408.411524]  dump_stack_lvl+0x90/0x158
[ 4408.411633]  dump_stack+0x1c/0x38
[ 4408.411741]  __might_resched+0x168/0x208
[ 4408.411839]  __might_sleep+0x54/0xb0
[ 4408.411936]  down_write+0x30/0xe8
[ 4408.412048]  start_dirop+0x3c/0xc0
[ 4408.412149]  simple_start_creating+0xb8/0xc8
[ 4408.412241]  debugfs_start_creating.part.0+0x68/0x180
[ 4408.412375]  __debugfs_create_file+0x80/0x1f8
[ 4408.412505]  debugfs_create_file_full+0x28/0x68
[ 4408.412637]  kvm_nested_s2_ptdump_create_debugfs+0xa0/0x108
[ 4408.412734]  kvm_vcpu_load_hw_mmu+0x27c/0x320
[ 4408.412839]  kvm_arch_vcpu_load+0x318/0x5a0
[ 4408.412971]  kvm_emulate_nested_eret+0x148/0x3d8
[ 4408.413072]  kvm_handle_eret+0x110/0x138
[ 4408.413190]  handle_exit+0x6c/0x1e8
[ 4408.413306]  kvm_arch_vcpu_ioctl_run+0x3c4/0xc90
[ 4408.413396]  kvm_vcpu_ioctl+0x1a0/0xa68
[ 4408.413508]  __arm64_sys_ioctl+0xd0/0x160
[L1] L2 exit[ 4408.413631]  invoke_syscall+0xa8/0x138
[ 4408.413723]  el0_svc_common.constprop.0+0x4c/0x140
[ 4408.413821]  do_el0_svc+0x28/0x58
[ 4408.413911]  el0_svc+0x48/0x230
[ 4408.414035]  el0t_64_sync_handler+0xc0/0x108
[ 4408.414166]  el0t_64_sync+0x1b4/0x1b8

I tried to move this function out under the KVM MMU lock, but then I see
a debug entry is duplicated error. I am not sure where exactly this 
nested stage 2 debugfs entry create function should go, your help is
much appreciated.

Thanks,
Itaru.

>  out:
>  	atomic_inc(&s2_mmu->refcnt);
>  
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> index 98763b291956..aebbbad85d38 100644
> --- a/arch/arm64/kvm/ptdump.c
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -10,12 +10,14 @@
>  #include <linux/kvm_host.h>
>  #include <linux/seq_file.h>
>  
> +#include <asm/cpufeature.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/kvm_pgtable.h>
>  #include <asm/ptdump.h>
>  
>  #define MARKERS_LEN		2
>  #define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> +#define S2FNAMESZ	sizeof("0x0123456789abcdef-0x0123456789abcdef-s2-disabled")
>  
>  struct kvm_ptdump_guest_state {
>  	struct kvm_s2_mmu	*mmu;
> @@ -277,6 +279,28 @@ static const struct file_operations kvm_pgtable_levels_fops = {
>  	.release	= kvm_pgtable_debugfs_close,
>  };
>  
> +void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu)
> +{
> +	struct dentry *dent;
> +	char file_name[S2FNAMESZ];
> +
> +	snprintf(file_name, sizeof(file_name), "0x%llx-0x%llx-s2-%sabled",
> +		 mmu->tlb_vttbr,
> +		 mmu->tlb_vtcr,
> +		 mmu->nested_stage2_enabled ? "en" : "dis");
> +
> +	dent = debugfs_create_file(file_name, 0400,
> +				   mmu->arch->debugfs_nv_dentry, mmu,
> +				   &kvm_ptdump_guest_fops);
> +
> +	mmu->shadow_pt_debugfs_dentry = dent;
> +}
> +
> +void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu)
> +{
> +	debugfs_remove(mmu->shadow_pt_debugfs_dentry);
> +}
> +
>  void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
>  {
>  	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> @@ -285,4 +309,7 @@ void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
>  			    &kvm->arch.mmu, &kvm_pgtable_range_fops);
>  	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
>  			    &kvm->arch.mmu, &kvm_pgtable_levels_fops);
> +	if (cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
> +		kvm->arch.debugfs_nv_dentry =
> +			debugfs_create_dir("nested", kvm->debugfs_dentry);
>  }
> -- 
> 2.43.0
> 


^ permalink raw reply

* [PATCH wireless] wifi: mt76: mt7615: avoid waiting for mac work under the mt76 mutex
From: Runyu Xiao @ 2026-06-12  4:13 UTC (permalink / raw)
  To: nbd
  Cc: lorenzo, ryder.lee, shayne.chen, sean.wang, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek, jianhao.xu, runyu.xiao, stable

mt7615_suspend() takes the mt76 mutex and then waits for mac_work with
cancel_delayed_work_sync().  mt7615_mac_work() takes the same mutex at
the top of the worker, so the suspend path can deadlock against the
delayed work it is trying to flush.

This issue was found by our static analysis tool and then manually
reviewed against the current tree.

The grounded PoC kept the mt7615_suspend() ->
cancel_delayed_work_sync(&phy->mt76->mac_work) path and the
mt7615_mac_work() -> mt7615_mutex_acquire() edge.  Lockdep reported:

  WARNING: possible circular locking dependency detected
  mt7615_mac_work+0x1b/0x29 [vuln_msv]
  __cancel_work_timer
  *** DEADLOCK ***

Stop queueing mac_work while the mutex is held, drop the mutex, and then
flush the delayed work from the sleepable post-unlock path.

Fixes: c6bf20109a3f ("mt76: mt7615: add WoW support")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
Notes:
  - Validated with a grounded Lockdep PoC that preserves the
    mt7615_suspend() -> cancel_delayed_work_sync(&phy->mt76->mac_work)
    path and the mt7615_mac_work() -> mt7615_mutex_acquire() edge.
  - checkpatch.pl --strict: clean.
  - Not tested on mt7615 hardware.

 drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 15fe155ac3f3..fcb619c0f6cf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -1242,7 +1242,8 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
 
 	clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
 	cancel_delayed_work_sync(&phy->scan_work);
-	cancel_delayed_work_sync(&phy->mt76->mac_work);
+	/* mac_work re-enters the mt76 mutex, so flush it after unlock. */
+	cancel_delayed_work(&phy->mt76->mac_work);
 
 	set_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
 	ieee80211_iterate_active_interfaces(hw,
@@ -1254,6 +1255,7 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
 		err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
 
 	mt7615_mutex_release(dev);
+	cancel_delayed_work_sync(&phy->mt76->mac_work);
 
 	return err;
 }
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 1/7] dt-bindings: media: qcom: Add Shikra CAMSS compatible
From: Nihal Kumar Gupta @ 2026-06-12  4:28 UTC (permalink / raw)
  To: Bryan O'Donoghue, Krzysztof Kozlowski
  Cc: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
	Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Robert Foss, Andi Shyti, Bjorn Andersson,
	Konrad Dybcio, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, linux-arm-msm, linux-media, devicetree,
	linux-kernel, linux-i2c, imx, linux-arm-kernel, Suresh Vankadara,
	Vikram Sharma
In-Reply-To: <ab1055a2-6916-4083-a360-62eb15171fe3@linaro.org>



On 11-06-2026 20:06, Bryan O'Donoghue wrote:
> 
> @Nihal.
> 
> If this is the only change you get asked to make, I will just fix this up on application for you. There's no need to v3 the series for this.

Thank you for offering to fix this up on application.
That works for me!

--
Regards,
Nihal Kumar Gupta


^ permalink raw reply

* Re: [PATCH] media: bcm2835-unicam: Fix querycap multiple caps
From: kernel test robot @ 2026-06-12  4:31 UTC (permalink / raw)
  To: Eugen Hristev, Raspberry Pi Kernel Maintenance,
	Mauro Carvalho Chehab, Florian Fainelli, Ray Jui, Scott Branden,
	Broadcom internal kernel review list, Sakari Ailus,
	Dave Stevenson, Laurent Pinchart, Jean-Michel Hautbois,
	Naushir Patuck
  Cc: oe-kbuild-all, linux-media, Hans Verkuil, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel, Eugen Hristev
In-Reply-To: <20260611-bcmpiqcap-v1-1-10cf7fb438df@kernel.org>

Hi Eugen,

kernel test robot noticed the following build errors:

[auto build test ERROR on a87737435cfa134f9cdcc696ba3080759d04cf72]

url:    https://github.com/intel-lab-lkp/linux/commits/Eugen-Hristev/media-bcm2835-unicam-Fix-querycap-multiple-caps/20260611-141320
base:   a87737435cfa134f9cdcc696ba3080759d04cf72
patch link:    https://lore.kernel.org/r/20260611-bcmpiqcap-v1-1-10cf7fb438df%40kernel.org
patch subject: [PATCH] media: bcm2835-unicam: Fix querycap multiple caps
config: arc-allmodconfig (https://download.01.org/0day-ci/archive/20260612/202606121218.nV4fMXUr-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 16.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260612/202606121218.nV4fMXUr-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202606121218.nV4fMXUr-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/media/platform/broadcom/bcm2835-unicam.c: In function 'unicam_querycap':
>> drivers/media/platform/broadcom/bcm2835-unicam.c:1836:27: error: 'node' undeclared (first use in this function)
    1836 |         if (is_image_node(node))
         |                           ^~~~
   drivers/media/platform/broadcom/bcm2835-unicam.c:1836:27: note: each undeclared identifier is reported only once for each function it appears in


vim +/node +1836 drivers/media/platform/broadcom/bcm2835-unicam.c

  1825	
  1826	/* -----------------------------------------------------------------------------
  1827	 *  V4L2 video device operations
  1828	 */
  1829	
  1830	static int unicam_querycap(struct file *file, void *priv,
  1831				   struct v4l2_capability *cap)
  1832	{
  1833		strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
  1834		strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
  1835	
> 1836		if (is_image_node(node))
  1837			cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE;
  1838		else
  1839			cap->capabilities |= V4L2_CAP_META_CAPTURE;
  1840	
  1841		return 0;
  1842	}
  1843	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* [PATCH 0/2] ACPM cpufreq with fast_switch support, fast path xfer in ACPM
From: Alexey Klimov @ 2026-06-12  4:34 UTC (permalink / raw)
  To: Tudor Ambarus, Sam Protsenko, Krzysztof Kozlowski, Peter Griffin,
	Alim Akhtar, Rafael J. Wysocki, Viresh Kumar
  Cc: Sudeep Holla, linux-samsung-soc, linux-arm-kernel, linux-pm,
	kernel-team, linux-kernel, Alexey Klimov

The series implements acpm_do_xfer_fast() that does as little
as possible to make it usabe in atomic context to eventually
use it in cpufreq path with ->fast_switch(). That's basically it.
Cpufreq deals directly with ACPM dvfs instead of going through
clk framework.

This series is Work-In-Progress / RFC.
This is currently a working prototype, but I am sending it as an RFC to
get feedback on the approach — specifically the ACPM fast path of sending
messages. If ACPM part is no-go then cpufreq is not needed.

Known TODO items:
 -- rx/tx channels locks rework;
 -- initial frequency fetching: Exynos850 firmware currently lacks a
    clean get_rate, so the driver falls back to dump defaults until the
    first freq transition.
 -- potential mailbox channels re-implementation.

Any thoughts, testing, or feedback on the architecture would be greatly
appreciated.

This was tested on Exynos850 with example of DT nodes described
in [1] and [2].

Dependencies are different series that adds Exynos850 ACPM support:
-- ACPM mailbox support for Exynos850:
https://lore.kernel.org/linux-samsung-soc/20260429-exynos850-mbox-dts-v1-1-7f3ad27ed4f4@linaro.org/
-- sram DT node:
https://lore.kernel.org/linux-samsung-soc/20260413-exynos850_sram-v1-1-7fda5b7fb7d4@linaro.org/
-- ACPM support on Exynos850: 
https://lore.kernel.org/linux-samsung-soc/20260513-exynos850-acpm-firmware-support-v1-0-3858d097e433@linaro.org/

(the above dependencies pull some other series as well)

[1]:

cpu0: cpu@0 {
	device_type = "cpu";
	compatible = "arm,cortex-a55";
	reg = <0x0>;
	clocks = <&acpm_ipc E850_CLK_ACPM_DVFS_CPUCL0>;
	enable-method = "psci";
	operating-points-v2 = <&cpucl0_opp_table>;
	capacity-dmips-mhz = <250>;
	dynamic-power-coefficient = <70>;
};

[2]:

	cpucl0_opp_table: opp-table-0 {
		compatible = "operating-points-v2";
		opp-shared;

		opp-130000000 {
			opp-hz = /bits/ 64 <130000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-182000000 {
			opp-hz = /bits/ 64 <182000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-247000000 {
			opp-hz = /bits/ 64 <247000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-351000000 {
			opp-hz = /bits/ 64 <351000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-442000000 {
			opp-hz = /bits/ 64 <442000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-546000000 {
			opp-hz = /bits/ 64 <546000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-650000000 {
			opp-hz = /bits/ 64 <650000000>;
			opp-microvolt = <625000>;
			clock-latency-ns = <500000>;
		};

		opp-806000000 {
			opp-hz = /bits/ 64 <806000000>;
			opp-microvolt = <656250>;
			clock-latency-ns = <500000>;
		};

		opp-949000000 {
			opp-hz = /bits/ 64 <949000000>;
			opp-microvolt = <681250>;
			clock-latency-ns = <500000>;
		};

		opp-1053000000 {
			opp-hz = /bits/ 64 <1053000000>;
			opp-microvolt = <706250>;
			clock-latency-ns = <500000>;
		};

		opp-1157000000 {
			opp-hz = /bits/ 64 <1157000000>;
			opp-microvolt = <737500>;
			clock-latency-ns = <500000>;
		};

		opp-1300000000 {
			opp-hz = /bits/ 64 <1300000000>;
			opp-microvolt = <781250>;
			clock-latency-ns = <500000>;
		};

		opp-1456000000 {
			opp-hz = /bits/ 64 <1456000000>;
			opp-microvolt = <825000>;
			clock-latency-ns = <500000>;
		};

		opp-1586000000 {
			opp-hz = /bits/ 64 <1586000000>;
			opp-microvolt = <875000>;
			clock-latency-ns = <500000>;
		};

		opp-1742000000 {
			opp-hz = /bits/ 64 <1742000000>;
			opp-microvolt = <937500>;
			clock-latency-ns = <500000>;
		};

		opp-1846000000 {
			opp-hz = /bits/ 64 <1846000000>;
			opp-microvolt = <981250>;
			clock-latency-ns = <500000>;
		};

		opp-2002000000 {
			opp-hz = /bits/ 64 <2002000000>;
			opp-microvolt = <1050000>;
			clock-latency-ns = <500000>;
		};

		opp-2106000000 {
			opp-hz = /bits/ 64 <2106000000>;
			opp-microvolt = <1106250>;
			clock-latency-ns = <500000>;
		};

		opp-2210000000 {
			opp-hz = /bits/ 64 <2210000000>;
			opp-microvolt = <1181250>;
			clock-latency-ns = <500000>;
		};
	};

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
Alexey Klimov (2):
      firmware: samsung: acpm: add fire-and-forget xfer support
      cpufreq: add ACPM-based CPU DVFS driver for Exynos SoCs

 drivers/cpufreq/Kconfig.arm                        |   8 +
 drivers/cpufreq/Makefile                           |   1 +
 drivers/cpufreq/acpm-cpufreq.c                     | 195 +++++++++++++++++++++
 drivers/cpufreq/cpufreq-dt-platdev.c               |   3 +
 drivers/firmware/samsung/exynos-acpm-dvfs.c        |  14 ++
 drivers/firmware/samsung/exynos-acpm-dvfs.h        |   3 +
 drivers/firmware/samsung/exynos-acpm.c             | 142 +++++++++++++--
 drivers/firmware/samsung/exynos-acpm.h             |   3 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |   2 +
 9 files changed, 361 insertions(+), 10 deletions(-)
---
base-commit: ec039126b7fac4e3af35ebccaa7c6f9b6875ba81
change-id: 20260612-acpm-fast-xfer-86c4de78c20b

Best regards,
-- 
Alexey Klimov <alexey.klimov@linaro.org>



^ permalink raw reply

* [PATCH 2/2] cpufreq: add ACPM-based CPU DVFS driver for Exynos SoCs
From: Alexey Klimov @ 2026-06-12  4:34 UTC (permalink / raw)
  To: Tudor Ambarus, Sam Protsenko, Krzysztof Kozlowski, Peter Griffin,
	Alim Akhtar, Rafael J. Wysocki, Viresh Kumar
  Cc: Sudeep Holla, linux-samsung-soc, linux-arm-kernel, linux-pm,
	kernel-team, linux-kernel, Alexey Klimov
In-Reply-To: <20260612-acpm-fast-xfer-v1-0-1aa6cd2268ba@linaro.org>

Exynos-based SoCs (e.g., Exynos850, gs101) manage CPU DVFS via an
ACPM co-processor (sometimes co-processor specifically called APM).
Historically, routing CPU frequencies through the clock framework
breaks fast frequency switching as it is implemented in cpufreq-dt.
The clk_set_rate() uses mutexes, which prevents the scheduler to
utilize schedutil's fast path.

Introduce a dedicated ACPM-based cpufreq driver that bypasses the clock
framework and communicates directly with the ACPM firmware protocol.
It implements ->fast_switch() to rely on acpm_dvfs_set_rate_fast(),
enabling faster frequency transitions.

Add Google gs101 and Samsung exynos850 to the cpufreq-dt-platdev
blocklist to prevent driver cpufreq-dt initialisation.

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
 drivers/cpufreq/Kconfig.arm          |   8 ++
 drivers/cpufreq/Makefile             |   1 +
 drivers/cpufreq/acpm-cpufreq.c       | 195 +++++++++++++++++++++++++++++++++++
 drivers/cpufreq/cpufreq-dt-platdev.c |   3 +
 4 files changed, 207 insertions(+)

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index a441668f9e0c..891ff4b6ec22 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -24,6 +24,14 @@ config ARM_AIROHA_SOC_CPUFREQ
 	help
 	  This adds the CPUFreq driver for Airoha EN7581 SoCs.
 
+config ARM_ACPM_CPUFREQ
+	tristate "ACPM based CPUFreq support"
+	depends on ARCH_EXYNOS || (COMPILE_TEST && 64BIT)
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver for Exynos-based machines
+	  with ACPM firmware.
+
 config ARM_APPLE_SOC_CPUFREQ
 	tristate "Apple Silicon SoC CPUFreq support"
 	depends on ARCH_APPLE || (COMPILE_TEST && 64BIT)
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 6c7a39b7f8d2..c54d2dd6629d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY)	+= amd_freq_sensitivity.o
 ##################################################################################
 # ARM SoC drivers
 obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ)	+= airoha-cpufreq.o
+obj-$(CONFIG_ARM_ACPM_CPUFREQ)		+= acpm-cpufreq.o
 obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ)	+= apple-soc-cpufreq.o
 obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)	+= armada-37xx-cpufreq.o
 obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ)	+= armada-8k-cpufreq.o
diff --git a/drivers/cpufreq/acpm-cpufreq.c b/drivers/cpufreq/acpm-cpufreq.c
new file mode 100644
index 000000000000..20fb79169993
--- /dev/null
+++ b/drivers/cpufreq/acpm-cpufreq.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Exynos ACPM-based CPUFreq DVFS driver
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+
+#define ACPM_DVFS_TRANSITION_TIMEOUT 400
+
+struct acpm_cpu_priv {
+	struct device *cpu_dev;
+	struct acpm_handle *handle;
+	unsigned int acpm_chan_id;
+	unsigned int clk_id;
+};
+
+static unsigned int acpm_soc_cpufreq_get_rate(unsigned int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
+	struct acpm_cpu_priv *priv;
+
+	if (unlikely(!policy))
+		return 0;
+
+	priv = policy->driver_data;
+
+	/* return priv->handle->ops->dvfs.get_rate(priv->handle, priv->acpm_chan_id,
+	 *					priv->clk_id) / 1000;
+	 */
+
+	/* TODO: FIXME. Exynos850 doesn't return rate via ACPM */
+	return policy->cur;
+}
+
+static int acpm_soc_cpufreq_set_target(struct cpufreq_policy *policy,
+				       unsigned int index)
+{
+	struct acpm_cpu_priv *priv = policy->driver_data;
+	unsigned long freq_khz = policy->freq_table[index].frequency;
+
+	/* standard slow path */
+	return priv->handle->ops->dvfs.set_rate(priv->handle, priv->acpm_chan_id,
+						priv->clk_id, freq_khz * 1000);
+}
+
+static unsigned int acpm_soc_cpufreq_fast_switch(struct cpufreq_policy *policy,
+						 unsigned int target_freq)
+{
+	struct acpm_cpu_priv *priv = policy->driver_data;
+	int ret;
+
+	ret = priv->handle->ops->dvfs.set_rate_fast(priv->handle, priv->acpm_chan_id,
+						    priv->clk_id, target_freq * 1000);
+	if (ret < 0)
+		return 0;
+
+	return target_freq;
+}
+
+static int acpm_soc_cpufreq_init(struct cpufreq_policy *policy)
+{
+	struct device *cpu_dev = get_cpu_device(policy->cpu);
+	struct cpufreq_frequency_table *freq_table;
+	struct acpm_cpu_priv *priv;
+	struct of_phandle_args args;
+	unsigned int transition_latency;
+	int ret;
+
+	if (!cpu_dev)
+		return -ENODEV;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	ret = of_parse_phandle_with_args(cpu_dev->of_node, "clocks",
+					 "#clock-cells", 0, &args);
+	if (ret) {
+		dev_err(cpu_dev, "failed to parse clocks property\n");
+		goto out_free_priv;
+	}
+
+	priv->clk_id = args.args[0];
+
+	/*
+	 * DVFS communication is expected to happen only via channel 0
+	 * for now for known SoCs with ACPM firmware. Hardcoding.
+	 */
+	priv->acpm_chan_id = 0;
+
+	priv->handle = devm_acpm_get_by_node(cpu_dev, args.np);
+	of_node_put(args.np);
+
+	if (IS_ERR(priv->handle)) {
+		ret = PTR_ERR(priv->handle);
+		goto out_free_priv;
+	}
+
+	priv->cpu_dev = cpu_dev;
+
+	ret = dev_pm_opp_of_add_table(cpu_dev);
+	if (ret < 0) {
+		dev_err(cpu_dev, "failed to add OPP table: %d\n", ret);
+		goto out_free_priv;
+	}
+
+	dev_pm_opp_of_get_sharing_cpus(cpu_dev, policy->cpus);
+
+	ret = dev_pm_opp_get_opp_count(cpu_dev);
+	if (ret <= 0) {
+		ret = -EPROBE_DEFER;
+		goto out_remove_table;
+	}
+
+	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+	if (ret) {
+		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+		goto out_remove_table;
+	}
+
+	policy->driver_data = priv;
+	policy->freq_table = freq_table;
+
+	transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev);
+	if (!transition_latency)
+		transition_latency = ACPM_DVFS_TRANSITION_TIMEOUT * NSEC_PER_USEC;
+
+	policy->cpuinfo.transition_latency = transition_latency;
+	policy->dvfs_possible_from_any_cpu = true;
+	policy->fast_switch_possible = true;
+	policy->suspend_freq = freq_table[0].frequency;
+
+	/* TODO: FIXME. Exynos850 doesn't expose rate of clocks via ACPM  (get_rate doesn't work) */
+	policy->cur = freq_table[0].frequency;
+
+	return 0;
+
+out_remove_table:
+	dev_pm_opp_of_remove_table(cpu_dev);
+out_free_priv:
+	kfree(priv);
+	return ret;
+}
+
+static void acpm_soc_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	struct acpm_cpu_priv *priv = policy->driver_data;
+
+	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+	dev_pm_opp_of_remove_table(priv->cpu_dev);
+	kfree(priv);
+}
+
+static struct cpufreq_driver acpm_soc_cpufreq_driver = {
+	.name		= "acpm-cpufreq",
+	.flags		= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+			  CPUFREQ_NEED_INITIAL_FREQ_CHECK | CPUFREQ_IS_COOLING_DEV,
+	.verify		= cpufreq_generic_frequency_table_verify,
+	.get		= acpm_soc_cpufreq_get_rate,
+	.init		= acpm_soc_cpufreq_init,
+	.exit		= acpm_soc_cpufreq_exit,
+	.target_index	= acpm_soc_cpufreq_set_target,
+	.fast_switch	= acpm_soc_cpufreq_fast_switch,
+	.register_em	= cpufreq_register_em_with_opp,
+	.set_boost	= cpufreq_boost_set_sw,
+	.suspend	= cpufreq_generic_suspend,
+};
+
+static int __init acpm_soc_cpufreq_module_init(void)
+{
+	if (!of_machine_is_compatible("google,gs101") &&
+	    !of_machine_is_compatible("samsung,exynos850"))
+		return -ENODEV;
+
+	return cpufreq_register_driver(&acpm_soc_cpufreq_driver);
+}
+module_init(acpm_soc_cpufreq_module_init);
+
+static void __exit acpm_soc_cpufreq_module_exit(void)
+{
+	cpufreq_unregister_driver(&acpm_soc_cpufreq_driver);
+}
+module_exit(acpm_soc_cpufreq_module_exit);
+
+MODULE_AUTHOR("Alexey Klimov <alexey.klimov@linaro.org>");
+MODULE_DESCRIPTION("ACPM-based CPUfreq DVFS driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index ff1204c666b1..ae58aa92fc40 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -186,6 +186,9 @@ static const struct of_device_id blocklist[] __initconst = {
 	{ .compatible = "qcom,sm8550", },
 	{ .compatible = "qcom,sm8650", },
 
+	{ .compatible = "google,gs101", },
+	{ .compatible = "samsung,exynos850", },
+
 	{ .compatible = "st,stih407", },
 	{ .compatible = "st,stih410", },
 	{ .compatible = "st,stih418", },

-- 
2.51.0



^ permalink raw reply related

* [PATCH 1/2] firmware: samsung: acpm: add fire-and-forget xfer support
From: Alexey Klimov @ 2026-06-12  4:34 UTC (permalink / raw)
  To: Tudor Ambarus, Sam Protsenko, Krzysztof Kozlowski, Peter Griffin,
	Alim Akhtar, Rafael J. Wysocki, Viresh Kumar
  Cc: Sudeep Holla, linux-samsung-soc, linux-arm-kernel, linux-pm,
	kernel-team, linux-kernel, Alexey Klimov
In-Reply-To: <20260612-acpm-fast-xfer-v1-0-1aa6cd2268ba@linaro.org>

The current ACPM IPC protocol relies on synchronous polling
(acpm_dequeue_by_polling) to process mailbox responses.
For CPU DVFS, cpufreqs schedutil governor requires ->fast_switch() to
execute in an atomic context. Waiting for firmware acknowledgments
in a loop in such case also using udelay(20) under spinlock doesn't
make a lot of sense. Experiemnts on Exynos850 showed that even with
removed udelay() or with it significantly decreased, the firmware
processing takes 15us...250us.

Introduce acpm_do_xfer_fast(), which implements a fire-and-forget
asynchronous path:
 - utilizes spin_trylock() to exit without sleeping if the channel
   is busy;
 - adds/sends the message and kicks the mailbox doorbell;
 - exits immediately, allowing fast_switch to complete quickly.

To prevent the unread asynchronous responses from permanently exhausting
the 63-slot sequence ring buffer, implement an acpm_drain_stale_rx().
This drains the RX queue during the fast path:
 - copies payloads and sets completion flags for sleeping
   synchronous users;
 - explicitly acks 'is_async' messages.

Hooks it up in the right places of ACPM dvfs machinery.

The channels {tx,rx}_lock needs probably a bit of rework to
differentiate between channels that support or need fast xfer and
those that do not.

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
 drivers/firmware/samsung/exynos-acpm-dvfs.c        |  14 ++
 drivers/firmware/samsung/exynos-acpm-dvfs.h        |   3 +
 drivers/firmware/samsung/exynos-acpm.c             | 142 +++++++++++++++++++--
 drivers/firmware/samsung/exynos-acpm.h             |   3 +
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |   2 +
 5 files changed, 154 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
index 7266312ef5a6..5411aa121b73 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.c
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -43,6 +43,20 @@ int acpm_dvfs_set_rate(struct acpm_handle *handle,
 	return acpm_do_xfer(handle, &xfer);
 }
 
+int acpm_dvfs_set_rate_fast(struct acpm_handle *handle,
+			    unsigned int acpm_chan_id, unsigned int clk_id,
+			    unsigned long rate)
+{
+	struct acpm_xfer xfer = {0};
+	u32 cmd[4];
+
+	acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
+	acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);
+
+	return acpm_do_xfer_fast(handle, &xfer);
+}
+
+
 static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
 {
 	cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.h b/drivers/firmware/samsung/exynos-acpm-dvfs.h
index b37b15426102..107d9aa27690 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.h
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.h
@@ -14,6 +14,9 @@ struct acpm_handle;
 int acpm_dvfs_set_rate(struct acpm_handle *handle,
 		       unsigned int acpm_chan_id, unsigned int id,
 		       unsigned long rate);
+int acpm_dvfs_set_rate_fast(struct acpm_handle *handle,
+			    unsigned int acpm_chan_id, unsigned int id,
+			    unsigned long rate);
 unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
 				 unsigned int acpm_chan_id,
 				 unsigned int clk_id);
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index 942a2e9f02f5..3caab47adf26 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -20,13 +20,13 @@
 #include <linux/mailbox/exynos-message.h>
 #include <linux/mailbox_client.h>
 #include <linux/module.h>
-#include <linux/mutex.h>
 #include <linux/math.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #include "exynos-acpm.h"
@@ -109,12 +109,16 @@ struct acpm_queue {
  * @rxcnt:	expected length of the response in 32-bit words.
  * @completed:	flag indicating if the firmware response has been fully
  *		processed.
+ * @is_async:	For fire-and-forget xfer. Set to true to just ack
+ *		responses without processing.
+ *		By default, set to false for regular senders.
  */
 struct acpm_rx_data {
 	u32 *cmd __counted_by_ptr(cmdcnt);
 	size_t cmdcnt;
 	size_t rxcnt;
 	bool completed;
+	bool is_async;
 };
 
 #define ACPM_SEQNUM_MAX    64
@@ -148,8 +152,8 @@ struct acpm_chan {
 	struct acpm_info *acpm;
 	struct acpm_queue tx;
 	struct acpm_queue rx;
-	struct mutex tx_lock;
-	struct mutex rx_lock;
+	spinlock_t tx_lock;
+	spinlock_t rx_lock;
 
 	unsigned int qlen;
 	unsigned int mlen;
@@ -232,7 +236,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer,
 
 	*native_match = false;
 
-	guard(mutex)(&achan->rx_lock);
+	guard(spinlock)(&achan->rx_lock);
 
 	rx_front = readl(achan->rx.front);
 	i = readl(achan->rx.rear);
@@ -297,6 +301,9 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer,
 				*native_match = true;
 		}
 
+		if (rx_data->is_async)
+			clear_bit_unlock(seqnum, achan->bitmap_seqnum);
+
 		i = (i + 1) % achan->qlen;
 	} while (i != rx_front);
 
@@ -306,6 +313,57 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer,
 	return 0;
 }
 
+static void acpm_drain_stale_rx(struct acpm_chan *achan)
+{
+	u32 rx_front, seqnum, rx_seqnum;
+	const void __iomem *base = achan->rx.base;
+	struct acpm_rx_data *rx_data;
+	u32 i, val, mlen = achan->mlen;
+
+	if (!spin_trylock(&achan->rx_lock))
+		return;
+
+	rx_front = readl(achan->rx.front);
+	i = readl(achan->rx.rear);
+
+	/* Get out quick if we nothing to process */
+	if (i == rx_front) {
+		spin_unlock(&achan->rx_lock);
+		return;
+	}
+
+	do {
+		val = readl(base + mlen * i);
+		rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, val);
+
+		if (rx_seqnum) {
+			seqnum = rx_seqnum - 1;
+			rx_data = &achan->rx_data[seqnum];
+
+			if (rx_data->rxcnt)
+				__ioread32_copy(rx_data->cmd, base + mlen * i, rx_data->rxcnt);
+
+			/* Signal the waiting thread (if any). If it hasn't started
+			 * spinning yet, it will see this instantly when it does. */
+			smp_store_release(&rx_data->completed, true);
+
+			/* Only free the sequence number if it belongs to an
+			 * async request. Senders who use regular acpm_do_xfer()
+			 * will free their own sequence numbers in
+			 * acpm_dequeue_by_polling().
+			 */
+			if (rx_data->is_async)
+				clear_bit_unlock(seqnum, achan->bitmap_seqnum);
+		}
+
+		i = (i + 1) % achan->qlen;
+	} while (i != rx_front);
+
+	writel(rx_front, achan->rx.rear);
+
+	spin_unlock(&achan->rx_lock);
+}
+
 /**
  * acpm_dequeue_by_polling() - RX dequeue by polling.
  * @achan:	ACPM channel info.
@@ -388,15 +446,15 @@ static int acpm_wait_for_queue_slots(struct acpm_chan *achan, u32 next_tx_front)
 }
 
 /**
- * acpm_prepare_xfer() - prepare a transfer before writing the message to the
+ * __acpm_prepare_xfer() - prepare a transfer before writing the message to the
  * TX queue.
  * @achan:	ACPM channel info.
  * @xfer:	reference to the transfer being prepared.
  *
  * Return: 0 on success, -errno otherwise.
  */
-static int acpm_prepare_xfer(struct acpm_chan *achan,
-			     const struct acpm_xfer *xfer)
+static int __acpm_prepare_xfer(struct acpm_chan *achan,
+			       const struct acpm_xfer *xfer, bool is_async)
 {
 	struct acpm_rx_data *rx_data;
 	u32 *txd = (u32 *)xfer->txd;
@@ -429,6 +487,7 @@ static int acpm_prepare_xfer(struct acpm_chan *achan,
 	/* Clear data for upcoming responses */
 	rx_data = &achan->rx_data[bit];
 	rx_data->completed = false;
+	rx_data->is_async = is_async;
 	memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->cmdcnt);
 	/* zero means no response expected */
 	rx_data->rxcnt = xfer->rxcnt;
@@ -436,6 +495,12 @@ static int acpm_prepare_xfer(struct acpm_chan *achan,
 	return 0;
 }
 
+static int acpm_prepare_xfer(struct acpm_chan *achan,
+			     const struct acpm_xfer *xfer)
+{
+	return __acpm_prepare_xfer(achan, xfer, false);
+}
+
 /**
  * acpm_wait_for_message_response - an helper to group all possible ways of
  * waiting for a synchronous message response.
@@ -452,6 +517,62 @@ static int acpm_wait_for_message_response(struct acpm_chan *achan,
 	return acpm_dequeue_by_polling(achan, xfer);
 }
 
+int acpm_do_xfer_fast(struct acpm_handle *handle, const struct acpm_xfer *xfer)
+{
+	struct acpm_info *acpm = handle_to_acpm_info(handle);
+	struct exynos_mbox_msg msg;
+	struct acpm_chan *achan;
+	u32 idx, tx_front;
+	int ret;
+
+	if (xfer->acpm_chan_id >= acpm->num_chans)
+		return -EINVAL;
+
+	achan = &acpm->chans[xfer->acpm_chan_id];
+
+	msg.chan_id = xfer->acpm_chan_id;
+	msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL;
+
+	/* Ideally should be a raw_spin_trylock.
+	 * If we can't get it immediately, then give up.
+	 */
+	if (!spin_trylock(&achan->tx_lock))
+		return -EBUSY;
+
+	/* clean up/ack previous responses */
+	acpm_drain_stale_rx(achan);
+
+	tx_front = readl(achan->tx.front);
+	idx = (tx_front + 1) % achan->qlen;
+
+	if (idx == readl(achan->tx.rear)) {
+		/* stalled; queue is full? */
+		spin_unlock(&achan->tx_lock);
+		return -EBUSY;
+	}
+
+	ret = __acpm_prepare_xfer(achan, xfer, true);
+	if (ret) {
+		spin_unlock(&achan->tx_lock);
+		return ret;
+	}
+
+	__iowrite32_copy(achan->tx.base + achan->mlen * tx_front,
+			 xfer->txd, xfer->txcnt);
+
+	/* advance TX front */
+	writel(idx, achan->tx.front);
+
+	/* ring the doorbell */
+	ret = mbox_send_message(achan->chan, (void *)&msg);
+	if (ret >= 0)
+		mbox_client_txdone(achan->chan, 0);
+
+	spin_unlock(&achan->tx_lock);
+
+	return ret < 0 ? ret : 0;
+}
+
 /**
  * acpm_do_xfer() - do one transfer.
  * @handle:	pointer to the acpm handle.
@@ -485,7 +606,7 @@ int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
 	msg.chan_id = xfer->acpm_chan_id;
 	msg.chan_type = EXYNOS_MBOX_CHAN_TYPE_DOORBELL;
 
-	scoped_guard(mutex, &achan->tx_lock) {
+	scoped_guard(spinlock, &achan->tx_lock) {
 		tx_front = readl(achan->tx.front);
 		idx = (tx_front + 1) % achan->qlen;
 
@@ -654,8 +775,8 @@ static int acpm_channels_init(struct acpm_info *acpm)
 		if (ret)
 			return ret;
 
-		mutex_init(&achan->rx_lock);
-		mutex_init(&achan->tx_lock);
+		spin_lock_init(&achan->rx_lock);
+		spin_lock_init(&achan->tx_lock);
 
 		cl->dev = dev;
 
@@ -675,6 +796,7 @@ static void acpm_clk_pdev_unregister(void *data)
 static const struct acpm_ops exynos_acpm_driver_ops = {
 	.dvfs = {
 		.set_rate = acpm_dvfs_set_rate,
+		.set_rate_fast = acpm_dvfs_set_rate_fast,
 		.get_rate = acpm_dvfs_get_rate,
 	},
 
diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
index 708f6b0102ac..210709326a1f 100644
--- a/drivers/firmware/samsung/exynos-acpm.h
+++ b/drivers/firmware/samsung/exynos-acpm.h
@@ -22,4 +22,7 @@ void acpm_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdcnt,
 int acpm_do_xfer(struct acpm_handle *handle,
 		 const struct acpm_xfer *xfer);
 
+int acpm_do_xfer_fast(struct acpm_handle *handle,
+		      const struct acpm_xfer *xfer);
+
 #endif /* __EXYNOS_ACPM_H__ */
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
index c6b35c0ff300..93c9b20517f8 100644
--- a/include/linux/firmware/samsung/exynos-acpm-protocol.h
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -16,6 +16,8 @@ struct device_node;
 struct acpm_dvfs_ops {
 	int (*set_rate)(struct acpm_handle *handle, unsigned int acpm_chan_id,
 			unsigned int clk_id, unsigned long rate);
+	int (*set_rate_fast)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+			     unsigned int clk_id, unsigned long rate);
 	unsigned long (*get_rate)(struct acpm_handle *handle,
 				  unsigned int acpm_chan_id,
 				  unsigned int clk_id);

-- 
2.51.0



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox