Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v1 1/3] dt-bindings: display: rockchip: analogix-dp: Expose inherited properties
From: Conor Dooley @ 2026-05-15  9:04 UTC (permalink / raw)
  To: Damon Ding
  Cc: Conor Dooley, hjc, heiko, andy.yan, maarten.lankhorst, mripard,
	tzimmermann, airlied, simona, robh, krzk+dt, conor+dt,
	andrzej.hajda, neil.armstrong, rfoss, Laurent.pinchart, jonas,
	jernej.skrabec, nicolas.frattaroli, cristian.ciocaltea,
	sebastian.reichel, dmitry.baryshkov, luca.ceresoli, dianders,
	m.szyprowski, dri-devel, devicetree, linux-arm-kernel,
	linux-rockchip, linux-kernel
In-Reply-To: <2f653664-27e9-4632-97e9-8b59cf7e585e@rock-chips.com>

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

On Fri, May 15, 2026 at 11:57:58AM +0800, Damon Ding wrote:
> Hi Conor,
> 
> On 5/15/2026 2:16 AM, Conor Dooley wrote:
> > On Thu, May 14, 2026 at 03:01:31PM +0800, Damon Ding wrote:
> > > Expose the inherited properties from the base analogix-dp schema
> > > to satisfy unevaluatedProperties constraints.
> > > 
> > > Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
> > 
> > Given it's unevaluatedProperties, not addtionalProperties, this patch
> > shouldn't be needed?
> > 
> 
> When I remove both the top-level data-lanes property and those explicit
> "xxx: true" property entries and run the dtbs check with:
> 
> make CHECK_DTBS=y CROSS_COMPILE=aarch64-linux-gnu- LT0=none LLVM=1
> LLVM_IAS=1 ARCH=arm64 rockchip/rk3588-evb1-v10.dtb
> rockchip/rk3588s-evb1-v10.dtb rockchip/rk3399-sapphire-excavator.dtb
> rockchip/rk3576-evb1-v10.dtb -j4
> 
> It results in validation errors like these:
> 
> /home/ding/drm-misc/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dtb:
> edp@27dc0000: ports:port@1:endpoint: Unevaluated properties are not allowed
> ('data-lanes' was unexpected)
>         from schema $id:
> http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> /home/ding/drm-misc/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dtb:
> edp@27dc0000: Unevaluated properties are not allowed ('force-hpd',
> 'interrupts', 'phy-names', 'phys', 'ports', 'reg' were unexpected)
>         from schema $id:
> http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
> 
> I suspect that the properties defined in the child binding are
> overriding/masking all the inherited properties from the parent Analogix DP
> schema.
> 
> Is there a better way to fix this issue without explicitly listing all
> inherited properties as true?

The example in this file uses most of the properties that you mention
above:
    dp@ff970000 {
      compatible = "rockchip,rk3288-dp";
      reg = <0xff970000 0x4000>;
      interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
      clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
      clock-names = "dp", "pclk";
      phys = <&dp_phy>;
      phy-names = "dp";
      resets = <&cru 111>;
      reset-names = "dp";
      rockchip,grf = <&grf>;
      pinctrl-0 = <&edp_hpd>;
      pinctrl-names = "default";

dt_binding_check reports no problems with this node, so I think the
problem might lie elsewhere?
There's no edp node in the dts you mention above, so this looks like an
interaction with something that's not yet upstream.

If this is required for the rk3576 edp, then you should include this
patch in the rk3576 edp support series rather than this one anyway where
it can actually be evaluated alongside the node it apparently causes
problems with.

pw-bot: changes-requested

Thanks,
Conor.

> 
> Best regards,
> Damon
> 
> > > ---
> > >   .../bindings/display/rockchip/rockchip,analogix-dp.yaml    | 7 +++++++
> > >   1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> > > index bb75d898a5c5..896ded87880f 100644
> > > --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> > > +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> > > @@ -50,6 +50,13 @@ properties:
> > >     aux-bus:
> > >       $ref: /schemas/display/dp-aux-bus.yaml#
> > > +  reg: true
> > > +  interrupts: true
> > > +  phys: true
> > > +  phy-names: true
> > > +  force-hpd: true
> > > +  ports: true
> > > +
> > >   required:
> > >     - compatible
> > >     - clocks
> > > -- 
> > > 2.34.1
> > > 
> > > 
> 

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

^ permalink raw reply

* [PATCH RFC 12/12] arm64: dts: mediatek: mt8188-geralt: Add WiFi/BT as M.2 E-key slot
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The MT8188 Geralt design features a chip-on-board WiFi/BT solution. This
is a M.2 E-key WiFi/BT board layout directly inserted into the mainboard
design. The connections to the rest of the board are almost the same as
if it were a separate M.2 card. The only addition is the PMU_EN pin on
the chip; on M.2 cards this would be tied to the primary power source.

Model the chip-on-board WiFi/BT solution as a M.2 E-key slot with PCIe,
USB and auxiliary signals. The PMU_EN pin, which enables the internal
power controls and regulators, is modeled as a regulator fed by the
pp3300_wlan regulator. Since power sequencing is now correctly modeled
using the M.2 E-key slot, drop the "regulator-always-on" property one
pp3300_wlan regulator. Also drop the comment in xhci2 saying "MT7921's
power is controlled by PCIe".

Also drop the voltage range on the pp3300_wlan regulator. This
"regulator" is just a load switch and does not provide any regulation.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../boot/dts/mediatek/mt8188-geralt.dtsi      | 93 ++++++++++++++++++-
 1 file changed, 89 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
index 4cb23595d17b..d7b5eb95ba0f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
@@ -86,13 +86,11 @@ pp3300_z1: regulator-pp3300-z1 {
 	pp3300_wlan: regulator-pp3300-wlan {
 		compatible = "regulator-fixed";
 		regulator-name = "pp3300_wlan";
-		regulator-always-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
 		enable-active-high;
 		gpio = <&pio 12 GPIO_ACTIVE_HIGH>;
 		pinctrl-0 = <&wlan_en>;
 		pinctrl-names = "default";
+		/* load switch */
 		vin-supply = <&pp3300_z1>;
 	};
 
@@ -159,6 +157,17 @@ ppvar_mipi_disp_avee: regulator-ppvar-mipi-disp-avee {
 		vin-supply = <&pp5000_z1>;
 	};
 
+	/* PMU_EN pin controls internal regulators and power sequence */
+	wlan_pmu: regulator-wlan-pmu {
+		compatible = "regulator-fixed";
+		regulator-name = "wlan-pmu";
+		enable-active-high;
+		gpio = <&pio 145 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&wlan_pmu_en>;
+		pinctrl-names = "default";
+		vin-supply = <&pp3300_wlan>;
+	};
+
 	reserved_memory: reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -193,6 +202,39 @@ adsp_dma_mem: memory@61000000 {
 			no-map;
 		};
 	};
+
+	wifi-bt-connector {
+		compatible = "pcie-m2-e-connector";
+		pinctrl-names = "default";
+		pinctrl-0 = <&m2_e_key_kill_pins>;
+		vpcie1v8-supply = <&mt6359_vcn18_ldo_reg>;
+		vpcie3v3-supply = <&wlan_pmu>;
+		w-disable1-gpios = <&pio 13 GPIO_ACTIVE_LOW>;
+		w-disable2-gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PCIe for WiFi */
+			port@0 {
+				reg = <0>;
+
+				wifi_ep: endpoint {
+					remote-endpoint = <&pcie_ep>;
+				};
+			};
+
+			/* USB for Bluetooth */
+			port@2 {
+				reg = <2>;
+
+				bt_ep: endpoint {
+					remote-endpoint = <&usb2_ep>;
+				};
+			};
+		};
+	};
 };
 
 &adsp {
@@ -656,6 +698,22 @@ &pcie {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie_pins>;
 	status = "okay";
+
+	pcie@0 {
+		compatible = "pciclass,0604";
+		reg = <0 0 0 0 0>;
+		device_type = "pci";
+		num-lanes = <1>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+
+		port {
+			pcie_ep: endpoint {
+				remote-endpoint = <&wifi_ep>;
+			};
+		};
+	};
 };
 
 &pciephy {
@@ -999,6 +1057,14 @@ pins-bus {
 		};
 	};
 
+	m2_e_key_kill_pins: m2-e-key-kill-pins {
+		pins-kill {
+			pinmux = <PINMUX_GPIO13__FUNC_B_GPIO13>,
+				 <PINMUX_GPIO14__FUNC_B_GPIO14>;
+			output-high;
+		};
+	};
+
 	mipi_disp_avdd_en: mipi-disp-avdd-en-pins {
 		pins-en-ppvar-mipi-disp {
 			pinmux = <PINMUX_GPIO3__FUNC_B_GPIO3>;
@@ -1163,6 +1229,13 @@ pins-bus {
 		};
 	};
 
+	wlan_pmu_en: wlan-pmu-en-pins {
+		pins-wlan-pmu-en {
+			pinmux = <PINMUX_GPIO145__FUNC_B_GPIO145>;
+			output-low;
+		};
+	};
+
 	wlan_en: wlan-en-pins {
 		pins-en-pp3300-wlan {
 			pinmux = <PINMUX_GPIO12__FUNC_B_GPIO12>;
@@ -1342,10 +1415,22 @@ vdosys1_ep_ext: endpoint@1 {
 };
 
 &xhci2 {
-	/* no power supply since MT7921's power is controlled by PCIe */
 	/* MT7921's USB BT has issues with USB2 LPM */
 	usb2-lpm-disable;
 	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+
+			usb2_ep: endpoint {
+				remote-endpoint = <&bt_ep>;
+			};
+		};
+	};
 };
 
 #include <arm/cros-ec-keyboard.dtsi>
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 11/12] arm64: dts: mediatek: mt8195-cherry: Add USB type-A connector
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The MT8195 Cherry design features a USB type-A connector for external
devices.

Add a proper representation for it with a node for the connector and
OF graph connection to the USB hub behind it.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../boot/dts/mediatek/mt8195-cherry.dtsi      | 72 ++++++++++++++++++-
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index c95a54de3567..b21cbe918c1f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -153,7 +153,6 @@ usb_vbus: regulator-5v0-usb-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "usb-vbus";
 		enable-active-high;
-		regulator-always-on;
 		vin-supply = <&pp5000_s5>;
 	};
 
@@ -267,6 +266,32 @@ tboard_thermistor2: thermal-sensor-t2 {
 						125000 44>;
 	};
 
+	usb-a-connector {
+		compatible = "usb-a-connector";
+		vbus-supply = <&usb_vbus>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				usb_a_u2_ep: endpoint {
+					remote-endpoint = <&usb2_hub_p3_ep>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				usb_a_u3_ep: endpoint {
+					remote-endpoint = <&usb3_hub_p3_ep>;
+				};
+			};
+		};
+	};
+
 	wifi-bt-connector {
 		compatible = "pcie-m2-e-connector";
 		pinctrl-names = "default";
@@ -1672,9 +1697,52 @@ vdosys1_ep_ext: endpoint@1 {
 
 &xhci0 {
 	rx-fifo-depth = <3072>;
-	vbus-supply = <&usb_vbus>;
+	#address-cells = <1>;
+	#size-cells = <0>;
 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
 	status = "okay";
+
+	usb3_hub: usb-hub@1 {
+		compatible = "usb5e3,620";
+		reg = <1>;
+		reset-gpios = <&pio 84 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&pp5000_s5>;
+		peer-hub = <&usb2_hub>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@3 {
+				reg = <3>;
+
+				usb3_hub_p3_ep: endpoint {
+					remote-endpoint = <&usb_a_u3_ep>;
+				};
+			};
+		};
+	};
+
+	usb2_hub: usb-hub@2 {
+		compatible = "usb5e3,610";
+		reg = <2>;
+		reset-gpios = <&pio 84 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&pp5000_s5>;
+		peer-hub = <&usb3_hub>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@3 {
+				reg = <3>;
+
+				usb2_hub_p3_ep: endpoint {
+					remote-endpoint = <&usb_a_u2_ep>;
+				};
+			};
+		};
+	};
 };
 
 &xhci2 {
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 08/12] arm64: dts: mediatek: mt8192-asurada: Add USB type-A connector
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The MT8192 Asurada design features a USB type-A connector for external
devices.

Add a proper representation for it with a node for the connector and
OF graph connection to the USB hub behind it.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../boot/dts/mediatek/mt8192-asurada.dtsi     | 74 ++++++++++++++++++-
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index b7387075cb87..fb4d92750770 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -292,6 +292,32 @@ sound: sound {
 		pinctrl-24 = <&aud_gpio_tdm_off_pins>;
 		pinctrl-25 = <&aud_gpio_tdm_on_pins>;
 	};
+
+	usb-a-connector {
+		compatible = "usb-a-connector";
+		vbus-supply = <&pp5000_a>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				usb_a_u2_ep: endpoint {
+					remote-endpoint = <&usb2_hub_p3_ep>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				usb_a_u3_ep: endpoint {
+					remote-endpoint = <&usb3_hub_p3_ep>;
+				};
+			};
+		};
+	};
 };
 
 &afe {
@@ -1702,11 +1728,53 @@ &uart0 {
 };
 
 &xhci {
-	status = "okay";
-
 	wakeup-source;
 	vusb33-supply = <&pp3300_g>;
-	vbus-supply = <&pp5000_a>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	usb3_hub: usb-hub@1 {
+		compatible = "usb5e3,620";
+		reg = <1>;
+		reset-gpios = <&pio 44 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&pp5000_a>;
+		peer-hub = <&usb2_hub>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@3 {
+				reg = <3>;
+
+				usb3_hub_p3_ep: endpoint {
+					remote-endpoint = <&usb_a_u3_ep>;
+				};
+			};
+		};
+	};
+
+	usb2_hub: usb-hub@2 {
+		compatible = "usb5e3,610";
+		reg = <2>;
+		reset-gpios = <&pio 44 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&pp5000_a>;
+		peer-hub = <&usb3_hub>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@3 {
+				reg = <3>;
+
+				usb2_hub_p3_ep: endpoint {
+					remote-endpoint = <&usb_a_u2_ep>;
+				};
+			};
+		};
+	};
 };
 
 #include <arm/cros-ec-keyboard.dtsi>
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 10/12] arm64: dts: mediatek: mt8195-cherry: Add M.2 E-key slot
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The Mt8195 Cherry design features an M.2 E-key slot for WiFi/BT combo
cards. Only PCIe and USB are wired from the SoC to the slot, along with
some auxiliary signals.

Add the proper representation for it, replacing the PCIe wifi node and
vpcie3v3-supply property under the PCIe controller, and the vbus-supply
property under the xhci3 node.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../boot/dts/mediatek/mt8195-cherry.dtsi      | 74 +++++++++++++++++--
 1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index ef7afc436aef..c95a54de3567 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -266,6 +266,47 @@ tboard_thermistor2: thermal-sensor-t2 {
 						120000 51
 						125000 44>;
 	};
+
+	wifi-bt-connector {
+		compatible = "pcie-m2-e-connector";
+		pinctrl-names = "default";
+		pinctrl-0 = <&m2_e_key_kill_pins>;
+		vpcie3v3-supply = <&pp3300_wlan>;
+		w-disable1-gpios = <&pio 61 GPIO_ACTIVE_LOW>;
+		w-disable2-gpios = <&pio 59 GPIO_ACTIVE_LOW>;
+		/* PCIe auxiliary signals wired to controller. */
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PCIe for WiFi */
+			port@0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				wifi_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pcie1_ep>;
+				};
+			};
+
+			/* USB for Bluetooth */
+			port@2 {
+				reg = <2>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				bt_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&usb3_ep>;
+				};
+			};
+
+			/* SDIO, UART and I2S not implemented */
+		};
+	};
 };
 
 &adsp {
@@ -791,14 +832,14 @@ pcie@0 {
 		reg = <0 0 0 0 0>;
 		device_type = "pci";
 		num-lanes = <1>;
-		vpcie3v3-supply = <&pp3300_wlan>;
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges;
 
-		wifi@0 {
-			reg = <0 0 0 0 0>;
-			wakeup-source;
+		port {
+			pcie1_ep: endpoint {
+				remote-endpoint = <&wifi_ep>;
+			};
 		};
 	};
 };
@@ -1085,6 +1126,14 @@ pins-bus {
 		};
 	};
 
+	m2_e_key_kill_pins: m2-e-key-kill-pins {
+		pins-kill {
+			pinmux = <PINMUX_GPIO61__FUNC_GPIO61>,
+				 <PINMUX_GPIO59__FUNC_GPIO59>;
+			output-high;
+		};
+	};
+
 	mmc0_pins_default: mmc0-default-pins {
 		pins-cmd-dat {
 			pinmux = <PINMUX_GPIO126__FUNC_MSDC0_DAT0>,
@@ -1637,9 +1686,24 @@ &xhci2 {
 &xhci3 {
 	/* MT7921's USB Bluetooth has issues with USB2 LPM */
 	usb2-lpm-disable;
-	vbus-supply = <&pp3300_wlan>;
 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
 	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			usb3_ep: endpoint@0 {
+				reg = <0>;
+				remote-endpoint = <&bt_ep>;
+			};
+		};
+	};
 };
 
 #include <arm/cros-ec-keyboard.dtsi>
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 07/12] dt-bindings: usb: mediatek,mtk-xhci: Allow ports for USB connections
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

MediaTek's XHCI implementation supports both USB 2.0 High Speed (HS)
and USB 3.x Super Speed (SS). The block can also be synthesized with
either HS-only capability or HS+SS capability.

For example, on the MT8195, the first two instances support both HS and
SS, while the latter two instances support only HS.

Allow a ports sub-node for describing USB connections. Port 1 is Super
Speed if the controller is SS-capable, otherwise it is High Speed. Port
2 is High Speed if SS-capable. This port mapping scheme directly matches
what the hardware returns in its capability registers.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../devicetree/bindings/usb/mediatek,mtk-xhci.yaml  | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 75ecce3bdc7a..d6c75bd20b78 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -184,6 +184,19 @@ properties:
   "#size-cells":
     const: 0
 
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Super Speed (SS) data bus if SS-capable;
+          otherwise High Speed (HS) data bus.
+
+      port@2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: High Speed (HS) data bus if controller is SS-capable.
+
 patternProperties:
   "@[0-9a-f]{1}$":
     type: object
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 09/12] arm64: dts: mediatek: mt8192-asurada: Add M.2 E-key slot
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The MT8192 Asurada design features an M.2 E-key slot for WiFi/BT combo
cards. Only PCIe and USB are wired from the SoC to the slot, along with
some auxiliary signals.

Add the proper representation for it, replacing the PCIe wifi node and
vpcie3v3-supply property under the PCIe controller. Also clean up the
pcie controller node.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 .../boot/dts/mediatek/mt8192-asurada.dtsi     | 65 +++++++++++++++++--
 1 file changed, 58 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index fb4d92750770..901240384a4a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -318,6 +318,41 @@ usb_a_u3_ep: endpoint {
 			};
 		};
 	};
+
+	wifi-bt-connector {
+		compatible = "pcie-m2-e-connector";
+		pinctrl-names = "default";
+		pinctrl-0 = <&m2_e_key_kill_pins>;
+		vpcie3v3-supply = <&pp3300_wlan>;
+		w-disable1-gpios = <&pio 61 GPIO_ACTIVE_LOW>;
+		w-disable2-gpios = <&pio 59 GPIO_ACTIVE_LOW>;
+		/* PCIe auxiliary signals wired to controller. */
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* PCIe for WiFi */
+			port@0 {
+				reg = <0>;
+
+				wifi_ep: endpoint {
+					remote-endpoint = <&pcie_ep>;
+				};
+			};
+
+			/* USB for Bluetooth */
+			port@2 {
+				reg = <2>;
+
+				bt_ep: endpoint {
+					remote-endpoint = <&usb2_hub_p4_ep>;
+				};
+			};
+
+			/* SDIO, UART and I2S not implemented */
+		};
+	};
 };
 
 &afe {
@@ -671,19 +706,19 @@ &pcie {
 	pinctrl-0 = <&pcie_pins>;
 	memory-region = <&wifi_restricted_dma_region>;
 
-	pcie0: pcie@0,0 {
+	pcie@0 {
+		compatible = "pciclass,0604";
+		reg = <0 0 0 0 0>;
 		device_type = "pci";
-		reg = <0x0000 0 0 0 0>;
 		num-lanes = <1>;
-		bus-range = <0x1 0x1>;
-
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges;
 
-		wifi: wifi@0,0 {
-			reg = <0x10000 0 0 0 0x100000>,
-			      <0x10000 0 0x100000 0 0x100000>;
+		port {
+			pcie_ep: endpoint {
+				remote-endpoint = <&wifi_ep>;
+			};
 		};
 	};
 };
@@ -1206,6 +1241,14 @@ pins-bus {
 		};
 	};
 
+	m2_e_key_kill_pins: m2-e-key-kill-pins {
+		pins-kill {
+			pinmux = <PINMUX_GPIO61__FUNC_GPIO61>,
+				 <PINMUX_GPIO59__FUNC_GPIO59>;
+			output-high;
+		};
+	};
+
 	mmc0_default_pins: mmc0-default-pins {
 		pins-cmd-dat {
 			pinmux = <PINMUX_GPIO184__FUNC_MSDC0_DAT0>,
@@ -1773,6 +1816,14 @@ usb2_hub_p3_ep: endpoint {
 					remote-endpoint = <&usb_a_u2_ep>;
 				};
 			};
+
+			port@4 {
+				reg = <4>;
+
+				usb2_hub_p4_ep: endpoint {
+					remote-endpoint = <&bt_ep>;
+				};
+			};
 		};
 	};
 };
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 06/12] Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP"
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

This reverts commit 454a1e3cd36c113341d7b71e8e691c6e47ab4a8a.

mtk-xhci handles both USB 2.0 High Speed (HS) and USB 3.x SuperSpeed
(SS) host connections. And there are USB 2.0 only mtk-xhci blocks.
The SSUSB controller handles the device or gadget mode. Saying that
SSUSB handles the HS portion is wrong.

Fixes: 454a1e3cd36c ("dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP")
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 231e6f35a986..75ecce3bdc7a 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -107,10 +107,6 @@ properties:
       - description: USB3/SS(P) PHY
       - description: USB2/HS PHY
 
-  port:
-    $ref: /schemas/graph.yaml#/properties/port
-    description: Super Speed (SS) Output endpoint to a Type-C connector
-
   vusb33-supply:
     description: Regulator of USB AVDD3.3v
 
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 05/12] usb: hub: Power on connected M.2 E-key connectors
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The new M.2 E-key connector can have a USB connection. For the USB device
on this connector to work, its power must be enabled and the W_DISABLE2#
signal deasserted. The connector driver handles this and provides a
toggle over the power sequencing API.

This feature currently only supports a directly connected (no mux in
between) M.2 E-key connector. Existing USB connector types are not
covered. The USB A connector was recently added to the onboard devices
driver. USB B connectors have historically been managed by the USB
gadget or dual-role device controller drivers. USB C connectors are
handled by TCPM drivers.

The power sequencing API does not know whether a power sequence provider
is not needed or not available yet, so we only request it for connectors
that we know need it, which at this time is just the E-key connector.

The feature is limited to OF platforms, since the connection is over an
OF graph. And it doesn't make sense to return an error when the power
sequencing framework is not enabled, as that would block all USB
devices. Therefor the function short circuits out if any of these
conditions happen.

Also, this is not implemented in the onboard USB devices driver. The
power sequencing API expects the consumer device to make the request,
but there is no device node to instantiate a platform device to tie
the driver to. The connector is not a child node of the USB host or
hub, and the graph connection is from a USB port to the connector.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/usb/core/hub.c  | 17 ++++++++++++-
 drivers/usb/core/hub.h  |  2 ++
 drivers/usb/core/port.c | 54 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 90ea597d42ae..4165f71e212b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -31,7 +31,9 @@
 #include <linux/minmax.h>
 #include <linux/mutex.h>
 #include <linux/random.h>
+#include <linux/of_graph.h>
 #include <linux/pm_qos.h>
+#include <linux/pwrseq/consumer.h>
 #include <linux/kobject.h>
 
 #include <linux/bitfield.h>
@@ -888,13 +890,25 @@ int usb_hub_set_port_power(struct usb_device *hdev, struct usb_hub *hub,
 {
 	int ret;
 
+	if (set)
+		ret = pwrseq_power_on(hub->ports[port1 - 1]->pwrseq);
+	else
+		ret = pwrseq_power_off(hub->ports[port1 - 1]->pwrseq);
+	if (ret)
+		return ret;
+
 	if (set)
 		ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
 	else
 		ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
 
-	if (ret)
+	if (ret) {
+		if (set)
+			pwrseq_power_off(hub->ports[port1 - 1]->pwrseq);
+		else
+			pwrseq_power_on(hub->ports[port1 - 1]->pwrseq);
 		return ret;
+	}
 
 	if (set)
 		set_bit(port1, hub->power_bits);
@@ -1867,6 +1881,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_host_interface *desc;
 	struct usb_device *hdev;
 	struct usb_hub *hub;
+	int ret;
 
 	desc = intf->cur_altsetting;
 	hdev = interface_to_usbdev(intf);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 9ebc5ef54a32..6039e5f5dcd7 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -85,6 +85,7 @@ struct usb_hub {
  * @port_owner: port's owner
  * @peer: related usb2 and usb3 ports (share the same connector)
  * @connector: USB Type-C connector
+ * @pwrseq: power sequencing descriptor for the port
  * @req: default pm qos request for hubs without port power control
  * @connect_type: port's connect type
  * @state: device state of the usb device attached to the port
@@ -104,6 +105,7 @@ struct usb_port {
 	struct usb_dev_state *port_owner;
 	struct usb_port *peer;
 	struct typec_connector *connector;
+	struct pwrseq_desc *pwrseq;
 	struct dev_pm_qos_request *req;
 	enum usb_port_connect_type connect_type;
 	enum usb_device_state state;
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index b1364f0c384c..2d09037fee93 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -7,11 +7,14 @@
  * Author: Lan Tianyu <tianyu.lan@intel.com>
  */
 
+#include <linux/cleanup.h>
 #include <linux/kstrtox.h>
 #include <linux/slab.h>
 #include <linux/string_choices.h>
 #include <linux/sysfs.h>
+#include <linux/of_graph.h>
 #include <linux/pm_qos.h>
+#include <linux/pwrseq/consumer.h>
 #include <linux/component.h>
 #include <linux/usb/of.h>
 
@@ -28,6 +31,9 @@ static bool usb_port_allow_power_off(struct usb_device *hdev,
 	if (hub_is_port_power_switchable(hub))
 		return true;
 
+	if (port_dev->pwrseq)
+		return true;
+
 	if (!IS_ENABLED(CONFIG_ACPI))
 		return false;
 
@@ -748,6 +754,32 @@ static const struct component_ops connector_ops = {
 	.unbind = connector_unbind,
 };
 
+static struct pwrseq_desc *usb_hub_port_pwrseq_get(struct usb_device *hub, int port1)
+{
+	struct device_node *node = dev_of_node(&hub->dev);
+	struct device_node *np __free(device_node) = NULL;
+
+	if (!IS_ENABLED(CONFIG_OF))
+		return NULL;
+
+	if (!IS_ENABLED(CONFIG_POWER_SEQUENCING))
+		return NULL;
+
+	if (!of_graph_is_present(node))
+		return NULL;
+
+	np = of_graph_get_remote_node(node, port1, -1);
+	if (!np)
+		return NULL;
+
+	if (!of_device_is_compatible(np, "pcie-m2-e-connector")) {
+		dev_dbg(&hub->dev, "remote endpoint %pOF not m2 connector", np);
+		return NULL;
+	}
+
+	return pwrseq_get_index(&hub->dev, "usb", port1);
+}
+
 int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 {
 	struct usb_port *port_dev;
@@ -801,10 +833,24 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 		goto err_put_kn;
 	}
 
+	port_dev->pwrseq = usb_hub_port_pwrseq_get(hdev, port1);
+	if (IS_ERR(port_dev->pwrseq)) {
+		retval = PTR_ERR(port_dev->pwrseq);
+		dev_err_probe(&port_dev->dev, retval,
+			      "failed to get power sequencing descriptor\n");
+		goto err_put_kn;
+	}
+
+	retval = pwrseq_power_on(port_dev->pwrseq);
+	if (retval) {
+		dev_err_probe(&port_dev->dev, retval, "failed to enable power\n");
+		goto err_put_pwrseq;
+	}
+
 	retval = component_add(&port_dev->dev, &connector_ops);
 	if (retval) {
 		dev_warn(&port_dev->dev, "failed to add component\n");
-		goto err_put_kn;
+		goto err_pwrseq_off;
 	}
 
 	find_and_link_peer(hub, port1);
@@ -842,6 +888,10 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 	}
 	return 0;
 
+err_pwrseq_off:
+	pwrseq_power_off(port_dev->pwrseq);
+err_put_pwrseq:
+	pwrseq_put(port_dev->pwrseq);
 err_put_kn:
 	sysfs_put(port_dev->state_kn);
 err_unregister:
@@ -858,6 +908,8 @@ void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
 	peer = port_dev->peer;
 	if (peer)
 		unlink_peers(port_dev, peer);
+	pwrseq_power_off(port_dev->pwrseq);
+	pwrseq_put(port_dev->pwrseq);
 	component_del(&port_dev->dev, &connector_ops);
 	sysfs_put(port_dev->state_kn);
 	device_unregister(&port_dev->dev);
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 04/12] usb: hub: Return actual error from hub_configure() in hub_probe()
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The addition of power sequencing descriptor handling in the USB hub code
requires dealing with deferred probing from pwrseq_get(). The power
sequencing provider may not yet be available when the USB hub probes.

Return the actual error code from hub_configure() when it fails, so that
the driver core can notice the deferred probe request.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/usb/core/hub.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24960ba9caa9..90ea597d42ae 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1998,14 +1998,15 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 		usb_set_interface(hdev, 0, 0);
 	}
 
-	if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) {
+	ret = hub_configure(hub, &desc->endpoint[0].desc);
+	if (ret >= 0) {
 		onboard_dev_create_pdevs(hdev, &hub->onboard_devs);
 
 		return 0;
 	}
 
 	hub_disconnect(intf);
-	return -ENODEV;
+	return ret;
 }
 
 static int
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 03/12] power: sequencing: pcie-m2: Add usb and sdio targets for E-key connector
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

The M.2 E-key connector allows either PCIe or SDIO for WiFi and USB or
UART for BT. Currently the driver only supports PCIe and UART.

Add power sequencing targets for SDIO and USB. To avoid adding a
complicated dependency tree, rename the existing power sequencing units
"pcie" and "uart" to "wifi" and "bt". The existing target names are left
untouched. The new "sdio" and "usb" targets just point to the renamed
"wifi" and "bt" units.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/power/sequencing/pwrseq-pcie-m2.c | 41 +++++++++++++++--------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index c9aed2c02e81..a5585f000ef1 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -62,46 +62,46 @@ static const struct pwrseq_unit_data *pwrseq_pcie_m2_unit_deps[] = {
 	NULL
 };
 
-static int pwrseq_pci_m2_e_uart_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_bt_enable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
 	return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
 }
 
-static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_bt_disable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
 	return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
 }
 
-static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = {
-	.name = "uart-enable",
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_bt_unit_data = {
+	.name = "bt-enable",
 	.deps = pwrseq_pcie_m2_unit_deps,
-	.enable = pwrseq_pci_m2_e_uart_enable,
-	.disable = pwrseq_pci_m2_e_uart_disable,
+	.enable = pwrseq_pci_m2_e_bt_enable,
+	.disable = pwrseq_pci_m2_e_bt_disable,
 };
 
-static int pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_wifi_enable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
 	return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 0);
 }
 
-static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq)
+static int pwrseq_pci_m2_e_wifi_disable(struct pwrseq_device *pwrseq)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 
 	return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1);
 }
 
-static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = {
-	.name = "pcie-enable",
+static const struct pwrseq_unit_data pwrseq_pcie_m2_e_wifi_unit_data = {
+	.name = "wifi-enable",
 	.deps = pwrseq_pcie_m2_unit_deps,
-	.enable = pwrseq_pci_m2_e_pcie_enable,
-	.disable = pwrseq_pci_m2_e_pcie_disable,
+	.enable = pwrseq_pci_m2_e_wifi_enable,
+	.disable = pwrseq_pci_m2_e_wifi_disable,
 };
 
 static const struct pwrseq_unit_data pwrseq_pcie_m2_m_pcie_unit_data = {
@@ -123,13 +123,24 @@ static int pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device *pwrseq)
 
 static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = {
 	.name = "uart",
-	.unit = &pwrseq_pcie_m2_e_uart_unit_data,
+	.unit = &pwrseq_pcie_m2_e_bt_unit_data,
 	.post_enable = pwrseq_pcie_m2_e_pwup_delay,
 };
 
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_usb_target_data = {
+	.name = "usb",
+	.unit = &pwrseq_pcie_m2_e_bt_unit_data,
+};
+
 static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = {
 	.name = "pcie",
-	.unit = &pwrseq_pcie_m2_e_pcie_unit_data,
+	.unit = &pwrseq_pcie_m2_e_wifi_unit_data,
+	.post_enable = pwrseq_pcie_m2_e_pwup_delay,
+};
+
+static const struct pwrseq_target_data pwrseq_pcie_m2_e_sdio_target_data = {
+	.name = "sdio",
+	.unit = &pwrseq_pcie_m2_e_wifi_unit_data,
 	.post_enable = pwrseq_pcie_m2_e_pwup_delay,
 };
 
@@ -140,7 +151,9 @@ static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
 
 static const struct pwrseq_target_data *pwrseq_pcie_m2_e_targets[] = {
 	&pwrseq_pcie_m2_e_pcie_target_data,
+	&pwrseq_pcie_m2_e_sdio_target_data,
 	&pwrseq_pcie_m2_e_uart_target_data,
+	&pwrseq_pcie_m2_e_usb_target_data,
 	NULL
 };
 
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 02/12] power: sequencing: pcie-m2: implement port index matching
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

For USB connections, the upstream USB (hub) device could be connected to
multiple M.2 E-key slots (or other power sequencer providers) via
different downstream USB ports. The provider needs a way to tell the
different connections apart so that the correct provider is matched.

In the previous change an index parameter was added for the consumer API
and the provider matching function. Implement port matching using the
index parameter. We simply check if the remote endpoint's port number
matches the index.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/power/sequencing/pwrseq-pcie-m2.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 16a332f9da7d..c9aed2c02e81 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -165,12 +165,28 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
 
 	/*
 	 * Traverse the 'remote-endpoint' nodes and check if the remote node's
-	 * parent matches the OF node of 'dev'.
+	 * parent matches the OF node of 'dev' and the port number matches
+	 * 'index'.
 	 */
 	for_each_endpoint_of_node(ctx->of_node, endpoint) {
+		struct device_node *remote_ep __free(device_node) =
+				of_graph_get_remote_endpoint(endpoint);
 		struct device_node *remote __free(device_node) =
-				of_graph_get_remote_port_parent(endpoint);
-		if (remote && (remote == dev_of_node(dev)))
+				of_graph_get_port_parent(remote_ep);
+		struct of_endpoint ep;
+
+		if (!remote)
+			continue;
+		if (remote != dev_of_node(dev))
+			continue;
+		/* For existing users of pwrseq_get(): index = -1 */
+		if (index < 0)
+			return PWRSEQ_MATCH_OK;
+
+		/* Check if the remote endpoint's port matches 'index'. */
+		if (of_graph_parse_endpoint(remote_ep, &ep) < 0)
+			continue;
+		if (ep.port == index)
 			return PWRSEQ_MATCH_OK;
 	}
 
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 01/12] power: sequencing: Add index parameter for getting power sequencer
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam
In-Reply-To: <20260515090149.3169406-1-wenst@chromium.org>

In some cases more than one sequencer could be associated with a
particular device. For example, a USB hub has multiple downstream ports,
and each port could be connected to a different M.2 E-key slot. In this
case the index would be the port number. The index tells power
sequencers for different slots (connected to different hub ports) apart.

For the consumer API, add a new pwrseq_get_index() for new users. The
original pwrseq_get() now calls pwrseq_get_index() with index = -1.

For the provider API, add the index parameter to the .match function
signature, and tweak all existing providers to match. Actual use of
the new index parameter will be introduced in the next change.

Other than the API change, no functional changes are intended.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/power/sequencing/core.c             | 12 ++++++++----
 drivers/power/sequencing/pwrseq-pcie-m2.c   |  2 +-
 drivers/power/sequencing/pwrseq-qcom-wcn.c  |  6 +++---
 drivers/power/sequencing/pwrseq-thead-gpu.c |  2 +-
 include/linux/pwrseq/consumer.h             |  6 ++++--
 include/linux/pwrseq/provider.h             |  2 +-
 6 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c
index 14335c4f813e..1a91ee6d416f 100644
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -612,6 +612,7 @@ struct pwrseq_match_data {
 	struct pwrseq_desc *desc;
 	struct device *dev;
 	const char *target;
+	int index;
 };
 
 static int pwrseq_match_device(struct device *pwrseq_dev, void *data)
@@ -627,7 +628,7 @@ static int pwrseq_match_device(struct device *pwrseq_dev, void *data)
 	if (!device_is_registered(&pwrseq->dev))
 		return 0;
 
-	ret = pwrseq->match(pwrseq, match_data->dev);
+	ret = pwrseq->match(pwrseq, match_data->dev, match_data->index);
 	if (ret == PWRSEQ_NO_MATCH || ret < 0)
 		return ret;
 
@@ -655,16 +656,18 @@ static int pwrseq_match_device(struct device *pwrseq_dev, void *data)
 }
 
 /**
- * pwrseq_get() - Get the power sequencer associated with this device.
+ * pwrseq_get_index() - Get the power sequencer associated with this device.
  * @dev: Device for which to get the sequencer.
  * @target: Name of the target exposed by the sequencer this device wants to
  *          reach.
+ * @index: Index of the sequencer associated with the device.
  *
  * Returns:
  * New power sequencer descriptor for use by the consumer driver or ERR_PTR()
  * on failure.
  */
-struct pwrseq_desc *pwrseq_get(struct device *dev, const char *target)
+struct pwrseq_desc *pwrseq_get_index(struct device *dev, const char *target,
+				     int index)
 {
 	struct pwrseq_match_data match_data;
 	int ret;
@@ -676,6 +679,7 @@ struct pwrseq_desc *pwrseq_get(struct device *dev, const char *target)
 	match_data.desc = desc;
 	match_data.dev = dev;
 	match_data.target = target;
+	match_data.index = index;
 
 	guard(rwsem_read)(&pwrseq_sem);
 
@@ -689,7 +693,7 @@ struct pwrseq_desc *pwrseq_get(struct device *dev, const char *target)
 
 	return_ptr(desc);
 }
-EXPORT_SYMBOL_GPL(pwrseq_get);
+EXPORT_SYMBOL_GPL(pwrseq_get_index);
 
 /**
  * pwrseq_put() - Release the power sequencer descriptor.
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index ef69ae268059..16a332f9da7d 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -158,7 +158,7 @@ static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_m_of_data = {
 };
 
 static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
-				 struct device *dev)
+				 struct device *dev, int index)
 {
 	struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 	struct device_node *endpoint __free(device_node) = NULL;
diff --git a/drivers/power/sequencing/pwrseq-qcom-wcn.c b/drivers/power/sequencing/pwrseq-qcom-wcn.c
index b55b4317e21b..ac6b34e01c51 100644
--- a/drivers/power/sequencing/pwrseq-qcom-wcn.c
+++ b/drivers/power/sequencing/pwrseq-qcom-wcn.c
@@ -335,7 +335,7 @@ static const char *const pwrseq_wcn3990_vregs[] = {
 };
 
 static int pwrseq_qcom_wcn3990_match(struct pwrseq_device *pwrseq,
-				     struct device *dev);
+				     struct device *dev, int index);
 
 static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn3990_of_data = {
 	.vregs = pwrseq_wcn3990_vregs,
@@ -436,13 +436,13 @@ static int pwrseq_qcom_wcn_match_regulator(struct pwrseq_device *pwrseq,
 }
 
 static int pwrseq_qcom_wcn_match(struct pwrseq_device *pwrseq,
-				 struct device *dev)
+				 struct device *dev, int index)
 {
 	return pwrseq_qcom_wcn_match_regulator(pwrseq, dev, "vddaon-supply");
 }
 
 static int pwrseq_qcom_wcn3990_match(struct pwrseq_device *pwrseq,
-				     struct device *dev)
+				     struct device *dev, int index)
 {
 	int ret;
 
diff --git a/drivers/power/sequencing/pwrseq-thead-gpu.c b/drivers/power/sequencing/pwrseq-thead-gpu.c
index a45318b4b2c1..cb7a6ea66c4b 100644
--- a/drivers/power/sequencing/pwrseq-thead-gpu.c
+++ b/drivers/power/sequencing/pwrseq-thead-gpu.c
@@ -115,7 +115,7 @@ static const struct pwrseq_target_data *pwrseq_thead_gpu_targets[] = {
 };
 
 static int pwrseq_thead_gpu_match(struct pwrseq_device *pwrseq,
-				  struct device *dev)
+				  struct device *dev, int index)
 {
 	struct pwrseq_thead_gpu_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
 	static const char *const clk_names[] = { "core", "sys" };
diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h
index 7d583b4f266e..d5d57cdb0c8e 100644
--- a/include/linux/pwrseq/consumer.h
+++ b/include/linux/pwrseq/consumer.h
@@ -11,10 +11,12 @@
 struct device;
 struct pwrseq_desc;
 
+#define pwrseq_get(dev, target) pwrseq_get_index(dev, target, -1)
+
 #if IS_ENABLED(CONFIG_POWER_SEQUENCING)
 
 struct pwrseq_desc * __must_check
-pwrseq_get(struct device *dev, const char *target);
+pwrseq_get_index(struct device *dev, const char *target, int index);
 void pwrseq_put(struct pwrseq_desc *desc);
 
 struct pwrseq_desc * __must_check
@@ -26,7 +28,7 @@ int pwrseq_power_off(struct pwrseq_desc *desc);
 #else /* CONFIG_POWER_SEQUENCING */
 
 static inline struct pwrseq_desc * __must_check
-pwrseq_get(struct device *dev, const char *target)
+pwrseq_get_index(struct device *dev, const char *target, int index)
 {
 	return ERR_PTR(-ENOSYS);
 }
diff --git a/include/linux/pwrseq/provider.h b/include/linux/pwrseq/provider.h
index 33b3d2c2e39d..a2ec6c612c8b 100644
--- a/include/linux/pwrseq/provider.h
+++ b/include/linux/pwrseq/provider.h
@@ -11,7 +11,7 @@ struct module;
 struct pwrseq_device;
 
 typedef int (*pwrseq_power_state_func)(struct pwrseq_device *);
-typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *);
+typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *, int);
 
 #define PWRSEQ_NO_MATCH 0
 #define PWRSEQ_MATCH_OK 1
-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply related

* [PATCH RFC 00/12] arm64: mediatek: Add M.2 E-key slot on Chromebooks
From: Chen-Yu Tsai @ 2026-05-15  9:01 UTC (permalink / raw)
  To: Bartosz Golaszewski, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, linux-pm, linux-usb, devicetree, linux-mediatek,
	linux-arm-kernel, linux-kernel, Manivannan Sadhasivam

Hi everyone,

This series is my attempt at enabling power sequencing for USB to support
the USB connection on M.2 E-key slots. M.2 E-key was enabled in v7.1-rc1
with just PCIe and UART supported [1].

Most of the series is based on next-20260508, while the DT changes also
depend on some other DT cleanup patches I sent [2][3].


Patch 1 reworks the power sequencing framework to allow matching against
different USB ports. The consumer API gains an "index" parameter (which
is the USB port number on the hub), while the provider API is reworked
to pass the index to the matching function of the providing driver.

Patch 2 implements the index matching in the pcie-m2 driver. Matching
only happens when a valid (>= 0) index is given.

Patch 3 reworks the power sequencing targets for the E-key connector in
the pcie-m2 driver to add targets for USB and SDIO. The former is used
later on in this series.

Patch 4 reworks the USB hub driver to return the actual error code from
hub_configure() in hub_probe(). This is needed in the next patch to
correctly return -EPROBE_DEFER.

Patch 5 lets the USB hub driver look for power sequencers for each port.
Currently this only works for M.2 E-key connections, but it could be
extended to cover other cases. It should also make port reset via turning
off the port VBUS work, even when VBUS is not directly controlled by the
hub.

I expect some discussion on this patch, because a) it adds some
OF-specific code into an otherwise generic (core) driver, and
b) it doesn't yet handle USB 2.0 / 3.x shared ports; it ends up powering
on the port twice, which negates the port reset part.

Patch 6 reverts an incorrectly modeled OF graph connection for the
MediaTek XHCI controller.

Patch 7 then adds a proper representation.

Patches 8 through 12 enable the M.2 E-key slots (used for WiFi/BT) and
USB type-A connectors found on MediaTek-based Chromebooks. These are
provided in this series for reference. The USB type-A connector changes,
while not directly related, have overlapping context, and was easier to
include. They were also used to test some extra local changes I tried
to convert the USB A connector from an onboard USB device to a power
sequencing provider.


As this series changes existing power sequencing API, and also uses the
changed API in subsequent patches, I think the best way to merge this
is for Bartosz to take the power sequencing patches and provide an
immutable tag for Greg to merge and then merge the USB patches.

The DT patches can go through the soc tree once all the driver and DT
binding changes are merged.


Thanks
ChenYu

P.S. I'll be at Embedded Recipes if anyone wants to discuss details.

[1] https://lore.kernel.org/all/20260326-pci-m2-e-v7-0-43324a7866e6@oss.qualcomm.com/
[2] https://lore.kernel.org/all/20260505101408.1796563-1-wenst@chromium.org/
[3] https://lore.kernel.org/all/20260514101254.2749300-1-wenst@chromium.org/


Chen-Yu Tsai (12):
  power: sequencing: Add index parameter for getting power sequencer
  power: sequencing: pcie-m2: implement port index matching
  power: sequencing: pcie-m2: Add usb and sdio targets for E-key
    connector
  usb: hub: Return actual error from hub_configure() in hub_probe()
  usb: hub: Power on connected M.2 E-key connectors
  Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed
    EP"
  dt-bindings: usb: mediatek,mtk-xhci: Allow ports for USB connections
  arm64: dts: mediatek: mt8192-asurada: Add USB type-A connector
  arm64: dts: mediatek: mt8192-asurada: Add M.2 E-key slot
  arm64: dts: mediatek: mt8195-cherry: Add M.2 E-key slot
  arm64: dts: mediatek: mt8195-cherry: Add USB type-A connector
  arm64: dts: mediatek: mt8188-geralt: Add WiFi/BT as M.2 E-key slot

 .../bindings/usb/mediatek,mtk-xhci.yaml       |  17 +-
 .../boot/dts/mediatek/mt8188-geralt.dtsi      |  93 ++++++++++-
 .../boot/dts/mediatek/mt8192-asurada.dtsi     | 139 +++++++++++++++--
 .../boot/dts/mediatek/mt8195-cherry.dtsi      | 146 +++++++++++++++++-
 drivers/power/sequencing/core.c               |  12 +-
 drivers/power/sequencing/pwrseq-pcie-m2.c     |  65 +++++---
 drivers/power/sequencing/pwrseq-qcom-wcn.c    |   6 +-
 drivers/power/sequencing/pwrseq-thead-gpu.c   |   2 +-
 drivers/usb/core/hub.c                        |  22 ++-
 drivers/usb/core/hub.h                        |   2 +
 drivers/usb/core/port.c                       |  54 ++++++-
 include/linux/pwrseq/consumer.h               |   6 +-
 include/linux/pwrseq/provider.h               |   2 +-
 13 files changed, 508 insertions(+), 58 deletions(-)

-- 
2.54.0.563.g4f69b47b94-goog



^ permalink raw reply

* [PATCH] arm_mpam: Fix software reset values of MPAMCFG_PRI
From: Ben Horgan @ 2026-05-15  8:58 UTC (permalink / raw)
  To: ben.horgan
  Cc: james.morse, reinette.chatre, fenghuay, linux-kernel,
	catalin.marinas, linux-arm-kernel

Priority partitioning is not supported other than to set the per-PARTID
defaults in MPAMCFG_PRI, INTPRI and DSPRI, to the highest priority. When 0
is the lowest priority, all ones is the highest priority. However, these
values are calculated with an extra higher bit set.

Luckily, there is still no chance of setting functional bits incorrectly.
When the priority widths are maximal, this is ensured as the fields have
width 16 and a u16 holds the value for each field. When the widths are
smaller, the higher order bits beyond the advertised widths,
MPAMF_PRI_IDR.DSPRI_WD and MPAMF_PRI_IDR.INTPRI_WD, in the priority fields
INTPRI and DSPRI are not used to calculate the priority.  It is not
specified whether these higher order bits are RAZ/WI or Res0 and so it is
desirable not to set them to avoid the chance of misleading reads.

Correct the priority reset values.

Fixes: 880df85d8673 ("arm_mpam: Probe and reset the rest of the features")
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
---
 drivers/resctrl/mpam_devices.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index 41b14344b16f..a627dc2c53de 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -1539,12 +1539,9 @@ static u16 mpam_wa_t241_calc_min_from_max(struct mpam_props *props,
 static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 				      struct mpam_config *cfg)
 {
-	u32 pri_val = 0;
 	u16 cmax = MPAMCFG_CMAX_CMAX;
 	struct mpam_msc *msc = ris->vmsc->msc;
 	struct mpam_props *rprops = &ris->props;
-	u16 dspri = GENMASK(rprops->dspri_wd, 0);
-	u16 intpri = GENMASK(rprops->intpri_wd, 0);
 
 	mutex_lock(&msc->part_sel_lock);
 	__mpam_part_sel(ris->ris_idx, partid, msc);
@@ -1609,16 +1606,25 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
 
 	if (mpam_has_feature(mpam_feat_intpri_part, rprops) ||
 	    mpam_has_feature(mpam_feat_dspri_part, rprops)) {
-		/* aces high? */
-		if (!mpam_has_feature(mpam_feat_intpri_part_0_low, rprops))
-			intpri = 0;
-		if (!mpam_has_feature(mpam_feat_dspri_part_0_low, rprops))
-			dspri = 0;
+		u32 pri_val = 0;
+
+		if (mpam_has_feature(mpam_feat_intpri_part, rprops)) {
+			u16 intpri = GENMASK(rprops->intpri_wd - 1, 0);
+
+			/* aces high? */
+			if (!mpam_has_feature(mpam_feat_intpri_part_0_low, rprops))
+				intpri = 0;
 
-		if (mpam_has_feature(mpam_feat_intpri_part, rprops))
 			pri_val |= FIELD_PREP(MPAMCFG_PRI_INTPRI, intpri);
-		if (mpam_has_feature(mpam_feat_dspri_part, rprops))
+		}
+		if (mpam_has_feature(mpam_feat_dspri_part, rprops)) {
+			u16 dspri = GENMASK(rprops->dspri_wd - 1, 0);
+
+			if (!mpam_has_feature(mpam_feat_dspri_part_0_low, rprops))
+				dspri = 0;
+
 			pri_val |= FIELD_PREP(MPAMCFG_PRI_DSPRI, dspri);
+		}
 
 		mpam_write_partsel_reg(msc, PRI, pri_val);
 	}
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH v5 3/8] arm64: entry: add unwind info for various kernel entries
From: Mark Rutland @ 2026-05-15  8:58 UTC (permalink / raw)
  To: Dylan Hatch
  Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
	Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
	Jiri Kosina, Jens Remus, Prasanna Kumar T S M, Puranjay Mohan,
	Song Liu, joe.lawrence, linux-toolchains, linux-kernel,
	live-patching, linux-arm-kernel, Randy Dunlap
In-Reply-To: <CADBMgpxBeYUdA5X8BPgkgz=KQyN=NQ760bXygwXfvVRScNzgbA@mail.gmail.com>

On Thu, May 14, 2026 at 08:30:43PM -0700, Dylan Hatch wrote:
> On Wed, Apr 29, 2026 at 8:26 AM Mark Rutland <mark.rutland@arm.com> wrote:
> > On Tue, Apr 28, 2026 at 06:36:38PM +0000, Dylan Hatch wrote:
> > > From: Weinan Liu <wnliu@google.com>
> > >
> > > DWARF CFI (Call Frame Information) specifies how to recover the return
> > > address and callee-saved registers at each PC in a given function.
> > > Compilers are able to generate the CFI annotations when they compile
> > > the code to assembly language. For handcrafted assembly, we need to
> > > annotate them by hand.
> > >
> > > Annotate minimal CFI to enable stacktracing using SFrame for kernel
> > > exception entries through el1*_64_*() paths
> >
> > I thought we were only consuming SFrame when unwinding an exeption
> > boundary?
> >
> > We shouldn't be taking exceptions _from_ the entry assembly functions
> > unless something has gone horribly wrong, and so I don't see why we'd
> > need CFI entries for the entry assembly functions.
> >
> > Am I missing some reason we need CFI entries for the entry assembly
> > functions? I strongly suspect it is not necessary to add these, and I'd
> > prefer to omit them.
> 
> I believe the el1 entry functions are called in an exception, and are
> called before call_on_irq_stack. 

Yes, but I don't think that matters. See below for more details.

> Example stacktrace segment:
> 
> [  262.119564]  handle_percpu_devid_irq+0xb4/0x348
> [  262.119913]  handle_irq_desc+0x3c/0x68
> [  262.120196]  generic_handle_domain_irq+0x20/0x40
> [  262.120678]  gic_handle_irq+0x48/0xe0
> [  262.121005]  call_on_irq_stack+0x30/0x48
> [  262.121412]  do_interrupt_handler+0x88/0xa0
> [  262.121779]  el1_interrupt+0x38/0x58
> [  262.122089]  el1h_64_irq_handler+0x18/0x30
> [  262.122617]  el1h_64_irq+0x6c/0x70

The segment immediately above can be unwound using FP, as frame records
were created consistently, and there are no exception boundaries. No CFI
needed.

It's legitimate to take an exception from parts of call_on_irq_stack(),
so it makes sense for that to have CFI, but for the specific unwind
segment above, CFI isn't necessary.

Everything in the stacktrace segment above was executed *after* HW took
the exception.

<< EXCEPTION BOUNDARY HERE >>

Everything in the stacktrace segment(s) below was executed *before* HW
took the exception.

The unwinder knows that it has crossed this exception boundary by virtue
of finding a FRAME_META_TYPE_PT_REGS frame record.

> [  262.123159]  _raw_spin_unlock_irq+0x10/0x60 (P)

The unwinder knows that the value of pt_regs::pc was *definitely* the PC
at the time the exception was taken, so that entry is reliable. No CFI
needed.

> [  262.123720]  __filemap_add_folio+0x200/0x580 (L)

The unwinder doesn't know whether the LR should be used, and needs CFI
to determine that.

After this point, an FP unwind can be used until we encounter the next
exception boundary.

> [  262.124145]  filemap_add_folio+0xec/0x300
> [  262.124674]  page_cache_ra_unbounded+0x128/0x368
> [  262.125338]  do_page_cache_ra+0x70/0x98
> [  262.125875]  page_cache_ra_order+0x460/0x4e0

The segment immediately above can be unwound using FP. No CFI needed.

> Here, el1h_64_irq is the last function that appears in the exception
> stack before _raw_spin_unlock_irq and __filemap_add_folio are
> recovered from the saved PC and LR, respectively. So we therefore need
> the CFI annotations in order to unwind through the full exception
> boundary.
> 
> Is my interpretation here correct?

Given you say "full exception boundary" here, I think we might be using
the term "exception boundary" to mean different things.

As per the example above, I'm using "exception boundary" to mean the a
point between two entries in the stacktrace where HW took an exception.

Did my comments on the example help?

> > > and irq entries through call_on_irq_stack()
> >
> > Needing some sort of unwind annotations for call_on_irq_stack() makes
> > sense to me, but don't we need something for other assembly functions
> > too?
> >
> > We can interrupt things like memset(); I assume we'll treat those as
> > unreliable until annotated?
> 
> While looking into adding these annotations, I noticed a pattern where
> a sibling call is made to a local function:
> 
> SYM_FUNC_START(__pi_memset)
> alternative_if_not ARM64_HAS_MOPS
>         b       __pi_memset_generic
> alternative_else_nop_endif
> 
>         mov     dst, dstin
>         setp    [dst]!, count!, val_x
>         setm    [dst]!, count!, val_x
>         sete    [dst]!, count!, val_x
>         ret
> SYM_FUNC_END(__pi_memset)
> 
> In this case, do we consider the stacktrace unreliable since
> __pi_memset may not appear in the trace?

This is a tail-call, and __pi_memset_generic() will not return to
__pi_memset(). Once the branch to __pi_memset_generic() has been
executed, it's fine for __pi_memset() to not show up in the trace.

The key thing is that no more instructions from __pi_memset() itself
will be executed unless it was called again (from its entry point).

> Or is this not important because assembly functions cannot be directly
> livepatched anyway?

To the best of my knowledge, reliable stacktrace is only used to
determine whether any thread is still within an old version of a
patchable function (including where it's within a callee thereof).

I am not aware of a case where we'd need to detect whether a thread is
still within a non-patchable function, but I can't rule out that as a
possibility.

That's more of a question for the livepatching maintainers.

Thanks,
Mark.


^ permalink raw reply

* Re: [PATCH v6 07/13] coresight: etm4x: fix inconsistencies with sysfs configuration
From: Leo Yan @ 2026-05-15  8:53 UTC (permalink / raw)
  To: Yeoreum Yun
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	mike.leach, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <20260422132203.977549-8-yeoreum.yun@arm.com>

On Wed, Apr 22, 2026 at 02:21:57PM +0100, Yeoreum Yun wrote:

[...]

>   - Since active_config and related fields are accessed only by the local CPU
>     in etm4_enable/disable_sysfs_smp_call() (similar to perf enable/disable),
>     remove the lock/unlock from the sysfs enable/disable path and
>     startup/dying_cpu except when to access config fields.

Thanks for writing this up, which is helpful for understanding.

[...]

> @@ -918,40 +948,29 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
>  
>  	/* enable any config activated by configfs */
>  	cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);

With the patch [1], we can move cscfg_config_sysfs_get_active_cfg() to
smp call. As a result, all things for enabling cscfg can be in the
same place.

[1] https://lore.kernel.org/linux-arm-kernel/20260511-arm_coresight_path_power_management_improvement-v12-14-1c9dcb1de8c9@arm.com/

> -	if (cfg_hash) {
> -		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
> -		if (ret) {
> -			etm4_release_trace_id(drvdata);
> -			return ret;
> -		}
> -	}
> -
> -	raw_spin_lock(&drvdata->spinlock);
> -
> -	drvdata->trcid = path->trace_id;
> -
> -	/* Tracer will never be paused in sysfs mode */
> -	drvdata->paused = false;
>  
>  	/*
>  	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
>  	 * ensures that register writes occur when cpu is powered.
>  	 */
>  	arg.drvdata = drvdata;
> +	arg.path = path;
> +	arg.cfg_hash = cfg_hash;
> +	arg.preset = preset;

Connect with the comment above , don't need to pass cfg_hash/preset anymore.

> +	raw_spin_lock(&drvdata->spinlock);
> +	arg.config = drvdata->config;
> +	raw_spin_unlock(&drvdata->spinlock);

Seems to me, this is right way for locking - here we simply use
spinlock for exclusive access config from sysfs knobs.

However, we avoid the config copy and directly access in SMP call?
we still can use the raw spinlock in SMP call.

My suggestion is:

- First use a patch to move the drvdata assignment to SMP call and
  remove spinlock;
- Then, rebase this patch for moving cscfg into SMP call.

If so, we only need add a new field "arg->path", right?


> @@ -1857,13 +1875,11 @@ static int etm4_starting_cpu(unsigned int cpu)
>  	if (!etmdrvdata[cpu])
>  		return 0;
>  
> -	raw_spin_lock(&etmdrvdata[cpu]->spinlock);

With the change [2], the starting and dying functions have been
removed.

If you rebase patches on the top PM series, then you will not bother
this. Anyway, this is right to remove spinlock for hotplug notifiers.

[2] https://lore.kernel.org/linux-arm-kernel/20260511-arm_coresight_path_power_management_improvement-v12-27-1c9dcb1de8c9@arm.com/



^ permalink raw reply

* Re: [PATCH] i2c: davinci: fix division by zero on missing clock-frequency
From: Chaitanya Sabnis @ 2026-05-15  8:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: brgl, andi.shyti, linux-arm-kernel, linux-i2c, linux-kernel,
	Sashiko
In-Reply-To: <1ce483f8-1d9a-40c3-a45e-6ca536010b20@lunn.ch>

Hi Andrew,

That makes complete sense. Updating the macro to Hz is a much cleaner
approach and aligns perfectly with the expected unit of the device
tree property.

I have track down the original commit for the Fixes: tag and send out a v2.

Thanks for the review!
Chaitanya


On Thu, May 14, 2026 at 5:46 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Thu, May 14, 2026 at 04:07:40PM +0530, Chaitanya Sabnis wrote:
> > When the 'clock-frequency' property is missing from the device tree,
> > the driver falls back to DAVINCI_I2C_DEFAULT_BUS_FREQ. However, this
> > macro is defined in kHz (100), whereas the device tree property is
> > expected in Hz.
> >
> > The probe function blindly divided the fallback value by 1000, causing
> > integer truncation that resulted in dev->bus_freq = 0. This triggered
> > a deterministic division-by-zero kernel panic when calculating clock
> > dividers later in the probe sequence.
> >
> > Fix this by isolating the division so it only applies to the Hz value
> > read from the device tree, cleanly assigning the kHz default otherwise.
>
> Why not keep the patch simple and just change the value of
> DAVINCI_I2C_DEFAULT_BUS_FREQ to Hz?
>
> > Reported-by: Sashiko <sashiko-bot@kernel.org>
> > Closes: https://lore.kernel.org/all/20260514044726.57297C2BCB7@smtp.kernel.org/
> > Signed-off-by: Chaitanya Sabnis <chaitanya.msabnis@gmail.com>
>
> Please also added a Fixes: tag.
>
>        Andrew


^ permalink raw reply

* Re: [PATCH 1/8] dt-bindings: arm-smmu: Update the description for Kaanapali GPU SMMU
From: Krzysztof Kozlowski @ 2026-05-15  8:41 UTC (permalink / raw)
  To: Akhil P Oommen
  Cc: Will Deacon, Robin Murphy, Joerg Roedel, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
	Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Sean Paul,
	linux-arm-kernel, iommu, devicetree, linux-kernel, linux-arm-msm,
	freedreno, dri-devel
In-Reply-To: <20260512-kaana-gpu-dt-v1-1-13e1c07c2050@oss.qualcomm.com>

On Tue, May 12, 2026 at 03:53:15AM +0530, Akhil P Oommen wrote:
> Extend the sm8750's clock description section to also cover Kaanapali GPU

There is nothing about sm8750 in the diff. Probably you wanted to
document the constraint of clock for Kaapanali Adreno SMMU?

> SMMU since it uses the same single "hlos" vote clock.
> 
> Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
> ---

Best regards,
Krzysztof



^ permalink raw reply

* [PATCH v2] i2c: davinci: fix division by zero on missing clock-frequency
From: Chaitanya Sabnis @ 2026-05-15  8:39 UTC (permalink / raw)
  To: brgl, andi.shyti
  Cc: linux-arm-kernel, linux-i2c, linux-kernel, Chaitanya Sabnis,
	Sashiko

When the 'clock-frequency' property is missing from the device tree,
the driver falls back to DAVINCI_I2C_DEFAULT_BUS_FREQ. However, this
macro was defined in kHz (100), whereas the device tree property is
expected in Hz.

The probe function divided the fallback value by 1000, causing
integer truncation that resulted in dev->bus_freq = 0. This triggered
a deterministic division-by-zero kernel panic when calculating clock
dividers later in the probe sequence.

Fix this by redefining DAVINCI_I2C_DEFAULT_BUS_FREQ in Hz (100000)
to match the expected device tree property unit, allowing the existing
division logic to work correctly for both cases.

Fixes: b04ce6385979 ("i2c: davinci: kill platform data")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260514044726.57297C2BCB7@smtp.kernel.org/
Signed-off-by: Chaitanya Sabnis <chaitanya.msabnis@gmail.com>
---
 drivers/i2c/busses/i2c-davinci.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index a773ba082321..bd0754abdcb7 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -760,9 +760,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 
 	r = device_property_read_u32(&pdev->dev, "clock-frequency", &prop);
 	if (r)
-		prop = DAVINCI_I2C_DEFAULT_BUS_FREQ;
-
-	dev->bus_freq = prop / 1000;
+		dev->bus_freq = DAVINCI_I2C_DEFAULT_BUS_FREQ;
+	else
+		dev->bus_freq = prop / 1000;
 
 	dev->has_pfunc = device_property_present(&pdev->dev, "ti,has-pfunc");
 
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH 2/2] drm/verisilicon: add support for Nuvoton MA35D1 DCUltra Lite display controller
From: Icenowy Zheng @ 2026-05-15  8:38 UTC (permalink / raw)
  To: Joey Lu, maarten.lankhorst, mripard, tzimmermann, airlied, simona,
	robh, krzk+dt, conor+dt
  Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
	linux-kernel
In-Reply-To: <1a42a168-1dbb-467e-9053-b5585a737f71@gmail.com>

在 2026-05-15五的 14:25 +0800,Joey Lu写道:
> 
> On 5/12/2026 9:12 PM, Icenowy Zheng wrote:
> > 在 2026-05-12二的 18:59 +0800,Joey Lu写道:
> > > On 5/12/2026 6:01 PM, Icenowy Zheng wrote:
> > > > 在 2026-05-12二的 17:06 +0800,Joey Lu写道:
> > > > 
> > > > ======= 8< =============
> > > > > > > > > diff --git a/drivers/gpu/drm/verisilicon/vs_bridge.c
> > > > > > > > > b/drivers/gpu/drm/verisilicon/vs_bridge.c
> > > > > > > > > index 7a93049368db..225af322de32 100644
> > > > > > > > > --- a/drivers/gpu/drm/verisilicon/vs_bridge.c
> > > > > > > > > +++ b/drivers/gpu/drm/verisilicon/vs_bridge.c
> > > > > > > > > @@ -164,13 +164,16 @@ static void
> > > > > > > > > vs_bridge_enable_common(struct
> > > > > > > > > vs_crtc *crtc,
> > > > > > > > >      			VSDC_DISP_PANEL_CONFIG_CLK_E
> > > > > > > > > N);
> > > > > > > > >      	regmap_set_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_CONFIG(output),
> > > > > > > > >      			VSDC_DISP_PANEL_CONFIG_RUNNI
> > > > > > > > > NG);
> > > > > > > > > -	regmap_clear_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_START,
> > > > > > > > > -			
> > > > > > > > > VSDC_DISP_PANEL_START_MULTI_DISP_SYNC);
> > > > > > > > > -	regmap_set_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_START,
> > > > > > > > > -
> > > > > > > > > 			VSDC_DISP_PANEL_START_RUNNIN
> > > > > > > > > G(ou
> > > > > > > > > tput));
> > > > > > > > >      
> > > > > > > > > -	regmap_set_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_CONFIG_EX(crtc-
> > > > > > > > > > id),
> > > > > > > > > -
> > > > > > > > > 			VSDC_DISP_PANEL_CONFIG_EX_CO
> > > > > > > > > MMIT);
> > > > > > > > > +	if (dc->info->has_config_ex) {
> > > > > > > > > +		regmap_clear_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_START,
> > > > > > > > > +				
> > > > > > > > > VSDC_DISP_PANEL_START_MULTI_DISP_SYNC);
> > > > > > > > > +		regmap_set_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_START,
> > > > > > > > > +				VSDC_DISP_PANEL_STAR
> > > > > > > > > T_RU
> > > > > > > > > NNIN
> > > > > > > > > G(ou
> > > > > > > > > tput
> > > > > > > > > ));
> > > > > > > > > +
> > > > > > > > > +		regmap_set_bits(dc->regs,
> > > > > > > > > VSDC_DISP_PANEL_CONFIG_EX(crtc->id),
> > > > > > > > > +				VSDC_DISP_PANEL_CONF
> > > > > > > > > IG_E
> > > > > > > > > X_CO
> > > > > > > > > MMIT
> > > > > > > > > );
> > > > > > > > Should the commit operation happen on
> > > > > > > > DC8000/DCUltraLite
> > > > > > > > too?
> > > > > > > > (By
> > > > > > > > writing to DcregFrameBufferConfig0.VALID).
> > > > > > > > 
> > > > > > > > Many registers written has "Note: This field is double
> > > > > > > > buffered" in
> > > > > > > > the
> > > > > > > > DCUltraLite documentation.
> > > > > > > > 
> > > > > > > > I suggest create a static function for commit -- write
> > > > > > > > to
> > > > > > > > the
> > > > > > > > corresponding commit bit on DC8200, and write to
> > > > > > > > DcregFrameBufferConfig0.VALID on DC8000/DCUltraLite.
> > > > > > > [a] There is no commit operation for DCUltra Lite.
> > > > > > > I'll not add a `VSDC_FB_CONFIG_VALID` macro. VALID
> > > > > > > (BIT(3))
> > > > > > > is a
> > > > > > > hardware-managed double-buffer status bit: hardware
> > > > > > > writes
> > > > > > > 1=PENDING
> > > > > > > when a new register set is ready and clears to 0=WORKING
> > > > > > > after
> > > > > > > the
> > > > > > > VBLANK copy. Software must never write it, and there is
> > > > > > > no
> > > > > > > polling
> > > > > > > use
> > > > > > It seems to be writable and controls whether register
> > > > > > buffering
> > > > > > is
> > > > > > enabled, see [1].
> > > > > > 
> > > > > > The description of this bit in MA35D1 TRM says "This
> > > > > > ensures a
> > > > > > frame
> > > > > > will always start with a valid working set if this register
> > > > > > is
> > > > > > programmed last, which reduces the need for SW to wait for
> > > > > > the
> > > > > > start of
> > > > > > a VBLANK signal in order to ensure all states are loaded
> > > > > > before
> > > > > > the
> > > > > > next VBLANK", which indicates some kind of "committing
> > > > > > write",
> > > > > > although
> > > > > > the code at [1] seems to indicate that double buffering is
> > > > > > only
> > > > > > enabled
> > > > > > when bit is cleared.
> > > > > > 
> > > > > > Anyway this bit should be programmable, and "Software must
> > > > > > never
> > > > > > write
> > > > > > it" contradicts with the MA35D1 TRM.
> > > > > > 
> > > > > > Thanks,
> > > > > > Icenowy
> > > > > > 
> > > > > > [1]
> > > > > > https://github.com/rockos-riscv/rockos-kernel/blob/rockos-v6.6.y/drivers/gpu/drm/eswin/es_dc_hw.c#L993
> > > > > Thank you for the correction. I'll add
> > > > > `#define VSDC_FB_CONFIG_VALID BIT(3)` to
> > > > > vs_primary_plane_regs.h
> > > > > and
> > > > > write it in `vs_primary_plane_commit()` for non-config_ex
> > > > > variants.
> > > > > > > case in the driver that requires a named constant. For
> > > > > > > non-
> > > > > > > config_ex
> > > > > > > variants, `vs_primary_plane_commit()` performs no commit
> > > > > > > operation —
> > > > > > > `VSDC_FB_CONFIG_ENABLE` (OUTPUT, BIT(0)) is set in
> > > > > > > `vs_crtc_atomic_enable()` and `VSDC_FB_CONFIG_RESET`
> > > > > > > (BIT(4))
> > > > > > > is
> > > > > > > set/cleared in the bridge enable/disable paths.
> > > > Well according to the driver code for DC8000 from Eswin, and
> > > > the
> > > > bit
> > > > named "VALID", maybe it should be cleared before programming
> > > > the
> > > > registers, and set after programming registers, to make the
> > > > process
> > > > of
> > > > programming registers atomic from the perspective of the
> > > > display
> > > > controller.
> > > > 
> > > > Anyway this should require testing on real hardware to verify.
> > > > 
> > > > By the way, I see multiple peripheral drivers for MA35D1 get
> > > > applied in
> > > > the torvalds tree, but the device tree is still only a
> > > > skeleton;
> > > > when
> > > > will the device tree be updated?
> > > > 
> > > > Thanks,
> > > > Icenowy
> > > Thanks for pointing this out. I’ll perform tests on real hardware
> > > since
> > > I haven’t used this bit before.
> > > 
> > > As for the device tree, we plan to update it comprehensively
> > > after
> > > completing several major IPs, with the goal of releasing the
> > > update
> > > later this year.
> > Well I bought a MA35D1 board (MYIR MYB-LMA35 + RGB LCD) earlier
> > this
> > year (and this is where I got the MA35D1 identification register
> > values). Hope I can have a chance to test this driver by myself.
> > 
> > As MMC, Ethernet and USB support is all applied, maybe it's already
> > worthy to update the device tree ;-)
> > 
> > Thanks,
> > Icenowy
> 
> Yes you can!
> 
> I have performed hardware validation on the MA35D1 and found that
> this 
> bit acts as a manual latch for the shadow registers rather than an 
> auto-clearing trigger, which clarifies the slightly ambiguous 
> description in the TRM.
> 
> Following your suggestion, I will align the implementation with
> ESWIN's 
> DC8000 logic: setting the VALID bit at atomic_begin and clearing it

Ah do you mean clearing it at begin and setting it at flush?

In the Eswin driver (which seems to be based on reference code by
Verisilicon, I saw similar driver code for DC8200),
dc_hw_enable_shadow_register() clears VALID bit when enable is true,
and all register setting sequences calls that function with enable =
true before setting and enable = false after setting.

In addition, considering this bit is called "VALID" instead of
"INVALID", I think it represents that the DC will apply the new setting
when it's set and keep the current setting when it's cleared, so I
think it should be cleared before modeset sequence and be set after
modeset sequence.

Thanks,
Icenowy

> at 
> atomic_flush. My tests confirm this allows the hardware to latch the 
> plane configuration correctly while avoiding the blank screen issues 
> observed with other configurations.
> 
> I am preparing the v2 patchset with this change, along with the 
> requested commit splits, and will submit it shortly.🙂
> 
> > > > > > ========= 8< ==========
> > > > > > 



^ permalink raw reply

* Re: [PATCH v2 16/16] MAINTAINERS: add MediaTek mt6323 PMIC thermal driver maintainer
From: Roman Vivchar @ 2026-05-15  8:38 UTC (permalink / raw)
  To: Krzysztof Kozlowski, AngeloGioacchino Del Regno, Matthias Brugger
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sen Chu,
	Sean Wang, Macpaul Lin, Lee Jones, Srinivas Kandagatla,
	Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	linux-iio, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm, Ben Grisdale
In-Reply-To: <20260514-sweet-electric-buffalo-841c18@quoll>

Hi Krzysztof,

On Thursday, May 14th, 2026 at 4:03 PM, Krzysztof Kozlowski <krzk@kernel.org> wrote:

> On Tue, May 12, 2026 at 08:18:30AM +0300, Roman Vivchar wrote:

...

> >
> > +MEDIATEK PMIC THERMAL DRIVER
> > +M:	Roman Vivchar <rva333@protonmail.com>
> > +S:	Odd Fixes
> 
> Odd Fixes means driver is half-abandonded, so please explain in the
> commit msg why you add yourself as maintainer but not really committed.
> Such entry makes more sense for subsystems, but if individual driver has
> odd-fixes stage, shouldn't we just remove this maintainer entry? If so,
> why adding it in the first place?

That is a fair point. As an individual contributor, I'm hesitant to use
"Maintained" indefinitely, but I understand that "Odd Fixes" for a new
driver is not the best idea either.

If no one else can take it, I'll change the status to "Maintained" for
v3, but I want to see if there's a more sustainable long-term home for
the drivers first.

Angelo, Matthias:
Since the patch series is about MediaTek PMIC drivers, would you be
open for taking drivers under "ARM/Mediatek SoC support" entry?
Or is there someone at MediaTek who might be interested in this?

Best regards,
Roman


^ permalink raw reply

* Re: [PATCH v2 0/5] scmi: Log client subsystem entity counts
From: Sudeep Holla @ 2026-05-15  8:29 UTC (permalink / raw)
  To: Alex Tran
  Cc: Jonathan Cameron, Sudeep Holla, Jyoti Bhayana, David Lechner,
	Nuno Sá, Andy Shevchenko, Cristian Marussi, Linus Walleij,
	Rafael J. Wysocki, Philipp Zabel, Viresh Kumar, Guenter Roeck,
	linux-iio, linux-kernel, arm-scmi, linux-arm-kernel, linux-gpio,
	linux-pm, linux-hwmon
In-Reply-To: <8857fc71-aec6-4682-b4f4-0bd463f367c4@oss.qualcomm.com>

On Thu, May 14, 2026 at 02:23:56PM -0700, Alex Tran wrote:
> On 5/14/2026 8:44 AM, Jonathan Cameron wrote:
> 
> > On Wed, 13 May 2026 10:16:53 -0700
> > Alex Tran <alex.tran@oss.qualcomm.com> wrote:
> >
> >> SCMI client drivers do not consistently log the number of supported
> >> entities discovered from firmware. This information is useful during
> >> debugging because it shows which domains or resources were exposed by
> >> firmware during probe.
> >>
> >> Add logging of the number of supported entities to the SCMI cpufreq,
> >> pinctrl, reset, hwmon, and powercap client drivers after a successful
> >> probe. This aligns these drivers with the existing logging in the SCMI
> >> power and performance domain drivers.
> >>
> >> Signed-off-by: Alex Tran <alex.tran@oss.qualcomm.com>
> > Hi Alex,
> >
> > Just curious but why +CC linux-iio and IIO folk?
> >
> > May be you had a false suggestion to add them from get maintainers.
> > If so be sure to check it's suggestions make sense!
> >
> > Not to worry - we can all hit the delete button ;)
> >
> > Jonathan
> Hi Jonathan,
> 
> Originally, there was another patch in this series to add the same
> functionality to scmi_iio probe but it was dropped. Apparently running b4
> prep --auto-to-cc does not prune stale entries from the cover letter. Will
> manually remove all entries and rerun the command in the future.
> 

I guessed so, but why was it dropped ? I don't agree to adding them elsewhere
just curious about why it was dropped in this case.

-- 
Regards,
Sudeep


^ permalink raw reply

* Re: [PATCH v7 13/20] KVM: arm64: Apply dynamic guest counter reservations
From: James Clark @ 2026-05-15  8:28 UTC (permalink / raw)
  To: Colton Lewis
  Cc: alexandru.elisei, pbonzini, corbet, linux, catalin.marinas, will,
	maz, oliver.upton, mizhang, joey.gouly, suzuki.poulose, yuzenghui,
	mark.rutland, shuah, gankulkarni, linux-doc, linux-kernel,
	linux-arm-kernel, kvmarm, linux-perf-users, linux-kselftest, kvm
In-Reply-To: <gsntlddlbylw.fsf@coltonlewis-kvm.c.googlers.com>



On 14/05/2026 8:05 pm, Colton Lewis wrote:
> James Clark <james.clark@linaro.org> writes:
> 
>> On 13/05/2026 5:45 pm, Colton Lewis wrote:
>>> James Clark <james.clark@linaro.org> writes:
> 
>>>> On 04/05/2026 10:18 pm, Colton Lewis wrote:
>>>>> Apply dynamic guest counter reservations by checking if the requested
>>>>> guest mask collides with any events the host has scheduled and calling
>>>>> pmu_perf_resched_update() with a hook that updates the mask of
>>>>> available counters in between schedule out and schedule in.
> 
>>>>> Signed-off-by: Colton Lewis <coltonlewis@google.com>
>>>>> ---
>>>>>    arch/arm64/kvm/pmu-direct.c  | 69 ++++++++++++++++++++++++++++++++
>>>>> ++++
>>>>>    include/linux/perf/arm_pmu.h |  1 +
>>>>>    2 files changed, 70 insertions(+)
> 
>>>>> diff --git a/arch/arm64/kvm/pmu-direct.c b/arch/arm64/kvm/pmu-direct.c
>>>>> index 2252d3b905db9..14cc419dbafad 100644
>>>>> --- a/arch/arm64/kvm/pmu-direct.c
>>>>> +++ b/arch/arm64/kvm/pmu-direct.c
>>>>> @@ -100,6 +100,73 @@ u8 kvm_pmu_hpmn(struct kvm_vcpu *vcpu)
>>>>>        return *host_data_ptr(nr_event_counters);
>>>>>    }
> 
>>>>> +/* Callback to update counter mask between perf scheduling */
>>>>> +static void kvm_pmu_update_mask(struct pmu *pmu, void *data)
>>>>> +{
>>>>> +    struct arm_pmu *arm_pmu = to_arm_pmu(pmu);
>>>>> +    unsigned long *new_mask = data;
>>>>> +
>>>>> +    bitmap_copy(arm_pmu->cntr_mask, new_mask, ARMPMU_MAX_HWEVENTS);
>>>>> +}
>>>>> +
>>>>> +/**
>>>>> + * kvm_pmu_set_guest_counters() - Handle dynamic counter reservations
>>>>> + * @cpu_pmu: struct arm_pmu to potentially modify
>>>>> + * @guest_mask: new guest mask for the pmu
>>>>> + *
>>>>> + * Check if guest counters will interfere with current host events 
>>>>> and
>>>>> + * call into perf_pmu_resched_update if a reschedule is required.
>>>>> + */
>>>>> +static void kvm_pmu_set_guest_counters(struct arm_pmu *cpu_pmu, u64
>>>>> guest_mask)
>>>>> +{
>>>>> +    struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
>>>>> +    DECLARE_BITMAP(guest_bitmap, ARMPMU_MAX_HWEVENTS);
>>>>> +    DECLARE_BITMAP(new_mask, ARMPMU_MAX_HWEVENTS);
>>>>> +    bool need_resched = false;
>>>>> +
>>>>> +    bitmap_from_arr64(guest_bitmap, &guest_mask, 
>>>>> ARMPMU_MAX_HWEVENTS);
>>>>> +    bitmap_copy(new_mask, cpu_pmu->hw_cntr_mask, 
>>>>> ARMPMU_MAX_HWEVENTS);
>>>>> +
>>>>> +    if (guest_mask) {
>>>>> +        /* Subtract guest counters from available host mask */
>>>>> +        bitmap_andnot(new_mask, new_mask, guest_bitmap,
>>>>> ARMPMU_MAX_HWEVENTS);
>>>>> +
>>>>> +        /* Did we collide with an active host event? */
>>>>> +        if (bitmap_intersects(cpuc->used_mask, guest_bitmap,
>>>>> ARMPMU_MAX_HWEVENTS)) {
>>>>> +            int idx;
>>>>> +
>>>>> +            need_resched = true;
>>>>> +            cpuc->host_squeezed = true;
>>>>> +
>>>>> +            /* Look for pinned events that are about to be 
>>>>> preempted */
>>>>> +            for_each_set_bit(idx, guest_bitmap, 
>>>>> ARMPMU_MAX_HWEVENTS) {
>>>>> +                if (test_bit(idx, cpuc->used_mask) && cpuc-
>>>>> >events[idx] &&
>>>>> +                    cpuc->events[idx]->attr.pinned) {
>>>>> +                    pr_warn_ratelimited("perf: Pinned host event
>>>>> squeezed out by KVM guest PMU partition\n");
> 
>>>> Hi Colton,
> 
>>>> I get "perf: Pinned host event squeezed out by KVM guest PMU partition"
>>>> even with arm_pmuv3.reserved_host_counters=3 for example. I would have
>>>> expected any non zero value to stop the warning.
> 
>>>> I think armv8pmu_get_single_idx() needs to be changed to allocate from
>>>> the high end host counters first. A more complicated option would be
>>>> checking to see if there are any non-pinned counters in the host
>>>> reserved half when a new pinned counter is opened, then swapping the
>>>> places of the new pinned and existing non-pinned counters so pinned
>>>> always prefer being put into the host half. But it's probably not worth
>>>> doing that.
> 
>>>> James
> 
> 
>>> I agree it makes the most sense to allocate from the top, but I'm happy
>>> the basic idea works.
> 
> 
>> Another thing I forgot to mention is that even with the ratelimited
>> warning, this spams the logs any time the host and guest are both using
>> the PMU and I'm not sure how useful that is.
> 
> I'm sure it does. I'll delete it.
> 

A warn_once might save someone a few hours of debugging, but we probably 
don't need more than that.

>>>>> +                    break;
>>>>> +                }
>>>>> +            }
>>>>> +        }
>>>>> +    } else {
>>>>> +        /*
>>>>> +         * Restoring to hw_cntr_mask.
>>>>> +         * Only resched if we previously squeezed an event.
>>>>> +         */
>>>>> +        if (cpuc->host_squeezed) {
>>>>> +            need_resched = true;
>>>>> +            cpuc->host_squeezed = false;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    if (need_resched) {
>>>>> +        /* Collision: run full perf reschedule */
>>>>> +        perf_pmu_resched_update(&cpu_pmu->pmu, kvm_pmu_update_mask,
>>>>> new_mask);
>>>>> +    } else {
>>>>> +        /* Host was never using guest counters anyway */
>>>>> +        bitmap_copy(cpu_pmu->cntr_mask, new_mask, 
>>>>> ARMPMU_MAX_HWEVENTS);
>>>>> +    }
>>>>> +}
>>>>> +
>>>>>    /**
>>>>>     * kvm_pmu_host_counter_mask() - Compute bitmask of host-reserved
>>>>> counters
>>>>>     * @pmu: Pointer to arm_pmu struct
>>>>> @@ -218,6 +285,7 @@ void kvm_pmu_load(struct kvm_vcpu *vcpu)
> 
>>>>>        pmu = vcpu->kvm->arch.arm_pmu;
>>>>>        guest_counters = kvm_pmu_guest_counter_mask(pmu);
>>>>> +    kvm_pmu_set_guest_counters(pmu, guest_counters);
>>>>>        kvm_pmu_apply_event_filter(vcpu);
> 
>>>>>        for_each_set_bit(i, &guest_counters, ARMPMU_MAX_HWEVENTS) {
>>>>> @@ -319,5 +387,6 @@ void kvm_pmu_put(struct kvm_vcpu *vcpu)
>>>>>        val = read_sysreg(pmintenset_el1);
>>>>>        __vcpu_assign_sys_reg(vcpu, PMINTENSET_EL1, val & mask);
> 
>>>>> +    kvm_pmu_set_guest_counters(pmu, 0);
>>>>>        preempt_enable();
>>>>>    }
>>>>> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/ 
>>>>> arm_pmu.h
>>>>> index f7b000bb3eca8..63f88fec5e80f 100644
>>>>> --- a/include/linux/perf/arm_pmu.h
>>>>> +++ b/include/linux/perf/arm_pmu.h
>>>>> @@ -75,6 +75,7 @@ struct pmu_hw_events {
> 
>>>>>        /* Active events requesting branch records */
>>>>>        unsigned int        branch_users;
>>>>> +    bool host_squeezed;
>>>>>    };
> 
>>>>>    enum armpmu_attr_groups {



^ permalink raw reply

* Re: [PATCH 04/10] dt-bindings: clock: Add Amlogic A9 AO clock controller
From: Krzysztof Kozlowski @ 2026-05-15  8:10 UTC (permalink / raw)
  To: Jian Hu
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Jerome Brunet, Xianwei Zhao,
	Kevin Hilman, Martin Blumenstingl, linux-kernel, linux-clk,
	devicetree, linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-4-41cb4071b7c9@amlogic.com>

On Mon, May 11, 2026 at 08:47:26PM +0800, Jian Hu wrote:
> Add the Always-On clock controller dt-bindings for the Amlogic A9
> SoC family.
> 
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  .../bindings/clock/amlogic,a9-aoclkc.yaml          | 76 ++++++++++++++++++++++
>  include/dt-bindings/clock/amlogic,a9-aoclkc.h      | 76 ++++++++++++++++++++++
>  2 files changed, 152 insertions(+)

All comments apply.

Best regards,
Krzysztof



^ 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