Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/2] arm64: dts: mba8mx: Add DSI->LVDS bridge IRQ
From: Frank Li @ 2026-03-25 15:47 UTC (permalink / raw)
  To: Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Alexander Stein
  Cc: imx, linux-arm-kernel, devicetree, linux-kernel, linux
In-Reply-To: <20260316135820.760073-1-alexander.stein@ew.tq-group.com>


On Mon, 16 Mar 2026 14:58:18 +0100, Alexander Stein wrote:
> Now that the bindings supports IRQ, add the IRQ line. Add a GPIO label
> as well.
> 
> 

Applied, thanks!

[1/2] arm64: dts: mba8mx: Add DSI->LVDS bridge IRQ
      commit: cca9457d5461202a08470a6c778e195ac7c7c775
[2/2] arm64: dts: freescale: tqma8mqml/tqma8mxnl-mba8mx: Add dual-channel LVDS overlay
      commit: e186e92cc785949b180710af8d9da826e45d57a2

Best regards,
-- 
Frank Li <Frank.Li@nxp.com>



^ permalink raw reply

* Re: [PATCH 1/2] arm64/entry: Fix involuntary preemption exception masking
From: Thomas Gleixner @ 2026-03-25 15:46 UTC (permalink / raw)
  To: Mark Rutland
  Cc: vladimir.murzin, peterz, catalin.marinas, ruanjinjie,
	linux-kernel, luto, will, linux-arm-kernel
In-Reply-To: <acPAzdtjK5w-rNqC@J2N7QTR9R3>

On Wed, Mar 25 2026 at 11:03, Mark Rutland wrote:
> On Sun, Mar 22, 2026 at 12:25:06AM +0100, Thomas Gleixner wrote:
>> The current sequence on entry is:
>> 
>>   // interrupts are disabled by interrupt/exception entry
>>   enter_from_kernel_mode()
>>      irqentry_enter(regs);
>>      mte_check_tfsr_entry();
>>      mte_disable_tco_entry();
>>      daif_inherit(regs);
>>      // interrupts are still disabled
>
> That last comment isn't quite right: we CAN and WILL enable interrupts
> in local_daif_inherit(), if and only if they were enabled in the context
> the exception was taken from.

Ok.

> As mentioned above, when handling an interrupt (rather than a
> synchronous exception), we don't use local_daif_inherit(), and instead
> use a different DAIF function to unmask everything except interrupts.
>
>> which then becomes:
>> 
>>   // interrupts are disabled by interrupt/exception entry
>>   irqentry_enter(regs)
>>      establish_state();
>>      // RCU is watching
>>      arch_irqentry_enter_rcu()
>>         mte_check_tfsr_entry();
>>         mte_disable_tco_entry();
>>         daif_inherit(regs);
>>      // interrupts are still disabled
>>           
>> Which is equivalent versus the MTE/DAIF requirements, no?
>
> As above, we can't use local_daif_inherit() here because we want
> different DAIF masking behavior for entry to interrupts and entry to
> synchronous exceptions. While we could pass some token around to
> determine the behaviour dynamically, that's less clear, more
> complicated, and results in worse code being generated for something we
> know at compile time.

I get it. Duh what a maze.

> If we can leave DAIF masked early on during irqentry_enter(), I don't
> see why we can't leave all DAIF exceptions masked until the end of
> irqentry_enter().

Yes. Entry is not an issue.

> I *think* what would work for us is we could split some of the exit
> handling (including involuntary preemption) into a "prepare" step, as we
> have for return to userspace. That way, arm64 could handle exiting
> something like:
>
> 	local_irq_disable();
> 	irqentry_exit_prepare(); // new, all generic logic
> 	local_daif_mask();
> 	arm64_exit_to_kernel_mode() {
> 		...
> 		irqentry_exit(); // ideally irqentry_exit_to_kernel_mode().
> 		...
> 	}
>
> ... and other architectures can use a combined exit_to_kernel_mode() (or
> whatever we call that), which does both, e.g.
>
> 	// either noinstr, __always_inline, or a macro
> 	void irqentry_prepare_and_exit(void)

That's a bad idea as that would require to do a full kernel rename of
all existing irqentry_exit() users.

> 	{
> 		irqentry_exit_prepare();
> 		irqentry_exit();
> 	}

Aside of the naming that should work.

Thanks,

        tglx






^ permalink raw reply

* Re: [PATCH v10 00/12] barrier: Add smp_cond_load_{relaxed,acquire}_timeout()
From: David Laight @ 2026-03-25 15:42 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Ankur Arora, Andrew Morton, linux-kernel, linux-arch,
	linux-arm-kernel, linux-pm, bpf, arnd, will, peterz, mark.rutland,
	harisokn, cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1,
	xueshuai, rdunlap, joao.m.martins, boris.ostrovsky, konrad.wilk
In-Reply-To: <acPo7l_pd5rnHpSX@arm.com>

On Wed, 25 Mar 2026 13:53:50 +0000
Catalin Marinas <catalin.marinas@arm.com> wrote:

> On Tue, Mar 17, 2026 at 09:17:05AM +0000, David Laight wrote:
> > On Mon, 16 Mar 2026 23:53:22 -0700
> > Ankur Arora <ankur.a.arora@oracle.com> wrote:  
> > > David Laight <david.laight.linux@gmail.com> writes:  
> > > > On arm64 I think you could use explicit sev and wfe - but that will wake all
> > > > 'sleeping' cpu; and you may not want the 'thundering herd'.    
> > > 
> > > Wouldn't we still have the same narrow window where the CPU disregards the IPI?  
> > 
> > You need a 'sevl' in the interrupt exit path.  
> 
> No need to, see the rule below in
> https://developer.arm.com/documentation/ddi0487/maa/2983-beijhbbd:
> 
> R_XRZRK
>   The Event Register for a PE is set by any of the following:
>   [...]
>   - An exception return.
> 

It is a shame the pages for the SEV and WFE instructions don't mention that.
And the copy I found doesn't have working hyperlinks to any other sections.
(Not even references to related instructions...)

You do need to at least comment that the "msr s0_3_c1_c0_0, %[ecycles]" is
actually WFET.
Is that using an absolute cycle count?
If so does it work if the time has already passed?
If it is absolute do you need to recalculate it every time around the loop?
__delay_cycles() contains guard(preempt_notrace()). I haven't looked what
that does but is it needed here since preemption is disabled?

Looking at the code I think the "sevl; wfe" pair should be higher up.
If they were before the evaluation of the condition then an IPI that set
need_resched() just after it was tested would cause a wakeup.
Clearly that won't help if the condition does anything that executes 'wfe'
and won't sleep if it sets the event - but I suspect they are unlikely.

I also wonder how long it takes the cpu to leave any low power state.
We definitely found that was an issue on some x86 cpu and had to both
disable the lowest low power state and completely rework some wakeup
code that really wanted a 'thundering herd' rather than the very gentle
'bring each cpu out of low power one at a time' that cv_broadcast()
gave it.

	David



^ permalink raw reply

* Re: [PATCH v2] arm64: dts: imx8mp-frdm: add sd, ethernet, wifi, usb and hdmi support
From: Frank Li @ 2026-03-25 15:37 UTC (permalink / raw)
  To: Fabian Pfitzner
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, devicetree, imx,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260316-fpf-imx8mp-frdm-v2-1-e2e8aadecb2f@pengutronix.de>

On Mon, Mar 16, 2026 at 10:25:04AM +0100, Fabian Pfitzner wrote:
> Add support for the following new features:
>
> - SD Card
> - Ethernet (FEC + EQOS)
> - Wifi
> - USB
> - HDMI
>
> The imx8mp-evk dt and the NXP downstream imx8mp-frdm dts were
> taken as a reference.
>
> Signed-off-by: Fabian Pfitzner <f.pfitzner@pengutronix.de>
> ---

Please rebase to https://git.kernel.org/pub/scm/linux/kernel/git/frank.li/linux.git/log/?h=for-next

Frank

> Changes in v2:
> - Reorder nodes by name
> - Remove unused "realtek,clkout-disable" property
> - Link to v1: https://lore.kernel.org/r/20260224-fpf-imx8mp-frdm-v1-1-d7f3b57c18e0@pengutronix.de
> ---
>  arch/arm64/boot/dts/freescale/imx8mp-frdm.dts | 407 ++++++++++++++++++++++++++
>  1 file changed, 407 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-frdm.dts b/arch/arm64/boot/dts/freescale/imx8mp-frdm.dts
> index 55690f5e53d7e1fbf7eae8a1f31eb064465ccb6c..c3691887bb8456c56de27af2e8432657ae2d77e6 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-frdm.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-frdm.dts
> @@ -42,6 +42,67 @@ memory@40000000 {
>  		reg = <0x0 0x40000000 0 0xc0000000>,
>  		      <0x1 0x00000000 0 0x40000000>;
>  	};
> +
> +	native-hdmi-connector {
> +		compatible = "hdmi-connector";
> +		label = "HDMI OUT";
> +		type = "a";
> +
> +		port {
> +			hdmi_in: endpoint {
> +				remote-endpoint = <&hdmi_tx_out>;
> +			};
> +		};
> +	};
> +
> +	reg_usdhc2_vmmc: regulator-sd {
> +		compatible = "regulator-fixed";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
> +		regulator-name = "VSD_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	reg_usb_vbus: regulator-vbus {
> +		compatible = "regulator-fixed";
> +		regulator-name = "USB_VBUS";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		gpio = <&pcal6416_1 5 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	reg_usdhc1_vmmc: regulator-wifi-vmmc {
> +		compatible = "regulator-fixed";
> +		regulator-name = "WLAN_EN";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&pcal6416_1 10 GPIO_ACTIVE_HIGH>;
> +		/*
> +		 * IW612 wifi chip needs more delay than other wifi chips to complete
> +		 * the host interface initialization after power up, otherwise the
> +		 * internal state of IW612 may be unstable, resulting in the failure of
> +		 * the SDIO3.0 switch voltage.
> +		 */
> +		enable-active-high;
> +		startup-delay-us = <20000>;
> +	};
> +
> +	reg_usdhc1_vqmmc: regulator-wifi-vqmmc {
> +		compatible = "regulator-fixed";
> +		regulator-name = "regulator-wifi-vqmmc";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		enable-active-high;
> +	};
> +
> +	sdio_pwrseq: usdhc1-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
> +	};
>  };
>
>  &A53_0 {
> @@ -60,6 +121,147 @@ &A53_3 {
>  	cpu-supply = <&reg_arm>;
>  };
>
> +&eqos {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_eqos>;
> +	phy-mode = "rgmii-id";
> +	phy-handle = <&ethphy0>;
> +	snps,force_thresh_dma_mode;
> +	snps,mtl-tx-config = <&mtl_tx_setup>;
> +	snps,mtl-rx-config = <&mtl_rx_setup>;
> +	status = "okay";
> +
> +	mdio {
> +		compatible = "snps,dwmac-mdio";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		ethphy0: ethernet-phy@2 {
> +			compatible = "ethernet-phy-ieee802.3-c22";
> +			reg = <2>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_eqos_phy>;
> +			reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
> +			reset-assert-us = <10000>;
> +			reset-deassert-us = <80000>;
> +		};
> +	};
> +
> +	mtl_tx_setup: tx-queues-config {
> +		snps,tx-queues-to-use = <5>;
> +
> +		queue0 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x1>;
> +		};
> +
> +		queue1 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x2>;
> +		};
> +
> +		queue2 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x4>;
> +		};
> +
> +		queue3 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x8>;
> +		};
> +
> +		queue4 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0xf0>;
> +		};
> +	};
> +
> +	mtl_rx_setup: rx-queues-config {
> +		snps,rx-queues-to-use = <5>;
> +		snps,rx-sched-sp;
> +
> +		queue0 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x1>;
> +			snps,map-to-dma-channel = <0>;
> +		};
> +
> +		queue1 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x2>;
> +			snps,map-to-dma-channel = <1>;
> +		};
> +
> +		queue2 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x4>;
> +			snps,map-to-dma-channel = <2>;
> +		};
> +
> +		queue3 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0x8>;
> +			snps,map-to-dma-channel = <3>;
> +		};
> +
> +		queue4 {
> +			snps,dcb-algorithm;
> +			snps,priority = <0xf0>;
> +			snps,map-to-dma-channel = <4>;
> +		};
> +	};
> +};
> +
> +&fec {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_fec>;
> +	phy-mode = "rgmii-id";
> +	phy-handle = <&ethphy1>;
> +	fsl,magic-packet;
> +	status = "okay";
> +
> +	mdio {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		ethphy1: ethernet-phy@1 {
> +			compatible = "ethernet-phy-ieee802.3-c22";
> +			reg = <1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_fec_phy>;
> +			eee-broken-1000t;
> +			reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
> +			reset-assert-us = <10000>;
> +			reset-deassert-us = <80000>;
> +			realtek,aldps-enable;
> +			realtek,clkout-disable;
> +		};
> +	};
> +};
> +
> +
> +&hdmi_pvi {
> +	status = "okay";
> +};
> +
> +&hdmi_tx {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_hdmi>;
> +	status = "okay";
> +
> +	ports {
> +		port@1 {
> +			hdmi_tx_out: endpoint {
> +				remote-endpoint = <&hdmi_in>;
> +			};
> +		};
> +	};
> +};
> +
> +&hdmi_tx_phy {
> +	status = "okay";
> +};
> +
>  &i2c1 {
>  	clock-frequency = <400000>;
>  	pinctrl-names = "default";
> @@ -218,6 +420,32 @@ &i2c3 {
>  	status = "okay";
>  };
>
> +&lcdif3 {
> +	status = "okay";
> +};
> +
> +&usb3_0 {
> +	status = "okay";
> +};
> +
> +&usb3_1 {
> +	status = "okay";
> +};
> +
> +&usb3_phy0 {
> +	status = "okay";
> +};
> +
> +&usb3_phy1 {
> +	vbus-supply = <&reg_usb_vbus>;
> +	status = "okay";
> +};
> +
> +&usb_dwc3_1 {
> +	dr_mode = "host";
> +	status = "okay";
> +};
> +
>  &snvs_pwrkey {
>  	status = "okay";
>  };
> @@ -237,6 +465,36 @@ &uart3 {
>  	status = "okay";
>  };
>
> +&usdhc1 {
> +	assigned-clocks = <&clk IMX8MP_CLK_USDHC1>;
> +	assigned-clock-rates = <200000000>;
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&pinctrl_usdhc1>;
> +	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
> +	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +	vmmc-supply = <&reg_usdhc1_vmmc>;
> +	vqmmc-supply = <&reg_usdhc1_vqmmc>;
> +	bus-width = <4>;
> +	non-removable;
> +	no-sd;
> +	no-mmc;
> +	status = "okay";
> +};
> +
> +&usdhc2 {
> +	assigned-clocks = <&clk IMX8MP_CLK_USDHC2>;
> +	assigned-clock-rates = <400000000>;
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
> +	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
> +	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
> +	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
> +	vmmc-supply = <&reg_usdhc2_vmmc>;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
>  &usdhc3 {
>  	assigned-clocks = <&clk IMX8MP_CLK_USDHC3>;
>  	assigned-clock-rates = <400000000>;
> @@ -250,6 +508,74 @@ &usdhc3 {
>  };
>
>  &iomuxc {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_hog>;
> +
> +	pinctrl_eqos: eqosgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x2
> +			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x2
> +			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x90
> +			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x90
> +			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x90
> +			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x90
> +			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
> +			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x90
> +			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x16
> +			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x16
> +			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x16
> +			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x16
> +			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x16
> +			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
> +		>;
> +	};
> +
> +	pinctrl_eqos_phy: eqosphygrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x10
> +		>;
> +	};
> +
> +	pinctrl_fec: fecgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC		0x2
> +			MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO		0x2
> +			MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0		0x90
> +			MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1		0x90
> +			MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2		0x90
> +			MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3		0x90
> +			MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC		0x90
> +			MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL	0x90
> +			MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0		0x16
> +			MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1		0x16
> +			MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2		0x16
> +			MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3		0x16
> +			MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL	0x16
> +			MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC		0x16
> +		>;
> +	};
> +
> +	pinctrl_fec_phy: fecphygrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02		0x10
> +		>;
> +	};
> +
> +	pinctrl_hdmi: hdmigrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC		0x10
> +		>;
> +	};
> +
> +	pinctrl_hog: hoggrp {
> +		fsl,pins = <
> +			/* Pin might be required by multiple drivers
> +			 * (e. g. HDMI Audio and HDMI TX)
> +			 */
> +			MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD		0x40000010
> +		>;
> +	};
> +
>  	pinctrl_i2c1: i2c1grp {
>  		fsl,pins = <
>  			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL	0x400001c2
> @@ -289,6 +615,12 @@ MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11	0x146
>  		>;
>  	};
>
> +	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
> +		>;
> +	};
> +
>  	pinctrl_uart2: uart2grp {
>  		fsl,pins = <
>  			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x140
> @@ -305,6 +637,81 @@ MX8MP_IOMUXC_ECSPI1_MISO__UART3_DCE_CTS	0x140
>  		>;
>  	};
>
> +	pinctrl_usdhc1: usdhc1grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK	0x190
> +			MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD	0x1d0
> +			MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0	0x1d0
> +			MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1	0x1d0
> +			MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2	0x1d0
> +			MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3	0x1d0
> +		>;
> +	};
> +
> +	pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK	0x194
> +			MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD	0x1d4
> +			MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0	0x1d4
> +			MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1	0x1d4
> +			MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2	0x1d4
> +			MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3	0x1d4
> +		>;
> +	};
> +
> +	pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK	0x196
> +			MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD	0x1d6
> +			MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0	0x1d6
> +			MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1	0x1d6
> +			MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2	0x1d6
> +			MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3	0x1d6
> +		>;
> +	};
> +
> +	pinctrl_usdhc2: usdhc2grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK	0x190
> +			MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD	0x1d0
> +			MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d0
> +			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
> +			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
> +			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
> +			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK	0x194
> +			MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD	0x1d4
> +			MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d4
> +			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
> +			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
> +			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
> +			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK	0x196
> +			MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD	0x1d6
> +			MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0	0x1d6
> +			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
> +			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
> +			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
> +			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12	0x1c4
> +		>;
> +	};
> +
>  	pinctrl_usdhc3: usdhc3grp {
>  		fsl,pins = <
>  			MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK	0x190
>
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20260224-fpf-imx8mp-frdm-402c4df06302
>
> Best regards,
> --
> Fabian Pfitzner <f.pfitzner@pengutronix.de>
>


^ permalink raw reply

* Re: [PATCH v6 1/5] mm: rmap: support batched checks of the references for large folios
From: Lorenzo Stoakes (Oracle) @ 2026-03-25 15:32 UTC (permalink / raw)
  To: Andrew Morton
  Cc: David Hildenbrand (Arm), Baolin Wang, Barry Song, catalin.marinas,
	will, lorenzo.stoakes, ryan.roberts, Liam.Howlett, vbabka, rppt,
	surenb, mhocko, riel, harry.yoo, jannh, willy, dev.jain, linux-mm,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260325083016.a32095bea3f04488a7c9005a@linux-foundation.org>

On Wed, Mar 25, 2026 at 08:30:16AM -0700, Andrew Morton wrote:
> On Wed, 25 Mar 2026 15:06:26 +0000 "Lorenzo Stoakes (Oracle)" <ljs@kernel.org> wrote:
>
> > > > Sorry unclear here - does the series need more work or does a follow up patch
> > > > need more work?
> > >
> > > Follow up!
> >
> > Ok good as in mm-stable now. Sadly means I don't get to review it but there we
> > go.
>
> Well, this was sent 6 weeks ago, at v6!

Yup I know, I've struggled to clear my backlog.

>
> But please go ahead.  If review is very bad, there's git-rebase
> (happens sometimes) or some followup fix and a minor bisection hole
> (happens a bit more often).
>
> And those followup fixes will trickle in all the way out to 7.1-rc7,
> via the hotfixes path.  This happens a great deal - about half(?) of
> hotfixes pertain to material we added in the current -rc cycle.
>

Well given the other tags it's unlikely that would happen, so it doesn't feel
really worthwhile at this point.

Really I guess I'd like to know the timing of when mm-stable is taken so I can
know the deadline for stuff like this.

Thanks, Lorenzo


^ permalink raw reply

* Re: [PATCH] arm64: dts: imx95-15x15-evk: remove regulator-always-on for reg_m2_pwr
From: Frank Li @ 2026-03-25 15:32 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, hongxing.zhu,
	Sherry Sun
  Cc: imx, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260317030418.441824-1-sherry.sun@nxp.com>


On Tue, 17 Mar 2026 11:04:18 +0800, Sherry Sun wrote:
> Now we use vpcie3v3aux-supply to keep 3.3Vaux supply enabled for the
> entire PCIe controller lifecycle, no need regulator-always-on property.
> 
> 

Applied, thanks!

[1/1] arm64: dts: imx95-15x15-evk: remove regulator-always-on for reg_m2_pwr
      commit: 66df8383703f78ea6fd935e8b986802117d396dd

Best regards,
-- 
Frank Li <Frank.Li@nxp.com>



^ permalink raw reply

* Re: [PATCH v2 0/4] arm64: dts: imx952-evk: Add audio sound cards
From: Frank Li @ 2026-03-25 15:30 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, devicetree,
	imx, linux-arm-kernel, linux-kernel, Shengjiu Wang
In-Reply-To: <20260316021439.2971610-1-shengjiu.wang@nxp.com>


On Mon, 16 Mar 2026 10:14:35 +0800, Shengjiu Wang wrote:
> Add audio device nodes and sound card (wm8962, PDM microphone, bt-sco).
> 
> Changes in v2:
> - use macro FSL_EDMA_RX for audio nodes in patch 1/4
> - update commit message to add ASRC2 info in patch 2/4
> - add acked by Daniel in patch 2/4, 3/4, 4/4
> 
> [...]

Applied, thanks!

[1/4] arm64: dts: imx952: Add audio device nodes
      commit: 9cdf26f3cb3fad99d48c59e2e8630939ca75a37c
[2/4] arm64: dts: imx952-evk: Add sound-wm8962 support
      commit: 48fe0319c1fe7c5b470e0b29975cd7395609319b
[3/4] arm64: dts: imx952-evk: Add bt-sco sound card support
      commit: bf99a2ea2c82ad4baa9476f7f168c649313b1751
[4/4] arm64: dts: imx952-evk: Add PDM microphone sound card support
      commit: 9846b69696e59097926f427dae90b3d7aed66846

Best regards,
-- 
Frank Li <Frank.Li@nxp.com>



^ permalink raw reply

* Re: [PATCH v6 1/5] mm: rmap: support batched checks of the references for large folios
From: Andrew Morton @ 2026-03-25 15:30 UTC (permalink / raw)
  To: Lorenzo Stoakes (Oracle)
  Cc: David Hildenbrand (Arm), Baolin Wang, Barry Song, catalin.marinas,
	will, lorenzo.stoakes, ryan.roberts, Liam.Howlett, vbabka, rppt,
	surenb, mhocko, riel, harry.yoo, jannh, willy, dev.jain, linux-mm,
	linux-arm-kernel, linux-kernel
In-Reply-To: <e227a7f7-0186-4d10-b7b4-c84ca8424bdd@lucifer.local>

On Wed, 25 Mar 2026 15:06:26 +0000 "Lorenzo Stoakes (Oracle)" <ljs@kernel.org> wrote:

> > > Sorry unclear here - does the series need more work or does a follow up patch
> > > need more work?
> >
> > Follow up!
> 
> Ok good as in mm-stable now. Sadly means I don't get to review it but there we
> go.

Well, this was sent 6 weeks ago, at v6!

But please go ahead.  If review is very bad, there's git-rebase
(happens sometimes) or some followup fix and a minor bisection hole
(happens a bit more often).

And those followup fixes will trickle in all the way out to 7.1-rc7,
via the hotfixes path.  This happens a great deal - about half(?) of
hotfixes pertain to material we added in the current -rc cycle.



^ permalink raw reply

* Re: [PATCH v3] PCI: dw-rockchip: Enable async probe by default
From: Dmitry Torokhov @ 2026-03-25 15:26 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Robin Murphy, Manivannan Sadhasivam, Manivannan Sadhasivam,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
	Bjorn Helgaas, Heiko Stuebner, Niklas Cassel, Shawn Lin,
	Hans Zhang, Nicolas Frattaroli, Wilfred Mallawa, linux-pci,
	linux-arm-kernel, linux-rockchip, linux-kernel, Anand Moon,
	Grimmauld, Greg Kroah-Hartman, Rafael J. Wysocki, driver-core,
	Lukas Wunner
In-Reply-To: <DHBYL7Y262J2.263EOC2JNN4RK@kernel.org>

On Wed, Mar 25, 2026 at 04:13:03PM +0100, Danilo Krummrich wrote:
> On Wed Mar 25, 2026 at 5:13 AM CET, Dmitry Torokhov wrote:
> > That means that you are kicking the majority devices (for now) into
> > deferral path. I do not think this is optimal.
> 
> That's not necessary, we'd only need to kick those into the deferral path that
> have PROBE_FORCE_SYNCHRONOUS, no?

Yes, it may limit the fallout, but as I explained in my other email
there seem to be a serious disconnect on what synchronous and
asynchronous probing mean.

I wonder, don't we get issues with phylib in other cases? Don't we ever
have a module resulting in creating a phy device triggering loading
another module on the same thread? Won't that result in a warning also?

Thanks.

-- 
Dmitry


^ permalink raw reply

* Re: [PATCH v7 0/2] Add support for Variscite DART-MX95 and Sonata board
From: Stefano Radaelli @ 2026-03-25 15:25 UTC (permalink / raw)
  To: Frank Li
  Cc: Francesco Dolcini, devicetree, linux-kernel, pierluigi.p,
	Stefano Radaelli, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, imx, linux-arm-kernel
In-Reply-To: <acP2UX6B5js_ozWm@lizhi-Precision-Tower-5810>

On Wed, Mar 25, 2026 at 10:50:57AM -0400, Frank Li wrote:
> >
> > How do you know that the correct copyright year is 2026?
> > The copyright years does not change to today just because it is the year
> > it was submitted.
> 
> At least it should include 2026 because it is new files in kernel tree.
> 
> >
> > I think that you should refrain yourself for doing these kind of changes
> > to the code when you apply patches.
> 
> If original owner have concern, I can update it in my tree.
> 

Hi Francesco, hi Frank,

thanks for the clarification.

In this specific case, I'm fine with keeping 2026 for these new files
introduced in the kernel tree.

Thank you all for taking care of this!

Best regards,
Stefano


^ permalink raw reply

* Re: [PATCH v3] PCI: dw-rockchip: Enable async probe by default
From: Dmitry Torokhov @ 2026-03-25 15:23 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Danilo Krummrich, Manivannan Sadhasivam, Manivannan Sadhasivam,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
	Bjorn Helgaas, Heiko Stuebner, Niklas Cassel, Shawn Lin,
	Hans Zhang, Nicolas Frattaroli, Wilfred Mallawa, linux-pci,
	linux-arm-kernel, linux-rockchip, linux-kernel, Anand Moon,
	Grimmauld, Greg Kroah-Hartman, Rafael J. Wysocki, driver-core,
	Lukas Wunner
In-Reply-To: <6cc25c83-6a5a-4785-9573-335371a94798@arm.com>

On Wed, Mar 25, 2026 at 03:01:03PM +0000, Robin Murphy wrote:
> On 25/03/2026 4:13 am, Dmitry Torokhov wrote:
> > On Thu, Mar 12, 2026 at 12:48:36PM +0000, Robin Murphy wrote:
> > > On 2026-03-11 9:09 pm, Danilo Krummrich wrote:
> > > > On Wed Mar 11, 2026 at 1:28 PM CET, Manivannan Sadhasivam wrote:
> > > > > On Wed, Mar 11, 2026 at 12:46:03PM +0100, Danilo Krummrich wrote:
> > > > > > On Wed Mar 11, 2026 at 6:24 AM CET, Manivannan Sadhasivam wrote:
> > > > > > > I have a contrary view here. If just a single driver or lib doesn't handle async
> > > > > > > probe, it cannot just force other drivers to not take the advantage of async
> > > > > > > probe. As I said above, enabling async probe easily saves a few hunderd ms or
> > > > > > > even more if there are more than one Root Port or Root Complex in an SoC.
> > > > > > 
> > > > > > Then the driver or lib has to be fixed / improved first or the driver core has
> > > > > > to be enabled to deal with a case where PROBE_FORCE_SYNCHRONOUS is requested
> > > > > > from an async path, etc.
> > > > > > 
> > > > > > In any case, applying the patch and breaking things (knowingly?) doesn't seem
> > > > > > like the correct approach.
> > > > > > 
> > > > > > > I strongly agree with you here that the underlying issue should be fixed. But
> > > > > > > the real impact to end users is not this splat, but not having the boot time
> > > > > > > optimization that this patch brings in. As an end user, one would want their
> > > > > > > systems to boot quickly and they wouldn't bother much about a harmless warning
> > > > > > > splat appearing in the dmesg log.
> > > > > > 
> > > > > > You mean quickly booting into a "harmless" potential deadlock condition the
> > > > > > warning splat tries to make people aware of? :)
> > > > > > 
> > > > > 
> > > > > Hmm, I overlooked the built-as-module part where the deadlock could be possible
> > > > > as indicated by the comment about the WARN_ON_ONCE().
> > > > > 
> > > > > But what is the path forward here? Do you want the phylib to fix the
> > > > > request_module() call or fix the driver core instead?
> > > > 
> > > > Here are a few thoughts.
> > > > 
> > > > In general, I think the best would be to get rid of the (affected)
> > > > PROBE_FORCE_SYNCHRONOUS cases.
> > > > 
> > > > Now, I guess this can be pretty hard for a PCI controller driver, as you can't
> > > > really predict what ends up being probed from you async context, i.e. it could
> > > > even be some other bus controller and things could even propagate further.
> > > > 
> > > > Not sure how big of a deal it is in practice though, there are not a lot of
> > > > PROBE_FORCE_SYNCHRONOUS drivers (left), but note that specifying neither
> > > > PROBE_FORCE_SYNCHRONOUS nor PROBE_PREFER_ASYNCHRONOUS currently results in
> > > > synchronous by default.
> > > > 
> > > > (Also, quite some other PCI controller drivers do set PROBE_PREFER_ASYNCHRONOUS
> > > > and apparently got lucky with it.)
> > > > 
> > > >   From a driver-core perspective I think we're rather limited on what we can do;
> > > > we are already in async context at this point and can't magically go back to
> > > > initcall context.
> > > > 
> > > > So, the only thing I can think of is to kick off work on a workqueue, which in
> > > > the end would be the same as the deferred probe handling.
> > > 
> > > Hmm, in fact, isn't the deferred probe mechanism itself actually quite
> > > appropriate? A suitable calling context isn't the most obvious "resource
> > > provider" to wait for, but ultimately it's still a case of "we don't
> > > have everything we need right now, but it's worth trying again soon".
> > > I may have missed some subtleties, but my instinct is that it could
> > > perhaps be as simple as something like this (completely untested).
> > > 
> > > Cheers,
> > > Robin.
> > > 
> > > ----->8-----
> > > 
> > > diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> > > index bea8da5f8a3a..3c4a0207ae3f 100644
> > > --- a/drivers/base/dd.c
> > > +++ b/drivers/base/dd.c
> > > @@ -954,6 +954,16 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
> > >   	if (data->check_async && async_allowed != data->want_async)
> > >   		return 0;
> > > +	/*
> > > +	 * Bus drivers may probe asynchronously, but be adding a child device
> > > +	 * whose driver still wants a synchronous probe. In this case, just
> > > +	 * defer it, to be triggered by the parent driver probe succeeding.
> > > +	 */
> > > +	if (!async_allowed && current_is_async()) {
> > > +		driver_deferred_probe_add(dev);
> > > +		return 0;
> > > +	}
> > 
> > That means that you are kicking the majority devices (for now) into
> > deferral path. I do not think this is optimal.
> 
> And probing drivers under conditions where they may go wrong or deadlock is
> better? I've not yet had a chance to actually test this myself to see the
> effect on timings, but whatever it might be, I can't imagine any *other*
> method of re-serialising child driver probes could be significantly better
> (or if it could be, that might represent some improvement we could make to
> the deferred probe mechanism in general anyway).

There is serious disconnect as to what asynchronous and synchronous
probing means. You do not go "back" to synchronous probing.

	/*
	 * Indicates whether we are considering asynchronous probing or
	 * not. Only initial binding after device or driver registration
	 * (including deferral processing) may be done asynchronously, the
	 * rest is always synchronous, as we expect it is being done by
	 * request from userspace.
	 */
	bool check_async;

So synchronous means that when you register device or driver we dun
probe immediately on the same thread that registered said device or
driver, while with async we _may_ schedule on a workqueue (but if the
system has already scheduled too much async it will be probed
synchronously or immediately).

So in the case we are discussing the probing of phy device is indeed
synchronous/immediate relative to the thread where the phy device is
registered.

> 
> I have finally got a bit of time this afternoon to pick this up again, so
> I'll have a play and try to finish the write-up capturing all the reasoning
> so far (it's a long one...)
> 
> > Does phy really need to request modules synchronously (and on its own)?
> > Why can't it rely on udev to load the modules and signal when phy
> > devices are ready?
> 
> Getting hung up on what phylib does in this one particular case is rather
> missing the point. There is a reason that we're still not forcing
> async_probe on for everything by default. Many drivers will still not have
> been tested and validated to handle it correctly, and while the majority of
> latent issues will likely just be concurrency bugs which can be fixed with
> better locking or whatever, even then we should be encouraging developers to
> actively test and look for such bugs to make their drivers "async probe
> clean", rather than knowingly enabling bugs to surface in the wild as weird
> and subtle breakage on end-user systems.

No. We have identified (at least IMO) that what phylib does is wrong. I
am not advocating forcing this PCI host to be marked for asycn probing
right now, before the phy issue is fixed, but I object to adding
workarounds to driver core which hurt other cases and may lead to phylib
never be fixed.

> 
> However, I imagine there will always remain some small minority of
> PROBE_FORCE_SYNCHRONOUS drivers - either for niche legitimate technical
> reasons, or just legacy drivers where updating them would take more effort
> than it's worth - so the driver core surely needs the ability to not do the
> wrong thing itself. That doesn't even need to be "optimal", it just needs to
> be functionally correct.

Again, your expectation of what sync probing means differs from what I
had in mind when implementing it. PROBE_FORCE_SYNCHRONOUS is typically
for drivers/modules that register both a device (typically a singleton)
and a driver, and want to unregister both and free all resources when
initialization fails for some reason. Think cases like PC keyboard
controller.

Thanks.

-- 
Dmitry


^ permalink raw reply

* [PATCH v5 01/12] scsi: ufs: core: Introduce a new ufshcd vops negotiate_pwr_mode()
From: Can Guo @ 2026-03-25 15:21 UTC (permalink / raw)
  To: avri.altman, bvanassche, beanhuo, peter.wang, martin.petersen,
	mani
  Cc: linux-scsi, Can Guo, Alim Akhtar, James E.J. Bottomley,
	Sai Krishna Potthuri, Ajay Neeli, Peter Griffin,
	Krzysztof Kozlowski, Chaotian Jing, Stanley Jhu, Orson Zhai,
	Baolin Wang, Chunyan Zhang, Matthias Brugger,
	AngeloGioacchino Del Regno, Bao D. Nguyen, Adrian Hunter,
	Archana Patni, open list,
	open list:UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER...,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES,
	moderated list:UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER...,
	open list:UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER...
In-Reply-To: <20260325152154.1604082-1-can.guo@oss.qualcomm.com>

Most vendor specific implemenations of vops pwr_change_notify(PRE_CHANGE)
are fulfilling two things at once:
- Vendor specific target power mode negotiation
- Vendor specific power mode change preparation

When TX Equalization is added into consideration, before power mode change
to a target power mode, TX Equalization Training (EQTR) needs be done for
that target power mode. In addition, UFSHCI spec requires to start TX EQTR
from HS-G1 (the most reliable High Speed Gear).

Adding TX EQTR before pwr_change_notify(PRE_CHANGE) is not applicable
because we don't know the negotiated power mode yet.

Adding TX EQTR post pwr_change_notify(PRE_CHANGE) is inappropriate
because pwr_change_notify(PRE_CHANGE) has finished preparation for a power
mode change to negotiated power mode, yet we are changing power mode to
HS-G1 for TX EQTR.

Add a new vops negotiate_pwr_mode() so that vendor specific power mode
negotiation can be fulfilled in its vendor specific implementations.
Later on, TX EQTR can be added post vops negotiate_pwr_mode() and before
vops pwr_change_notify(PRE_CHANGE).

Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
 drivers/ufs/core/ufshcd-priv.h     | 14 +++++-
 drivers/ufs/core/ufshcd.c          | 70 ++++++++++++++++++++++++------
 drivers/ufs/host/ufs-amd-versal2.c |  3 --
 drivers/ufs/host/ufs-exynos.c      | 34 +++++++--------
 drivers/ufs/host/ufs-hisi.c        | 23 +++++-----
 drivers/ufs/host/ufs-mediatek.c    | 40 ++++++++---------
 drivers/ufs/host/ufs-qcom.c        | 24 +++++-----
 drivers/ufs/host/ufs-sprd.c        |  3 --
 drivers/ufs/host/ufshcd-pci.c      |  6 +--
 include/ufs/ufshcd.h               | 17 +++++---
 10 files changed, 143 insertions(+), 91 deletions(-)

diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index 7d6d19361af9..3b6958d9297a 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -167,14 +167,24 @@ static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba,
 	return 0;
 }
 
+static inline int ufshcd_vops_negotiate_pwr_mode(struct ufs_hba *hba,
+						 const struct ufs_pa_layer_attr *dev_max_params,
+						 struct ufs_pa_layer_attr *dev_req_params)
+{
+	if (hba->vops && hba->vops->negotiate_pwr_mode)
+		return hba->vops->negotiate_pwr_mode(hba, dev_max_params,
+					dev_req_params);
+
+	return -ENOTSUPP;
+}
+
 static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	if (hba->vops && hba->vops->pwr_change_notify)
 		return hba->vops->pwr_change_notify(hba, status,
-					dev_max_params, dev_req_params);
+					dev_req_params);
 
 	return -ENOTSUPP;
 }
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 8349fe2090db..91b5d5b02d22 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -335,8 +335,6 @@ static void ufshcd_suspend_clkscaling(struct ufs_hba *hba);
 static int ufshcd_scale_clks(struct ufs_hba *hba, unsigned long freq,
 			     bool scale_up);
 static irqreturn_t ufshcd_intr(int irq, void *__hba);
-static int ufshcd_change_power_mode(struct ufs_hba *hba,
-			     struct ufs_pa_layer_attr *pwr_mode);
 static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on);
 static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on);
 static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
@@ -4662,8 +4660,26 @@ static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba)
 	return 0;
 }
 
-static int ufshcd_change_power_mode(struct ufs_hba *hba,
-			     struct ufs_pa_layer_attr *pwr_mode)
+/**
+ * ufshcd_dme_change_power_mode() - UniPro DME Power Mode change sequence
+ * @hba: per-adapter instance
+ * @pwr_mode: pointer to the target power mode (gear/lane) attributes
+ *
+ * This function handles the low-level DME (Device Management Entity)
+ * configuration required to transition the UFS link to a new power mode. It
+ * performs the following steps:
+ * 1. Checks if the requested mode matches the current state.
+ * 2. Sets M-PHY and UniPro attributes including Gear (PA_RXGEAR/TXGEAR),
+ *    Lanes, Termination, and HS Series (PA_HSSERIES).
+ * 3. Configures default UniPro timeout values (DL_FC0, etc.) unless
+ *    explicitly skipped via quirks.
+ * 4. Triggers the actual hardware mode change via ufshcd_uic_change_pwr_mode().
+ * 5. Updates the HBA's cached power information on success.
+ *
+ * Return: 0 on success, non-zero error code on failure.
+ */
+static int ufshcd_dme_change_power_mode(struct ufs_hba *hba,
+					struct ufs_pa_layer_attr *pwr_mode)
 {
 	int ret;
 
@@ -4747,6 +4763,34 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
 	return ret;
 }
 
+/**
+ * ufshcd_change_power_mode() - Change UFS Link Power Mode
+ * @hba: per-adapter instance
+ * @pwr_mode: pointer to the target power mode (gear/lane) attributes
+ *
+ * This function handles the high-level sequence for changing the UFS link
+ * power mode. It triggers vendor-specific pre-change notification,
+ * executes the DME (Device Management Entity) power mode change sequence,
+ * and, upon success, triggers vendor-specific post-change notification.
+ *
+ * Return: 0 on success, non-zero error code on failure.
+ */
+int ufshcd_change_power_mode(struct ufs_hba *hba,
+			     struct ufs_pa_layer_attr *pwr_mode)
+{
+	int ret;
+
+	ufshcd_vops_pwr_change_notify(hba, PRE_CHANGE, pwr_mode);
+
+	ret = ufshcd_dme_change_power_mode(hba, pwr_mode);
+
+	if (!ret)
+		ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, pwr_mode);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ufshcd_change_power_mode);
+
 /**
  * ufshcd_config_pwr_mode - configure a new power mode
  * @hba: per-adapter instance
@@ -4760,19 +4804,17 @@ int ufshcd_config_pwr_mode(struct ufs_hba *hba,
 	struct ufs_pa_layer_attr final_params = { 0 };
 	int ret;
 
-	ret = ufshcd_vops_pwr_change_notify(hba, PRE_CHANGE,
-					desired_pwr_mode, &final_params);
+	ret = ufshcd_vops_negotiate_pwr_mode(hba, desired_pwr_mode,
+					     &final_params);
+	if (ret) {
+		if (ret != -ENOTSUPP)
+			dev_err(hba->dev, "Failed to negotiate power mode: %d, use desired as is\n",
+				ret);
 
-	if (ret)
 		memcpy(&final_params, desired_pwr_mode, sizeof(final_params));
+	}
 
-	ret = ufshcd_change_power_mode(hba, &final_params);
-
-	if (!ret)
-		ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, NULL,
-					&final_params);
-
-	return ret;
+	return ufshcd_change_power_mode(hba, &final_params);
 }
 EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode);
 
diff --git a/drivers/ufs/host/ufs-amd-versal2.c b/drivers/ufs/host/ufs-amd-versal2.c
index 40543db621a1..52031b7256fd 100644
--- a/drivers/ufs/host/ufs-amd-versal2.c
+++ b/drivers/ufs/host/ufs-amd-versal2.c
@@ -443,7 +443,6 @@ static int ufs_versal2_phy_ratesel(struct ufs_hba *hba, u32 activelanes, u32 rx_
 }
 
 static int ufs_versal2_pwr_change_notify(struct ufs_hba *hba, enum ufs_notify_change_status status,
-					 const struct ufs_pa_layer_attr *dev_max_params,
 					 struct ufs_pa_layer_attr *dev_req_params)
 {
 	struct ufs_versal2_host *host = ufshcd_get_variant(hba);
@@ -451,8 +450,6 @@ static int ufs_versal2_pwr_change_notify(struct ufs_hba *hba, enum ufs_notify_ch
 	int ret = 0;
 
 	if (status == PRE_CHANGE) {
-		memcpy(dev_req_params, dev_max_params, sizeof(struct ufs_pa_layer_attr));
-
 		/* If it is not a calibrated part, switch PWRMODE to SLOW_MODE */
 		if (!host->attcompval0 && !host->attcompval1 && !host->ctlecompval0 &&
 		    !host->ctlecompval1) {
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
index 76fee3a79c77..77a6c8e44485 100644
--- a/drivers/ufs/host/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -818,12 +818,10 @@ static u32 exynos_ufs_get_hs_gear(struct ufs_hba *hba)
 }
 
 static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
 	struct phy *generic_phy = ufs->phy;
-	struct ufs_host_params host_params;
 	int ret;
 
 	if (!dev_req_params) {
@@ -832,18 +830,6 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
 		goto out;
 	}
 
-	ufshcd_init_host_params(&host_params);
-
-	/* This driver only support symmetric gear setting e.g. hs_tx_gear == hs_rx_gear */
-	host_params.hs_tx_gear = exynos_ufs_get_hs_gear(hba);
-	host_params.hs_rx_gear = exynos_ufs_get_hs_gear(hba);
-
-	ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
-	if (ret) {
-		pr_err("%s: failed to determine capabilities\n", __func__);
-		goto out;
-	}
-
 	if (ufs->drv_data->pre_pwr_change)
 		ufs->drv_data->pre_pwr_change(ufs, dev_req_params);
 
@@ -1677,17 +1663,30 @@ static int exynos_ufs_link_startup_notify(struct ufs_hba *hba,
 	return ret;
 }
 
+static int exynos_ufs_negotiate_pwr_mode(struct ufs_hba *hba,
+					 const struct ufs_pa_layer_attr *dev_max_params,
+					 struct ufs_pa_layer_attr *dev_req_params)
+{
+	struct ufs_host_params host_params;
+
+	ufshcd_init_host_params(&host_params);
+
+	/* This driver only support symmetric gear setting e.g. hs_tx_gear == hs_rx_gear */
+	host_params.hs_tx_gear = exynos_ufs_get_hs_gear(hba);
+	host_params.hs_rx_gear = exynos_ufs_get_hs_gear(hba);
+
+	return ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
+}
+
 static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	int ret = 0;
 
 	switch (status) {
 	case PRE_CHANGE:
-		ret = exynos_ufs_pre_pwr_mode(hba, dev_max_params,
-					      dev_req_params);
+		ret = exynos_ufs_pre_pwr_mode(hba, dev_req_params);
 		break;
 	case POST_CHANGE:
 		ret = exynos_ufs_post_pwr_mode(hba, dev_req_params);
@@ -2015,6 +2014,7 @@ static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.exit				= exynos_ufs_exit,
 	.hce_enable_notify		= exynos_ufs_hce_enable_notify,
 	.link_startup_notify		= exynos_ufs_link_startup_notify,
+	.negotiate_pwr_mode		= exynos_ufs_negotiate_pwr_mode,
 	.pwr_change_notify		= exynos_ufs_pwr_change_notify,
 	.setup_clocks			= exynos_ufs_setup_clocks,
 	.setup_xfer_req			= exynos_ufs_specify_nexus_t_xfer_req,
diff --git a/drivers/ufs/host/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c
index 6f2e6bf31225..993e20ac211d 100644
--- a/drivers/ufs/host/ufs-hisi.c
+++ b/drivers/ufs/host/ufs-hisi.c
@@ -298,6 +298,17 @@ static void ufs_hisi_set_dev_cap(struct ufs_host_params *host_params)
 	ufshcd_init_host_params(host_params);
 }
 
+static int ufs_hisi_negotiate_pwr_mode(struct ufs_hba *hba,
+				       const struct ufs_pa_layer_attr *dev_max_params,
+				       struct ufs_pa_layer_attr *dev_req_params)
+{
+	struct ufs_host_params host_params;
+
+	ufs_hisi_set_dev_cap(&host_params);
+
+	return ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
+}
+
 static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba)
 {
 	struct ufs_hisi_host *host = ufshcd_get_variant(hba);
@@ -362,10 +373,8 @@ static void ufs_hisi_pwr_change_pre_change(struct ufs_hba *hba)
 
 static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
-	struct ufs_host_params host_params;
 	int ret = 0;
 
 	if (!dev_req_params) {
@@ -377,14 +386,6 @@ static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba,
 
 	switch (status) {
 	case PRE_CHANGE:
-		ufs_hisi_set_dev_cap(&host_params);
-		ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
-		if (ret) {
-			dev_err(hba->dev,
-			    "%s: failed to determine capabilities\n", __func__);
-			goto out;
-		}
-
 		ufs_hisi_pwr_change_pre_change(hba);
 		break;
 	case POST_CHANGE:
@@ -543,6 +544,7 @@ static const struct ufs_hba_variant_ops ufs_hba_hi3660_vops = {
 	.name = "hi3660",
 	.init = ufs_hi3660_init,
 	.link_startup_notify = ufs_hisi_link_startup_notify,
+	.negotiate_pwr_mode = ufs_hisi_negotiate_pwr_mode,
 	.pwr_change_notify = ufs_hisi_pwr_change_notify,
 	.suspend = ufs_hisi_suspend,
 	.resume = ufs_hisi_resume,
@@ -552,6 +554,7 @@ static const struct ufs_hba_variant_ops ufs_hba_hi3670_vops = {
 	.name = "hi3670",
 	.init = ufs_hi3670_init,
 	.link_startup_notify = ufs_hisi_link_startup_notify,
+	.negotiate_pwr_mode = ufs_hisi_negotiate_pwr_mode,
 	.pwr_change_notify = ufs_hisi_pwr_change_notify,
 	.suspend = ufs_hisi_suspend,
 	.resume = ufs_hisi_resume,
diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 05892b9ac528..7b45cf0428af 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1317,6 +1317,23 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	return err;
 }
 
+static int ufs_mtk_negotiate_pwr_mode(struct ufs_hba *hba,
+				      const struct ufs_pa_layer_attr *dev_max_params,
+				      struct ufs_pa_layer_attr *dev_req_params)
+{
+	struct ufs_host_params host_params;
+
+	ufshcd_init_host_params(&host_params);
+	host_params.hs_rx_gear = UFS_HS_G5;
+	host_params.hs_tx_gear = UFS_HS_G5;
+
+	if (dev_max_params->pwr_rx == SLOW_MODE ||
+	    dev_max_params->pwr_tx == SLOW_MODE)
+		host_params.desired_working_mode = UFS_PWM_MODE;
+
+	return ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
+}
+
 static bool ufs_mtk_pmc_via_fastauto(struct ufs_hba *hba,
 				     struct ufs_pa_layer_attr *dev_req_params)
 {
@@ -1372,26 +1389,10 @@ static void ufs_mtk_adjust_sync_length(struct ufs_hba *hba)
 }
 
 static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	struct ufs_mtk_host *host = ufshcd_get_variant(hba);
-	struct ufs_host_params host_params;
-	int ret;
-
-	ufshcd_init_host_params(&host_params);
-	host_params.hs_rx_gear = UFS_HS_G5;
-	host_params.hs_tx_gear = UFS_HS_G5;
-
-	if (dev_max_params->pwr_rx == SLOW_MODE ||
-	    dev_max_params->pwr_tx == SLOW_MODE)
-		host_params.desired_working_mode = UFS_PWM_MODE;
-
-	ret = ufshcd_negotiate_pwr_params(&host_params, dev_max_params, dev_req_params);
-	if (ret) {
-		pr_info("%s: failed to determine capabilities\n",
-			__func__);
-	}
+	int ret = 0;
 
 	if (ufs_mtk_pmc_via_fastauto(hba, dev_req_params)) {
 		ufs_mtk_adjust_sync_length(hba);
@@ -1503,7 +1504,6 @@ static int ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba)
 
 static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status stage,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	int ret = 0;
@@ -1515,8 +1515,7 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba,
 			reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER);
 			ufs_mtk_auto_hibern8_disable(hba);
 		}
-		ret = ufs_mtk_pre_pwr_change(hba, dev_max_params,
-					     dev_req_params);
+		ret = ufs_mtk_pre_pwr_change(hba, dev_req_params);
 		break;
 	case POST_CHANGE:
 		if (ufshcd_is_auto_hibern8_supported(hba))
@@ -2318,6 +2317,7 @@ static const struct ufs_hba_variant_ops ufs_hba_mtk_vops = {
 	.setup_clocks        = ufs_mtk_setup_clocks,
 	.hce_enable_notify   = ufs_mtk_hce_enable_notify,
 	.link_startup_notify = ufs_mtk_link_startup_notify,
+	.negotiate_pwr_mode  = ufs_mtk_negotiate_pwr_mode,
 	.pwr_change_notify   = ufs_mtk_pwr_change_notify,
 	.apply_dev_quirks    = ufs_mtk_apply_dev_quirks,
 	.fixup_dev_quirks    = ufs_mtk_fixup_dev_quirks,
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 375fd24ba458..cdc769886e82 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -966,13 +966,21 @@ static void ufs_qcom_set_tx_hs_equalizer(struct ufs_hba *hba, u32 gear, u32 tx_l
 	}
 }
 
-static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
-				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
-				struct ufs_pa_layer_attr *dev_req_params)
+static int ufs_qcom_negotiate_pwr_mode(struct ufs_hba *hba,
+				       const struct ufs_pa_layer_attr *dev_max_params,
+				       struct ufs_pa_layer_attr *dev_req_params)
 {
 	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 	struct ufs_host_params *host_params = &host->host_params;
+
+	return ufshcd_negotiate_pwr_params(host_params, dev_max_params, dev_req_params);
+}
+
+static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
+				      enum ufs_notify_change_status status,
+				      struct ufs_pa_layer_attr *dev_req_params)
+{
+	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
 	int ret = 0;
 
 	if (!dev_req_params) {
@@ -982,13 +990,6 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
 
 	switch (status) {
 	case PRE_CHANGE:
-		ret = ufshcd_negotiate_pwr_params(host_params, dev_max_params, dev_req_params);
-		if (ret) {
-			dev_err(hba->dev, "%s: failed to determine capabilities\n",
-					__func__);
-			return ret;
-		}
-
 		/*
 		 * During UFS driver probe, always update the PHY gear to match the negotiated
 		 * gear, so that, if quirk UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH is enabled,
@@ -2341,6 +2342,7 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
 	.setup_clocks           = ufs_qcom_setup_clocks,
 	.hce_enable_notify      = ufs_qcom_hce_enable_notify,
 	.link_startup_notify    = ufs_qcom_link_startup_notify,
+	.negotiate_pwr_mode	= ufs_qcom_negotiate_pwr_mode,
 	.pwr_change_notify	= ufs_qcom_pwr_change_notify,
 	.apply_dev_quirks	= ufs_qcom_apply_dev_quirks,
 	.fixup_dev_quirks       = ufs_qcom_fixup_dev_quirks,
diff --git a/drivers/ufs/host/ufs-sprd.c b/drivers/ufs/host/ufs-sprd.c
index 65bd8fb96b99..a5e8c591bead 100644
--- a/drivers/ufs/host/ufs-sprd.c
+++ b/drivers/ufs/host/ufs-sprd.c
@@ -161,14 +161,11 @@ static int ufs_sprd_common_init(struct ufs_hba *hba)
 
 static int sprd_ufs_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	struct ufs_sprd_host *host = ufshcd_get_variant(hba);
 
 	if (status == PRE_CHANGE) {
-		memcpy(dev_req_params, dev_max_params,
-			sizeof(struct ufs_pa_layer_attr));
 		if (host->unipro_ver >= UFS_UNIPRO_VER_1_8)
 			ufshcd_dme_configure_adapt(hba, dev_req_params->gear_tx,
 						   PA_INITIAL_ADAPT);
diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c
index 5f65dfad1a71..8a4f2381a32e 100644
--- a/drivers/ufs/host/ufshcd-pci.c
+++ b/drivers/ufs/host/ufshcd-pci.c
@@ -145,7 +145,7 @@ static int ufs_intel_set_lanes(struct ufs_hba *hba, u32 lanes)
 
 	pwr_info.lane_rx = lanes;
 	pwr_info.lane_tx = lanes;
-	ret = ufshcd_config_pwr_mode(hba, &pwr_info);
+	ret = ufshcd_change_power_mode(hba, &pwr_info);
 	if (ret)
 		dev_err(hba->dev, "%s: Setting %u lanes, err = %d\n",
 			__func__, lanes, ret);
@@ -154,17 +154,15 @@ static int ufs_intel_set_lanes(struct ufs_hba *hba, u32 lanes)
 
 static int ufs_intel_lkf_pwr_change_notify(struct ufs_hba *hba,
 				enum ufs_notify_change_status status,
-				const struct ufs_pa_layer_attr *dev_max_params,
 				struct ufs_pa_layer_attr *dev_req_params)
 {
 	int err = 0;
 
 	switch (status) {
 	case PRE_CHANGE:
-		if (ufshcd_is_hs_mode(dev_max_params) &&
+		if (ufshcd_is_hs_mode(dev_req_params) &&
 		    (hba->pwr_info.lane_rx != 2 || hba->pwr_info.lane_tx != 2))
 			ufs_intel_set_lanes(hba, 2);
-		memcpy(dev_req_params, dev_max_params, sizeof(*dev_req_params));
 		break;
 	case POST_CHANGE:
 		if (ufshcd_is_hs_mode(dev_req_params)) {
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index 8563b6648976..51c2555bea73 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -302,11 +302,10 @@ struct ufs_pwr_mode_info {
  *                     variant specific Uni-Pro initialization.
  * @link_startup_notify: called before and after Link startup is carried out
  *                       to allow variant specific Uni-Pro initialization.
+ * @negotiate_pwr_mode: called to negotiate power mode.
  * @pwr_change_notify: called before and after a power mode change
  *			is carried out to allow vendor spesific capabilities
- *			to be set. PRE_CHANGE can modify final_params based
- *			on desired_pwr_mode, but POST_CHANGE must not alter
- *			the final_params parameter
+ *			to be set.
  * @setup_xfer_req: called before any transfer request is issued
  *                  to set some things
  * @setup_task_mgmt: called before any task management request is issued
@@ -347,10 +346,12 @@ struct ufs_hba_variant_ops {
 				     enum ufs_notify_change_status);
 	int	(*link_startup_notify)(struct ufs_hba *,
 				       enum ufs_notify_change_status);
-	int	(*pwr_change_notify)(struct ufs_hba *,
-			enum ufs_notify_change_status status,
-			const struct ufs_pa_layer_attr *desired_pwr_mode,
-			struct ufs_pa_layer_attr *final_params);
+	int	(*negotiate_pwr_mode)(struct ufs_hba *hba,
+				      const struct ufs_pa_layer_attr *desired_pwr_mode,
+				      struct ufs_pa_layer_attr *final_params);
+	int	(*pwr_change_notify)(struct ufs_hba *hba,
+				     enum ufs_notify_change_status status,
+				     struct ufs_pa_layer_attr *final_params);
 	void	(*setup_xfer_req)(struct ufs_hba *hba, int tag,
 				  bool is_scsi_cmd);
 	void	(*setup_task_mgmt)(struct ufs_hba *, int, u8);
@@ -1361,6 +1362,8 @@ extern int ufshcd_dme_set_attr(struct ufs_hba *hba, u32 attr_sel,
 			       u8 attr_set, u32 mib_val, u8 peer);
 extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
 			       u32 *mib_val, u8 peer);
+extern int ufshcd_change_power_mode(struct ufs_hba *hba,
+				    struct ufs_pa_layer_attr *pwr_mode);
 extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
 			struct ufs_pa_layer_attr *desired_pwr_mode);
 extern int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode);
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 00/12] scsi: ufs: Add TX Equalization support for UFS 5.0
From: Can Guo @ 2026-03-25 15:21 UTC (permalink / raw)
  To: avri.altman, bvanassche, beanhuo, peter.wang, martin.petersen,
	mani
  Cc: linux-scsi, Can Guo, Matthias Brugger, AngeloGioacchino Del Regno,
	open list:ARM/Mediatek SoC support:Keyword:mediatek,
	moderated list:ARM/Mediatek SoC support:Keyword:mediatek,
	moderated list:ARM/Mediatek SoC support:Keyword:mediatek

Hi,

The UFS v5.0 and UFSHCI v5.0 standards have published, introducing support
for HS-G6 (46.6 Gbps per lane) through the new UniPro V3.0 interconnect
layer and M-PHY V6.0 physical layer specifications. To achieve reliable
operation at these higher speeds, UniPro V3.0 introduces TX Equalization
and Pre-Coding mechanisms that are essential for signal integrity.

This patch series implements TX Equalization support in the UFS core
driver as specified in UFSHCI v5.0, along with the necessary vendor
operations and a reference implementation for Qualcomm UFS host
controllers.

Background
==========

TX Equalization is a signal conditioning technique that compensates for
channel impairments at high data rates (HS-G4 through HS-G6). It works
by adjusting two key parameters:

- PreShoot: Pre-emphasis applied before the main signal transition
- DeEmphasis: De-emphasis applied after the main signal transition

UniPro V3.0 defines TX Equalization Training (EQTR) procedure to
automatically discover optimal TX Equalization settings. The EQTR
procedure:

1. Starts from the most reliable link state (HS-G1)
2. Iterates through all possible PreShoot and DeEmphasis combinations
3. Evaluates signal quality using Figure of Merit (FOM) measurements
4. Selects the best settings for both host and device TX lanes

For HS-G6, Pre-Coding is also introduced to further improve signal
quality. Pre-Coding must be enabled on both transmitter and receiver
when the RX_FOM indicates it is required.

Implementation Overview
=======================

The implementation follows the UFSHCI v5.0 specification and consists of:

Core Infrastructure (Patches 1-6):
- New vops callback negotiate_pwr_mode() to allow vendors to negotiate
  power mode parameters before applying TX Equalization settings
- Support for HS-G6 gear enumeration
- Complete TX EQTR procedure implementation in ufs-txeq.c
- Debugfs interface for TX Equalization parameter inspection and manual
  retraining
- Module parameters for adaptive TX Equalization control

Qualcomm Implementation (Patches 7-11):
- PHY-specific configurations for TX EQTR procedure
- Vendor-specific FOM measurement support
- TX Equalization settings application
- Enable TX Equalization for HW version 0x7 and onwards

The implementation is designed to be vendor-agnostic, with platform-
specific details handled through the vops callbacks. Other vendors can
add support by implementing the three new vops:

- tx_eqtr_notify(): Called before/after TX EQTR for vendor setup
- apply_tx_eqtr_settings(): Apply vendor-specific PHY configurations
- get_rx_fom(): Retrieve vendor-specific FOM measurements if needed

Module Parameters
=================

The implementation provides several module parameters for flexibility:

- use_adaptive_txeq: Enable/disable adaptive TX Equalization (default: false)
- adaptive_txeq_gear: Minimum gear for adaptive TX EQ (default: HS-G6)
- use_txeq_presets: Use only the 8 standaird presets (default: false)
- txeq_presets_selected[]: Select specific presets for EQTR

Testing
=======

This patch series has been tested on Qualcomm platforms with UFS 5.0
devices, validating:

- Successful TX EQTR completion for HS-G6
- Proper FOM evaluation and optimal settings selection
- Pre-Coding enablement for HS-G6
- Power mode changes with TX Equalization settings applied
- Report of TX Equalization settings via debugfs entries
- Report of TX EQTR histories via debug entries (see next section)
- Re-training TX Equalization via debugfs entry

Example of TX EQTR history
==========================

# cat /sys/kernel/debug/ufshcd/*ufshcd*/tx_eq_hs_gear6/device_tx_eqtr_record
Device TX EQTR record summary -
Target Power Mode: HS-G6, Rate-B
Most recent record index: 2
Most recent record timestamp: 219573378 us

TX Lane 0 FOM - PreShoot\DeEmphasis
\       0        1        2        3        4        5        6        7
0      50       70       65        -        -        -        -        x
1       x        x        x        x        x        x        x        x
2     100       90       70        -        -        -        -        x
3       x        x        x        x        x        x        x        x
4      95       90        -        -        -        -        -        x
5       -        -        -        -        -        -        -        x
6       x        x        x        x        x        x        x        x
7       x        x        x        x        x        x        x        x

TX Lane 1 FOM - PreShoot\DeEmphasis
\       0        1        2        3        4        5        6        7
0      50       70       60        -        -        -        -        x
1       x        x        x        x        x        x        x        x
2     100       80       65        -        -        -        -        x
3       x        x        x        x        x        x        x        x
4      95       85        -        -        -        -        -        x
5       -        -        -        -        -        -        -        x
6       x        x        x        x        x        x        x        x
7       x        x        x        x        x        x        x        x

Patch Structure
===============

Patches 1-3: Preparatory changes for power mode negotiation and HS-G6
Patch 4: Core TX Equalization and EQTR implementation
Patches 5-7: Debugfs support for TX Equalization
Patches 8-12: Qualcomm vendor implementation

Next
====

One more series has been developed to enhance TX Equalization support,
which will be submitted for review after this series is accepted:

- Provide board specific (static) TX Equalization settings from DTS
- Parse static TX Equalization settings from DTS if provided
- Apply static TX Equalization settings if use_adaptive_txeq is disabled
- Add support for UFS v5.0 attributes qTxEQGnSettings & wTxEQGnSettingsExt
- Enable persistent storage and retrieval of optimal TX Equalization settings

v4 -> v5:
1. Addressed comments from Bean in patch 7, returned -EINVAL when
   negotiated gear != requested gear in function ufshcd_retrain_tx_eq().
2. Addressed comments from Peter in patch 4, moved usage of
   &hba->tx_eq_params[gear - 1] after checks on gear and improved the
   checks on gear in function ufshcd_config_tx_eq_settings().

v3 -> v4:
1. Incorporated comments from Bart and Peter.
2. In patch 1, removed redundant checks on dev_req_params
3. In patch 1, moved error prints out of vops negotiate_pwr_mode()
4. In patch 1, removed vops implemenation ufs_versal2_negotiate_pwr_mode(),
   sprd_ufs_negotiate_pwr_mode() and ufs_intel_lkf_negotiate_pwr_mode() as
   they are simply doing memcpy().
5. In patch 3, initialize UFS_HS_GEAR_MAX as UFS_HS_G6. 
6. In patch 4, adjusted places where UFS_HS_GEAR_MAX is used.
7. In patch 4, defined inline func ufs_hs_rate_to_str() instead of macro.
8. In patch 4, changed default value of use_txeq_presets to 'false'.
8. In patch 4, optimized ufshcd_tx_eq_params and ufshcd_tx_eq_settings.
9. In patch 4, optimized memory usage of ufshcd_tx_eq_params.
10. In patch 5, updated places which use fields in ufshcd_tx_eq_params.
11. In patch 7, used 'retrain' instead of 'refresh'.
12. In patch 10, introduced a few macros.

v2 -> v3:
1. Incorporated comments from Bart, Bean and Mani.
2. In patch 4, made ufshcd_config_pwr_mode() ignore TX EQTR error.
3. Added patch 6 to introduce helpers to pause/resume command processing.
4. In patch 7, changed debugfs entry to 'tx_eq_ctrl' and used 'refresh'
   as input to trigger TX Equalization refreshing.
5. In patch 7, renamed ufshcd_retrain_tx_eq() to ufshcd_refresh_tx_eq().
6. Fixed typos and coding style issues.

v1 -> v2:
1. Incorporated Bart's comments.
2. Fixed typos and coding style issues.
3. Added enum ufshcd_pmc_policy and use enum instead of boolen parameter.
4. Updated TX Equalization debugfs entries structure.
5. Extracted ufshcd_pause/resume_command_processing() in ufshcd.c.
6. Updated sequence in Qualcomm's vops get_rx_fom() implementation.

Can Guo (12):
  scsi: ufs: core: Introduce a new ufshcd vops negotiate_pwr_mode()
  scsi: ufs: core: Pass force_pmc to ufshcd_config_pwr_mode() as a
    parameter
  scsi: ufs: core: Add UFS_HS_G6 and UFS_HS_GEAR_MAX to enum
    ufs_hs_gear_tag
  scsi: ufs: core: Add support for TX Equalization
  scsi: ufs: core: Add debugfs entries for TX Equalization params
  scsi: ufs: core: Add helpers to pause and resume command processing
  scsi: ufs: core: Add support to retrain TX Equalization via debugfs
  scsi: ufs: ufs-qcom: Fixup PAM-4 TX L0_L1_L2_L3 adaptation pattern
    length
  scsi: ufs: ufs-qcom: Implement vops tx_eqtr_notify()
  scsi: ufs: ufs-qcom: Implement vops get_rx_fom()
  scsi: ufs: ufs-qcom: Implement vops apply_tx_eqtr_settings()
  scsi: ufs: ufs-qcom: Enable TX Equalization

 drivers/ufs/core/Makefile          |    2 +-
 drivers/ufs/core/ufs-debugfs.c     |  290 +++++++
 drivers/ufs/core/ufs-txeq.c        | 1293 ++++++++++++++++++++++++++++
 drivers/ufs/core/ufshcd-priv.h     |   59 +-
 drivers/ufs/core/ufshcd.c          |  192 ++++-
 drivers/ufs/host/ufs-amd-versal2.c |    3 -
 drivers/ufs/host/ufs-exynos.c      |   34 +-
 drivers/ufs/host/ufs-hisi.c        |   23 +-
 drivers/ufs/host/ufs-mediatek.c    |   40 +-
 drivers/ufs/host/ufs-qcom.c        |  591 ++++++++++++-
 drivers/ufs/host/ufs-qcom.h        |   42 +
 drivers/ufs/host/ufs-sprd.c        |    3 -
 drivers/ufs/host/ufshcd-pci.c      |    7 +-
 include/ufs/ufshcd.h               |  174 +++-
 include/ufs/unipro.h               |  141 ++-
 15 files changed, 2779 insertions(+), 115 deletions(-)
 create mode 100644 drivers/ufs/core/ufs-txeq.c

-- 
2.34.1



^ permalink raw reply

* Re: [PATCH v1] media: rkisp1: Add support for CAC
From: Jacopo Mondi @ 2026-03-25 15:21 UTC (permalink / raw)
  To: Barnabás Pőcze
  Cc: Dafna Hirschfeld, Laurent Pinchart, Mauro Carvalho Chehab,
	Heiko Stuebner, linux-media, linux-rockchip, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20260323140216.1486161-1-barnabas.pocze@ideasonboard.com>

Hi Barnabás

On Mon, Mar 23, 2026 at 03:02:16PM +0100, Barnabás Pőcze wrote:
> The CAC block implements chromatic aberration correction. Expose it to
> userspace using the extensible parameters format. This was tested on the
> i.MX8MP platform, but based on available documentation it is also present
> in the RK3399 variant (V10). Thus presumably also in later versions,
> so no feature flag is introduced.
>
> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>

Only minors..

> ---
>  .../platform/rockchip/rkisp1/rkisp1-params.c  |  69 ++++++++++++
>  .../platform/rockchip/rkisp1/rkisp1-regs.h    |  21 +++-
>  include/uapi/linux/rkisp1-config.h            | 106 +++++++++++++++++-
>  3 files changed, 193 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> index 6442436a5e428..b889af9dcee45 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> @@ -64,6 +64,7 @@ union rkisp1_ext_params_config {
>  	struct rkisp1_ext_params_compand_bls_config compand_bls;
>  	struct rkisp1_ext_params_compand_curve_config compand_curve;
>  	struct rkisp1_ext_params_wdr_config wdr;
> +	struct rkisp1_ext_params_cac_config cac;
>  };
>
>  enum rkisp1_params_formats {
> @@ -1413,6 +1414,48 @@ static void rkisp1_wdr_config(struct rkisp1_params *params,
>  				     RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);
>  }
>
> +static void
> +rkisp1_cac_config(struct rkisp1_params *params,
> +		  const struct rkisp1_cif_isp_cac_config *arg)

Fits in one line without going over 80 cols

> +{
> +	u32 regval;
> +
> +	/*
> +	 * The enable bit is in the same register (RKISP1_CIF_ISP_CAC_CTRL),
> +	 * so only set the clipping mode, and do not modify the other bits.
> +	 */
> +	regval = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL);
> +	regval &= ~(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE |
> +		    RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE);
> +	regval |= FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE, arg->h_clip_mode) |
> +		  FIELD_PREP(RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE, arg->v_clip_mode);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_CTRL, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK, arg->h_count_start) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK, arg->v_count_start);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_COUNT_START, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_A_RED_MASK, arg->red[0]) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_A_BLUE_MASK, arg->blue[0]);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_A, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_B_RED_MASK, arg->red[1]) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_B_BLUE_MASK, arg->blue[1]);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_B, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_C_RED_MASK, arg->red[2]) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_C_BLUE_MASK, arg->blue[2]);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_C, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK, arg->x_nf) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK, arg->x_ns);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_X_NORM, regval);
> +
> +	regval = FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK, arg->y_nf) |
> +		 FIELD_PREP(RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK, arg->y_ns);
> +	rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CAC_Y_NORM, regval);
> +}
> +
>  static void
>  rkisp1_isp_isr_other_config(struct rkisp1_params *params,
>  			    const struct rkisp1_params_cfg *new_params)
> @@ -2089,6 +2132,25 @@ static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
>  				      RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
>  }
>
> +static void rkisp1_ext_params_cac(struct rkisp1_params *params,
> +				  const union rkisp1_ext_params_config *block)
> +{
> +	const struct rkisp1_ext_params_cac_config *cac = &block->cac;
> +
> +	if (cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
> +		rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> +					RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
> +		return;
> +	}
> +
> +	rkisp1_cac_config(params, &cac->config);
> +
> +	if ((cac->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
> +	    !(params->enabled_blocks & BIT(cac->header.type)))
> +		rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> +				      RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
> +}
> +
>  typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
>  			     const union rkisp1_ext_params_config *config);
>
> @@ -2185,6 +2247,10 @@ static const struct rkisp1_ext_params_handler {
>  		.handler	= rkisp1_ext_params_wdr,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC] = {
> +		.handler	= rkisp1_ext_params_cac,
> +		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> +	},
>  };
>
>  #define RKISP1_PARAMS_BLOCK_INFO(block, data) \
> @@ -2215,6 +2281,7 @@ rkisp1_ext_params_block_types_info[] = {
>  	RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
>  	RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
>  	RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),
> +	RKISP1_PARAMS_BLOCK_INFO(CAC, cac),
>  };
>
>  static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==
> @@ -2474,6 +2541,8 @@ void rkisp1_params_disable(struct rkisp1_params *params)
>  	rkisp1_ie_enable(params, false);
>  	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
>  				RKISP1_CIF_ISP_DPF_MODE_EN);
> +	rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CAC_CTRL,
> +				RKISP1_CIF_ISP_CAC_CTRL_ENABLE);
>  }
>
>  static const struct rkisp1_params_ops rkisp1_v10_params_ops = {
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> index fbeb186cde0d5..8e25537459bbd 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
> @@ -724,6 +724,23 @@
>  #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK		GENMASK(20, 16)
>  #define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX		16U
>
> +/* CAC */
> +#define RKISP1_CIF_ISP_CAC_CTRL_ENABLE		BIT(0)
> +#define RKISP1_CIF_ISP_CAC_CTRL_V_CLIP_MODE	GENMASK(2, 1)
> +#define RKISP1_CIF_ISP_CAC_CTRL_H_CLIP_MODE	GENMASK(3, 3)
> +#define RKISP1_CIF_ISP_CAC_COUNT_START_H_MASK	GENMASK(12, 0)
> +#define RKISP1_CIF_ISP_CAC_COUNT_START_V_MASK	GENMASK(28, 16)
> +#define RKISP1_CIF_ISP_CAC_A_RED_MASK		GENMASK(8, 0)
> +#define RKISP1_CIF_ISP_CAC_A_BLUE_MASK		GENMASK(24, 16)
> +#define RKISP1_CIF_ISP_CAC_B_RED_MASK		GENMASK(8, 0)
> +#define RKISP1_CIF_ISP_CAC_B_BLUE_MASK		GENMASK(24, 16)
> +#define RKISP1_CIF_ISP_CAC_C_RED_MASK		GENMASK(8, 0)
> +#define RKISP1_CIF_ISP_CAC_C_BLUE_MASK		GENMASK(24, 16)

All these masks for coefficients 0, 1 and 2 are identical. Maybe
#define RKISP1_CIF_ISP_CAC_RED_MASK		GENMASK(8, 0)
#define RKISP1_CIF_ISP_CAC_BLUE_MASK		GENMASK(24, 16)

is enough

> +#define RKISP1_CIF_ISP_CAC_X_NORM_NF_MASK	GENMASK(4, 0)
> +#define RKISP1_CIF_ISP_CAC_X_NORM_NS_MASK	GENMASK(19, 16)
> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NF_MASK	GENMASK(4, 0)
> +#define RKISP1_CIF_ISP_CAC_Y_NORM_NS_MASK	GENMASK(19, 16)
> +
>  /* =================================================================== */
>  /*                            CIF Registers                            */
>  /* =================================================================== */
> @@ -1196,8 +1213,8 @@
>  #define RKISP1_CIF_ISP_CAC_A			(RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
>  #define RKISP1_CIF_ISP_CAC_B			(RKISP1_CIF_ISP_CAC_BASE + 0x0000000c)
>  #define RKISP1_CIF_ISP_CAC_C			(RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
> -#define RKISP1_CIF_ISP_X_NORM			(RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
> -#define RKISP1_CIF_ISP_Y_NORM			(RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
> +#define RKISP1_CIF_ISP_CAC_X_NORM		(RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
> +#define RKISP1_CIF_ISP_CAC_Y_NORM		(RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
>
>  #define RKISP1_CIF_ISP_EXP_BASE			0x00002600
>  #define RKISP1_CIF_ISP_EXP_CTRL			(RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
> diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
> index b2d2a71f7baff..d8acccaddd0e9 100644
> --- a/include/uapi/linux/rkisp1-config.h
> +++ b/include/uapi/linux/rkisp1-config.h
> @@ -967,6 +967,92 @@ struct rkisp1_cif_isp_wdr_config {
>  	__u8 use_iref;
>  };
>
> +/*
> + * enum rkisp1_cif_isp_cac_h_clip_mode - horizontal clipping mode
> + *
> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX: +/- 4 pixels
> + * @RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX: +/- 4/5 pixels depending on bayer position
> + */
> +enum rkisp1_cif_isp_cac_h_clip_mode {
> +	RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4PX = 0,
> +	RKISP1_CIF_ISP_CAC_H_CLIP_MODE_4_5PX = 1,
> +};
> +
> +/**
> + * enum rkisp1_cif_isp_cac_v_clip_mode - vertical clipping mode
> + *
> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX: +/- 2 pixels
> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX: +/- 3 pixels
> + * @RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX: +/- 3/4 pixels depending on bayer position
> + */
> +enum rkisp1_cif_isp_cac_v_clip_mode {
> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_2PX = 0,
> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3PX = 1,
> +	RKISP1_CIF_ISP_CAC_V_CLIP_MODE_3_4PX = 2,
> +};
> +
> +/**
> + * struct rkisp1_cif_isp_cac_config - chromatic aberration correction configuration
> + *
> + * The correction is carried out by shifting the red and blue pixels relative
> + * to the green ones, depending on the distance from the optical center:

Yes, the distance to the center is one parameter, but the shifting
amount depends on other things. I would drop the last part of the
sentence and move the description of the two below fields after the
text

> + *
> + * @h_count_start: horizontal coordinate of the optical center (13-bit unsigned integer; [1,8191])
> + * @v_count_start: vertical coordinate of the optical center (13-bit unsigned integer; [1,8191])

so these could go just before @x_nf

> + *
> + * For each pixel, the x/y distances from the optical center are calculated and

I forgot: did we establish that the correction is applied to the
euclidean distance or to x and y separately ?

> + * then transformed into the [0,255] range based on the following formula:

s/transformed/normalized ?

> + *
> + *   (((d << 4) >> s) * f) >> 5
> + *
> + * where `d` is the distance, `s` and `f` are the normalization parameters:

Can you use 'ns' and 'nf' to match the below ?

> + *
> + * @x_nf: horizontal normalization scale parameter (5-bit unsigned integer; [0,31])
> + * @x_ns: horizontal normalization shift parameter (4-bit unsigned integer; [0,15])
> + *
> + * @y_nf: vertical normalization scale parameter (5-bit unsigned integer; [0,31])
> + * @y_ns: vertical normalization shift parameter (4-bit unsigned integer; [0,15])
> + *
> + * These parameters should be chosen based on the image resolution, the position
> + * of the optical center, and the shape of pixels: so that no normalized distance

s/pixels:/pixels/

> + * is larger than 255. If the pixels have square shape, the two sets of parameters
> + * should be equal.
> + *
> + * The actual amount of correction is calculated with a third degree polynomial:
> + *
> + *   c[0] * r + c[1] * r^2 + c[2] * r^3
> + *
> + * where `c` is the set of coefficients for the given color, and `r` is distance:
> + *
> + * @red: red coefficients (5.4 two's complement; [-16,15.9375])
> + * @blue: blue coefficients (5.4 two's complement; [-16,15.9375])
> + *
> + * Finally, the amount is clipped as requested:
> + *
> + * @h_clip_mode: maximum horizontal shift (from enum rkisp1_cif_isp_cac_h_clip_mode)
> + * @v_clip_mode: maximum vertical shift (from enum rkisp1_cif_isp_cac_v_clip_mode)
> + *
> + * A positive result will shift away from the optical center, while a negative
> + * one will shift towards the optical center. In the latter case, the pixel
> + * values at the edges are duplicated.
> + */
> +struct rkisp1_cif_isp_cac_config {
> +	__u8 h_clip_mode;
> +	__u8 v_clip_mode;
> +
> +	__u16 h_count_start;
> +	__u16 v_count_start;
> +
> +	__u16 red[3];
> +	__u16 blue[3];
> +
> +	__u8 x_nf;
> +	__u8 x_ns;
> +
> +	__u8 y_nf;
> +	__u8 y_ns;
> +};
> +
>  /*---------- PART2: Measurement Statistics ------------*/
>
>  /**
> @@ -1161,6 +1247,7 @@ enum rkisp1_ext_params_block_type {
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
>  	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
> +	RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC,
>  };
>
>  /* For backward compatibility */
> @@ -1507,6 +1594,22 @@ struct rkisp1_ext_params_wdr_config {
>  	struct rkisp1_cif_isp_wdr_config config;
>  } __attribute__((aligned(8)));
>
> +/**
> + * struct rkisp1_ext_params_cac_config - RkISP1 extensible params CAC config
> + *
> + * RkISP1 extensible parameters CAC block.
> + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CAC`.
> + *
> + * @header: The RkISP1 extensible parameters header, see
> + *	    :c:type:`rkisp1_ext_params_block_header`
> + * @config: CAC configuration, see
> + *	    :c:type:`rkisp1_cif_isp_cac_config`
> + */
> +struct rkisp1_ext_params_cac_config {
> +	struct rkisp1_ext_params_block_header header;
> +	struct rkisp1_cif_isp_cac_config config;
> +} __attribute__((aligned(8)));
> +
>  /*
>   * The rkisp1_ext_params_compand_curve_config structure is counted twice as it
>   * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types.
> @@ -1532,7 +1635,8 @@ struct rkisp1_ext_params_wdr_config {
>  	sizeof(struct rkisp1_ext_params_compand_bls_config)		+\
>  	sizeof(struct rkisp1_ext_params_compand_curve_config)		+\
>  	sizeof(struct rkisp1_ext_params_compand_curve_config)		+\
> -	sizeof(struct rkisp1_ext_params_wdr_config))
> +	sizeof(struct rkisp1_ext_params_wdr_config)			+\
> +	sizeof(struct rkisp1_ext_params_cac_config))

All minors, please add
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Thanks
  j

>
>  /**
>   * enum rksip1_ext_param_buffer_version - RkISP1 extensible parameters version
> --
> 2.53.0
>
>


^ permalink raw reply

* Re: [PATCH] arm64: dts: imx8mp: Add DT overlays for DH i.MX8M Plus DHCOM SoM and boards
From: Frank Li @ 2026-03-25 15:16 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-arm-kernel, Christoph Niedermaier, Conor Dooley,
	Fabio Estevam, Krzysztof Kozlowski, Pengutronix Kernel Team,
	Rob Herring, Sascha Hauer, devicetree, imx, kernel, linux-kernel
In-Reply-To: <e580bc1d-96ce-43c5-880f-bb8ee31fda28@nabladev.com>

On Tue, Mar 24, 2026 at 10:43:25PM +0100, Marek Vasut wrote:
> On 3/24/26 9:00 PM, Frank Li wrote:
> > On Tue, Mar 24, 2026 at 06:39:10PM +0100, Marek Vasut wrote:
> > > On 3/24/26 5:01 PM, Frank Li wrote:
> > > > On Fri, Mar 13, 2026 at 12:24:04AM +0100, Marek Vasut wrote:
> > > > ...
> > > >
> > > > > diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-overlay-panel-ch101olhlwh.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-overlay-panel-ch101olhlwh.dtsi
> > > > > new file mode 100644
> > > > > index 0000000000000..534737363c9f0
> > > > > --- /dev/null
> > > > > +++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-overlay-panel-ch101olhlwh.dtsi
> > > > > @@ -0,0 +1,42 @@
> > > > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > > > +/*
> > > > > + * Copyright (C) 2022 Marek Vasut
> > > >
> > > > 2026?
> > >
> > > That was the original copyright year when this was implemented, but I can
> > > update it to 2022-2026 ?
> >
> > Okay, you upstream this year.
>
> Right, V2 does extend the copyrights until this year.
>
> > > > > + */
> > > > > +
> > > > > +&display_bl {
> > > > > +	pwms = <&pwm1 0 5000000 0>;
> > > > > +};
> > > > > +
> > > > > +&DH_OVERLAY_PANEL_I2C_BUS {
> > > >
> > > > why upcase for label, generally it should be lower case
> > >
> > > Because this label is really a macro , please read on.
> > >
> > > > > +	#address-cells = <1>;
> > > > > +	#size-cells = <0>;
> > > > > +
> > > > > +	touchscreen@41 {
> > > > > +		compatible = "ilitek,ili251x";
> > > > > +		pinctrl-0 = <DH_OVERLAY_PANEL_I2C_TOUCHSCREEN_PINCTRL>;
> > > > > +		pinctrl-names = "default";
> > > > > +		reg = <0x41>;
> > > >
> > > > reg should second property,  please dt-format for new dts files.
> > > > check others
> > > What is "dt-format" ? Linux kernel source tree, even current next, does not
> > > mention such a tool . I did run schema check and checkpatch on these
> > > patches. obv.
> >
> > I send out at many place, https://github.com/lznuaa/dt-format
> > I write small tools to detect and fix node and property order problem,
> > it may be buggy.
> >
> > These node order problem is easy to detected and fix by tools to save
> > review cycle and focus on the important stuff.
> Maybe "make dtbs_check" target could include this tool , to make people
> aware of it ?

Good suggest, but it is not mature and not everyone agree all code style
yet. practice and run at imx project firstly. It is not perfected, but
helpful.

Frank


^ permalink raw reply

* Re: [PATCH v3] PCI: dw-rockchip: Enable async probe by default
From: Danilo Krummrich @ 2026-03-25 15:13 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Robin Murphy, Manivannan Sadhasivam, Manivannan Sadhasivam,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
	Bjorn Helgaas, Heiko Stuebner, Niklas Cassel, Shawn Lin,
	Hans Zhang, Nicolas Frattaroli, Wilfred Mallawa, linux-pci,
	linux-arm-kernel, linux-rockchip, linux-kernel, Anand Moon,
	Grimmauld, Greg Kroah-Hartman, Rafael J. Wysocki, driver-core,
	Lukas Wunner
In-Reply-To: <acNgUoWWMCi1oLU4@google.com>

On Wed Mar 25, 2026 at 5:13 AM CET, Dmitry Torokhov wrote:
> That means that you are kicking the majority devices (for now) into
> deferral path. I do not think this is optimal.

That's not necessary, we'd only need to kick those into the deferral path that
have PROBE_FORCE_SYNCHRONOUS, no?


^ permalink raw reply

* Re: [PATCH bpf-next v10 1/5] bpf: Move constants blinding out of arch-specific JITs
From: Alexei Starovoitov @ 2026-03-25 15:12 UTC (permalink / raw)
  To: Xu Kuohai
  Cc: bot+bpf-ci, bpf, LKML, linux-arm-kernel, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Martin KaFai Lau, Eduard,
	Yonghong Song, Puranjay Mohan, Anton Protopopov,
	Alexis Lothoré (eBPF Foundation), Shahab Vahedi,
	Russell King, Tiezhu Yang, Hengqi Chen, Johan Almbladh,
	Paul Burton, Hari Bathini, Christophe Leroy, Naveen N. Rao,
	Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
	Ilya Leoshkevich, Heiko Carstens, Vasily Gorbik, David S. Miller,
	Wang YanQing, Martin KaFai Lau, Chris Mason, Ihor Solodrai
In-Reply-To: <5b24cd1d-a8cf-4c9c-a0c8-c79c10ea80e4@huaweicloud.com>

On Wed, Mar 25, 2026 at 12:47 AM Xu Kuohai <xukuohai@huaweicloud.com> wrote:
>
> On 3/24/2026 8:46 PM, bot+bpf-ci@kernel.org wrote:
> >> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> >> index 67eb12b637a5..8f52f4b6c3af 100644
> >> --- a/kernel/bpf/core.c
> >> +++ b/kernel/bpf/core.c
> >
> > [ ... ]
> >
> >> @@ -1507,13 +1507,16 @@ static void adjust_insn_arrays(struct bpf_prog *prog, u32 off, u32 len)
> >>   #endif
> >>   }
> >>
> >> -struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
> >> +struct bpf_prog *bpf_jit_blind_constants(struct bpf_verifier_env *env, struct bpf_prog *prog)
> >>   {
> >
> > [ ... ]
> >
> >> -            tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten);
> >> -            if (IS_ERR(tmp)) {
> >> +            if (env)
> >> +                    tmp = bpf_patch_insn_data(env, subprog_start + i, insn_buff, rewritten);
> >> +            else
> >> +                    tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten);
> >
> > When env is non-NULL, bpf_patch_insn_data() adjusts env->insn_aux_data
> > via adjust_insn_aux_data() and env->subprog_info via
> > adjust_subprog_starts(). This shifts subprogram start positions to
> > account for the expanded instructions.
> >
>
> Right, but only the subsequent subprogs are shifted, the current subprog
> is not. Since we are patching the main prog when env is non-NULL, and
> subprog_start is always 0 for a main prog, subprog_start is not needed
> here and can be removed.

sashiko found other bugs too:
https://sashiko.dev/#/patchset/20260324122052.342751-1-xukuohai%40huaweicloud.com

Pls fix them all.


^ permalink raw reply

* Re: [PATCH RESEND v8 3/6] mfd: max77759: add register bitmasks and modify irq configs for charger
From: Lee Jones @ 2026-03-25 15:10 UTC (permalink / raw)
  To: Amit Sunil Dhamne via B4 Relay
  Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	André Draszik, Greg Kroah-Hartman, Badhri Jagan Sridharan,
	Heikki Krogerus, Peter Griffin, Tudor Ambarus, Alim Akhtar,
	Mark Brown, Matti Vaittinen, Andrew Morton, linux-kernel,
	linux-pm, devicetree, linux-usb, linux-arm-kernel,
	linux-samsung-soc, RD Babiera, Kyle Tso, Amit Sunil Dhamne
In-Reply-To: <20260314-max77759-charger-v8-3-226ca5f8c7d2@google.com>

On Sat, 14 Mar 2026, Amit Sunil Dhamne via B4 Relay wrote:

> From: Amit Sunil Dhamne <amitsd@google.com>
> 
> Add register bitmasks for charger function.
> 
> In addition split the charger IRQs further such that each bit represents
> an IRQ downstream of charger regmap irq chip. In addition populate the
> ack_base to offload irq ack to the regmap irq chip framework.
> 
> Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
> Reviewed-by: André Draszik <andre.draszik@linaro.org>
> ---
>  drivers/mfd/max77759.c       |  91 ++++++++++++++++++++--
>  include/linux/mfd/max77759.h | 176 ++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 230 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/mfd/max77759.c b/drivers/mfd/max77759.c
> index a7efe233ec8c..288746f675b8 100644
> --- a/drivers/mfd/max77759.c
> +++ b/drivers/mfd/max77759.c
> @@ -201,8 +201,24 @@ static const struct regmap_config max77759_regmap_config_charger = {
>   *         - SYSUVLO_INT
>   *         - FSHIP_NOT_RD
>   *     - CHGR_INT: charger
> - *       - CHG_INT
> - *       - CHG_INT2
> + *       - INT1
> + *         - AICL
> + *         - CHGIN
> + *         - WCIN
> + *         - CHG
> + *         - BAT
> + *         - INLIM
> + *         - THM2
> + *         - BYP
> + *       - INT2
> + *         - INSEL
> + *         - SYS_UVLO1
> + *         - SYS_UVLO2
> + *         - BAT_OILO
> + *         - CHG_STA_CC
> + *         - CHG_STA_CV
> + *         - CHG_STA_TO
> + *         - CHG_STA_DONE
>   */
>  enum {
>  	MAX77759_INT_MAXQ,
> @@ -256,8 +286,38 @@ static const struct regmap_irq max77759_topsys_irqs[] = {
>  };
>  
>  static const struct regmap_irq max77759_chgr_irqs[] = {
> -	REGMAP_IRQ_REG(MAX77759_CHARGER_INT_1, 0, GENMASK(7, 0)),
> -	REGMAP_IRQ_REG(MAX77759_CHARGER_INT_2, 1, GENMASK(7, 0)),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_AICL, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_AICL),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_CHGIN, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_CHGIN),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_WCIN, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_WCIN),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_CHG, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_CHG),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_BAT, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_BAT),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_INLIM, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_INLIM),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_THM2, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_THM2),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT1_BYP, 0,
> +		       MAX77759_CHGR_REG_CHG_INT_BYP),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_INSEL, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_INSEL),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_SYS_UVLO1, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO1),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_SYS_UVLO2, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO2),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_BAT_OILO, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_BAT_OILO),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_CC, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CC),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_CV, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CV),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_TO, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_CHG_STA_TO),
> +	REGMAP_IRQ_REG(MAX77759_CHGR_INT2_CHG_STA_DONE, 1,
> +		       MAX77759_CHGR_REG_CHG_INT2_CHG_STA_DONE),
>  };
>  
>  static const struct regmap_irq_chip max77759_pmic_irq_chip = {
> @@ -302,6 +362,7 @@ static const struct regmap_irq_chip max77759_chrg_irq_chip = {

Minor nit: The new code in this patch consistently uses "chgr" as the prefix
for charger-related names. To improve consistency, how about we rename this
struct to `max77759_chgr_irq_chip`?

>  	.domain_suffix = "CHGR",
>  	.status_base = MAX77759_CHGR_REG_CHG_INT,
>  	.mask_base = MAX77759_CHGR_REG_CHG_INT_MASK,
> +	.ack_base = MAX77759_CHGR_REG_CHG_INT,
>  	.num_regs = 2,
>  	.irqs = max77759_chgr_irqs,
>  	.num_irqs = ARRAY_SIZE(max77759_chgr_irqs),
> @@ -325,8 +386,22 @@ static const struct resource max77759_gpio_resources[] = {
>  };
>  
>  static const struct resource max77759_charger_resources[] = {
> -	DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_1, "INT1"),
> -	DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_2, "INT2"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_AICL,         "AICL"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_CHGIN,        "CHGIN"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_WCIN,         "WCIN"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_CHG,          "CHG"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_BAT,          "BAT"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_INLIM,        "INLIM"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_THM2,         "THM2"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT1_BYP,          "BYP"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_INSEL,        "INSEL"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_SYS_UVLO1,    "SYS_UVLO1"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_SYS_UVLO2,    "SYS_UVLO2"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_BAT_OILO,     "BAT_OILO"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_CC,   "CHG_STA_CC"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_CV,   "CHG_STA_CV"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_TO,   "CHG_STA_TO"),
> +	DEFINE_RES_IRQ_NAMED(MAX77759_CHGR_INT2_CHG_STA_DONE, "CHG_STA_DONE"),
>  };
>  
>  static const struct mfd_cell max77759_cells[] = {
> diff --git a/include/linux/mfd/max77759.h b/include/linux/mfd/max77759.h
> index c6face34e385..fd5aea21ab2e 100644
> --- a/include/linux/mfd/max77759.h
> +++ b/include/linux/mfd/max77759.h
> @@ -59,35 +59,65 @@
>  #define MAX77759_MAXQ_REG_AP_DATAIN0            0xb1
>  #define MAX77759_MAXQ_REG_UIC_SWRST             0xe0
>  
> -#define MAX77759_CHGR_REG_CHG_INT               0xb0
> -#define MAX77759_CHGR_REG_CHG_INT2              0xb1
> -#define MAX77759_CHGR_REG_CHG_INT_MASK          0xb2
> -#define MAX77759_CHGR_REG_CHG_INT2_MASK         0xb3
> -#define MAX77759_CHGR_REG_CHG_INT_OK            0xb4
> -#define MAX77759_CHGR_REG_CHG_DETAILS_00        0xb5
> -#define MAX77759_CHGR_REG_CHG_DETAILS_01        0xb6
> -#define MAX77759_CHGR_REG_CHG_DETAILS_02        0xb7
> -#define MAX77759_CHGR_REG_CHG_DETAILS_03        0xb8
> -#define MAX77759_CHGR_REG_CHG_CNFG_00           0xb9
> -#define MAX77759_CHGR_REG_CHG_CNFG_01           0xba
> -#define MAX77759_CHGR_REG_CHG_CNFG_02           0xbb
> -#define MAX77759_CHGR_REG_CHG_CNFG_03           0xbc
> -#define MAX77759_CHGR_REG_CHG_CNFG_04           0xbd
> -#define MAX77759_CHGR_REG_CHG_CNFG_05           0xbe
> -#define MAX77759_CHGR_REG_CHG_CNFG_06           0xbf
> -#define MAX77759_CHGR_REG_CHG_CNFG_07           0xc0
> -#define MAX77759_CHGR_REG_CHG_CNFG_08           0xc1
> -#define MAX77759_CHGR_REG_CHG_CNFG_09           0xc2
> -#define MAX77759_CHGR_REG_CHG_CNFG_10           0xc3
> -#define MAX77759_CHGR_REG_CHG_CNFG_11           0xc4
> -#define MAX77759_CHGR_REG_CHG_CNFG_12           0xc5
> -#define MAX77759_CHGR_REG_CHG_CNFG_13           0xc6
> -#define MAX77759_CHGR_REG_CHG_CNFG_14           0xc7
> -#define MAX77759_CHGR_REG_CHG_CNFG_15           0xc8
> -#define MAX77759_CHGR_REG_CHG_CNFG_16           0xc9
> -#define MAX77759_CHGR_REG_CHG_CNFG_17           0xca
> -#define MAX77759_CHGR_REG_CHG_CNFG_18           0xcb
> -#define MAX77759_CHGR_REG_CHG_CNFG_19           0xcc
> +#define MAX77759_CHGR_REG_CHG_INT                      0xb0
> +#define   MAX77759_CHGR_REG_CHG_INT_AICL               BIT(7)
> +#define   MAX77759_CHGR_REG_CHG_INT_CHGIN              BIT(6)
> +#define   MAX77759_CHGR_REG_CHG_INT_WCIN               BIT(5)
> +#define   MAX77759_CHGR_REG_CHG_INT_CHG                BIT(4)
> +#define   MAX77759_CHGR_REG_CHG_INT_BAT                BIT(3)
> +#define   MAX77759_CHGR_REG_CHG_INT_INLIM              BIT(2)
> +#define   MAX77759_CHGR_REG_CHG_INT_THM2               BIT(1)
> +#define   MAX77759_CHGR_REG_CHG_INT_BYP                BIT(0)
> +#define MAX77759_CHGR_REG_CHG_INT2                     0xb1
> +#define   MAX77759_CHGR_REG_CHG_INT2_INSEL             BIT(7)
> +#define   MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO1         BIT(6)
> +#define   MAX77759_CHGR_REG_CHG_INT2_SYS_UVLO2         BIT(5)
> +#define   MAX77759_CHGR_REG_CHG_INT2_BAT_OILO          BIT(4)
> +#define   MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CC        BIT(3)
> +#define   MAX77759_CHGR_REG_CHG_INT2_CHG_STA_CV        BIT(2)
> +#define   MAX77759_CHGR_REG_CHG_INT2_CHG_STA_TO        BIT(1)
> +#define   MAX77759_CHGR_REG_CHG_INT2_CHG_STA_DONE      BIT(0)
> +#define MAX77759_CHGR_REG_CHG_INT_MASK                 0xb2
> +#define MAX77759_CHGR_REG_CHG_INT2_MASK                0xb3
> +#define MAX77759_CHGR_REG_CHG_INT_OK                   0xb4
> +#define MAX77759_CHGR_REG_CHG_DETAILS_00               0xb5
> +#define   MAX77759_CHGR_REG_CHG_DETAILS_00_CHGIN_DTLS  GENMASK(6, 5)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_01               0xb6
> +#define   MAX77759_CHGR_REG_CHG_DETAILS_01_BAT_DTLS    GENMASK(6, 4)
> +#define   MAX77759_CHGR_REG_CHG_DETAILS_01_CHG_DTLS    GENMASK(3, 0)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_02               0xb7
> +#define   MAX77759_CHGR_REG_CHG_DETAILS_02_CHGIN_STS   BIT(5)
> +#define MAX77759_CHGR_REG_CHG_DETAILS_03               0xb8
> +#define MAX77759_CHGR_REG_CHG_CNFG_00                  0xb9
> +#define   MAX77759_CHGR_REG_CHG_CNFG_00_MODE           GENMASK(3, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_01                  0xba
> +#define MAX77759_CHGR_REG_CHG_CNFG_02                  0xbb
> +#define   MAX77759_CHGR_REG_CHG_CNFG_02_CHGCC          GENMASK(5, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_03                  0xbc
> +#define MAX77759_CHGR_REG_CHG_CNFG_04                  0xbd
> +#define   MAX77759_CHGR_REG_CHG_CNFG_04_CHG_CV_PRM     GENMASK(5, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_05                  0xbe
> +#define MAX77759_CHGR_REG_CHG_CNFG_06                  0xbf
> +#define   MAX77759_CHGR_REG_CHG_CNFG_06_CHGPROT        GENMASK(3, 2)
> +#define MAX77759_CHGR_REG_CHG_CNFG_07                  0xc0
> +#define MAX77759_CHGR_REG_CHG_CNFG_08                  0xc1
> +#define MAX77759_CHGR_REG_CHG_CNFG_09                  0xc2
> +#define   MAX77759_CHGR_REG_CHG_CNFG_09_CHGIN_ILIM     GENMASK(6, 0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_10                  0xc3
> +#define MAX77759_CHGR_REG_CHG_CNFG_11                  0xc4
> +#define MAX77759_CHGR_REG_CHG_CNFG_12                  0xc5
> +/* Wireless Charging input channel select */
> +#define   MAX77759_CHGR_REG_CHG_CNFG_12_WCINSEL        BIT(6)
> +/* CHGIN/USB input channel select */
> +#define   MAX77759_CHGR_REG_CHG_CNFG_12_CHGINSEL       BIT(5)
> +#define MAX77759_CHGR_REG_CHG_CNFG_13                  0xc6
> +#define MAX77759_CHGR_REG_CHG_CNFG_14                  0xc7
> +#define MAX77759_CHGR_REG_CHG_CNFG_15                  0xc8
> +#define MAX77759_CHGR_REG_CHG_CNFG_16                  0xc9
> +#define MAX77759_CHGR_REG_CHG_CNFG_17                  0xca
> +#define MAX77759_CHGR_REG_CHG_CNFG_18                  0xcb
> +#define   MAX77759_CHGR_REG_CHG_CNFG_18_WDTEN          BIT(0)
> +#define MAX77759_CHGR_REG_CHG_CNFG_19                  0xcc
>  
>  /* MaxQ opcodes for max77759_maxq_command() */
>  #define MAX77759_MAXQ_OPCODE_MAXLENGTH (MAX77759_MAXQ_REG_AP_DATAOUT32 - \
> @@ -101,6 +131,94 @@
>  #define MAX77759_MAXQ_OPCODE_USER_SPACE_READ     0x81
>  #define MAX77759_MAXQ_OPCODE_USER_SPACE_WRITE    0x82
>  
> +/*
> + * Charger Input Status
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_UNDERVOLTAGE:
> + *     Charger input voltage (Vchgin) < Under Voltage Threshold (Vuvlo)
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE: Vchgin > Vuvlo and
> + *     Vchgin < (Battery Voltage (Vbatt) + system voltage (Vsys))
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_OVERVOLTAGE:
> + *     Vchgin > Over Voltage threshold (Vovlo)
> + * @MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID:
> + *     Vchgin > Vuvlo, Vchgin < Vovlo and Vchgin > (Vsys + Vbatt)
> + */
> +enum max77759_chgr_chgin_dtls_status {
> +	MAX77759_CHGR_CHGIN_DTLS_VBUS_UNDERVOLTAGE,
> +	MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE,
> +	MAX77759_CHGR_CHGIN_DTLS_VBUS_OVERVOLTAGE,
> +	MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID,
> +};
> +
> +/*
> + * Battery Details
> + * @MAX77759_CHGR_BAT_DTLS_NO_BATT_CHG_SUSP:
> + *     No battery and the charger suspended
> + * @MAX77759_CHGR_BAT_DTLS_DEAD_BATTERY: Vbatt < Vtrickle
> + * @MAX77759_CHGR_BAT_DTLS_BAT_CHG_TIMER_FAULT:
> + *     Charging suspended due to timer fault
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OKAY:
> + *     Battery okay and Vbatt > Min Sys Voltage (Vsysmin)
> + * @MAX77759_CHGR_BAT_DTLS_BAT_UNDERVOLTAGE:
> + *     Battery is okay. Vtrickle < Vbatt < Vsysmin
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OVERVOLTAGE:
> + *     Battery voltage > Overvoltage threshold
> + * @MAX77759_CHGR_BAT_DTLS_BAT_OVERCURRENT:
> + *     Battery current exceeds overcurrent threshold
> + * @MAX77759_CHGR_BAT_DTLS_BAT_ONLY_MODE:
> + *     Battery only mode and battery level not available
> + */
> +enum max77759_chgr_bat_dtls_states {
> +	MAX77759_CHGR_BAT_DTLS_NO_BATT_CHG_SUSP,
> +	MAX77759_CHGR_BAT_DTLS_DEAD_BATTERY,
> +	MAX77759_CHGR_BAT_DTLS_BAT_CHG_TIMER_FAULT,
> +	MAX77759_CHGR_BAT_DTLS_BAT_OKAY,
> +	MAX77759_CHGR_BAT_DTLS_BAT_UNDERVOLTAGE,
> +	MAX77759_CHGR_BAT_DTLS_BAT_OVERVOLTAGE,
> +	MAX77759_CHGR_BAT_DTLS_BAT_OVERCURRENT,
> +	MAX77759_CHGR_BAT_DTLS_BAT_ONLY_MODE,
> +};
> +
> +/*
> + * Charger Details
> + * @MAX77759_CHGR_CHG_DTLS_PREQUAL: Charger in prequalification mode
> + * @MAX77759_CHGR_CHG_DTLS_CC:      Charger in fast charge const curr mode
> + * @MAX77759_CHGR_CHG_DTLS_CV:      Charger in fast charge const voltage mode
> + * @MAX77759_CHGR_CHG_DTLS_TO:      Charger is in top off mode
> + * @MAX77759_CHGR_CHG_DTLS_DONE:    Charger is done
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_1:  Reserved
> + * @MAX77759_CHGR_CHG_DTLS_TIMER_FAULT:   Charger is in timer fault mode
> + * @MAX77759_CHGR_CHG_DTLS_SUSP_BATT_THM:
> + *     Charger is suspended as bettery removal detected

Typo here, s/bettery/battery/.

> + * @MAX77759_CHGR_CHG_DTLS_OFF:
> + *     Charger is off. Input invalid or charger disabled
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_2:  Reserved
> + * @MAX77759_CHGR_CHG_DTLS_RSVD_3:  Reserved
> + * @MAX77759_CHGR_CHG_DTLS_OFF_WDOG_TIMER:
> + *     Charger is off as watchdog timer expired
> + * @MAX77759_CHGR_CHG_DTLS_SUSP_JEITA:    Charger is in JEITA control mode
> + */
> +enum max77759_chgr_chg_dtls_states {

Just a small style suggestion, could you please align the descriptions in this
kerneldoc block? It improves readability. Using a consistent number of spaces
or tabs after the colon helps.

Feel free to use up to 100-chars if it improves readability.

> +	MAX77759_CHGR_CHG_DTLS_PREQUAL,
> +	MAX77759_CHGR_CHG_DTLS_CC,
> +	MAX77759_CHGR_CHG_DTLS_CV,
> +	MAX77759_CHGR_CHG_DTLS_TO,
> +	MAX77759_CHGR_CHG_DTLS_DONE,
> +	MAX77759_CHGR_CHG_DTLS_RSVD_1,
> +	MAX77759_CHGR_CHG_DTLS_TIMER_FAULT,
> +	MAX77759_CHGR_CHG_DTLS_SUSP_BATT_THM,
> +	MAX77759_CHGR_CHG_DTLS_OFF,
> +	MAX77759_CHGR_CHG_DTLS_RSVD_2,
> +	MAX77759_CHGR_CHG_DTLS_RSVD_3,
> +	MAX77759_CHGR_CHG_DTLS_OFF_WDOG_TIMER,
> +	MAX77759_CHGR_CHG_DTLS_SUSP_JEITA,
> +};
> +
> +enum max77759_chgr_mode {
> +	MAX77759_CHGR_MODE_OFF,
> +	MAX77759_CHGR_MODE_CHG_BUCK_ON = 0x5,
> +	MAX77759_CHGR_MODE_OTG_BOOST_ON = 0xA,
> +};
> +
>  /**
>   * struct max77759 - core max77759 internal data structure
>   *

-- 
Lee Jones [李琼斯]


^ permalink raw reply

* Re: [PATCH v3 3/7] pinctrl: pinctrl-generic: add __pinctrl_generic_pins_function_dt_node_to_map()
From: Frank Li @ 2026-03-25 15:09 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Linus Walleij, Peter Rosin, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rafał Miłecki, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
	devicetree, imx, linux-arm-kernel, Haibo Chen
In-Reply-To: <20260325-riding-browbeat-293b47f43d82@spud>

On Wed, Mar 25, 2026 at 10:33:05AM +0000, Conor Dooley wrote:
> On Tue, Mar 24, 2026 at 04:16:10PM -0400, Frank Li wrote:
> > On Fri, Mar 20, 2026 at 09:54:45AM -0400, Frank Li wrote:
> > > On Fri, Mar 20, 2026 at 02:27:21PM +0100, Linus Walleij wrote:
> > > > On Thu, Mar 19, 2026 at 12:04 AM Frank Li <Frank.li@nxp.com> wrote:
> > > > > On Mon, Mar 16, 2026 at 10:37:28AM +0100, Linus Walleij wrote:
> > > >
> > > > > > That said: in this case you're just adding a parameter, just add
> > > > > > the parameter and change all of the in-tree users to pass false
> > > > > > or whatever you need, these is just one (1) in-tree user anyway.
> > > > >
> > > > > pinctrl_generic_pins_function_dt_node_to_map() directly feed to
> > > > > .dt_node_to_map() callback, add parameter will impact too much.
> > > >
> > > > Why do you say that. It already has many parameters, one more
> > > > or less doesn't matter. It's not like this call is performance-critical.
> > > > Just change the users.
> > >
> > > In only user drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c,
> > > 	.dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map;
> > >
> > > pinctrl_generic_pins_function_dt_node_to_map() need match .dt_node_to_map()'s
> > > declear.
> > >
> > > So it can't direct add two parameters in pinctrl_generic_pins_function_dt_node_to_map()
> > > Need simple wrap function, which other in pinctrl-mpfs-mssio.c or in
> > > pinconf.h.
> > >
> > > If add two parameter in .dt_node_to_map(), need change all functions, which
> > > .dt_node_to_map = xxx_to_map(). and OF core part.
> >
> > Linus Walleij:
> > 	Is my explain clear enough? I am preparing respin it?
> >
> > 	is okay use wrap function
> > 	pinctrl_generic_pins_function_dt_node_to_map_ext()?
>
> I don't understand this patch. The function is called
> pinctrl_generic_pins_function_dt_node_to_map(). You have no pins.
> You're adding a parameter to make a function with *pins* in its name not
> use pins. The new function doesn't use pins but has pins in the name.
> At the very least function names should not be misleading.
>
> I was going to suggest pulling out the relevant portions and creating
> some helpers that could be used by multiple different-but-similar
> functions, but I don't actually even think that there's much in common.
> Most damningly I think, you don't actually read either the functions or
> pins properties at all and neither are permitted by your binding.
> So turns out you use neither pins or functions...
>
> You don't actually have any of these properties which runs counter to the
> goal of the function, which is parsing. With this in mind, it feels to me
> like you're trying way too hard to make use of a generic function when the
> right thing to do is probably just have an entirely custom function.
> Maybe that's a custom implementation in your driver, or a new function
> here, but I think writing that will highlight just how little of the
> code would be shared between the existing function and what your
> use-case needs: no pin configuration stuff, no reading of the devicetree
> other than the node names and no dealing with the label pointing to the
> "wrong" place.
>
> I recently bought a spacemit k1 board to go and write a sister function
> to pinctrl_generic_pins_function_dt_node_to_map() that deals with pins
> and groups (because that's a pretty common pattern).
> I would be calling that pinctrl_generic_pinmux_dt_node_to_map(),
> because it that's the property it deals with. I have honestly got no
> idea what to call one for this situation since you don't have any of the
> properties in pinmux-node.yaml. Maybe that's a sign.

At v2, I implemented customize dt_node_to_map(), Linus Walleij think it is
too similar with pinctrl_generic_pins_function_dt_node_to_map(), so ask me
to enhanance and reuse pinctrl_generic_pins_function_dt_node_to_map().

Frank
>
> Cheers,
> Conor.




^ permalink raw reply

* Re: [PATCH v6 1/5] mm: rmap: support batched checks of the references for large folios
From: Lorenzo Stoakes (Oracle) @ 2026-03-25 15:06 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: Baolin Wang, Barry Song, akpm, catalin.marinas, will,
	lorenzo.stoakes, ryan.roberts, Liam.Howlett, vbabka, rppt, surenb,
	mhocko, riel, harry.yoo, jannh, willy, dev.jain, linux-mm,
	linux-arm-kernel, linux-kernel
In-Reply-To: <e3e374cc-ddf2-4112-b063-6cb1839ea566@kernel.org>

On Wed, Mar 25, 2026 at 03:58:36PM +0100, David Hildenbrand (Arm) wrote:
> On 3/25/26 15:36, Lorenzo Stoakes (Oracle) wrote:
> > On Mon, Mar 16, 2026 at 03:15:18PM +0100, David Hildenbrand (Arm) wrote:
> >> On 3/16/26 07:25, Baolin Wang wrote:
> >>>
> >>>
> >>>
> >>> Sure. However, after investigating RISC‑V and x86, I found that
> >>> ptep_clear_flush_young() does not flush the TLB on these architectures:
> >>>
> >>> int ptep_clear_flush_young(struct vm_area_struct *vma,
> >>>                unsigned long address, pte_t *ptep)
> >>> {
> >>>     /*
> >>>      * On x86 CPUs, clearing the accessed bit without a TLB flush
> >>>      * doesn't cause data corruption. [ It could cause incorrect
> >>>      * page aging and the (mistaken) reclaim of hot pages, but the
> >>>      * chance of that should be relatively low. ]
> >>>      *
> >>>      * So as a performance optimization don't flush the TLB when
> >>>      * clearing the accessed bit, it will eventually be flushed by
> >>>      * a context switch or a VM operation anyway. [ In the rare
> >>>      * event of it not getting flushed for a long time the delay
> >>>      * shouldn't really matter because there's no real memory
> >>>      * pressure for swapout to react to. ]
> >>>      */
> >>>     return ptep_test_and_clear_young(vma, address, ptep);
> >>> }
> >>
> >> You'd probably want an arch helper then, that tells you whether
> >> a flush_tlb_range() after ptep_test_and_clear_young() is required.
> >>
> >> Or some special flush_tlb_range() helper.
> >>
> >> I agree that it requires more work.
> >
> > Sorry unclear here - does the series need more work or does a follow up patch
> > need more work?
>
> Follow up!

Ok good as in mm-stable now. Sadly means I don't get to review it but there we
go.

>
> --
> Cheers,
>
> David

Thanks, Lorenzo


^ permalink raw reply

* Re: [PATCH v2 2/6] arm64: dts: freescale: Add Verdin iMX95 support
From: Frank Li @ 2026-03-25 15:01 UTC (permalink / raw)
  To: Francesco Dolcini
  Cc: Ernest Van Hoecke, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Ernest Van Hoecke, Emanuele Ghidoli, Francesco Dolcini,
	devicetree, linux-kernel, imx, linux-arm-kernel
In-Reply-To: <20260325112724.GA7964@francesco-nb>

On Wed, Mar 25, 2026 at 12:27:24PM +0100, Francesco Dolcini wrote:
> On Tue, Mar 24, 2026 at 12:14:35PM -0400, Frank Li wrote:
> > On Fri, Mar 13, 2026 at 09:57:43AM +0100, Ernest Van Hoecke wrote:
> > > From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> > >
> > > Add support for the Toradex Verdin iMX95 and its development carrier
> > > board.
> > >
> > > The module consists of an NXP i.MX95 family SoC, up to 16GB LPDDR4x RAM,
> > > up to 128GB of storage, a USB 3.2 OTG and USB 2.0 Host, a Gigabit
> > > Ethernet PHY, an I2C EEPROM and Temperature Sensor, an RX8130 RTC, an
> > > I3C bus, one Quad lane CSI interface, one Quad lane DSI or CSI
> > > interface, one LVDS interface (one or two channels), and some optional
> > > addons: TPM 2.0, and a WiFi/BT module.
> > >
> > > Link: https://www.toradex.com/computer-on-modules/verdin-arm-family/nxp-imx95
> > > Link: https://www.toradex.com/products/carrier-board/verdin-development-board-kit
> > > Co-developed-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
> > > Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
> > > Co-developed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
> > > Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
> > > Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> > > ---
> > > v2: Reordered nodes alphanumerically by node name
> > > v1: https://lore.kernel.org/all/20260305-verdin-imx95-upstream-frank-li-base-v1-2-823fad02def9@toradex.com/
> > > ---
> > > +
> > > +/* Verdin UART_1, connector X50 through RS485 transceiver */
> > > +&lpuart7 {
> > > +	rs485-rts-active-low;
> > > +	rs485-rx-during-tx;
> > > +	linux,rs485-enabled-at-boot-time;
> > > +
> >
> > Nit: needn't empty line between status and other property, suggest run
> > https://github.com/lznuaa/dt-format to speed up process.
>
> Please review Documentation/devicetree/bindings/dts-coding-style.rst.
>
> Quoting from there
>  > "status" (if applicable), preceded by a blank line if there is content before the property
>
> I would be careful on taking every detail of such a style guide literally,
> but your comment here is not correct and it's not helping anyone.

Thank you point out,  there are not extra empty line in existing dts.
git grep -r -a3 "status =" arch/arm64/boot/dts/

I think it should update dts-coding-style.rst to match most existing one.

Frank

>
> Francesco
>


^ permalink raw reply

* Re: [PATCH v3] PCI: dw-rockchip: Enable async probe by default
From: Robin Murphy @ 2026-03-25 15:01 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Danilo Krummrich, Manivannan Sadhasivam, Manivannan Sadhasivam,
	Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
	Bjorn Helgaas, Heiko Stuebner, Niklas Cassel, Shawn Lin,
	Hans Zhang, Nicolas Frattaroli, Wilfred Mallawa, linux-pci,
	linux-arm-kernel, linux-rockchip, linux-kernel, Anand Moon,
	Grimmauld, Greg Kroah-Hartman, Rafael J. Wysocki, driver-core,
	Lukas Wunner
In-Reply-To: <acNgUoWWMCi1oLU4@google.com>

On 25/03/2026 4:13 am, Dmitry Torokhov wrote:
> On Thu, Mar 12, 2026 at 12:48:36PM +0000, Robin Murphy wrote:
>> On 2026-03-11 9:09 pm, Danilo Krummrich wrote:
>>> On Wed Mar 11, 2026 at 1:28 PM CET, Manivannan Sadhasivam wrote:
>>>> On Wed, Mar 11, 2026 at 12:46:03PM +0100, Danilo Krummrich wrote:
>>>>> On Wed Mar 11, 2026 at 6:24 AM CET, Manivannan Sadhasivam wrote:
>>>>>> I have a contrary view here. If just a single driver or lib doesn't handle async
>>>>>> probe, it cannot just force other drivers to not take the advantage of async
>>>>>> probe. As I said above, enabling async probe easily saves a few hunderd ms or
>>>>>> even more if there are more than one Root Port or Root Complex in an SoC.
>>>>>
>>>>> Then the driver or lib has to be fixed / improved first or the driver core has
>>>>> to be enabled to deal with a case where PROBE_FORCE_SYNCHRONOUS is requested
>>>>> from an async path, etc.
>>>>>
>>>>> In any case, applying the patch and breaking things (knowingly?) doesn't seem
>>>>> like the correct approach.
>>>>>
>>>>>> I strongly agree with you here that the underlying issue should be fixed. But
>>>>>> the real impact to end users is not this splat, but not having the boot time
>>>>>> optimization that this patch brings in. As an end user, one would want their
>>>>>> systems to boot quickly and they wouldn't bother much about a harmless warning
>>>>>> splat appearing in the dmesg log.
>>>>>
>>>>> You mean quickly booting into a "harmless" potential deadlock condition the
>>>>> warning splat tries to make people aware of? :)
>>>>>
>>>>
>>>> Hmm, I overlooked the built-as-module part where the deadlock could be possible
>>>> as indicated by the comment about the WARN_ON_ONCE().
>>>>
>>>> But what is the path forward here? Do you want the phylib to fix the
>>>> request_module() call or fix the driver core instead?
>>>
>>> Here are a few thoughts.
>>>
>>> In general, I think the best would be to get rid of the (affected)
>>> PROBE_FORCE_SYNCHRONOUS cases.
>>>
>>> Now, I guess this can be pretty hard for a PCI controller driver, as you can't
>>> really predict what ends up being probed from you async context, i.e. it could
>>> even be some other bus controller and things could even propagate further.
>>>
>>> Not sure how big of a deal it is in practice though, there are not a lot of
>>> PROBE_FORCE_SYNCHRONOUS drivers (left), but note that specifying neither
>>> PROBE_FORCE_SYNCHRONOUS nor PROBE_PREFER_ASYNCHRONOUS currently results in
>>> synchronous by default.
>>>
>>> (Also, quite some other PCI controller drivers do set PROBE_PREFER_ASYNCHRONOUS
>>> and apparently got lucky with it.)
>>>
>>>   From a driver-core perspective I think we're rather limited on what we can do;
>>> we are already in async context at this point and can't magically go back to
>>> initcall context.
>>>
>>> So, the only thing I can think of is to kick off work on a workqueue, which in
>>> the end would be the same as the deferred probe handling.
>>
>> Hmm, in fact, isn't the deferred probe mechanism itself actually quite
>> appropriate? A suitable calling context isn't the most obvious "resource
>> provider" to wait for, but ultimately it's still a case of "we don't
>> have everything we need right now, but it's worth trying again soon".
>> I may have missed some subtleties, but my instinct is that it could
>> perhaps be as simple as something like this (completely untested).
>>
>> Cheers,
>> Robin.
>>
>> ----->8-----
>>
>> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
>> index bea8da5f8a3a..3c4a0207ae3f 100644
>> --- a/drivers/base/dd.c
>> +++ b/drivers/base/dd.c
>> @@ -954,6 +954,16 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
>>   	if (data->check_async && async_allowed != data->want_async)
>>   		return 0;
>> +	/*
>> +	 * Bus drivers may probe asynchronously, but be adding a child device
>> +	 * whose driver still wants a synchronous probe. In this case, just
>> +	 * defer it, to be triggered by the parent driver probe succeeding.
>> +	 */
>> +	if (!async_allowed && current_is_async()) {
>> +		driver_deferred_probe_add(dev);
>> +		return 0;
>> +	}
> 
> That means that you are kicking the majority devices (for now) into
> deferral path. I do not think this is optimal.

And probing drivers under conditions where they may go wrong or deadlock 
is better? I've not yet had a chance to actually test this myself to see 
the effect on timings, but whatever it might be, I can't imagine any 
*other* method of re-serialising child driver probes could be 
significantly better (or if it could be, that might represent some 
improvement we could make to the deferred probe mechanism in general 
anyway).

I have finally got a bit of time this afternoon to pick this up again, 
so I'll have a play and try to finish the write-up capturing all the 
reasoning so far (it's a long one...)

> Does phy really need to request modules synchronously (and on its own)?
> Why can't it rely on udev to load the modules and signal when phy
> devices are ready?

Getting hung up on what phylib does in this one particular case is 
rather missing the point. There is a reason that we're still not forcing 
async_probe on for everything by default. Many drivers will still not 
have been tested and validated to handle it correctly, and while the 
majority of latent issues will likely just be concurrency bugs which can 
be fixed with better locking or whatever, even then we should be 
encouraging developers to actively test and look for such bugs to make 
their drivers "async probe clean", rather than knowingly enabling bugs 
to surface in the wild as weird and subtle breakage on end-user systems.

However, I imagine there will always remain some small minority of 
PROBE_FORCE_SYNCHRONOUS drivers - either for niche legitimate technical 
reasons, or just legacy drivers where updating them would take more 
effort than it's worth - so the driver core surely needs the ability to 
not do the wrong thing itself. That doesn't even need to be "optimal", 
it just needs to be functionally correct.

Thanks,
Robin.

> 
> Seems like a deficiency on PHY subsystem that is stuck in times long
> past.
> 
> Thanks.
> 



^ permalink raw reply

* Re: [PATCH v6 1/5] mm: rmap: support batched checks of the references for large folios
From: David Hildenbrand (Arm) @ 2026-03-25 14:58 UTC (permalink / raw)
  To: Lorenzo Stoakes (Oracle)
  Cc: Baolin Wang, Barry Song, akpm, catalin.marinas, will,
	lorenzo.stoakes, ryan.roberts, Liam.Howlett, vbabka, rppt, surenb,
	mhocko, riel, harry.yoo, jannh, willy, dev.jain, linux-mm,
	linux-arm-kernel, linux-kernel
In-Reply-To: <e5cb474a-a84d-4edc-8289-d68378feee7d@lucifer.local>

On 3/25/26 15:36, Lorenzo Stoakes (Oracle) wrote:
> On Mon, Mar 16, 2026 at 03:15:18PM +0100, David Hildenbrand (Arm) wrote:
>> On 3/16/26 07:25, Baolin Wang wrote:
>>>
>>>
>>>
>>> Sure. However, after investigating RISC‑V and x86, I found that
>>> ptep_clear_flush_young() does not flush the TLB on these architectures:
>>>
>>> int ptep_clear_flush_young(struct vm_area_struct *vma,
>>>                unsigned long address, pte_t *ptep)
>>> {
>>>     /*
>>>      * On x86 CPUs, clearing the accessed bit without a TLB flush
>>>      * doesn't cause data corruption. [ It could cause incorrect
>>>      * page aging and the (mistaken) reclaim of hot pages, but the
>>>      * chance of that should be relatively low. ]
>>>      *
>>>      * So as a performance optimization don't flush the TLB when
>>>      * clearing the accessed bit, it will eventually be flushed by
>>>      * a context switch or a VM operation anyway. [ In the rare
>>>      * event of it not getting flushed for a long time the delay
>>>      * shouldn't really matter because there's no real memory
>>>      * pressure for swapout to react to. ]
>>>      */
>>>     return ptep_test_and_clear_young(vma, address, ptep);
>>> }
>>
>> You'd probably want an arch helper then, that tells you whether
>> a flush_tlb_range() after ptep_test_and_clear_young() is required.
>>
>> Or some special flush_tlb_range() helper.
>>
>> I agree that it requires more work.
> 
> Sorry unclear here - does the series need more work or does a follow up patch
> need more work?

Follow up!

-- 
Cheers,

David


^ permalink raw reply

* Re: [PATCH v11 03/22] drm: Add new general DRM property "color format"
From: Maxime Ripard @ 2026-03-25 14:56 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Nicolas Frattaroli, Harry Wentland, Leo Li, Rodrigo Siqueira,
	Alex Deucher, Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Dmitry Baryshkov, Sascha Hauer, Rob Herring, Jonathan Corbet,
	Shuah Khan, kernel, amd-gfx, dri-devel, linux-kernel,
	linux-arm-kernel, linux-rockchip, intel-gfx, intel-xe, linux-doc,
	Werner Sembach, Andri Yngvason, Marius Vlad
In-Reply-To: <acPA60Ci3n_t__xF@intel.com>

[-- Attachment #1: Type: text/plain, Size: 5249 bytes --]

On Wed, Mar 25, 2026 at 01:03:07PM +0200, Ville Syrjälä wrote:
> On Wed, Mar 25, 2026 at 09:24:27AM +0100, Maxime Ripard wrote:
> > On Tue, Mar 24, 2026 at 09:53:35PM +0200, Ville Syrjälä wrote:
> > > On Tue, Mar 24, 2026 at 08:10:11PM +0100, Nicolas Frattaroli wrote:
> > > > On Tuesday, 24 March 2026 18:00:45 Central European Standard Time Ville Syrjälä wrote:
> > > > > On Tue, Mar 24, 2026 at 05:01:07PM +0100, Nicolas Frattaroli wrote:
> > > > > > +enum drm_connector_color_format {
> > > > > > +	/**
> > > > > > +	 * @DRM_CONNECTOR_COLOR_FORMAT_AUTO: The driver or display protocol
> > > > > > +	 * helpers should pick a suitable color format. All implementations of a
> > > > > > +	 * specific display protocol must behave the same way with "AUTO", but
> > > > > > +	 * different display protocols do not necessarily have the same "AUTO"
> > > > > > +	 * semantics.
> > > > > > +	 *
> > > > > > +	 * For HDMI, "AUTO" picks RGB, but falls back to YCbCr 4:2:0 if the
> > > > > > +	 * bandwidth required for full-scale RGB is not available, or the mode
> > > > > > +	 * is YCbCr 4:2:0-only, as long as the mode and output both support
> > > > > > +	 * YCbCr 4:2:0.
> > > > > > +	 *
> > > > > > +	 * For display protocols other than HDMI, the recursive bridge chain
> > > > > > +	 * format selection picks the first chain of bridge formats that works,
> > > > > > +	 * as has already been the case before the introduction of the "color
> > > > > > +	 * format" property. Non-HDMI bridges should therefore either sort their
> > > > > > +	 * bus output formats by preference, or agree on a unified auto format
> > > > > > +	 * selection logic that's implemented in a common state helper (like
> > > > > > +	 * how HDMI does it).
> > > > > > +	 */
> > > > > > +	DRM_CONNECTOR_COLOR_FORMAT_AUTO = 0,
> > > > > > +
> > > > > > +	/**
> > > > > > +	 * @DRM_CONNECTOR_COLOR_FORMAT_RGB444: RGB output format
> > > > > > +	 */
> > > > > > +	DRM_CONNECTOR_COLOR_FORMAT_RGB444,
> > > > > > +
> > > > > > +	/**
> > > > > > +	 * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR444: YCbCr 4:4:4 output format (ie.
> > > > > > +	 * not subsampled)
> > > > > > +	 */
> > > > > > +	DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
> > > > > > +
> > > > > > +	/**
> > > > > > +	 * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR422: YCbCr 4:2:2 output format (ie.
> > > > > > +	 * with horizontal subsampling)
> > > > > > +	 */
> > > > > > +	DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
> > > > > > +
> > > > > > +	/**
> > > > > > +	 * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR420: YCbCr 4:2:0 output format (ie.
> > > > > > +	 * with horizontal and vertical subsampling)
> > > > > > +	 */
> > > > > > +	DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
> > > > > 
> > > > > Seems like this should document what the quantization range
> > > > > should be for each format.
> > > > > 
> > > > 
> > > > I don't think so? If you want per-component bit depth values,
> > > > DRM_FORMAT_* defines would be the appropriate values to use. This
> > > > enum is more abstract than that, and is there to communicate
> > > > YUV vs. RGB and chroma subsampling, with bit depth being handled
> > > > by other properties.
> > > > 
> > > > If you mean the factor used for subsampling, then that'd only be
> > > > relevant if YCBCR410 was supported where one chroma plane isn't
> > > > halved but quartered in resolution. I suspect 4:1:0 will never
> > > > be added; no digital display protocol standard supports it to my
> > > > knowledge, and hopefully none ever will.
> > > 
> > > No, I mean the quantization range (16-235 vs. 0-255 etc).
> > > 
> > > The i915 behaviour is that YCbCr is always limited range,
> > > RGB can either be full or limited range depending on the 
> > > "Broadcast RGB" property and other related factors.
> > 
> > So far the HDMI state has both the format and quantization range as
> > different fields. I'm not sure we need to document the range in the
> > format field, maybe only mention it's not part of the format but has a
> > field of its own?
> 
> I think we only have it for RGB (on some drivers only?). For YCbCr
> I think the assumption is limited range everywhere.
> 
> But I'm not really concerned about documenting struct members.
> What I'm talking about is the *uapi* docs. Surely userspace
> will want to know what the new property actually does so the
> uapi needs to be documented properly. And down the line some
> new driver might also implement the wrong behaviour if there
> is no clear specification.

Ack

> So I'm thinking (or perhaps hoping) the rule might be something like:
> - YCbCr limited range 
> - RGB full range if "Broadcast RGB" property is not present

Isn't it much more complicated than that for HDMI though? My
recollection was that any VIC but VIC1 would be limited range, and
anything else full range?

> - RGB full or limited range based on the "Broadcast RGB" property
>   if it's present
> 
> I think the "Broadcast RGB" property itself might also be lacking
> proper uapi docs, so that may need to be remedied as well.

I took care of documenting it when merging the HDMI helpers:
https://docs.kernel.org/gpu/drm-kms.html#hdmi-specific-connector-properties

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

^ permalink raw reply

* Re: [PATCH v2 01/11] arm64: Skip update of an idreg field affected by an override
From: Suzuki K Poulose @ 2026-03-25 14:54 UTC (permalink / raw)
  To: Catalin Marinas, Marc Zyngier
  Cc: linux-arm-kernel, kvmarm, Fuad Tabba, Will Deacon, Mark Rutland,
	Joey Gouly, Oliver Upton, Zenghui Yu
In-Reply-To: <abwXl35xQ2ze1XwJ@arm.com>

On 19/03/2026 15:34, Catalin Marinas wrote:
> On Mon, Mar 02, 2026 at 11:56:42AM +0000, Marc Zyngier wrote:
>> When computing the new value od an idreg that contains a field
>> affected by an override, do not update that particular field.
>>
>> The value computed at init-time must be kept as-is, as that's
>> what the user has asked for, for better or worse.
>>
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> ---
>>   arch/arm64/kernel/cpufeature.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
>> index c31f8e17732a3..28fc77443ccd3 100644
>> --- a/arch/arm64/kernel/cpufeature.c
>> +++ b/arch/arm64/kernel/cpufeature.c
>> @@ -1224,6 +1224,13 @@ static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
>>   		s64 ftr_cur = arm64_ftr_value(ftrp, reg->sys_val);
>>   		s64 ftr_new = arm64_ftr_value(ftrp, new);
>>   
>> +		/*
>> +		 * Don't alter the initial value that has been forced
>> +		 * by an override.
>> +		 */
>> +		if ((reg->override->mask & arm64_ftr_mask(ftrp)) == arm64_ftr_mask(ftrp))
>> +			continue;
> 
> I got lost in the in the cpufeature framework, so I may be missing
> something.
> 
> Let's say the primary CPU has a feature field with value 2 and we want
> to override it to value 1. For e.g. a LOWER_SAFE feature, boot_cpu_data
> will stored the overridden value of 1.
> 
> A secondary CPU comes online with the same feature missing, so value 0.
> With the above change, we no longer update the system-wide feature
> value, leave it as 1. Later on, for a system feature we may turn it on
> even though the secondary CPU does not support it.
> 
> In summary, this makes the overridden field sticky for secondary CPUs
> even if they don't support it.

That is true. I think we should let the secondary CPUs alter the values,
with initial CPU feature value with the override value set, the system
could then choose the safest among the override and the others.

> 
> Unrelated to your patch, I think we can similarly fail to reject
> secondary CPUs in check_early_cpu_features() -> verify_local_cpu_caps()
> because of __read_sysreg_by_encoding() which uses the override value
> unconditionally. From this perspective, we are now consistent with your
> patch above.

This is true as well and the override takes the priority and with the
wrong level of override value the system could be made to think that
some features are available even when it is unsafe to do so.
We should sanitise the values read by __read_sysreg_by_encoding() with
the "overrides". I can cook something up.

> 
> In all cases we taint the kernel for FTR_STRICT features but that may go
> unnoticed or if we had FTR_NONSTRICT (does it even matter in this
> case?).
> 
> Maybe that's the intended use and blame the user for passing the wrong
> override. We are still slightly inconsistent depending on what the boot

This is correct. We should at least WARN for impossible overrides on the
secondaries. (We only do that for boot CPUs today). The other issue with
this is WEAK_LOCAL cpu features where we use the capability wherever
available. May be we could reduce the severity of the warning to 
pr_warn_once().

Suzuki

> CPU supports where we still decide whether accept or reject an override.
> We don't do this for secondaries.
> 
> Anyway, I'm not opposing to this patch if that's what's intended. I'm
> sure I'll forget everything about this framework in a couple of weeks.
> 


	



^ permalink raw reply


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