* Re: [PATCH v5 0/4] PCI: Add DOE support for endpoint
From: Aksh Garg @ 2026-06-12 7:58 UTC (permalink / raw)
To: Frank Li
Cc: linux-pci, linux-doc, mani, kwilczynski, bhelgaas, corbet, kishon,
skhan, lukas, cassel, alistair, linux-arm-kernel, linux-kernel,
s-vadapalli, danishanwar, srk
In-Reply-To: <aise1tIyTj4WLU89@lizhi-Precision-Tower-5810>
On 12/06/26 02:17, Frank Li wrote:
> On Wed, Jun 10, 2026 at 03:32:52PM +0530, Aksh Garg wrote:
>> This patch series introduces the framework for supporting the Data
>> Object Exchange (DOE) feature for PCIe endpoint devices. Please refer
>> to the documentation added in patch 4 for details on the feature and
>> implementation architecture.
>>
>> The implementation provides a common framework for all PCIe endpoint
>> controllers, not specific to any particular SoC vendor.
>>
Hi Frank,
>
> General question, does DOE generate irq when received msg for HOST? I have
> not related irq handle code.
>
The EPC hardware is expected to raise IRQ when it receives DOE signals
from the host. The example IRQ code handler have been provided below.
When the response DOE is ready for the host, the signal_task_complete()
in pci-ep-doe.c invokes completion callback function, through which the
EPC driver handles to send the response back to the host using the DOE
mailbox.
> Any program to test it? such as pci_endpoint_test, need at least one real
> user to use it.
>
Currently there is no EPC driver upstream which support DOE yet.
However, you can refer to the conversation at [1] where the plan to add
user for this framework has been discussed.
Regards,
Aksh Garg
> Frank
>
>> The changes since v1 are documented in the respective patch descriptions.
>>
>> v4: https://lore.kernel.org/all/20260522052434.802034-1-a-garg7@ti.com/
>> v3: https://lore.kernel.org/all/20260427051725.223704-1-a-garg7@ti.com/
>> v2: https://lore.kernel.org/all/20260401073022.215805-1-a-garg7@ti.com/
>> v1 (RFC): https://lore.kernel.org/all/20260213123603.420941-1-a-garg7@ti.com/
>>
>> Below is a code demonstration showing the integration of DOE-EP APIs with
>> EPC drivers.
>>
>> Note: The provided code is just to show how an EPC driver is expected to
>> utilize the pci_ep_doe_process_request() and pci_ep_doe_abort() APIs,
>> and might not cover all the corner cases. The below implementation
>> also expects the EPC hardware to have some memory buffer to store the
>> data from(for) write_mailbox(read_mailbox) DOE capability registers.
>>
>> ============================================================================
>>
>> /* ========== DOE Completion Callback (invoked by DOE-EP core) ========== */
>>
>> static void doe_completion_cb(struct pci_epc *epc, u8 func_no, u16 cap_offset,
>> int status, u16 vendor, u8 type,
>> void *response_pl, size_t response_pl_sz)
>> {
>> struct epc_driver *drv = epc_get_drvdata(epc);
>> u32 *response = (u32 *)response_pl;
>> u32 header1, header2;
>> int payload_dw, i;
>>
>> if (readl(drv->base + PF_DOE_CTRL_REG(func_no, cap_offset)) & DOE_CTRL_ABORT) {
>> /* Aborted: do not send response */
>> goto free;
>> }
>>
>> if (status < 0) {
>> /* Error: set ERROR bit in DOE Status register */
>> writel(1 << DOE_STATUS_ERROR,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>> goto free;
>> }
>>
>> /* Success: write DOE headers first, then response to the read memory */
>>
>> /* Header 1: Vendor ID (bits 15:0) | Type (bits 23:16) */
>> header1 = (type << 16) | vendor;
>> writel(header1, drv->base + PF_DOE_RD_MEMORY_WR_REG(func_no, cap_offset));
>>
>> /* Header 2: Length in DW (including 2 DW of headers + payload) */
>> payload_dw = DIV_ROUND_UP(response_pl_sz, sizeof(u32));
>> header2 = 2 + payload_dw; /* 2 header DWs + payload */
>> writel(header2, drv->base + PF_DOE_RD_MEMORY_WR_REG(func_no, cap_offset));
>>
>> /* Set READY bit to signal response ready */
>> writel(1 << DOE_STATUS_READY,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>>
>> /* Write response payload DWORDs to Read memory */
>> for (i = 0; i < payload_dw; i++)
>> writel(response[i],
>> drv->base + PF_DOE_RD_MEMORY_WR_REG(func_no, cap_offset));
>>
>> /* Wait for the memory to empty before clearing the READY bit */
>> while (!RD_MEMORY_EMPTY()) {/* wait */}
>>
>> writel(0 << DOE_STATUS_READY,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>>
>> free:
>> /* unset BUSY bit */
>> writel(0 << DOE_STATUS_BUSY,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>>
>> kfree(response_pl);
>> }
>>
>> /* ========== DOE Interrupt Handler (triggered on GO bit from root complex) ========== */
>>
>> static irqreturn_t doe_interrupt_handler(int irq, void *priv)
>> {
>> struct epc_driver *drv = priv;
>> u16 cap_offset = extract_cap_offset_from_irq(irq);
>> u8 func_no = extract_func_from_irq(irq);
>> u32 header1, header2, length_dw, *request;
>> u16 vendor;
>> u8 type;
>> int i, ret;
>>
>> /* Read first header DWORD: Vendor ID (bits 15:0) | Type (bits 23:16) */
>> header1 = readl(drv->base + PF_DOE_WR_MEMORY_RD_REG(func_no, cap_offset));
>> vendor = header1 & 0xFFFF;
>> type = (header1 >> 16) & 0xFF;
>>
>> /* Read second header DWORD: Length in DW (includes 2 DW of headers) */
>> header2 = readl(drv->base + PF_DOE_WR_MEMORY_RD_REG(func_no, cap_offset));
>> length_dw = header2 & 0x3FFFF; /* Bits 17:0 */
>>
>> if (!length_dw)
>> length_dw = PCI_DOE_MAX_LENGTH;
>>
>> length_dw -= 2; /* Subtract 2 DW of headers to get payload length */
>> /* Allocate buffer for complete request (headers + payload) */
>> request = kzalloc(length_dw * sizeof(u32), GFP_ATOMIC);
>> if (!request) {
>> writel(1 << DOE_STATUS_ERROR,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>> return IRQ_HANDLED;
>> }
>>
>> /* Read remaining payload DWORDs from Write memory */
>> for (i = 0; i < length_dw; i++) {
>> while (WR_MEMORY_EMPTY()) { /* wait */ }
>> request[i] = readl(drv->base + PF_DOE_WR_MEMORY_RD_REG(func_no, cap_offset));
>> }
>>
>> mutex_lock(&lock);
>> /* Check the ABORT bit, if set then return */
>> if (readl(drv->base + PF_DOE_CTRL_REG(func_no, cap_offset)) & DOE_CTRL_ABORT) {
>> kfree(request);
>> mutex_unlock(&lock);
>> return IRQ_HANDLED;
>> }
>>
>> /* Set BUSY bit */
>> writel(1 << DOE_STATUS_BUSY,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>> mutex_unlock(&lock);
>>
>> /* Hand off to DOE-EP core for asynchronous processing */
>> ret = pci_ep_doe_process_request(drv->epc, func_no, cap_offset,
>> vendor, type, (void *)request,
>> length_dw * sizeof(u32),
>> doe_completion_cb);
>> if (ret) {
>> writel(1 << DOE_STATUS_ERROR,
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>> kfree(request);
>> }
>>
>> return IRQ_HANDLED;
>> }
>>
>> /* ========== Abort Handler (triggered on ABORT bit from root complex) ========== */
>>
>> static irqreturn_t doe_abort_handler(int irq, void *priv)
>> {
>> struct epc_driver *drv = priv;
>> u16 cap_offset = extract_cap_offset_from_irq(irq);
>> u8 func_no = extract_func_from_irq(irq);
>>
>> mutex_lock(&lock);
>>
>> /* call abort API only if BUSY bit set (pci_ep_doe_process_request() called) */
>> if (readl(drv->base + PF_DOE_STATUS_REG(func_no, cap_offset)) & DOE_STATUS_BUSY)
>> pci_ep_doe_abort(drv->epc, func_no, cap_offset);
>>
>> mutex_unlock(&lock);
>>
>> /* Discard Write memory contents */
>> writel(DOE_WR_MEMORY_CTRL_DISCARD,
>> drv->base + PF_DOE_WR_MEMORY_CTRL_REG(func_no, cap_offset));
>>
>> /* Clear status bits */
>> writel((0 << DOE_STATUS_ERROR) | (0 << DOE_STATUS_READY),
>> drv->base + PF_DOE_STATUS_REG(func_no, cap_offset));
>>
>> return IRQ_HANDLED;
>> }
>>
>> ====================================================================================
>>
>> Aksh Garg (4):
>> PCI/DOE: Move common definitions to the header file
>> PCI: endpoint: Add DOE mailbox support for endpoint functions
>> PCI: endpoint: Add support for DOE initialization and setup in EPC
>> core
>> Documentation: PCI: Add documentation for DOE endpoint support
>>
>> Documentation/PCI/endpoint/index.rst | 1 +
>> .../PCI/endpoint/pci-endpoint-doe.rst | 333 ++++++++++
>> drivers/pci/doe.c | 11 -
>> drivers/pci/endpoint/Kconfig | 14 +
>> drivers/pci/endpoint/Makefile | 1 +
>> drivers/pci/endpoint/pci-ep-doe.c | 594 ++++++++++++++++++
>> drivers/pci/endpoint/pci-epc-core.c | 104 +++
>> drivers/pci/pci.h | 48 ++
>> include/linux/pci-doe.h | 8 +
>> include/linux/pci-epc.h | 9 +
>> 10 files changed, 1112 insertions(+), 11 deletions(-)
>> create mode 100644 Documentation/PCI/endpoint/pci-endpoint-doe.rst
>> create mode 100644 drivers/pci/endpoint/pci-ep-doe.c
>>
>> --
>> 2.34.1
>>
^ permalink raw reply
* Re: [PATCH v2 4/7] arm64: dts: qcom: shikra: Add CCI definitions
From: Vladimir Zapolskiy @ 2026-06-12 8:01 UTC (permalink / raw)
To: Nihal Kumar Gupta, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <20260608-shikra-camss-review-v2-4-ca1936bf1219@oss.qualcomm.com>
On 6/8/26 17:06, Nihal Kumar Gupta wrote:
> Qualcomm Shikra SoC has one Camera Control Interface (CCI)
> containing two I2C hosts.
>
> Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
> arch/arm64/boot/dts/qcom/shikra.dtsi | 70 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 70 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
> index b93ce4a92a998ea5d9d4268d2fd46030fafc4084..fed71131491ebf6e261bfcd14b5d4a2624837878 100644
> --- a/arch/arm64/boot/dts/qcom/shikra.dtsi
> +++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
> @@ -348,6 +348,38 @@ tlmm: pinctrl@500000 {
> gpio-ranges = <&tlmm 0 0 165>;
> wakeup-parent = <&mpm>;
>
> + cci_i2c0_default: cci-i2c0-default-state {
> + /* SDA, SCL */
> + pins = "gpio36", "gpio37";
> + function = "cci_i2c0";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> +
> + cci_i2c0_sleep: cci-i2c0-sleep-state {
> + /* SDA, SCL */
> + pins = "gpio36", "gpio37";
> + function = "cci_i2c0";
> + drive-strength = <2>;
> + bias-pull-down;
> + };
> +
> + cci_i2c1_default: cci-i2c1-default-state {
> + /* SDA, SCL */
> + pins = "gpio41", "gpio42";
> + function = "cci_i2c1";
> + drive-strength = <2>;
> + bias-pull-up;
> + };
> +
> + cci_i2c1_sleep: cci-i2c1-sleep-state {
> + /* SDA, SCL */
> + pins = "gpio41", "gpio42";
> + function = "cci_i2c1";
> + drive-strength = <2>;
> + bias-pull-down;
> + };
> +
> qup_uart0_default: qup-uart0-default-state {
> pins = "gpio0", "gpio1";
> function = "qup0_se0";
> @@ -701,6 +733,44 @@ port@1 {
> reg = <1>;
> };
> };
> +
> + };
> +
> + cci: cci@5c1b000 {
> + compatible = "qcom,shikra-cci", "qcom,msm8996-cci";
> + reg = <0x0 0x05c1b000 0x0 0x1000>;
> +
> + interrupts = <GIC_SPI 206 IRQ_TYPE_EDGE_RISING 0>;
> +
> + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>,
> + <&gcc GCC_CAMSS_CCI_0_CLK>;
> + clock-names = "ahb",
> + "cci";
> +
> + power-domains = <&gcc GCC_CAMSS_TOP_GDSC>;
> +
> + pinctrl-0 = <&cci_i2c0_default &cci_i2c1_default>;
> + pinctrl-1 = <&cci_i2c0_sleep &cci_i2c1_sleep>;
> + pinctrl-names = "default", "sleep";
> +
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + status = "disabled";
> +
> + cci_i2c0: i2c-bus@0 {
> + reg = <0>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + cci_i2c1: i2c-bus@1 {
> + reg = <1>;
> + clock-frequency = <400000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> };
>
> qupv3_0: geniqup@4ac0000 {
>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
--
Best wishes,
Vladimir
^ permalink raw reply
* Re: [PATCH v2 5/7] arm64: dts: qcom: shikra: Add pin configuration for mclks
From: Vladimir Zapolskiy @ 2026-06-12 8:02 UTC (permalink / raw)
To: Nihal Kumar Gupta, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <20260608-shikra-camss-review-v2-5-ca1936bf1219@oss.qualcomm.com>
On 6/8/26 17:06, Nihal Kumar Gupta wrote:
> Add pinctrl configuration for the four available camera master clocks.
>
> Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/shikra.dtsi | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
> index fed71131491ebf6e261bfcd14b5d4a2624837878..2f0f7710c2897e140495afd8d4e8bde50f356096 100644
> --- a/arch/arm64/boot/dts/qcom/shikra.dtsi
> +++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
> @@ -380,6 +380,34 @@ cci_i2c1_sleep: cci-i2c1-sleep-state {
> bias-pull-down;
> };
>
> + cam_mclk0_default: cam-mclk0-default-state {
> + pins = "gpio34";
> + function = "cam_mclk";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +
> + cam_mclk1_default: cam-mclk1-default-state {
> + pins = "gpio35";
> + function = "cam_mclk";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +
> + cam_mclk2_default: cam-mclk2-default-state {
> + pins = "gpio96";
> + function = "cam_mclk";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +
> + cam_mclk3_default: cam-mclk3-default-state {
> + pins = "gpio98";
> + function = "cam_mclk";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +
> qup_uart0_default: qup-uart0-default-state {
> pins = "gpio0", "gpio1";
> function = "qup0_se0";
>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
--
Best wishes,
Vladimir
^ permalink raw reply
* [PATCH v1 06/11] KVM: arm64: Factor out reusable vCPU reset helpers
From: tabba @ 2026-06-12 6:59 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton
Cc: Fuad Tabba, Will Deacon, Catalin Marinas, Quentin Perret,
Vincent Donnefort, Sebastian Ene, Per Larsen, Suzuki K Poulose,
Zenghui Yu, Joey Gouly, Steffen Eiden, Mark Rutland,
Jonathan Cameron, Hyunwoo Kim, linux-arm-kernel, kvmarm,
linux-kernel
In-Reply-To: <20260612065925.755562-1-tabba@google.com>
Pull the reusable pieces out of kvm_reset_vcpu(): expose the reset
PSTATE values in kvm_arm.h, and split the core register reset and the
PSCI-driven reset into kvm_reset_vcpu_core() and kvm_reset_vcpu_psci().
A follow-up series reuses these to reset protected vCPUs at EL2.
No functional change intended.
Signed-off-by: Fuad Tabba <tabba@google.com>
---
arch/arm64/include/asm/kvm_arm.h | 12 ++++++
arch/arm64/include/asm/kvm_emulate.h | 58 +++++++++++++++++++++++++++
arch/arm64/kvm/reset.c | 60 ++--------------------------
3 files changed, 73 insertions(+), 57 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3f9233b5a130..aba4ec09acd2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -348,4 +348,16 @@
{ PSR_AA32_MODE_UND, "32-bit UND" }, \
{ PSR_AA32_MODE_SYS, "32-bit SYS" }
+/*
+ * ARMv8 Reset Values
+ */
+#define VCPU_RESET_PSTATE_EL1 (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
+ PSR_F_BIT | PSR_D_BIT)
+
+#define VCPU_RESET_PSTATE_EL2 (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
+ PSR_F_BIT | PSR_D_BIT)
+
+#define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
+ PSR_AA32_I_BIT | PSR_AA32_F_BIT)
+
#endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index aed9fc0b717b..8436e71c402d 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -704,4 +704,62 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)
vcpu->arch.hcrx_el2 |= HCRX_EL2_EnASR;
}
}
+
+/* Reset a vcpu's core registers. */
+static inline void kvm_reset_vcpu_core(struct kvm_vcpu *vcpu)
+{
+ u32 pstate;
+
+ if (vcpu_el1_is_32bit(vcpu)) {
+ pstate = VCPU_RESET_PSTATE_SVC;
+ } else if (vcpu_has_nv(vcpu)) {
+ pstate = VCPU_RESET_PSTATE_EL2;
+ } else {
+ pstate = VCPU_RESET_PSTATE_EL1;
+ }
+
+ /* Reset core registers */
+ memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));
+ memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
+ vcpu->arch.ctxt.spsr_abt = 0;
+ vcpu->arch.ctxt.spsr_und = 0;
+ vcpu->arch.ctxt.spsr_irq = 0;
+ vcpu->arch.ctxt.spsr_fiq = 0;
+ vcpu_gp_regs(vcpu)->pstate = pstate;
+}
+
+/* PSCI reset handling for a vcpu. */
+static inline void kvm_reset_vcpu_psci(struct kvm_vcpu *vcpu,
+ struct vcpu_reset_state *reset_state)
+{
+ unsigned long target_pc = reset_state->pc;
+
+ /* Gracefully handle Thumb2 entry point */
+ if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
+ target_pc &= ~1UL;
+ vcpu_set_thumb(vcpu);
+ }
+
+ /* Propagate caller endianness */
+ if (reset_state->be)
+ kvm_vcpu_set_be(vcpu);
+
+ *vcpu_pc(vcpu) = target_pc;
+
+ /*
+ * We may come from a state where either a PC update was
+ * pending (SMC call resulting in PC being increpented to
+ * skip the SMC) or a pending exception. Make sure we get
+ * rid of all that, as this cannot be valid out of reset.
+ *
+ * Note that clearing the exception mask also clears PC
+ * updates, but that's an implementation detail, and we
+ * really want to make it explicit.
+ */
+ vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
+ vcpu_clear_flag(vcpu, EXCEPT_MASK);
+ vcpu_clear_flag(vcpu, INCREMENT_PC);
+ vcpu_set_reg(vcpu, 0, reset_state->r0);
+}
+
#endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 60969d90bdd3..e22d0be9e57c 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -34,18 +34,6 @@
static u32 __ro_after_init kvm_ipa_limit;
unsigned int __ro_after_init kvm_host_sve_max_vl;
-/*
- * ARMv8 Reset Values
- */
-#define VCPU_RESET_PSTATE_EL1 (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
- PSR_F_BIT | PSR_D_BIT)
-
-#define VCPU_RESET_PSTATE_EL2 (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
- PSR_F_BIT | PSR_D_BIT)
-
-#define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
- PSR_AA32_I_BIT | PSR_AA32_F_BIT)
-
unsigned int __ro_after_init kvm_sve_max_vl;
int __init kvm_arm_init_sve(void)
@@ -191,7 +179,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
{
struct vcpu_reset_state reset_state;
bool loaded;
- u32 pstate;
scoped_guard(spinlock, &vcpu->arch.mp_state_lock) {
reset_state = vcpu->arch.reset_state;
@@ -210,21 +197,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
kvm_vcpu_reset_sve(vcpu);
}
- if (vcpu_el1_is_32bit(vcpu))
- pstate = VCPU_RESET_PSTATE_SVC;
- else if (vcpu_has_nv(vcpu))
- pstate = VCPU_RESET_PSTATE_EL2;
- else
- pstate = VCPU_RESET_PSTATE_EL1;
-
/* Reset core registers */
- memset(vcpu_gp_regs(vcpu), 0, sizeof(*vcpu_gp_regs(vcpu)));
- memset(&vcpu->arch.ctxt.fp_regs, 0, sizeof(vcpu->arch.ctxt.fp_regs));
- vcpu->arch.ctxt.spsr_abt = 0;
- vcpu->arch.ctxt.spsr_und = 0;
- vcpu->arch.ctxt.spsr_irq = 0;
- vcpu->arch.ctxt.spsr_fiq = 0;
- vcpu_gp_regs(vcpu)->pstate = pstate;
+ kvm_reset_vcpu_core(vcpu);
/* Reset system registers */
kvm_reset_sys_regs(vcpu);
@@ -233,36 +207,8 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
* Additional reset state handling that PSCI may have imposed on us.
* Must be done after all the sys_reg reset.
*/
- if (reset_state.reset) {
- unsigned long target_pc = reset_state.pc;
-
- /* Gracefully handle Thumb2 entry point */
- if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) {
- target_pc &= ~1UL;
- vcpu_set_thumb(vcpu);
- }
-
- /* Propagate caller endianness */
- if (reset_state.be)
- kvm_vcpu_set_be(vcpu);
-
- *vcpu_pc(vcpu) = target_pc;
-
- /*
- * We may come from a state where either a PC update was
- * pending (SMC call resulting in PC being increpented to
- * skip the SMC) or a pending exception. Make sure we get
- * rid of all that, as this cannot be valid out of reset.
- *
- * Note that clearing the exception mask also clears PC
- * updates, but that's an implementation detail, and we
- * really want to make it explicit.
- */
- vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
- vcpu_clear_flag(vcpu, EXCEPT_MASK);
- vcpu_clear_flag(vcpu, INCREMENT_PC);
- vcpu_set_reg(vcpu, 0, reset_state.r0);
- }
+ if (reset_state.reset)
+ kvm_reset_vcpu_psci(vcpu, &reset_state);
/* Reset timer */
kvm_timer_vcpu_reset(vcpu);
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* Re: [PATCH v2 6/7] arm64: dts: qcom: shikra-cqm-cqs-evk-imx577-camera: Add DT overlay
From: Vladimir Zapolskiy @ 2026-06-12 8:10 UTC (permalink / raw)
To: Nihal Kumar Gupta, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <20260608-shikra-camss-review-v2-6-ca1936bf1219@oss.qualcomm.com>
On 6/8/26 17:06, Nihal Kumar Gupta wrote:
> Shikra CQM and CQS are retail variants sharing the same PM4125 PMIC
> and identical camera supply rails. The only difference between them
> is the integrated modem on CQM, which does not affect camera hardware.
>
> Add a shared overlay for optional IMX577 integration via CSIPHY1,
> used by both CQM and CQS EVK boards.
>
> Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 6 ++
> .../dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso | 70 ++++++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 9 +++
> arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 9 +++
> 4 files changed, 94 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index a9e9d829fb962386b3975f345ec006504607130a..76b8f144983827f4905a72935e8d5291a227dc97 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -337,6 +337,12 @@ dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb
> dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb
> dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb
> dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
> +
> +shikra-cqm-evk-imx577-camera-dtbs := shikra-cqm-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
> +shikra-cqs-evk-imx577-camera-dtbs := shikra-cqs-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
> +
> +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk-imx577-camera.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk-imx577-camera.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso
> new file mode 100644
> index 0000000000000000000000000000000000000000..e3dad7c81e5e8aeb1061c784b5b893965f914a6f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso
> @@ -0,0 +1,70 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/clock/qcom,shikra-gcc.h>
> +#include <dt-bindings/gpio/gpio.h>
> +
> +&camss {
> + vdd-csiphy-1p2-supply = <&pm4125_l5>;
> + vdd-csiphy-1p8-supply = <&pm4125_l13>;
> +
> + status = "okay";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@1 {
> + reg = <1>;
> +
> + csiphy1_ep: endpoint {
> + data-lanes = <0 1 2 3>;
> + remote-endpoint = <&imx577_ep1>;
> + };
> + };
> + };
> +};
> +
> +&cci {
> + status = "okay";
> +};
> +
> +&cci_i2c1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + camera@1a {
> + compatible = "sony,imx577";
> + reg = <0x1a>;
> +
> + reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
> + pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>;
> + pinctrl-names = "default";
> +
> + clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
> + assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
> + assigned-clock-rates = <24000000>;
> +
> + /*
> + * avdd and dvdd are supplied by on-board regulators on the
> + * IMX577 module from the connector's 3.3 V rail; they are
> + * not SoC-controlled. dovdd (1.8 V) powers the carrier board
> + * level-shifter that translates CCI I2C and reset lines
> + * between the SoC and the connector.
> + */
> + dovdd-supply = <&pm4125_l15>;
> +
> + port {
> + imx577_ep1: endpoint {
> + link-frequencies = /bits/ 64 <600000000>;
> + data-lanes = <0 1 2 3>;
The numeration of data-lanes shall be started from 1, this has to be fixed.
> + remote-endpoint = <&csiphy1_ep>;
> + };
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> index 0a52ab9b7a4c34d371f5ac23efe59d1c9d2723f4..0d5c3e31b1f613157d4d2ec6947c630f1031b73b 100644
> --- a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> @@ -38,3 +38,12 @@ &sdhc_1 {
>
> status = "okay";
> };
> +
> +&tlmm {
> + cam1_reset_default: cam1-reset-default-state {
> + pins = "gpio33";
> + function = "gpio";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +};
Since it's a mezzanine specific pinctl assignment, it shall go to the
correspondent .dtso file.
It's a concidence that one .dtso file is good enough for describing the
mezzanine for two diffferent boards, but let's exploit it by keeping one
dt overlay file as it is now.
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> index b3f19a64d7aed3121ef092df684b19a4de39b497..515af370ca014a668dc035ff944fb82b6e09ceeb 100644
> --- a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> @@ -38,3 +38,12 @@ &sdhc_1 {
>
> status = "okay";
> };
> +
> +&tlmm {
> + cam1_reset_default: cam1-reset-default-state {
> + pins = "gpio33";
> + function = "gpio";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +};
>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
--
Best wishes,
Vladimir
^ permalink raw reply
* Re: [PATCH v2 7/7] arm64: dts: qcom: shikra-iqs-evk-imx577-camera: Add DT overlay
From: Vladimir Zapolskiy @ 2026-06-12 8:11 UTC (permalink / raw)
To: Nihal Kumar Gupta, Bryan O'Donoghue, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma
In-Reply-To: <20260608-shikra-camss-review-v2-7-ca1936bf1219@oss.qualcomm.com>
On 6/8/26 17:06, Nihal Kumar Gupta wrote:
> Shikra IQS is an industrial-grade variant using PM8150 PMIC, requiring
> different CSIPHY and sensor supply rails compared to the retail boards
> (CQM and CQS) which use PM4125.
>
> Add a dedicated overlay for optional IMX577 integration via CSIPHY1.
>
> Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 2 +
> .../dts/qcom/shikra-iqs-evk-imx577-camera.dtso | 70 ++++++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 9 +++
> 3 files changed, 81 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index 76b8f144983827f4905a72935e8d5291a227dc97..09f2318d1c12c4239a6a7bac4ecbca38eb65ffa2 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -340,9 +340,11 @@ dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
>
> shikra-cqm-evk-imx577-camera-dtbs := shikra-cqm-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
> shikra-cqs-evk-imx577-camera-dtbs := shikra-cqs-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
> +shikra-iqs-evk-imx577-camera-dtbs := shikra-iqs-evk.dtb shikra-iqs-evk-imx577-camera.dtbo
>
> dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk-imx577-camera.dtb
> dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk-imx577-camera.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk-imx577-camera.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
> diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso
> new file mode 100644
> index 0000000000000000000000000000000000000000..340d6303adc6e1bea55f1bd0598175f0cb269737
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso
> @@ -0,0 +1,70 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/clock/qcom,shikra-gcc.h>
> +#include <dt-bindings/gpio/gpio.h>
> +
> +&camss {
> + vdd-csiphy-1p2-supply = <&pm8150_l11>;
> + vdd-csiphy-1p8-supply = <&pm8150_l12>;
> +
> + status = "okay";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@1 {
> + reg = <1>;
> +
> + csiphy1_ep: endpoint {
> + data-lanes = <0 1 2 3>;
> + remote-endpoint = <&imx577_ep1>;
> + };
> + };
> + };
> +};
> +
> +&cci {
> + status = "okay";
> +};
> +
> +&cci_i2c1 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + camera@1a {
> + compatible = "sony,imx577";
> + reg = <0x1a>;
> +
> + reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
> + pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>;
> + pinctrl-names = "default";
> +
> + clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
> + assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
> + assigned-clock-rates = <24000000>;
> +
> + /*
> + * avdd and dvdd are supplied by on-board regulators on the
> + * IMX577 module from the connector's 3.3 V rail; they are
> + * not SoC-controlled. dovdd (1.8 V) powers the carrier board
> + * level-shifter that translates CCI I2C and reset lines
> + * between the SoC and the connector.
> + */
> + dovdd-supply = <&pm8150_l15>;
> +
> + port {
> + imx577_ep1: endpoint {
> + link-frequencies = /bits/ 64 <600000000>;
> + data-lanes = <0 1 2 3>;
Same as before, the numeration of data lanes starts from 1.
> + remote-endpoint = <&csiphy1_ep>;
> + };
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
> index 3003a47bd7594206f0ac54957e0af509fa365f54..811fd5da4af7babd412d70fee84434849846dc2f 100644
> --- a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
> @@ -38,3 +38,12 @@ &sdhc_1 {
>
> status = "okay";
> };
> +
> +&tlmm {
> + cam1_reset_default: cam1-reset-default-state {
> + pins = "gpio33";
> + function = "gpio";
> + drive-strength = <2>;
> + bias-disable;
> + };
> +};
>
This part goes directly to the mezzanine .dtso file.
After fixing it,
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
--
Best wishes,
Vladimir
^ permalink raw reply
* Re: [PATCH v7 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-06-12 8:14 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: <1b10c279-bdb7-4901-aa40-bca36dcec350@lunn.ch>
On Fri, Jun 12, 2026 at 3:04 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > 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.
>
> I think some comments would be good. It was not clear to my how this
> works.
>
> Andrew
Hi Andrew,
Understood. I will add a detailed comment block explaining this hardware I2C
isolation and the out-of-band update mechanism above the EEPROM node in v8.
Thanks for the review!
Best regards,
Kyle Hsieh
^ permalink raw reply
* Re: [PATCH] spi: uniphier: Fix completion initialization order before devm_request_irq()
From: Kunihiko Hayashi @ 2026-06-12 8:17 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-arm-kernel, linux-kernel, Sangyun Kim,
Kyungwook Boo, stable, Masami Hiramatsu
In-Reply-To: <airBmzYhnxuK_xdh@sirena.co.uk>
Hi Mark,
On 2026/06/11 23:09, Mark Brown wrote:
> On Thu, Jun 11, 2026 at 08:31:37PM +0900, Kunihiko Hayashi wrote:
>> The driver calls devm_request_irq() before initializing the completion
>> used by the interrupt handler. Because the interrupt may occur immediately
>> after devm_request_irq(), the handler may execute before init_completion().
>
> This doesn't apply against current code, please check and resend.
That seems a bit strange. I applied this patch to v7.0 and linux-next successfully.
Which tree did you apply to and fail?
Thank you,
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply
* Re: [PATCH 1/1] ARM: dts: aspeed: g6: Add AST2600 pwm tacho controller
From: Grégoire Layet @ 2026-06-12 7:43 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <e865e2e71a39c86a8afb6af49d9ebcf6839a9a2a.camel@codeconstruct.com.au>
Hi Andrew,
Too bad, I didn't looked at the right place.
Thank's !
^ permalink raw reply
* Re: [PATCH v5 3/4] PCI: endpoint: Add support for DOE initialization and setup in EPC core
From: Aksh Garg @ 2026-06-12 8:24 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-doc, mani, kwilczynski, bhelgaas, corbet, kishon,
skhan, lukas, cassel, alistair, linux-arm-kernel, linux-kernel,
s-vadapalli, danishanwar, srk
In-Reply-To: <20260611191252.GA499821@bhelgaas>
On 12/06/26 00:42, Bjorn Helgaas wrote:
> On Wed, Jun 10, 2026 at 03:32:55PM +0530, Aksh Garg wrote:
>> Add pci_epc_init_capabilities() in EPC core driver to initialize and
>> setup the capabilities supported by the EPC driver. This calls
>> pci_epc_doe_setup() to setup the DOE framework for an endpoint controller,
>> which discovers the DOE capabilities (extended capability ID 0x2E), and
>> registers each discovered DOE mailbox for all the functions in the
>> endpoint controller.
>>
>> Add pci_epc_deinit_capabilities() in EPC core driver for cleanup of the
>> resources used by the capabilities of the EPC driver. This calls
>> pci_ep_doe_destroy() to destroy all DOE mailboxes and free associated
>> resources.
>>
>> Co-developed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
>> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
>> Signed-off-by: Aksh Garg <a-garg7@ti.com>
>> ---
>> +/**
>> + * pci_epc_doe_setup() - Discover and setup DOE mailboxes for all functions
>> + * @epc: the EPC device on which DOE mailboxes has to be setup
>> + *
>> + * Discover DOE (Data Object Exchange) capabilities for all physical functions
>> + * in the endpoint controller and register DOE mailboxes.
>> + *
>> + * Returns: 0 on success, -errno on failure
>> + */
>> +static int pci_epc_doe_setup(struct pci_epc *epc)
>> +{
>> + u8 func_no, vfunc_no = 0;
>> + u16 cap_offset;
>> + int ret;
>> +
>> + if (!epc->ops || !epc->ops->find_ext_capability)
>> + return -EINVAL;
>
Hi Bjorn,
Thank you for your feedback comments. I will work on them and post v6
series incorporating the changes.
> I don't see anything that sets pci_epc_ops.find_ext_capability in this
> series, so this looks currently unused and untestable, so likely not
> mergeable as-is. What's the plan for users of this?
>
Currently there is no EPC driver upstream which supports DOE yet.
However, I am working on a platform which supports DOE (support for
which would be added soon). Mani pointed out that if EPC driver support
for the same is guaranteed to be added soon, the APIs can be merged
first.
For the demonstration purpose, he asked to show how an EPC driver is
expected to use the API as a snippet in the cover letter itself.
I will add a code snippet in the cover letter, which sets
pci_epc_ops.find_ext_capability as well, if that is acceptable.
Regards,
Aksh Garg
>> + /* Discover DOE capabilities for all functions */
>> + for (func_no = 0; func_no < epc->max_functions; func_no++) {
>> + mutex_lock(&epc->lock);
>> + cap_offset = epc->ops->find_ext_capability(epc, func_no,
>> + vfunc_no, 0,
>> + PCI_EXT_CAP_ID_DOE);
>> + mutex_unlock(&epc->lock);
>> +
>> + while (cap_offset) {
>> + /* Register this DOE mailbox */
>> + ret = pci_ep_doe_add_mailbox(epc, func_no, cap_offset);
>> + if (ret) {
>> + dev_warn(&epc->dev,
>> + "[pf%d:offset %x] failed to add DOE mailbox\n",
>> + func_no, cap_offset);
>> + }
>> +
>> + mutex_lock(&epc->lock);
>> + cap_offset = epc->ops->find_ext_capability(epc, func_no,
>> + vfunc_no, cap_offset,
>> + PCI_EXT_CAP_ID_DOE);
>> + mutex_unlock(&epc->lock);
>> + }
>> + }
>> +
>> + dev_dbg(&epc->dev, "DOE mailboxes setup complete\n");
>> + return 0;
>> +}
>> +
^ permalink raw reply
* Re: [PATCH] ARM: multi_v7_defconfig: Enable dma-buf heaps
From: Maxime Ripard @ 2026-06-12 8:33 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, linux-arm-kernel, soc, Andrew Davis
In-Reply-To: <422d7885-67bf-485b-b2fc-f0604a2213db@app.fastmail.com>
[-- Attachment #1: Type: text/plain, Size: 881 bytes --]
Hi Arnd,
On Wed, May 27, 2026 at 10:50:02AM +0200, Arnd Bergmann wrote:
> On Wed, May 27, 2026, at 10:41, Maxime Ripard wrote:
> > Now that the system and CMA heaps can be built as modules, enable both
> > as modules in the arm multi_v7_defconfig.
> >
> > Suggested-by: Andrew Davis <afd@ti.com>
> > Signed-off-by: Maxime Ripard <mripard@kernel.org>
>
> I'd like to wait until we have resolved the build regression
> from the earlier patch[1][2]. I don't have a strong opinion on how
> to resolve it, but at least for now Christoph is asking to have
> your change reverted.
I believe it's now fixed, even though not through a revert, and is on
its way to Linus:
https://lore.kernel.org/dri-devel/c7a9dbb0-a5c8-4e67-904e-1a52b3de9bb4@linux.intel.com/
arch/arm doesn't select ARCH_HAS_MEM_ENCRYPT afaik, so this patch can be
applied as is I think?
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* [PATCH] arm64: dts: aspeed: Fix duplicate pinctrl labels and address scheme
From: Andrew Jeffery @ 2026-06-12 8:33 UTC (permalink / raw)
To: soc; +Cc: linux-arm-kernel, joel, Ryan Chen, Andrew Jeffery
From: Ryan Chen <ryan_chen@aspeedtech.com>
A report from shashiko-bot highlighted some concerns concurrent to
application of the series[1].
Fix duplicate pinctrl_tach{0-15} and pinctrl_n{cts,dcd,dsr,ri}5 labels
in aspeed-g7-soc1-pinctrl.dtsi. These didn't cause errors from dtc
because dtc accepts duplicate labels for duplicate nodes specified
through a node reference[2].
Drop the cpu-index from secondary/tertiary container nodes: reduce
the "#address-cells" from 2 to 1 and update unit-addresses and reg
accordingly. The 2-cell scheme was proposed in an early mailing list
sketch to prompt discussion[3], but the design evolved in ways that made
it unnecessary.
Also remove URL comments from the DTS. The links were to comments in
the kernel sources with discussion justifying the approach, but are not
necessary to carry forward.
[arj: Extend discussion in the commit message]
Link: https://lore.kernel.org/all/20260609025708.ADBFE1F00893@smtp.kernel.org/ [1]
Link: https://lore.kernel.org/all/b226339bb2abe42ce23e90eadbc654b426131083.camel@codeconstruct.com.au/ [2]
Link: https://lore.kernel.org/all/1a2ca78746e00c2ec4bfc2953a897c48376ed36f.camel@codeconstruct.com.au/ [3]
Suggested-by: Andrew Jeffery <andrew@codeconstruct.com.au>
Fixes: e77bb5dc5759 ("arm64: dts: aspeed: Add initial AST27xx SoC device tree")
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
Link: https://patch.msgid.link/20260611-dtsi_fix-v1-1-ef2b7cd86d6d@aspeedtech.com
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
---
Hello SoC maintainers,
Here's a patch containing Ryan's fixes for issues in the report from
sashiko-bot linked in the commit message. The series in question was
inadvertently sent to soc@ before consensus had been reached through
review, and applied to soc/dt concurrent to some of the discussion on
the list.
Thanks,
Andrew
---
arch/arm64/boot/dts/aspeed/aspeed-g7-a35.dtsi | 14 ++-
.../boot/dts/aspeed/aspeed-g7-soc1-pinctrl.dtsi | 102 ---------------------
2 files changed, 6 insertions(+), 110 deletions(-)
diff --git a/arch/arm64/boot/dts/aspeed/aspeed-g7-a35.dtsi b/arch/arm64/boot/dts/aspeed/aspeed-g7-a35.dtsi
index ef283d95649a..58193c3c3696 100644
--- a/arch/arm64/boot/dts/aspeed/aspeed-g7-a35.dtsi
+++ b/arch/arm64/boot/dts/aspeed/aspeed-g7-a35.dtsi
@@ -84,32 +84,30 @@ l2: l2-cache0 {
};
secondary {
- #address-cells = <2>;
- /* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/of/address.c?h=v6.16#n491 */
+ #address-cells = <1>;
#size-cells = <0>;
- /* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/of/address.c?h=v6.16#n430 */
- ssp_nvic: interrupt-controller@1,e000e100 {
+ ssp_nvic: interrupt-controller@e000e100 {
compatible = "arm,v7m-nvic";
#interrupt-cells = <2>;
#address-cells = <0>;
interrupt-controller;
- reg = <1 0xe000e100>;
+ reg = <0xe000e100>;
arm,num-irq-priority-bits = <3>;
status = "disabled";
};
};
tertiary {
- #address-cells = <2>;
+ #address-cells = <1>;
#size-cells = <0>;
- tsp_nvic: interrupt-controller@2,e000e100 {
+ tsp_nvic: interrupt-controller@e000e100 {
compatible = "arm,v7m-nvic";
#interrupt-cells = <2>;
#address-cells = <0>;
interrupt-controller;
- reg = <2 0xe000e100>;
+ reg = <0xe000e100>;
arm,num-irq-priority-bits = <3>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/aspeed/aspeed-g7-soc1-pinctrl.dtsi b/arch/arm64/boot/dts/aspeed/aspeed-g7-soc1-pinctrl.dtsi
index 72d93323593d..6edf14617b09 100644
--- a/arch/arm64/boot/dts/aspeed/aspeed-g7-soc1-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/aspeed/aspeed-g7-soc1-pinctrl.dtsi
@@ -496,87 +496,6 @@ pinctrl_hvi3c15_default: hvi3c15-default-state {
function = "I3C15";
groups = "HVI3C15";
};
-
- pinctrl_tach0_default: tach0-default-state {
- function = "TACH0";
- groups = "TACH0";
- };
-
- pinctrl_tach1_default: tach1-default-state {
- function = "TACH1";
- groups = "TACH1";
- };
-
- pinctrl_tach2_default: tach2-default-state {
- function = "TACH2";
- groups = "TACH2";
- };
-
- pinctrl_tach3_default: tach3-default-state {
- function = "TACH3";
- groups = "TACH3";
- };
-
- pinctrl_tach4_default: tach4-default-state {
- function = "TACH4";
- groups = "TACH4";
- };
-
- pinctrl_tach5_default: tach5-default-state {
- function = "TACH5";
- groups = "TACH5";
- };
-
- pinctrl_tach6_default: tach6-default-state {
- function = "TACH6";
- groups = "TACH6";
- };
-
- pinctrl_tach7_default: tach7-default-state {
- function = "TACH7";
- groups = "TACH7";
- };
-
- pinctrl_tach8_default: tach8-default-state {
- function = "TACH8";
- groups = "TACH8";
- };
-
- pinctrl_tach9_default: tach9-default-state {
- function = "TACH9";
- groups = "TACH9";
- };
-
- pinctrl_tach10_default: tach10-default-state {
- function = "TACH10";
- groups = "TACH10";
- };
-
- pinctrl_tach11_default: tach11-default-state {
- function = "TACH11";
- groups = "TACH11";
- };
-
- pinctrl_tach12_default: tach12-default-state {
- function = "TACH12";
- groups = "TACH12";
- };
-
- pinctrl_tach13_default: tach13-default-state {
- function = "TACH13";
- groups = "TACH13";
- };
-
- pinctrl_tach14_default: tach14-default-state {
- function = "TACH14";
- groups = "TACH14";
- };
-
- pinctrl_tach15_default: tach15-default-state {
- function = "TACH15";
- groups = "TACH15";
- };
-
pinctrl_thru0_default: thru0-default-state {
function = "THRU0";
groups = "THRU0";
@@ -940,27 +859,6 @@ pinctrl_uart3_default: uart3-default-state {
function = "UART3";
groups = "UART3";
};
-
- pinctrl_ncts5_default: ncts5-default-state {
- function = "NCTS5";
- groups = "NCTS5";
- };
-
- pinctrl_ndcd5_default: ndcd5-default-state {
- function = "NDCD5";
- groups = "NDCD5";
- };
-
- pinctrl_ndsr5_default: ndsr5-default-state {
- function = "NDSR5";
- groups = "NDSR5";
- };
-
- pinctrl_nri5_default: nri5-default-state {
- function = "NRI5";
- groups = "NRI5";
- };
-
pinctrl_ndtr5_default: ndtr5-default-state {
function = "NDTR5";
groups = "NDTR5";
---
base-commit: 564edaca14861ba9e58d4e646d272c677296d285
change-id: 20260612-aspeed-arm64-dt-942a86cbed33
Best regards,
--
Andrew Jeffery <andrew@codeconstruct.com.au>
^ permalink raw reply related
* Re: [PATCH] net: airoha: Fix variable shadowing in airoha_ppe_flush_sram_entries()
From: Lorenzo Bianconi @ 2026-06-12 8:40 UTC (permalink / raw)
To: Wayen.Yan; +Cc: netdev, linux-arm-kernel, linux-mediatek
In-Reply-To: <6a2b40e4.4dd82583.3a5c46.e52f@mx.google.com>
[-- Attachment #1: Type: text/plain, Size: 1288 bytes --]
> In airoha_ppe_flush_sram_entries(), the inner "int err" declaration
> shadows the outer "err" variable. When airoha_ppe_foe_commit_sram_entry()
> fails and the loop breaks, the function returns the outer err which is
> always 0, silently swallowing the error.
>
> Remove the inner declaration so the assignment writes to the outer
> variable and errors are properly propagated.
>
> Fixes: 620d7b91aadb ("net: airoha: ppe: Flush PPE SRAM table during PPE setup")
> Signed-off-by: Wayen.Yan <win847@gmail.com>
> ---
> drivers/net/ethernet/airoha/airoha_ppe.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index 5c9dff6..2b849d4 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -1333,8 +1333,6 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
> int i, err = 0;
>
> for (i = 0; i < sram_num_entries; i++) {
> - int err;
> -
> memset(&hwe[i], 0, sizeof(*hwe));
> err = airoha_ppe_foe_commit_sram_entry(ppe, i);
> if (err)
I guess we can drop the outer err and just return here in case of error.
What do you think?
Regards,
Lorenzo
> --
> 2.51.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v5 1/6] optee: ffa: Add NULL check in optee_ffa_lend_protmem
From: Mostafa Saleh @ 2026-06-12 8:41 UTC (permalink / raw)
To: Jens Wiklander
Cc: Sebastian Ene, op-tee, linux-kernel, kvmarm, linux-arm-kernel,
maz, oupton, joey.gouly, suzuki.poulose, catalin.marinas,
sumit.garg, vdonnefort, sudeep.holla
In-Reply-To: <CAHUa44FO02DKqqNeFuRfx8bQjwcNRfPMF2=8MdjMUFp6vYUpNw@mail.gmail.com>
On Mon, Jun 08, 2026 at 03:16:49PM +0200, Jens Wiklander wrote:
> On Fri, Jun 5, 2026 at 2:01 PM Sebastian Ene <sebastianene@google.com> wrote:
> >
> > On Tue, May 26, 2026 at 03:19:29PM +0000, Mostafa Saleh wrote:
> > > Sashiko (locally) reports a possible null dereference under memory
> > > pressure due to the lack of validation of the allocated pointer.
> > >
> > > Fix that by adding the missing check.
> > >
> > > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > > ---
> > > drivers/tee/optee/ffa_abi.c | 3 +++
> > > 1 file changed, 3 insertions(+)
> > >
> > > diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> > > index b4372fa268d0..633715b98625 100644
> > > --- a/drivers/tee/optee/ffa_abi.c
> > > +++ b/drivers/tee/optee/ffa_abi.c
> > > @@ -698,6 +698,9 @@ static int optee_ffa_lend_protmem(struct optee *optee, struct tee_shm *protmem,
> > > int rc;
> > >
> > > mem_attr = kzalloc_objs(*mem_attr, ma_count);
> > > + if (!mem_attr)
> > > + return -ENOMEM;
> > > +
> > > for (n = 0; n < ma_count; n++) {
> > > mem_attr[n].receiver = mem_attrs[n] & U16_MAX;
> > > mem_attr[n].attrs = mem_attrs[n] >> 16;
> > > --
> > > 2.54.0.746.g67dd491aae-goog
> > >
> >
> > Thanks for fixing this and for including my other patches in the series
> > Reviewed-by: Sebastian Ene <sebastianene@google.com>
>
> Please add a Fixes: tag. This patch is independent of the others in
> the patch set, so if you send it alone with the Fixes: tag I'll pick
> it up.
I posted a v6 for this patch with the Fixes tag [1]
[1] https://lore.kernel.org/all/20260527150236.1978655-2-smostafa@google.com/
Thanks,
Mostafa
>
> Cheers,
> Jens
^ permalink raw reply
* [PATCH v10 0/6] clk: Support spread spectrum and use it in clk-scmi
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
Sorry for the long delay from v9 -> v10.
Since the assigned-clock-sscs property [1] has been accepted into the device
tree schema, we can now support it in the Linux clock driver. Therefore,
I've picked up the previously submitted work [2] titled "clk: Support
spread spectrum and use it in clk-pll144x and clk-scmi."
As more than six months have passed since [2] was posted, I’m treating this
patchset as a new submission rather than a v3.
- Introduce clk_set_spread_spectrum to set the parameters for enabling
spread spectrum of a clock.
- Parse 'assigned-clock-sscs' and configure it by default before using the
clock. This property is parsed before parsing clock rate.
- Enable this feature for clk-scmi on i.MX95.
Because SCMI spec will not include spread spectrum as a standard
extension, we still need to use NXP i.MX OEM extension.
[1] https://github.com/devicetree-org/dt-schema/pull/154
[2] https://lore.kernel.org/all/20250205-clk-ssc-v2-0-fa73083caa92@nxp.com/
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v10:
- For patch 4: per Stephen's comments, write a new testsuite, not modifying rate
tests. Updated commit log, and dropped the R-b tag.
- Rebased to next-20260609
- Link to v9: https://lore.kernel.org/linux-clk/177743031609.5403.8748588339056479001@localhost.localdomain/
Changes in v9:
- Rebased to next-20260311
- Fix kunit test by setting return value to 0 when there is no
assigned-clocks in patch 3
- Link to v8: https://lore.kernel.org/r/20260302-clk-ssc-v7-1-v8-0-2356443a7e4c@nxp.com
Changes in v8:
- Add R-b from Cristian for patch 5 and patch 6
- Add comment for scmi_clk_oem_info in patch 6
- Rebased to next-20260227
- Link to v7: https://lore.kernel.org/r/20251231-clk-ssc-v7-1-v7-0-380e8b58f9e3@nxp.com
Changes in v7:
- Add R-b from Sebin
- Drop __free usage per comment from Krzysztof in patch 3
- Link to v6: https://lore.kernel.org/linux-clk/20251128-clk-ssc-v6-2-v6-0-cfafdb5d6811@nxp.com/
Changes in v6:
- Add kunit build warning
- Update OEM string comparation per Sebin
- Link to v5: https://lore.kernel.org/linux-clk/20251009-clk-ssc-v5-1-v5-0-d6447d76171e@nxp.com/
Changes in v5:
- Per Stephen, export clk_hw_set_spread_spectrum, use enum for method,
add const for set_spread_spectrum and rename clk_ss/conf to ss_conf.
- Per Sebin, Cristian, Sudeep, I added clk-scmi-oem.c to support vendor
extensions.
- Link to v4: https://lore.kernel.org/arm-scmi/aNQPWO6pfA_3mmxf@redhat.com/T/#me81231bf286e2a8e4e00a68707ed1e525a2b4a3d
Changes in v4:
- Add R-b for patch 1 from Brian
- Drop unecessary change in patch 4 Per Brian
- Link to v3: https://lore.kernel.org/r/20250912-clk-ssc-version1-v3-0-fd1e07476ba1@nxp.com
Changes in v3:
- New patch 1 for dt-bindings per comment from Brian
https://lore.kernel.org/all/aLeEFzXkPog_dt2B@x1/
This might not be good to add a new dt-binding file in v3. But this is
quite a simple file that just has four macros to encode modulation
method. So hope this is fine for DT maintainers.
- Add Brain's R-b for patch 2
- New patch 3 to add Kunit test per Brain. Since Brain helped
draft part of the code, I added Co-developed-by tag from Brain.
- Link to v2: https://lore.kernel.org/r/20250901-clk-ssc-version1-v2-0-1d0a486dffe6@nxp.com
Changes in v2:
- Simplify the code in patch 2 per Dan Carpenter and Brian Masney
- Rebased to next-20250829
- Link to v1: https://lore.kernel.org/r/20250812-clk-ssc-version1-v1-0-cef60f20d770@nxp.com
---
Peng Fan (6):
dt-bindings: clock: Add spread spectrum definition
clk: Introduce clk_hw_set_spread_spectrum
clk: conf: Support assigned-clock-sscs
clk: Add KUnit tests for assigned-clock-sscs
clk: scmi: Introduce common header for SCMI clock interface
clk: scmi: Add i.MX95 OEM extension support for SCMI clock driver
drivers/clk/Makefile | 12 +-
drivers/clk/clk-conf.c | 76 ++++++++
drivers/clk/clk-scmi-oem.c | 108 +++++++++++
drivers/clk/clk-scmi.c | 44 ++---
drivers/clk/clk-scmi.h | 51 ++++++
drivers/clk/clk.c | 27 +++
drivers/clk/clk_test.c | 203 ++++++++++++++++++++-
drivers/clk/kunit_clk_assigned_rates.h | 10 +
.../clk/kunit_clk_assigned_rates_u64_multiple.dtso | 6 +
...t_clk_assigned_rates_u64_multiple_consumer.dtso | 6 +
drivers/clk/kunit_clk_assigned_rates_u64_one.dtso | 3 +
.../kunit_clk_assigned_rates_u64_one_consumer.dtso | 3 +
drivers/clk/kunit_clk_assigned_sscs_multiple.dtso | 20 ++
.../kunit_clk_assigned_sscs_multiple_consumer.dtso | 24 +++
drivers/clk/kunit_clk_assigned_sscs_null.dtso | 16 ++
.../clk/kunit_clk_assigned_sscs_null_consumer.dtso | 20 ++
drivers/clk/kunit_clk_assigned_sscs_one.dtso | 16 ++
.../clk/kunit_clk_assigned_sscs_one_consumer.dtso | 20 ++
drivers/clk/kunit_clk_assigned_sscs_without.dtso | 15 ++
.../kunit_clk_assigned_sscs_without_consumer.dtso | 19 ++
drivers/clk/kunit_clk_assigned_sscs_zero.dtso | 12 ++
.../clk/kunit_clk_assigned_sscs_zero_consumer.dtso | 16 ++
include/dt-bindings/clock/clock.h | 14 ++
include/linux/clk-provider.h | 31 ++++
24 files changed, 740 insertions(+), 32 deletions(-)
---
base-commit: 49e02880ec0a8c378e811bc9d85da188d7c6204c
change-id: 20260611-clk-v10-846cfd3e561f
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply
* [PATCH v10 1/6] dt-bindings: clock: Add spread spectrum definition
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Per dt-schema, the modulation methods are: down-spread(3), up-spread(2),
center-spread(1), no-spread(0). So define them in dt-bindings to avoid
write the magic number in device tree.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Sebin Francis <sebin.francis@ti.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
include/dt-bindings/clock/clock.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/dt-bindings/clock/clock.h b/include/dt-bindings/clock/clock.h
new file mode 100644
index 0000000000000..155e2653a120b
--- /dev/null
+++ b/include/dt-bindings/clock/clock.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright 2025 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_H
+#define __DT_BINDINGS_CLOCK_H
+
+#define CLK_SSC_NO_SPREAD 0
+#define CLK_SSC_CENTER_SPREAD 1
+#define CLK_SSC_UP_SPREAD 2
+#define CLK_SSC_DOWN_SPREAD 3
+
+#endif /* __DT_BINDINGS_CLOCK_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v10 2/6] clk: Introduce clk_hw_set_spread_spectrum
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Add clk_hw_set_spread_spectrum to configure a clock to enable spread
spectrum feature. set_spread_spectrum ops is added for clk drivers to
have their own hardware specific implementation.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Sebin Francis <sebin.francis@ti.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/clk.c | 27 +++++++++++++++++++++++++++
include/linux/clk-provider.h | 31 +++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 048adfa86a5d0..8c78621cde253 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2774,6 +2774,33 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL_GPL(clk_set_max_rate);
+int clk_hw_set_spread_spectrum(struct clk_hw *hw, const struct clk_spread_spectrum *ss_conf)
+{
+ struct clk_core *core;
+ int ret;
+
+ if (!hw)
+ return 0;
+
+ core = hw->core;
+
+ clk_prepare_lock();
+
+ ret = clk_pm_runtime_get(core);
+ if (ret)
+ goto fail;
+
+ if (core->ops->set_spread_spectrum)
+ ret = core->ops->set_spread_spectrum(hw, ss_conf);
+
+ clk_pm_runtime_put(core);
+
+fail:
+ clk_prepare_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_hw_set_spread_spectrum);
+
/**
* clk_get_parent - return the parent of a clk
* @clk: the clk whose parent gets returned
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b01a38fef8cf2..7d3747378739c 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -6,6 +6,7 @@
#ifndef __LINUX_CLK_PROVIDER_H
#define __LINUX_CLK_PROVIDER_H
+#include <dt-bindings/clock/clock.h>
#include <linux/of.h>
#include <linux/of_clk.h>
@@ -84,6 +85,26 @@ struct clk_duty {
unsigned int den;
};
+enum clk_ssc_method {
+ CLK_SPREAD_NO = CLK_SSC_NO_SPREAD,
+ CLK_SPREAD_CENTER = CLK_SSC_CENTER_SPREAD,
+ CLK_SPREAD_UP = CLK_SSC_UP_SPREAD,
+ CLK_SPREAD_DOWN = CLK_SSC_DOWN_SPREAD,
+};
+
+/**
+ * struct clk_spread_spectrum - Structure encoding spread spectrum of a clock
+ *
+ * @modfreq_hz: Modulation frequency
+ * @spread_bp: Modulation percent in permyriad
+ * @method: Modulation method
+ */
+struct clk_spread_spectrum {
+ u32 modfreq_hz;
+ u32 spread_bp;
+ enum clk_ssc_method method;
+};
+
/**
* struct clk_ops - Callback operations for hardware clocks; these are to
* be provided by the clock implementation, and will be called by drivers
@@ -174,6 +195,12 @@ struct clk_duty {
* separately via calls to .set_parent and .set_rate.
* Returns 0 on success, -EERROR otherwise.
*
+ * @set_spread_spectrum: Optional callback used to configure the spread
+ * spectrum modulation frequency, percentage, and method
+ * to reduce EMI by spreading the clock frequency over a
+ * wider range.
+ * Returns 0 on success, -EERROR otherwise.
+ *
* @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy
* is expressed in ppb (parts per billion). The parent accuracy is
* an input parameter.
@@ -249,6 +276,8 @@ struct clk_ops {
int (*set_rate_and_parent)(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate, u8 index);
+ int (*set_spread_spectrum)(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf);
unsigned long (*recalc_accuracy)(struct clk_hw *hw,
unsigned long parent_accuracy);
int (*get_phase)(struct clk_hw *hw);
@@ -1436,6 +1465,8 @@ void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
unsigned long *max_rate);
void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
unsigned long max_rate);
+int clk_hw_set_spread_spectrum(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf);
static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
{
--
2.34.1
^ permalink raw reply related
* [PATCH v10 3/6] clk: conf: Support assigned-clock-sscs
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Parse the Spread Spectrum Configuration(SSC) from device tree and configure
them before using the clock.
Each SSC is three u32 elements which means '<modfreq spreaddepth
modmethod>', so assigned-clock-sscs is an array of multiple three u32
elements.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Sebin Francis <sebin.francis@ti.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/clk-conf.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index 303a0bb26e54a..550b8ae375a2c 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -155,6 +155,78 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
return 0;
}
+static int __set_clk_spread_spectrum(struct device_node *node, bool clk_supplier)
+{
+ u32 elem_size = sizeof(struct clk_spread_spectrum);
+ struct clk_spread_spectrum *sscs;
+ struct of_phandle_args clkspec;
+ int rc, count, index;
+ struct clk *clk;
+
+ /* modfreq, spreadPercent, modmethod */
+ count = of_property_count_elems_of_size(node, "assigned-clock-sscs", elem_size);
+ if (count <= 0)
+ return 0;
+
+ sscs = kcalloc(count, elem_size, GFP_KERNEL);
+ if (!sscs)
+ return -ENOMEM;
+
+ rc = of_property_read_u32_array(node, "assigned-clock-sscs", (u32 *)sscs,
+ count * 3);
+ if (rc)
+ goto free_sscs;
+
+ for (index = 0; index < count; index++) {
+ struct clk_spread_spectrum *conf = &sscs[index];
+ struct clk_hw *hw;
+
+ if (!conf->modfreq_hz && !conf->spread_bp && !conf->method)
+ continue;
+
+ rc = of_parse_phandle_with_args(node, "assigned-clocks", "#clock-cells",
+ index, &clkspec);
+ if (rc < 0) {
+ /* skip empty (null) phandles */
+ if (rc == -ENOENT) {
+ rc = 0;
+ continue;
+ } else
+ goto free_sscs;
+ }
+
+ if (clkspec.np == node && !clk_supplier) {
+ of_node_put(clkspec.np);
+ goto free_sscs;
+ }
+
+ clk = of_clk_get_from_provider(&clkspec);
+ of_node_put(clkspec.np);
+ if (IS_ERR(clk)) {
+ if (PTR_ERR(clk) != -EPROBE_DEFER)
+ pr_warn("clk: couldn't get clock %d for %pOF\n",
+ index, node);
+ rc = PTR_ERR(clk);
+ goto free_sscs;
+ }
+
+ hw = __clk_get_hw(clk);
+ rc = clk_hw_set_spread_spectrum(hw, conf);
+ if (rc < 0) {
+ pr_err("clk: couldn't set %s clk spread spectrum %u %u %u: %d\n",
+ __clk_get_name(clk), conf->modfreq_hz, conf->spread_bp,
+ conf->method, rc);
+ /* Do not fail */
+ rc = 0;
+ }
+ clk_put(clk);
+ }
+
+free_sscs:
+ kfree(sscs);
+ return rc;
+}
+
/**
* of_clk_set_defaults() - parse and set assigned clocks configuration
* @node: device node to apply clock settings for
@@ -174,6 +246,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
if (!node)
return 0;
+ rc = __set_clk_spread_spectrum(node, clk_supplier);
+ if (rc < 0)
+ return rc;
+
rc = __set_clk_parents(node, clk_supplier);
if (rc < 0)
return rc;
--
2.34.1
^ permalink raw reply related
* [PATCH v10 4/6] clk: Add KUnit tests for assigned-clock-sscs
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Add KUnit test coverage for the assigned-clock-sscs DT property that
configures spread spectrum on clocks before they are used.
Extend the existing test infrastructure to support spread spectrum:
- Add struct clk_spread_spectrum field to clk_dummy_context and a
clk_dummy_set_spread_spectrum callback
- Wire set_spread_spectrum into all dummy clock ops
- Extend clk_assigned_rates_register_clk and test parameter struct
to propagate initial SSCS values
Add a new separate test suite clk_assigned_sscs with three categories:
1. clk_assigned_sscs_assigns_one — verifies that a single
assigned-clock-sscs entry correctly configures spread spectrum
on one clock, testing both provider and consumer paths
2. clk_assigned_sscs_assigns_multiple — verifies that multiple
assigned-clock-sscs entries configure spread spectrum on two
clocks, testing both provider and consumer paths
3. clk_assigned_sscs_skips — verifies that malformed DT properties
are correctly skipped without error: missing assigned-clocks,
zero-valued SSCS, and null phandles, tested for both provider
and consumer scenarios
New DT overlays are added for all test scenarios:
- kunit_clk_assigned_sscs_one{,consumer} — single valid entry
- kunit_clk_assigned_sscs_multiple{,consumer} — two valid entries
- kunit_clk_assigned_sscs_without{,consumer} — missing assigned-clocks
- kunit_clk_assigned_sscs_zero{,consumer} — all-zero SSCS values
- kunit_clk_assigned_sscs_null{,consumer} — null phandle
Co-developed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/Makefile | 10 +
drivers/clk/clk_test.c | 203 ++++++++++++++++++++-
drivers/clk/kunit_clk_assigned_rates.h | 10 +
.../clk/kunit_clk_assigned_rates_u64_multiple.dtso | 6 +
...t_clk_assigned_rates_u64_multiple_consumer.dtso | 6 +
drivers/clk/kunit_clk_assigned_rates_u64_one.dtso | 3 +
.../kunit_clk_assigned_rates_u64_one_consumer.dtso | 3 +
drivers/clk/kunit_clk_assigned_sscs_multiple.dtso | 20 ++
.../kunit_clk_assigned_sscs_multiple_consumer.dtso | 24 +++
drivers/clk/kunit_clk_assigned_sscs_null.dtso | 16 ++
.../clk/kunit_clk_assigned_sscs_null_consumer.dtso | 20 ++
drivers/clk/kunit_clk_assigned_sscs_one.dtso | 16 ++
.../clk/kunit_clk_assigned_sscs_one_consumer.dtso | 20 ++
drivers/clk/kunit_clk_assigned_sscs_without.dtso | 15 ++
.../kunit_clk_assigned_sscs_without_consumer.dtso | 19 ++
drivers/clk/kunit_clk_assigned_sscs_zero.dtso | 12 ++
.../clk/kunit_clk_assigned_sscs_zero_consumer.dtso | 16 ++
17 files changed, 416 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index cc108a75a9008..6a726331b6c9e 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -18,6 +18,16 @@ clk-test-y := clk_test.o \
kunit_clk_assigned_rates_without_consumer.dtbo.o \
kunit_clk_assigned_rates_zero.dtbo.o \
kunit_clk_assigned_rates_zero_consumer.dtbo.o \
+ kunit_clk_assigned_sscs_one.dtbo.o \
+ kunit_clk_assigned_sscs_one_consumer.dtbo.o \
+ kunit_clk_assigned_sscs_multiple.dtbo.o \
+ kunit_clk_assigned_sscs_multiple_consumer.dtbo.o \
+ kunit_clk_assigned_sscs_null.dtbo.o \
+ kunit_clk_assigned_sscs_null_consumer.dtbo.o \
+ kunit_clk_assigned_sscs_without.dtbo.o \
+ kunit_clk_assigned_sscs_without_consumer.dtbo.o \
+ kunit_clk_assigned_sscs_zero.dtbo.o \
+ kunit_clk_assigned_sscs_zero_consumer.dtbo.o \
kunit_clk_hw_get_dev_of_node.dtbo.o \
kunit_clk_parent_data_test.dtbo.o
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index b1961daac5e22..824adc95e0b2f 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -28,6 +28,7 @@ static const struct clk_ops empty_clk_ops = { };
struct clk_dummy_context {
struct clk_hw hw;
unsigned long rate;
+ struct clk_spread_spectrum sscs;
};
static unsigned long clk_dummy_recalc_rate(struct clk_hw *hw,
@@ -83,6 +84,17 @@ static int clk_dummy_set_rate(struct clk_hw *hw,
return 0;
}
+static int clk_dummy_set_spread_spectrum(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf)
+{
+ struct clk_dummy_context *ctx =
+ container_of(hw, struct clk_dummy_context, hw);
+
+ ctx->sscs = *ss_conf;
+
+ return 0;
+}
+
static int clk_dummy_single_set_parent(struct clk_hw *hw, u8 index)
{
if (index >= clk_hw_get_num_parents(hw))
@@ -100,18 +112,21 @@ static const struct clk_ops clk_dummy_rate_ops = {
.recalc_rate = clk_dummy_recalc_rate,
.determine_rate = clk_dummy_determine_rate,
.set_rate = clk_dummy_set_rate,
+ .set_spread_spectrum = clk_dummy_set_spread_spectrum,
};
static const struct clk_ops clk_dummy_maximize_rate_ops = {
.recalc_rate = clk_dummy_recalc_rate,
.determine_rate = clk_dummy_maximize_rate,
.set_rate = clk_dummy_set_rate,
+ .set_spread_spectrum = clk_dummy_set_spread_spectrum,
};
static const struct clk_ops clk_dummy_minimize_rate_ops = {
.recalc_rate = clk_dummy_recalc_rate,
.determine_rate = clk_dummy_minimize_rate,
.set_rate = clk_dummy_set_rate,
+ .set_spread_spectrum = clk_dummy_set_spread_spectrum,
};
static const struct clk_ops clk_dummy_single_parent_ops = {
@@ -3097,6 +3112,7 @@ struct clk_assigned_rates_context {
* @overlay_end: Pointer to end of DT overlay to apply for test
* @rate0: Initial rate of first clk
* @rate1: Initial rate of second clk
+ * @sscs: Initial spread spectrum settings
* @consumer_test: true if a consumer is being tested
*/
struct clk_assigned_rates_test_param {
@@ -3105,6 +3121,7 @@ struct clk_assigned_rates_test_param {
u8 *overlay_end;
unsigned long rate0;
unsigned long rate1;
+ struct clk_spread_spectrum sscs;
bool consumer_test;
};
@@ -3116,7 +3133,7 @@ static void
clk_assigned_rates_register_clk(struct kunit *test,
struct clk_dummy_context *ctx,
struct device_node *np, const char *name,
- unsigned long rate)
+ unsigned long rate, const struct clk_spread_spectrum *sscs)
{
struct clk_init_data init = { };
@@ -3124,6 +3141,7 @@ clk_assigned_rates_register_clk(struct kunit *test,
init.ops = &clk_dummy_rate_ops;
ctx->hw.init = &init;
ctx->rate = rate;
+ ctx->sscs = *sscs;
KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, np, &ctx->hw));
KUNIT_ASSERT_EQ(test, ctx->rate, rate);
@@ -3167,14 +3185,16 @@ static int clk_assigned_rates_test_init(struct kunit *test)
KUNIT_ASSERT_LT(test, clk_cells, 2);
clk_assigned_rates_register_clk(test, &ctx->clk0, np,
- "test_assigned_rate0", test_param->rate0);
+ "test_assigned_rate0", test_param->rate0,
+ &test_param->sscs);
if (clk_cells == 0) {
KUNIT_ASSERT_EQ(test, 0,
of_clk_add_hw_provider_kunit(test, np, of_clk_hw_simple_get,
&ctx->clk0.hw));
} else if (clk_cells == 1) {
clk_assigned_rates_register_clk(test, &ctx->clk1, np,
- "test_assigned_rate1", test_param->rate1);
+ "test_assigned_rate1", test_param->rate1,
+ &test_param->sscs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
data = kunit_kzalloc(test, struct_size(data, hws, 2), GFP_KERNEL));
@@ -3403,6 +3423,182 @@ static struct kunit_suite clk_assigned_rates_suite = {
.init = clk_assigned_rates_test_init,
};
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one_consumer);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple_consumer);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without_consumer);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero_consumer);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null);
+OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null_consumer);
+
+static void clk_assigned_sscs_assigns_one(struct kunit *test)
+{
+ struct clk_assigned_rates_context *ctx = test->priv;
+
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
+}
+
+/* Test cases that assign sscs for one clk */
+static const struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_one_test_params[] = {
+ {
+ /*
+ * Test that a single cell assigned-clock-sscs property
+ * assigns the sscs when the property is in the provider.
+ */
+ .desc = "provider assigns",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one),
+ },
+ {
+ /*
+ * Test that a single cell assigned-clock-sscs property
+ * assigns the sscs when the property is in the consumer.
+ */
+ .desc = "consumer assigns",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one_consumer),
+ .consumer_test = true,
+ },
+};
+KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_one,
+ clk_assigned_sscs_assigns_one_test_params, desc)
+
+static void clk_assigned_sscs_assigns_multiple(struct kunit *test)
+{
+ struct clk_assigned_rates_context *ctx = test->priv;
+
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
+ KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.modfreq_hz, ASSIGNED_SSCS_1_MODFREQ);
+ KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.spread_bp, ASSIGNED_SSCS_1_SPREAD);
+ KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.method, ASSIGNED_SSCS_1_METHOD);
+}
+
+/* Test cases that assign sscs for multiple clks */
+static const
+struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_multiple_test_params[] = {
+ {
+ /*
+ * Test that a multiple cell assigned-clock-sscs property
+ * assigns the sscs when the property is in the provider.
+ */
+ .desc = "provider assigns",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple),
+ },
+ {
+ /*
+ * Test that a multiple cell assigned-clock-sscs property
+ * assigns the sscs when the property is in the consumer.
+ */
+ .desc = "consumer assigns",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple_consumer),
+ .consumer_test = true,
+ },
+};
+KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_multiple,
+ clk_assigned_sscs_assigns_multiple_test_params,
+ desc)
+
+static void clk_assigned_sscs_skips(struct kunit *test)
+{
+ struct clk_assigned_rates_context *ctx = test->priv;
+ const struct clk_assigned_rates_test_param *test_param = test->param_value;
+
+ KUNIT_EXPECT_NE(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
+ KUNIT_EXPECT_NE(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
+ KUNIT_EXPECT_NE(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, test_param->sscs.modfreq_hz);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, test_param->sscs.spread_bp);
+ KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, test_param->sscs.method);
+}
+
+/* Test cases that skip changing the sscs due to malformed DT */
+static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_params[] = {
+ {
+ /*
+ * Test that an assigned-clock-sscs property without an assigned-clocks
+ * property fails when the property is in the provider.
+ */
+ .desc = "provider missing assigned-clocks",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without),
+ .sscs = {50000, 60000, 3},
+ },
+ {
+ /*
+ * Test that an assigned-clock-sscs property without an assigned-clocks
+ * property fails when the property is in the consumer.
+ */
+ .desc = "consumer missing assigned-clocks",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without_consumer),
+ .sscs = {50000, 60000, 3},
+ .consumer_test = true,
+ },
+ {
+ /*
+ * Test that an assigned-clock-sscs property of zero doesn't
+ * set sscs when the property is in the provider.
+ */
+ .desc = "provider assigned-clock-sscs of zero",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero),
+ .sscs = {50000, 60000, 3},
+ },
+ {
+ /*
+ * Test that an assigned-clock-sscs property of zero doesn't
+ * set sscs when the property is in the consumer.
+ */
+ .desc = "consumer assigned-clock-sscs of zero",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero_consumer),
+ .sscs = {50000, 60000, 3},
+ .consumer_test = true,
+ },
+ {
+ /*
+ * Test that an assigned-clocks property with a null phandle
+ * doesn't set sscs when the property is in the provider.
+ */
+ .desc = "provider assigned-clocks null phandle",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null),
+ .sscs = {50000, 60000, 3},
+ },
+ {
+ /*
+ * Test that an assigned-clocks property with a null phandle
+ * doesn't set sscs when the property is in the consumer.
+ */
+ .desc = "consumer assigned-clocks null phandle",
+ TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null_consumer),
+ .sscs = {50000, 60000, 3},
+ .consumer_test = true,
+ },
+};
+KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_skips,
+ clk_assigned_sscs_skips_test_params,
+ desc)
+
+static struct kunit_case clk_assigned_sscs_test_cases[] = {
+ KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_one,
+ clk_assigned_sscs_assigns_one_gen_params),
+ KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_multiple,
+ clk_assigned_sscs_assigns_multiple_gen_params),
+ KUNIT_CASE_PARAM(clk_assigned_sscs_skips,
+ clk_assigned_sscs_skips_gen_params),
+ {}
+};
+
+/*
+ * Test suite for assigned-clock-sscs DT property.
+ */
+static struct kunit_suite clk_assigned_sscs_suite = {
+ .name = "clk_assigned_sscs",
+ .test_cases = clk_assigned_sscs_test_cases,
+ .init = clk_assigned_rates_test_init,
+};
+
static const struct clk_init_data clk_hw_get_dev_of_node_init_data = {
.name = "clk_hw_get_dev_of_node",
.ops = &empty_clk_ops,
@@ -3544,6 +3740,7 @@ static struct kunit_suite clk_hw_get_dev_of_node_test_suite = {
kunit_test_suites(
&clk_assigned_rates_suite,
+ &clk_assigned_sscs_suite,
&clk_hw_get_dev_of_node_test_suite,
&clk_leaf_mux_set_rate_parent_test_suite,
&clk_test_suite,
diff --git a/drivers/clk/kunit_clk_assigned_rates.h b/drivers/clk/kunit_clk_assigned_rates.h
index df2d84dcaa935..d7ae5ec2d25be 100644
--- a/drivers/clk/kunit_clk_assigned_rates.h
+++ b/drivers/clk/kunit_clk_assigned_rates.h
@@ -1,8 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <dt-bindings/clock/clock.h>
+
#ifndef _KUNIT_CLK_ASSIGNED_RATES_H
#define _KUNIT_CLK_ASSIGNED_RATES_H
#define ASSIGNED_RATES_0_RATE 1600000
#define ASSIGNED_RATES_1_RATE 9700000
+#define ASSIGNED_SSCS_0_MODFREQ 10000
+#define ASSIGNED_SSCS_0_SPREAD 30000
+#define ASSIGNED_SSCS_0_METHOD CLK_SSC_CENTER_SPREAD
+#define ASSIGNED_SSCS_1_MODFREQ 20000
+#define ASSIGNED_SSCS_1_SPREAD 40000
+#define ASSIGNED_SSCS_1_METHOD CLK_SSC_UP_SPREAD
+
#endif
diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso
index 389b4e2eb7f74..3a717dab2d00b 100644
--- a/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso
+++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso
@@ -12,5 +12,11 @@ clk: kunit-clock {
<&clk 1>;
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>,
/bits/ 64 <ASSIGNED_RATES_1_RATE>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>,
+ <ASSIGNED_SSCS_1_MODFREQ
+ ASSIGNED_SSCS_1_SPREAD
+ ASSIGNED_SSCS_1_METHOD>;
};
};
diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso
index 3e117fd59b7da..cbee7cbad068f 100644
--- a/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso
+++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso
@@ -16,5 +16,11 @@ kunit-clock-consumer {
<&clk 1>;
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>,
/bits/ 64 <ASSIGNED_RATES_1_RATE>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>,
+ <ASSIGNED_SSCS_1_MODFREQ
+ ASSIGNED_SSCS_1_SPREAD
+ ASSIGNED_SSCS_1_METHOD>;
};
};
diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso
index 87041264e8f54..9b04d6927f083 100644
--- a/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso
+++ b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso
@@ -10,5 +10,8 @@ clk: kunit-clock {
#clock-cells = <0>;
assigned-clocks = <&clk>;
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
};
};
diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso
index 3259c003aec0b..4784d40520f41 100644
--- a/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso
+++ b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso
@@ -14,5 +14,8 @@ kunit-clock-consumer {
compatible = "test,clk-consumer";
assigned-clocks = <&clk>;
assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
};
};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso b/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso
new file mode 100644
index 0000000000000..e3472f95987c3
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_multiple.dtso
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <1>;
+ assigned-clocks = <&clk 0>,
+ <&clk 1>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>,
+ <ASSIGNED_SSCS_1_MODFREQ
+ ASSIGNED_SSCS_1_SPREAD
+ ASSIGNED_SSCS_1_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso
new file mode 100644
index 0000000000000..6e8971bd272ab
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_multiple_consumer.dtso
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <1>;
+ };
+
+ kunit-clock-consumer {
+ compatible = "test,clk-consumer";
+ assigned-clocks = <&clk 0>,
+ <&clk 1>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>,
+ <ASSIGNED_SSCS_1_MODFREQ
+ ASSIGNED_SSCS_1_SPREAD
+ ASSIGNED_SSCS_1_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_null.dtso b/drivers/clk/kunit_clk_assigned_sscs_null.dtso
new file mode 100644
index 0000000000000..43b2068c845de
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_null.dtso
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ assigned-clocks = <0>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso
new file mode 100644
index 0000000000000..bda008f5aaa35
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_null_consumer.dtso
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ };
+
+ kunit-clock-consumer {
+ compatible = "test,clk-consumer";
+ assigned-clocks = <0>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_one.dtso b/drivers/clk/kunit_clk_assigned_sscs_one.dtso
new file mode 100644
index 0000000000000..91f585b5d8c9b
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_one.dtso
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ assigned-clocks = <&clk>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso
new file mode 100644
index 0000000000000..0bc8a03c20412
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_one_consumer.dtso
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ };
+
+ kunit-clock-consumer {
+ compatible = "test,clk-consumer";
+ assigned-clocks = <&clk>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_without.dtso b/drivers/clk/kunit_clk_assigned_sscs_without.dtso
new file mode 100644
index 0000000000000..08660846b55c1
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_without.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso
new file mode 100644
index 0000000000000..e1c089c6f0c02
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_without_consumer.dtso
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+#include "kunit_clk_assigned_rates.h"
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ };
+
+ kunit-clock-consumer {
+ compatible = "test,clk-consumer";
+ assigned-clock-sscs = <ASSIGNED_SSCS_0_MODFREQ
+ ASSIGNED_SSCS_0_SPREAD
+ ASSIGNED_SSCS_0_METHOD>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_zero.dtso b/drivers/clk/kunit_clk_assigned_sscs_zero.dtso
new file mode 100644
index 0000000000000..f39f4e754e532
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_zero.dtso
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ assigned-clocks = <&clk>;
+ assigned-clock-sscs = <0 0 0>;
+ };
+};
diff --git a/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso b/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso
new file mode 100644
index 0000000000000..d6bd7dfada7e2
--- /dev/null
+++ b/drivers/clk/kunit_clk_assigned_sscs_zero_consumer.dtso
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ clk: kunit-clock {
+ compatible = "test,clk-assigned-rates";
+ #clock-cells = <0>;
+ };
+
+ kunit-clock-consumer {
+ compatible = "test,clk-consumer";
+ assigned-clocks = <&clk>;
+ assigned-clock-sscs = <0 0 0>;
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v10 5/6] clk: scmi: Introduce common header for SCMI clock interface
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Added a new header file 'clk-scmi.h' to define common structures and
interfaces for the SCMI clock driver. This header will also be used by
OEM-specific extensions to ensure consistency and reusability.
Moved relevant structure definitions from the driver implementation to
'clk-scmi.h' to facilitate shared usage.
Reviewed-by: Sebin Francis <sebin.francis@ti.com>
Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/clk-scmi.c | 27 +--------------------------
drivers/clk/clk-scmi.h | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 7c562559ad8bb..d88e78cc9a12e 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -13,32 +13,7 @@
#include <linux/module.h>
#include <linux/scmi_protocol.h>
-#define NOT_ATOMIC false
-#define ATOMIC true
-
-enum scmi_clk_feats {
- SCMI_CLK_ATOMIC_SUPPORTED,
- SCMI_CLK_STATE_CTRL_SUPPORTED,
- SCMI_CLK_RATE_CTRL_SUPPORTED,
- SCMI_CLK_PARENT_CTRL_SUPPORTED,
- SCMI_CLK_DUTY_CYCLE_SUPPORTED,
- SCMI_CLK_FEATS_COUNT
-};
-
-#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT)
-
-static const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
-
-struct scmi_clk {
- u32 id;
- struct device *dev;
- struct clk_hw hw;
- const struct scmi_clock_info *info;
- const struct scmi_protocol_handle *ph;
- struct clk_parent_data *parent_data;
-};
-
-#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
+const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
diff --git a/drivers/clk/clk-scmi.h b/drivers/clk/clk-scmi.h
new file mode 100644
index 0000000000000..6ef6adc77c836
--- /dev/null
+++ b/drivers/clk/clk-scmi.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2025 NXP
+ */
+
+#ifndef __SCMI_CLK_H
+#define __SCMI_CLK_H
+
+#include <linux/bits.h>
+#include <linux/scmi_protocol.h>
+#include <linux/types.h>
+
+#define NOT_ATOMIC false
+#define ATOMIC true
+
+enum scmi_clk_feats {
+ SCMI_CLK_ATOMIC_SUPPORTED,
+ SCMI_CLK_STATE_CTRL_SUPPORTED,
+ SCMI_CLK_RATE_CTRL_SUPPORTED,
+ SCMI_CLK_PARENT_CTRL_SUPPORTED,
+ SCMI_CLK_DUTY_CYCLE_SUPPORTED,
+ SCMI_CLK_FEATS_COUNT
+};
+
+#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT)
+
+struct scmi_clk {
+ u32 id;
+ struct device *dev;
+ struct clk_hw hw;
+ const struct scmi_clock_info *info;
+ const struct scmi_protocol_handle *ph;
+ struct clk_parent_data *parent_data;
+};
+
+#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
+
+extern const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
+
+#endif
--
2.34.1
^ permalink raw reply related
* [PATCH v10 6/6] clk: scmi: Add i.MX95 OEM extension support for SCMI clock driver
From: Peng Fan (OSS) @ 2026-06-12 8:46 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sudeep Holla, Cristian Marussi,
Sebin Francis
Cc: linux-kernel, linux-clk, devicetree, arm-scmi, linux-arm-kernel,
Peng Fan
In-Reply-To: <20260612-clk-v10-v10-0-eb92484eda38@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
- Introduce 'clk-scmi-oem.c' to support vendor-specific OEM extensions
for the SCMI clock driver, allows clean integration of vendor-specific
features without impacting the core SCMI clock driver logic.
- Extend 'clk-scmi.h' with 'scmi_clk_oem' structure and related
declarations.
- Initialize OEM extensions via 'scmi_clk_oem_init()'.
- Support querying OEM-specific features and setting spread spectrum.
- Pass 'scmi_device' to 'scmi_clk_ops_select()' for OEM data access.
Reviewed-by: Sebin Francis <sebin.francis@ti.com>
Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/clk/Makefile | 2 +-
drivers/clk/clk-scmi-oem.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
drivers/clk/clk-scmi.c | 19 ++++++--
drivers/clk/clk-scmi.h | 11 +++++
4 files changed, 136 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 6a726331b6c9e..c2ae700ec0f2a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -98,7 +98,7 @@ obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o
obj-$(CONFIG_COMMON_CLK_RPMI) += clk-rpmi.o
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
-obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
+obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o clk-scmi-oem.o
obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o
obj-$(CONFIG_COMMON_CLK_SI5341) += clk-si5341.o
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
diff --git a/drivers/clk/clk-scmi-oem.c b/drivers/clk/clk-scmi-oem.c
new file mode 100644
index 0000000000000..be11d359b4ec3
--- /dev/null
+++ b/drivers/clk/clk-scmi-oem.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Vendor OEM extension for System Control and Power Interface (SCMI)
+ * Protocol based clock driver
+ *
+ * Copyright 2025 NXP
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/scmi_imx_protocol.h>
+#include <linux/scmi_protocol.h>
+
+#include "clk-scmi.h"
+
+#define SCMI_CLOCK_CFG_IMX_SSC 0x80
+#define SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK GENMASK(7, 0)
+#define SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK GENMASK(23, 8)
+#define SCMI_CLOCK_IMX_SS_ENABLE_MASK BIT(24)
+
+/*
+ * Selection is based on SCMI vendor_id/sub_vendor_id and optional machine
+ * compatible string, without involving impl_ver. impl_ver‑specific behavior
+ * should be considered a bug and handled via SCMI Quirk framework.
+ */
+struct scmi_clk_oem_info {
+ char *vendor_id;
+ char *sub_vendor_id;
+ char *compatible;
+ const void *data;
+};
+
+static int
+scmi_clk_imx_set_spread_spectrum(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf)
+{
+ struct scmi_clk *clk = to_scmi_clk(hw);
+ int ret;
+ u32 val;
+
+ /*
+ * extConfigValue[7:0] - spread percentage (%)
+ * extConfigValue[23:8] - Modulation Frequency
+ * extConfigValue[24] - Enable/Disable
+ * extConfigValue[31:25] - Reserved
+ */
+ val = FIELD_PREP(SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK, ss_conf->spread_bp / 10000);
+ val |= FIELD_PREP(SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK, ss_conf->modfreq_hz);
+ if (ss_conf->method != CLK_SPREAD_NO)
+ val |= SCMI_CLOCK_IMX_SS_ENABLE_MASK;
+ ret = scmi_proto_clk_ops->config_oem_set(clk->ph, clk->id,
+ SCMI_CLOCK_CFG_IMX_SSC,
+ val, false);
+ if (ret)
+ dev_warn(clk->dev,
+ "Failed to set spread spectrum(%u,%u,%u) for clock ID %d\n",
+ ss_conf->modfreq_hz, ss_conf->spread_bp, ss_conf->method,
+ clk->id);
+
+ return ret;
+}
+
+static int
+scmi_clk_imx_query_oem_feats(const struct scmi_protocol_handle *ph, u32 id,
+ unsigned int *feats_key)
+{
+ int ret;
+ u32 val;
+
+ ret = scmi_proto_clk_ops->config_oem_get(ph, id,
+ SCMI_CLOCK_CFG_IMX_SSC,
+ &val, NULL, false);
+ if (!ret)
+ *feats_key |= BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED);
+
+ return 0;
+}
+
+static const struct scmi_clk_oem scmi_clk_oem_imx = {
+ .query_ext_oem_feats = scmi_clk_imx_query_oem_feats,
+ .set_spread_spectrum = scmi_clk_imx_set_spread_spectrum,
+};
+
+static const struct scmi_clk_oem_info info[] = {
+ { SCMI_IMX_VENDOR, SCMI_IMX_SUBVENDOR, NULL, &scmi_clk_oem_imx },
+};
+
+int scmi_clk_oem_init(struct scmi_device *sdev)
+{
+ const struct scmi_handle *handle = sdev->handle;
+ int i, size = ARRAY_SIZE(info);
+
+ for (i = 0; i < size; i++) {
+ if (strcmp(handle->version->vendor_id, info[i].vendor_id) ||
+ strcmp(handle->version->sub_vendor_id, info[i].sub_vendor_id))
+ continue;
+ if (info[i].compatible &&
+ !of_machine_is_compatible(info[i].compatible))
+ continue;
+
+ break;
+ }
+
+ if (i < size)
+ dev_set_drvdata(&sdev->dev, (void *)info[i].data);
+
+ return 0;
+}
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index d88e78cc9a12e..2dd50c5b4ea8f 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -13,6 +13,8 @@
#include <linux/module.h>
#include <linux/scmi_protocol.h>
+#include "clk-scmi.h"
+
const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
@@ -210,6 +212,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
static const struct clk_ops *
scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
{
+ struct scmi_clk_oem *oem_data = dev_get_drvdata(dev);
struct clk_ops *ops;
ops = devm_kzalloc(dev, sizeof(*ops), GFP_KERNEL);
@@ -256,11 +259,15 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
ops->set_duty_cycle = scmi_clk_set_duty_cycle;
}
+ if (oem_data && (feats_key & BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED)))
+ ops->set_spread_spectrum = oem_data->set_spread_spectrum;
+
return ops;
}
/**
* scmi_clk_ops_select() - Select a proper set of clock operations
+ * @sdev: pointer to the SCMI device
* @sclk: A reference to an SCMI clock descriptor
* @atomic_capable: A flag to indicate if atomic mode is supported by the
* transport
@@ -285,8 +292,8 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
* NULL otherwise.
*/
static const struct clk_ops *
-scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
- unsigned int atomic_threshold_us,
+scmi_clk_ops_select(struct scmi_device *sdev, struct scmi_clk *sclk,
+ bool atomic_capable, unsigned int atomic_threshold_us,
const struct clk_ops **clk_ops_db, size_t db_size)
{
int ret;
@@ -294,6 +301,7 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
const struct scmi_clock_info *ci = sclk->info;
unsigned int feats_key = 0;
const struct clk_ops *ops;
+ struct scmi_clk_oem *oem_data = dev_get_drvdata(&sdev->dev);
/*
* Note that when transport is atomic but SCMI protocol did not
@@ -318,6 +326,9 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
&val, NULL, false);
if (!ret)
feats_key |= BIT(SCMI_CLK_DUTY_CYCLE_SUPPORTED);
+
+ if (oem_data && oem_data->query_ext_oem_feats)
+ oem_data->query_ext_oem_feats(sclk->ph, sclk->id, &feats_key);
}
if (WARN_ON(feats_key >= db_size))
@@ -375,6 +386,8 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
clk_data->num = count;
hws = clk_data->hws;
+ scmi_clk_oem_init(sdev);
+
transport_is_atomic = handle->is_transport_atomic(handle,
&atomic_threshold_us);
@@ -406,7 +419,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
* to avoid sharing the devm_ allocated clk_ops between multiple
* SCMI clk driver instances.
*/
- scmi_ops = scmi_clk_ops_select(sclk, transport_is_atomic,
+ scmi_ops = scmi_clk_ops_select(sdev, sclk, transport_is_atomic,
atomic_threshold_us,
scmi_clk_ops_db,
ARRAY_SIZE(scmi_clk_ops_db));
diff --git a/drivers/clk/clk-scmi.h b/drivers/clk/clk-scmi.h
index 6ef6adc77c836..d7f63f36c56d1 100644
--- a/drivers/clk/clk-scmi.h
+++ b/drivers/clk/clk-scmi.h
@@ -7,6 +7,7 @@
#define __SCMI_CLK_H
#include <linux/bits.h>
+#include <linux/clk-provider.h>
#include <linux/scmi_protocol.h>
#include <linux/types.h>
@@ -19,6 +20,7 @@ enum scmi_clk_feats {
SCMI_CLK_RATE_CTRL_SUPPORTED,
SCMI_CLK_PARENT_CTRL_SUPPORTED,
SCMI_CLK_DUTY_CYCLE_SUPPORTED,
+ SCMI_CLK_EXT_OEM_SSC_SUPPORTED,
SCMI_CLK_FEATS_COUNT
};
@@ -37,4 +39,13 @@ struct scmi_clk {
extern const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
+struct scmi_clk_oem {
+ int (*query_ext_oem_feats)(const struct scmi_protocol_handle *ph,
+ u32 id, unsigned int *feats_key);
+ int (*set_spread_spectrum)(struct clk_hw *hw,
+ const struct clk_spread_spectrum *ss_conf);
+};
+
+int scmi_clk_oem_init(struct scmi_device *dev);
+
#endif
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 3/3] arm64/coco: Add pKVM as a CC platform
From: Mostafa Saleh @ 2026-06-12 8:44 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: linux-arm-kernel, linux-kernel, akpm, catalin.marinas, will, rppt,
maz
In-Reply-To: <yq5a1pemsmuj.fsf@kernel.org>
On Thu, Jun 04, 2026 at 02:29:00PM +0530, Aneesh Kumar K.V wrote:
> Mostafa Saleh <smostafa@google.com> writes:
>
> > pKVM does support memory encryption, expose that to the rest of
> > the kernel through cc_platform_has()
> >
> > At the moment, all devices inside the guest are emulated which
> > requires its memory to be shared back to the host (decrypted), so
> > set force_dma_unencrypted() to always return true.
> >
> > Although, typically pKVM guests rely on restricted-dma-pools to
> > bounce traffic, with this change, it is possible to solely rely on
> > the default SWIOTLB for that (assuming the appropriate size is set
> > from the command line)
> >
> > Signed-off-by: Mostafa Saleh <smostafa@google.com>
> > ---
> > This change is critical for the ongoing refactoring of the DMA-API[1]
> > that will break protected guests under pKVM with this patch. That is
> > due to this rework will make the state of the SWIOTLB and restricted
> > dma pools depends on the value returned by cc_platform_has()
> >
> > [1] https://lore.kernel.org/all/20260522042815.370873-1-aneesh.kumar@kernel.org/
> > ---
> > arch/arm64/include/asm/hypervisor.h | 13 +++++++++++++
> > arch/arm64/include/asm/mem_encrypt.h | 3 ++-
> > arch/arm64/kernel/rsi.c | 12 ------------
> > arch/arm64/mm/init.c | 15 ++++++++++++++-
> > drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 3 +++
> > 5 files changed, 32 insertions(+), 14 deletions(-)
> >
> > index d66291def0f4..26fe9c3f22e3 100644
[...]
> > --- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
> > +++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
> > @@ -17,6 +17,7 @@
> > #include <asm/hypervisor.h>
> >
> > static size_t pkvm_granule;
> > +DEFINE_STATIC_KEY_FALSE_RO(pkvm_guest);
> >
>
> Do we need EXPORT_SYMBOL on this?
I was not sure about that, all users of this are in tree, I saw RME
code have the EXPORT but did not know why?
Thanks,
Mostafa
>
>
> -aneesh
^ permalink raw reply
* Re: [PATCH v8 next 04/10] arm_mpam: Refactor rmid to reqPARTID/PMG mapping
From: Zeng Heng @ 2026-06-12 8:44 UTC (permalink / raw)
To: James Morse, ben.horgan, Dave.Martin, tan.shaopeng,
reinette.chatre, fenghuay, tglx, will, hpa, bp, babu.moger,
dave.hansen, mingo, tony.luck, gshan, catalin.marinas
Cc: linux-arm-kernel, x86, linux-kernel, wangkefeng.wang, sunnanyong
In-Reply-To: <2944b506-a462-42f8-95cf-404241fb27f0@arm.com>
Hi James,
>> @@ -478,6 +518,7 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
>> enum resctrl_conf_type cdp_type, u32 closid, u32 rmid, u64 *val)
>> {
>> struct mon_cfg cfg;
>> + u32 reqpartid = rmid2reqpartid(rmid);
>>
>> if (!mpam_is_enabled())
>> return -EINVAL;
>> @@ -493,8 +534,8 @@ static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_c
>> cfg = (struct mon_cfg) {
>> .mon = mon_idx,
>> .match_pmg = true,
>> - .partid = closid,
>> - .pmg = rmid,
>> + .partid = (cdp_type == CDP_CODE) ? reqpartid + 1 : reqpartid,
>> + .pmg = rmid2pmg(rmid),
>
> Not using the CLOSID here breaks multiple control groups.
>
After carefully reviewing your comments and Martin's patch series,
I tried to understand why there is insistence that CLOSID information
is necessary to support multiple control groups, but that is actually
not the case.
Before proceeding, please allow me to refer to base_partid as CPARTID
(control partition ID; I'm no longer borrowing the intPARTID concept
here). The associated partids_per_closid all share the same control
scheme.
The partids derived from partids_per_closid under a given CPARTID,
I will call MPARTID (monitor partition ID; no longer borrowing the
reqPARTID concept). These represent the PARTIDs used for different
monitoring groups under the same control scheme.
I've summarized the ID translation schemes from James and Martin as
follows:
+-------------------------------+------------------+
| CLOSID |{CDP}| RMID |
+-------------------------------+------------+-----+
| MPARTID | PMG |
| CPARTID(or MPARTID_hi) : MPARTID_lo | |
+--------------------------------------------+-----+
Where closid = cpartid (base_partid or mpartid_hi),
rmid = mpartid_lo * pmg_num + pmg,
with mpartid_lo in the range [0, partids_per_closid).
In this scheme, CLOSID and RMID are coupled together to form MPARTID,
which represents the monitor group PARTID.
In current patchset design, decoupling CLOSID and RMID, letting them
represent CPARTID and MPARTID respectively:
+---------------------------------------------+
| CLOSID |{CDP}|
+---------------------------------------------+
| CPARTID |
+---------------------------------------------+
+---------------------------------------------+
| RMID |
+---------------------------------------+-----+
| MPARTID | PMG |
| MPARTID_hi(or CPARTID) : MPARTID_lo | |
+---------------------------------------+-----+
Where closid = cpartid (base_partid or mpartid_hi),
rmid = mpartid * pmg_num + pmg,
and mpartid = mpartid_hi * partids_per_closid + mpartid_lo .
The design intent is to decouple CLOSID and RMID, rather than having
RMID depend on CLOSID to derive MPARTID. This decoupling is essential
for future dynamic allocation, because the relationship between MPARTID
and CPARTID must rely on table lookup rather than linear mapping. If
don't decouple in the static allocation design, we would need another
refactor when considering dynamic allocation extensibility.
The control path uses CLOSID alone (CPARTID), and the monitor path uses
RMID alone (the (MPARTID, PMG) pair). This definition also aligns
closely with the native resctrl concepts: CLOSID (Class of Service ID,
corresponding to CPARTID) and RMID (Resource Monitor ID, corresponding
to the (MPARTID, PMG) pair).
In the end, the number of control groups is determined by the number of
CPARTIDs. Both of these ID translation schemes support multiple control
groups.
Please allow me to rework the patch series into v9 based on my current
patches, incorporating your review feedback.
Best Regards,
Zeng Heng
^ permalink raw reply
* [GIT PULL] KVM/arm64 updates for 7.2
From: Marc Zyngier @ 2026-06-12 8:48 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Anshuman Khandual, Catalin Marinas, Eric Auger, Fuad Tabba,
Hyunwoo Kim, Jackie Liu, Joey Gouly, Mark Rutland, Oliver Upton,
Sascha Bischoff, Vincent Donnefort, Wei-Lin Chang, Will Deacon,
Zenghui Yu, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvmarm,
kvm, linux-arm-kernel
Paolo,
This is a bit of an odd merge window on the KVM/arm64 front. There is
absolutely no new feature in the pull request. It is purely fixes,
because it is simply becoming too hard to review new stuff when so
many AI-fuelled fixes hit the list. And even then, I've arbitrarily
tagged the branch today, knowing that there is quite a backlog of
fixes that I will send very shortly, probably before -rc1.
So here it is: only fixes and very minor improvements, all over the
place. Details in the tag below.
Please pull,
M.
The following changes since commit 5200f5f493f79f14bbdc349e402a40dfb32f23c8:
Linux 7.1-rc4 (2026-05-17 13:59:58 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-7.2
for you to fetch changes up to 1ee27dacbe5dc4def481794d899d67b0d4570094:
Merge branch kvm-arm64/nv-mmu-7.2 into kvmarm-master/next (2026-06-12 09:29:34 +0100)
----------------------------------------------------------------
KVM/arm64 updates for 7.2
* New features:
- None. Zilch. Nada. Que dalle.
* Fixes and other improvements:
- Significant cleanup of the vgic-v5 PPI support which was merged in
7.1. This makes the code more maintainable, and squashes a couple
of bugs in the meantime.
- Set of fixes for the handling of the MMU in an NV context,
particularly VNCR-triggered faults. S1POE support is fixed
as well.
- Large set of pKVM fixes, mostly addressing recurring issues
around hypervisor tracking of donated pages in obscure cases
where the donation could fail and leave things in a bizarre
state.
- Fixes for the so-called "lazy vgic init", which resulted in
sleeping operations in non-preemptible sections. This turned
out to be far more invasive than initially expected...
- Reduce the overhead of L1/L2 context switch by not touching
the FP registers.
- Fix the way non-implemented page sizes are dealt with when
a guest insist on using them for S2 translation.
- The usual set of low-impact fixes and cleanups all over the map.
----------------------------------------------------------------
Fuad Tabba (5):
KVM: arm64: Guard against NULL vcpu on VHE hyp panic path
KVM: arm64: Fix __deactivate_fgt macro parameter typo
KVM: arm64: Seed pkvm_ownership_selftest vcpu memcache
KVM: arm64: Pre-check vcpu memcache for host->guest share
KVM: arm64: Pre-check vcpu memcache for host->guest donate
Hyunwoo Kim (2):
KVM: arm64: Clear __hyp_running_vcpu when flushing the pKVM hyp vCPU
KVM: arm64: Bound used_lrs when flushing the pKVM hyp vCPU
Jackie Liu (1):
KVM: arm64: vgic-its: Make ABI commit helpers return void
Marc Zyngier (29):
KVM: arm64: nv: Track L2 to L1 exception emulation
KVM: arm64: nv: Don't save/restore FP register during a nested ERET or exception
KVM: arm64: timer: Repaint kvm_timer_{should,irq_can}_fire() to kvm_timer_{pending,enabled}()
KVM: arm64: Simplify userspace notification of interrupt state
KVM: arm64: timer: Kill the per-timer irq level cache
KVM: arm64: pmu: Kill the PMU interrupt level cache
KVM: arm64: vgic-v2: Force vgic init on injection outside the run loop
KVM: arm64: vgic-v2: Don't init the vgic on in-kernel interrupt injection
KVM: arm64: vgic-v5: Add for_each_visible_v5_ppi() iterator
KVM: arm64: vgic-v5: Move PPI caps into kvm_vgic_global_state
KVM: arm64: vgic-v5: Remove use of __assign_bit() with a constant
KVM: arm64: vgic-v5: Drop pointless ARM64_HAS_GICV5_CPUIF check
KVM: arm64: vgic: Constify struct irq_ops usage
KVM: arm64: vgic: Consolidate vgic_allocate_private_irqs_locked()
KVM: arm64: vgic-v5: Drop defensive checks from vgic_v5_ppi_queue_irq_unlock()
KVM: arm64: vgic: Rationalise per-CPU irq accessor
KVM: arm64: vgic-v5: Limit support to 64 PPIs
KVM: arm64: Key CPTR_EL2.E0POE propagation on FEAT_S1POE
KVM: arm64: Wire AT S1E1A in the system instruction handling table
arm64: cpufeature: Expose ID_AA64ISAR2_EL1.ATS1A to KVM
KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB
KVM: arm64: nv: Hold kvm->mmu_lock while initialising vcpu->arch.vncr_tlb
Merge branch kvm-arm64/no-lazy-vgic-init into kvmarm-master/next
Merge branch kvm-arm64/nv-fp-elision into kvmarm-master/next
Merge branch kvm-arm64/nv-granule-sizes into kvmarm-master/next
Merge branch kvm-arm64/pkvm-fixes-7.2 into kvmarm-master/next
Merge branch kvm-arm64/vgic-v5-PPI-fixes into kvmarm-master/next
Merge branch kvm-arm64/misc-7.2 into kvmarm-master/next
Merge branch kvm-arm64/nv-mmu-7.2 into kvmarm-master/next
Oliver Upton (5):
KVM: arm64: Don't leak PFN when kvm_translate_vncr() races MMU notifier
KVM: arm64: nv: Fully update VNCR fixmap state in kvm_translate_vncr()
KVM: arm64: nv: Inject SEA TTW when desc update can't write to GPA
KVM: arm64: Restart instruction upon race in __kvm_at_s12()
KVM: arm64: nv: Restart stage-1 walk if stage-2 desc update fails
Sascha Bischoff (9):
KVM: arm64: vgic-v5: Add missing trap handing for NV triage
KVM: arm64: vgic-v5: Atomically assign bits to PPI DVI bitmap
KVM: arm64: selftests: Add missing GIC CDEN to no-vgic-v5 selftest
KVM: arm64: selftests: Cleanup unused vars in GICv5 PPI selftest
KVM: arm64: selftests: Improve error handling for GICv5 PPI selftest
Documentation: KVM: Fix typos in VGICv5 documentation
Documentation: KVM: Clarify that PMU_V3_IRQ IntID requirements for GICv5
irqchip/gic-v5: Immediately exec priority drop following activate
KVM: arm64: Fix arch timer interrupts for GICv3-on-GICv5 guests
Vincent Donnefort (4):
KVM: arm64: Reset page order in pKVM hyp_pool
KVM: arm64: Fix __pkvm_init_vm error path
KVM: arm64: Add fail-safe for refcounted pages in __pkvm_hyp_donate_host
KVM: arm64: Set a Linux errno on SMCCC error in kvm_call_hyp_nvhe()
Wei-Lin Chang (5):
KVM: arm64: nv: Rename vtcr_to_walk_info() to setup_s2_walk()
KVM: arm64: Factor out TG0/1 decoding of VTCR and TCR
KVM: arm64: nv: Use literal granule size in TLBI range calculation
KVM: arm64: Fallback to a supported value for unsupported guest TGx
KVM: arm64: Fix block mapping validity check in stage-1 walker
Will Deacon (1):
KVM: arm64: Don't populate TPIDR_EL2 in finalise_el2()
Zenghui Yu (Huawei) (1):
KVM: arm64: Remove @arch from __load_stage2()
tabba@google.com (4):
KVM: arm64: Flush HCR_EL2.VSE to deliver SErrors to pKVM guests
KVM: arm64: Free hyp-share tracking node when share hypercall fails
KVM: arm64: Avoid host/hyp share desync on unshare hypercall failure
KVM: arm64: Roll back partial shares on kvm_share_hyp() failure
Documentation/virt/kvm/devices/arm-vgic-v5.rst | 6 +-
Documentation/virt/kvm/devices/vcpu.rst | 7 +-
arch/arm64/include/asm/kvm_host.h | 8 +-
arch/arm64/include/asm/kvm_hyp.h | 1 +
arch/arm64/include/asm/kvm_mmu.h | 3 +-
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kernel/hyp-stub.S | 4 +-
arch/arm64/kvm/arch_timer.c | 137 +++++++--------
arch/arm64/kvm/arm.c | 41 +++--
arch/arm64/kvm/at.c | 146 +++++++++++----
arch/arm64/kvm/emulate-nested.c | 12 ++
arch/arm64/kvm/fpsimd.c | 26 +++
arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 3 +-
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 21 ++-
arch/arm64/kvm/hyp/nvhe/mem_protect.c | 37 ++--
arch/arm64/kvm/hyp/nvhe/page_alloc.c | 21 ++-
arch/arm64/kvm/hyp/nvhe/pkvm.c | 4 +-
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
arch/arm64/kvm/hyp/nvhe/tlb.c | 4 +-
arch/arm64/kvm/hyp/vgic-v5-sr.c | 82 ++-------
arch/arm64/kvm/hyp/vhe/switch.c | 2 +-
arch/arm64/kvm/hyp/vhe/tlb.c | 4 +-
arch/arm64/kvm/mmu.c | 39 ++++-
arch/arm64/kvm/nested.c | 234 ++++++++++++++++---------
arch/arm64/kvm/pmu-emul.c | 31 +---
arch/arm64/kvm/sys_regs.c | 20 +--
arch/arm64/kvm/vgic/vgic-init.c | 45 ++---
arch/arm64/kvm/vgic/vgic-irqfd.c | 6 +
arch/arm64/kvm/vgic/vgic-its.c | 21 +--
arch/arm64/kvm/vgic/vgic-kvm-device.c | 9 +-
arch/arm64/kvm/vgic/vgic-v5.c | 51 ++----
arch/arm64/kvm/vgic/vgic.c | 33 ++--
arch/arm64/kvm/vgic/vgic.h | 3 +
drivers/irqchip/irq-gic-v5.c | 13 +-
include/kvm/arm_arch_timer.h | 7 +-
include/kvm/arm_pmu.h | 5 +-
include/kvm/arm_vgic.h | 19 +-
tools/testing/selftests/kvm/arm64/no-vgic.c | 1 +
tools/testing/selftests/kvm/arm64/vgic_v5.c | 10 +-
40 files changed, 651 insertions(+), 470 deletions(-)
^ permalink raw reply
* Re: [PATCH v7 11/30] drm/display: bridge_connector: Wire up HDMI 2.0 scrambler callbacks
From: Maxime Ripard @ 2026-06-12 8:52 UTC (permalink / raw)
To: Cristian Ciocaltea
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Luca Ceresoli, Sandy Huang,
Heiko Stübner, Andy Yan, Daniel Stone, Dave Stevenson,
Maíra Canal, Raspberry Pi Kernel Maintenance, kernel,
dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260602-dw-hdmi-qp-scramb-v7-11-445eb54ee1ed@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 4179 bytes --]
On Tue, Jun 02, 2026 at 01:44:11AM +0300, Cristian Ciocaltea wrote:
> Connect the bridge connector's .scrambler_{enable|disable} callbacks to
> the underlying bridge's .hdmi_scrambler_{enable|disable} funcs when
> DRM_BRIDGE_OP_HDMI_SCRAMBLER is advertised.
>
> This completes the bridge connector plumbing so that the SCDC
> scrambling helpers can control source-side scrambling through the
> bridge chain.
>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> ---
> drivers/gpu/drm/display/drm_bridge_connector.c | 41 +++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
> index 9d21b1b57b0d..d048ab49eade 100644
> --- a/drivers/gpu/drm/display/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/display/drm_bridge_connector.c
> @@ -555,6 +555,32 @@ static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connec
> return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len);
> }
>
> +static int drm_bridge_connector_scrambler_enable(struct drm_connector *connector)
> +{
> + struct drm_bridge_connector *bridge_connector =
> + to_drm_bridge_connector(connector);
> + struct drm_bridge *bridge;
> +
> + bridge = bridge_connector->bridge_hdmi;
> + if (!bridge)
> + return -EINVAL;
> +
> + return bridge->funcs->hdmi_scrambler_enable(bridge);
> +}
> +
> +static int drm_bridge_connector_scrambler_disable(struct drm_connector *connector)
> +{
> + struct drm_bridge_connector *bridge_connector =
> + to_drm_bridge_connector(connector);
> + struct drm_bridge *bridge;
> +
> + bridge = bridge_connector->bridge_hdmi;
> + if (!bridge)
> + return -EINVAL;
> +
> + return bridge->funcs->hdmi_scrambler_disable(bridge);
> +}
> +
> static const struct drm_edid *
> drm_bridge_connector_read_edid(struct drm_connector *connector)
> {
> @@ -580,7 +606,7 @@ static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
> .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe,
> .write_infoframe = drm_bridge_connector_write_hdmi_infoframe,
> },
> - /* audio, hdr_drm and spd are set dynamically during init */
> + /* scrambler, audio, hdr_drm and spd are set dynamically during init */
> };
>
> static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = {
> @@ -886,6 +912,11 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> !bridge->funcs->hdmi_clear_spd_infoframe))
> return ERR_PTR(-EINVAL);
>
> + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER &&
> + (!bridge->funcs->hdmi_scrambler_enable ||
> + !bridge->funcs->hdmi_scrambler_disable))
> + return ERR_PTR(-EINVAL);
> +
> bridge_connector->bridge_hdmi = drm_bridge_get(bridge);
>
> if (bridge->supported_formats)
> @@ -990,6 +1021,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
> bridge_connector->hdmi_funcs.spd =
> drm_bridge_connector_hdmi_spd_infoframe;
>
> + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SCRAMBLER) {
> + bridge_connector->hdmi_funcs.scrambler_enable =
> + drm_bridge_connector_scrambler_enable;
> + bridge_connector->hdmi_funcs.scrambler_disable =
> + drm_bridge_connector_scrambler_disable;
> + connector->hdmi.scrambler_supported = true;
> + }
> +
I think we're taking this backwards. The scrambler support isn't
optional: either the controller supports HDMI < 2.0, and then it doesn't
exist, or it supports >= 2.0 and then it's mandatory.
You're considering it optional here, when it's never actually optional
(unlike YUV420 for example)
I still think we should list, somehow, the capabilities of the
controller to the helpers, like max tmds rate supported, formats, etc.
We've so far put everything as an argument to drmm_connector_hdmi_init
but it becomes a bit overloaded, and I wonder if introducing a callback
wouldn't solve this, kind of like what we have for planes and formats.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox