* [PATCH v6 07/23] phy: rockchip: usbdp: Keep clocks running on PHY re-init
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
When a mode change is required rk_udphy_power_on() disables
the clocks and then calls rk_udphy_setup(), which then enables
all the clocks again before continuing with rk_udphy_init().
Considering that rk_udphy_init() does assert the reset lines,
re-enabling the clocks is just delaying things. Avoid it by
directly calling rk_udphy_init().
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 6dff4dfc9363..c05ee65a9f73 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1011,8 +1011,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
- rk_udphy_disable(udphy);
- ret = rk_udphy_setup(udphy);
+ ret = rk_udphy_init(udphy);
if (ret)
return ret;
udphy->mode_change = false;
--
2.53.0
^ permalink raw reply related
* [PATCH v6 09/23] phy: rockchip: usbdp: Fix LFPS detect threshold control
From: Sebastian Reichel @ 2026-06-19 15:29 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, William Wu
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
From: William Wu <william.wu@rock-chips.com>
According to the LFPS Tx Low Power/LFPS Rx Detect Threshold [1],
the device under test(DUT) must not respond if LFPS below the
minimum LFPS Rx Detect Threshold 100mV. Test fail on Rockchip
platforms, because the default LFPS detect threshold is set to
65mV.
The USBDP PHY LFPS detect threshold voltage could be set to
30mV ~ 140mV, and since there could be 10-20% PVT variation,
we set LFPS detect threshold voltage to 110mV.
[1] https://compliance.usb.org/resources/LFPS_Rx_Tx_Low_Power_Compliance_Update_Rev5.pdf
Signed-off-by: William Wu <william.wu@rock-chips.com>
[Taken over from rockchip's kernel tree; the registers are not described
in the TRM]
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index a44babac3517..7ed539d8c791 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -413,7 +413,8 @@ static const struct reg_sequence rk_udphy_init_sequence[] = {
{0x0070, 0x7d}, {0x0074, 0x68},
{0x0af4, 0x1a}, {0x1af4, 0x1a},
{0x0440, 0x3f}, {0x10d4, 0x08},
- {0x20d4, 0x08}, {0x0024, 0x6e}
+ {0x20d4, 0x08}, {0x0024, 0x6e},
+ {0x09c0, 0x0a}, {0x19c0, 0x0a}
};
static inline int rk_udphy_grfreg_write(struct regmap *base,
--
2.53.0
^ permalink raw reply related
* [PATCH v6 10/23] phy: rockchip: usbdp: Add missing mode_change update
From: Sebastian Reichel @ 2026-06-19 15:29 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
rk_udphy_set_typec_default_mapping() updates the available modes,
but does not set the mode_change as required. This results in
missing re-initialization and thus non-working DisplayPort.
Fix this issue by introducing a new helper to update the available
modes.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 7ed539d8c791..2ff05ef6eeac 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -619,6 +619,15 @@ static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
}
+static void rk_udphy_mode_set(struct rk_udphy *udphy, u8 mode)
+{
+ if (udphy->mode == mode)
+ return;
+
+ udphy->mode_change = true;
+ udphy->mode = mode;
+}
+
static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
{
if (udphy->flip) {
@@ -649,7 +658,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
}
- udphy->mode = UDPHY_MODE_DP_USB;
+ rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
}
static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
@@ -1388,10 +1397,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
usleep_range(750, 800);
rk_udphy_dp_hpd_event_trigger(udphy, true);
} else if (data->status & DP_STATUS_HPD_STATE) {
- if (udphy->mode != mode) {
- udphy->mode = mode;
- udphy->mode_change = true;
- }
+ rk_udphy_mode_set(udphy, mode);
rk_udphy_dp_hpd_event_trigger(udphy, true);
} else {
rk_udphy_dp_hpd_event_trigger(udphy, false);
--
2.53.0
^ permalink raw reply related
* [PATCH v6 11/23] phy: rockchip: usbdp: Support single-lane DP
From: Sebastian Reichel @ 2026-06-19 15:29 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
From: Zhang Yubing <yubing.zhang@rock-chips.com>
Implement support for using just a single DisplayPort line.
Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 64 +++++++++++++------------------
1 file changed, 27 insertions(+), 37 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 2ff05ef6eeac..a87cb5c0596e 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -193,6 +193,7 @@ struct rk_udphy {
int id;
bool dp_in_use;
+ int dp_lanes;
/* PHY const config */
const struct rk_udphy_cfg *cfgs;
@@ -537,6 +538,13 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
* <0 1> dpln0 dpln1 usbrx usbtx
* <2 3> usbrx usbtx dpln0 dpln1
* ---------------------------------------------------------------------------
+ * if 1 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x>;
+ * sample as follow:
+ * ---------------------------------------------------------------------------
+ * B11-B10 A2-A3 A11-A10 B2-B3
+ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
+ * <0> dpln0 \ usbrx usbtx
+ * ---------------------------------------------------------------------------
*/
static void rk_udphy_dplane_select(struct rk_udphy *udphy)
@@ -544,18 +552,18 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
const struct rk_udphy_cfg *cfg = udphy->cfgs;
u32 value = 0;
- switch (udphy->mode) {
- case UDPHY_MODE_DP:
- value |= 2 << udphy->dp_lane_sel[2] * 2;
+ switch (udphy->dp_lanes) {
+ case 4:
value |= 3 << udphy->dp_lane_sel[3] * 2;
+ value |= 2 << udphy->dp_lane_sel[2] * 2;
fallthrough;
- case UDPHY_MODE_DP_USB:
- value |= 0 << udphy->dp_lane_sel[0] * 2;
+ case 2:
value |= 1 << udphy->dp_lane_sel[1] * 2;
- break;
+ fallthrough;
- case UDPHY_MODE_USB:
+ case 1:
+ value |= 0 << udphy->dp_lane_sel[0] * 2;
break;
default:
@@ -568,28 +576,6 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
}
-static int rk_udphy_dplane_get(struct rk_udphy *udphy)
-{
- int dp_lanes;
-
- switch (udphy->mode) {
- case UDPHY_MODE_DP:
- dp_lanes = 4;
- break;
-
- case UDPHY_MODE_DP_USB:
- dp_lanes = 2;
- break;
-
- case UDPHY_MODE_USB:
- default:
- dp_lanes = 0;
- break;
- }
-
- return dp_lanes;
-}
-
static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
{
u32 val = 0;
@@ -659,6 +645,7 @@ static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
}
rk_udphy_mode_set(udphy, UDPHY_MODE_DP_USB);
+ udphy->dp_lanes = 2;
}
static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
@@ -897,7 +884,7 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
return 0;
}
- if (num_lanes != 2 && num_lanes != 4)
+ if (num_lanes != 1 && num_lanes != 2 && num_lanes != 4)
return dev_err_probe(udphy->dev, -EINVAL,
"invalid number of lane mux\n");
@@ -923,9 +910,11 @@ static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
}
udphy->mode = UDPHY_MODE_DP;
- if (num_lanes == 2) {
+ udphy->dp_lanes = num_lanes;
+ if (num_lanes == 1 || num_lanes == 2) {
udphy->mode |= UDPHY_MODE_USB;
- udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
+ udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP) ||
+ (udphy->lane_mux_sel[1] == PHY_LANE_MUX_DP);
}
return 0;
@@ -1074,18 +1063,17 @@ static int rk_udphy_dp_phy_exit(struct phy *phy)
static int rk_udphy_dp_phy_power_on(struct phy *phy)
{
struct rk_udphy *udphy = phy_get_drvdata(phy);
- int ret, dp_lanes;
+ int ret;
mutex_lock(&udphy->mutex);
- dp_lanes = rk_udphy_dplane_get(udphy);
- phy_set_bus_width(phy, dp_lanes);
+ phy_set_bus_width(phy, udphy->dp_lanes);
ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
if (ret)
goto unlock;
- rk_udphy_dplane_enable(udphy, dp_lanes);
+ rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
rk_udphy_dplane_select(udphy);
@@ -1368,6 +1356,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
mode = UDPHY_MODE_DP;
+ udphy->dp_lanes = 4;
break;
case TYPEC_DP_STATE_D:
@@ -1384,6 +1373,7 @@ static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
}
mode = UDPHY_MODE_DP_USB;
+ udphy->dp_lanes = 2;
break;
}
@@ -1532,7 +1522,7 @@ static int rk_udphy_probe(struct platform_device *pdev)
ret = PTR_ERR(udphy->phy_dp);
return dev_err_probe(dev, ret, "failed to create DP phy\n");
}
- phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
+ phy_set_bus_width(udphy->phy_dp, udphy->dp_lanes);
udphy->phy_dp->attrs.max_link_rate = 8100;
phy_set_drvdata(udphy->phy_dp, udphy);
--
2.53.0
^ permalink raw reply related
* [PATCH v6 12/23] phy: rockchip: usbdp: Rename DP lane functions
From: Sebastian Reichel @ 2026-06-19 15:29 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
The common prefix for DisplayPort related functions is rk_udphy_dp_
(with a final _), so update the two DP lane functions to follow that
scheme.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index a87cb5c0596e..e8b2adecb08a 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -547,7 +547,7 @@ static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
* ---------------------------------------------------------------------------
*/
-static void rk_udphy_dplane_select(struct rk_udphy *udphy)
+static void rk_udphy_dp_lane_select(struct rk_udphy *udphy)
{
const struct rk_udphy_cfg *cfg = udphy->cfgs;
u32 value = 0;
@@ -576,7 +576,7 @@ static void rk_udphy_dplane_select(struct rk_udphy *udphy)
FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
}
-static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
+static void rk_udphy_dp_lane_enable(struct rk_udphy *udphy, int dp_lanes)
{
u32 val = 0;
int i;
@@ -1073,9 +1073,9 @@ static int rk_udphy_dp_phy_power_on(struct phy *phy)
if (ret)
goto unlock;
- rk_udphy_dplane_enable(udphy, udphy->dp_lanes);
+ rk_udphy_dp_lane_enable(udphy, udphy->dp_lanes);
- rk_udphy_dplane_select(udphy);
+ rk_udphy_dp_lane_select(udphy);
unlock:
mutex_unlock(&udphy->mutex);
@@ -1093,7 +1093,7 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy)
struct rk_udphy *udphy = phy_get_drvdata(phy);
mutex_lock(&udphy->mutex);
- rk_udphy_dplane_enable(udphy, 0);
+ rk_udphy_dp_lane_enable(udphy, 0);
rk_udphy_power_off(udphy, UDPHY_MODE_DP);
mutex_unlock(&udphy->mutex);
--
2.53.0
^ permalink raw reply related
* [PATCH v6 05/23] phy: rockchip: usbdp: Drop seamless DP takeover
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, Sashiko
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
If the bootloader already enabled DP, keeping it enabled here means
the DRM stack can do a seamless takeover. Right now the DRM does not
support this and the code will leak clock resources on module removal,
so just drop this feature.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-phy/20260612164107.C7DB21F000E9@smtp.kernel.org/
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 2845a012eafc..ffe39c968c70 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -936,9 +936,9 @@ static int rk_udphy_get_initial_status(struct rk_udphy *udphy)
regmap_read(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, &value);
if (FIELD_GET(CMN_DP_LANE_MUX_ALL, value) && FIELD_GET(CMN_DP_LANE_EN_ALL, value))
- udphy->status = UDPHY_MODE_DP;
- else
- rk_udphy_disable(udphy);
+ dev_dbg(udphy->dev, "Started with DP PHY pre-enabled; seamless takeover unsupported\n");
+
+ rk_udphy_disable(udphy);
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v6 06/23] phy: rockchip: usbdp: Limit DP lane count to muxed lanes
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, Sashiko
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
In theory the DP controller could request 4 lanes when the PHY is
restricted to 2 lanes as the other half is used by USB3.
With the current user (DW-DP) this cannot happen, but as the check is
cheap and users might change in the future protect things accordingly.
Not doing so would corrupt USB3 usage by the following code configuring
the voltages.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-phy/20260612165546.98E1F1F000E9@smtp.kernel.org/
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index ffe39c968c70..6dff4dfc9363 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1126,6 +1126,9 @@ static int rk_udphy_dp_phy_verify_link_rate(struct rk_udphy *udphy,
static int rk_udphy_dp_phy_verify_lanes(struct rk_udphy *udphy,
struct phy_configure_opts_dp *dp)
{
+ if (dp->lanes > udphy->dp_lanes)
+ return -EINVAL;
+
switch (dp->lanes) {
case 1:
case 2:
--
2.53.0
^ permalink raw reply related
* [PATCH v6 02/23] phy: rockchip: usbdp: Update mode_change after error handling
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, Sashiko
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
If rk_udphy_init() or rk_udphy_setup() fails, the reinit will not be
tried again. Fix this by only updating the variable after all potential
errors have been handled.
Note, that no errors have been seen on real hardware and failures would
most likely be fatal and require at least a full reboot as the function
already asserts the PHY reset lines. So this is more of a theoretical
issue.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-phy/20260612163835.8D5471F000E9@smtp.kernel.org/
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index fba35510d88c..a5ffdf7a6e76 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1000,15 +1000,14 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
}
if (udphy->status == UDPHY_MODE_NONE) {
- udphy->mode_change = false;
ret = rk_udphy_setup(udphy);
if (ret)
return ret;
if (udphy->mode & UDPHY_MODE_USB)
rk_udphy_u3_port_disable(udphy, false);
- } else if (udphy->mode_change) {
udphy->mode_change = false;
+ } else if (udphy->mode_change) {
udphy->status = UDPHY_MODE_NONE;
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
@@ -1017,6 +1016,7 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
ret = rk_udphy_setup(udphy);
if (ret)
return ret;
+ udphy->mode_change = false;
}
udphy->status |= mode;
--
2.53.0
^ permalink raw reply related
* [PATCH v6 00/23] phy: rockchip: usbdp: Fixes, DP 1-lane support and cleanups
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, Sashiko, William Wu
This series overhauls the Rockchip USBDP driver; apart from a
a bunch of cleanups and small improvements the main goal is to
get the driver ready for proper USB-C DP AltMode support. At
the moment it only contains a semi-working state.
Once this series has landed, it unblocks enabling proper USB-C
DP AltMode on the RK3588 and RK3576 platforms incl. runtime PM
for the Synopsys DesignWare DisplayPort controller.
Apart from this series, further changes are required on the
DRM side. There are no compile-time dependencies between the
DRM side and the PHY side, but the PHY side must be applied
to avoid SErrors once runtime PM is added to the DisplayPort
controller driver. Thus it would be really good to land this
series ASAP as it blocks the DRM side.
Changes in v6:
- Link to v5: https://lore.kernel.org/r/20260612-rockchip-usbdp-cleanup-v5-0-efc83069869f@collabora.com
- Add explicit <linux/string_choices.h> include in last patch (Sashiko)
- Add new patch moving mode_change update after error handling (Sashiko)
- Add new patch fixing error masking of devm_clk_bulk_get_all() (Sashiko)
- Add new patch dropping seamless DP takeover as it is non-functional and buggy (Sashiko)
- Add new patch limiting DP lane count to muxed lanes (Sashiko)
- Add error handling in the patch that keeps clocks running on PHY re-init (Sashiko)
- Also look for DP being configured to second lane for the flip config
in DP single-lane mode, which should at least keep USB working for
this super unusual config (Sashiko)
- Drop useless ret variable in patch introducing guard() for the mutex
- Add error handling for PHY re-enablement in the patch fixing support for
DP-only -> USB mode (Sashiko)
Changes in v5:
- Link to v4: https://lore.kernel.org/r/20260428-rockchip-usbdp-cleanup-v4-0-7775671ece22@collabora.com
- Picked up Acked-by from Rob Herring for DT binding
- Fix typos in commit messages/comments
- Add Fixes tag to "Do not looe USB3 PHY status" patch
- Collect Reviewed-by: Neil Armstrong for multiple patches
- Drop now unused code from "Drop DP HPD handling" patch (Sashiko)
- Ignore mux events not involving DP AltMode (Sashiko)
- Add new patch to support going back from DP only mode to USB combo
mode; technically this is a fix, but DP mode does not yet work
upstream, so it does not matter (Sashiko)
- Add new patch adding a few debug messages, which are useful
to investigate potential hotplug issues in the future
- Sashiko comments about the DT binding and property usage
are wrong as the first port is for the superspeed lanes
used for DP and USB, while the last port is just about
DP aux. I ignored them.
- There is a pre-existing bug, that can already be hit with the
upstream kernel and that the series doesn't fix properly:
Accessing the USB3 controller registers requires the USB PHY
running, since it provides a clock. Re-initializing the PHY
means there is a race-condition - if the system tries to access
the USB3 controller in parallel to the re-init, the system will
hang and/or fail with an SError. By keeping the clocks running
and only asserting the resets this time is minimized by this
series. A proper fix for this will be looked into independently
from this series.
- I used v7.1-rc6 as base, but the driver has no changes since
6.18 even in linux-next and there are no pending patches for
it on the mailinglist either, so it applies to *any* recent
kernel branch.
Changes in v4:
- Link to v3: https://lore.kernel.org/r/20260313-rockchip-usbdp-cleanup-v3-0-3e8fe89a35b5@collabora.com
- rebased to v7.1-rc1 (no changes)
- Update DRM bridge registration patch to avoid registration when DP aux
port is not connected to anything, since this results in errors and some
boards use USBDP instances for USB3 only.
- Add patch renaming mode_change into phy_needs_reinit
- Add patch to re-init PHY on orientation change
- Add patch to factor out lane_mux_sel setup
- Add patch to handle mutex via guard functions
Changes in v3:
- Link to v2: https://lore.kernel.org/r/20260213-rockchip-usbdp-cleanup-v2-0-b67ec225f96e@collabora.com
- Add patch to register the USBDP PHY as DRM bridge
- Add patch to describe ports in DT binding (used by the DRM bridge)
- Add patch to drop HPD handling from the PHY
Changes in v2:
- Link to v1: https://lore.kernel.org/r/20260203-rockchip-usbdp-cleanup-v1-0-16a6f92ed176@collabora.com
- Added new patches to fix USB3 SError
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
Frank Wang (1):
phy: rockchip: usbdp: Amend SSC modulation deviation
Sebastian Reichel (20):
dt-bindings: phy: rockchip-usbdp: add improved ports scheme
phy: rockchip: usbdp: Update mode_change after error handling
phy: rockchip: usbdp: Do not lose USB3 PHY status
phy: rockchip: usbdp: Fix devm_clk_bulk_get_all check
phy: rockchip: usbdp: Drop seamless DP takeover
phy: rockchip: usbdp: Limit DP lane count to muxed lanes
phy: rockchip: usbdp: Keep clocks running on PHY re-init
phy: rockchip: usbdp: Add missing mode_change update
phy: rockchip: usbdp: Rename DP lane functions
phy: rockchip: usbdp: Use FIELD_PREP_WM16_CONST
phy: rockchip: usbdp: Cleanup DP lane selection function
phy: rockchip: usbdp: Register DP aux bridge
phy: rockchip: usbdp: Drop DP HPD handling
phy: rockchip: usbdp: Rename mode_change to phy_needs_reinit
phy: rockchip: usbdp: Re-init the PHY on orientation change
phy: rockchip: usbdp: Factor out lane_mux_sel setup
phy: rockchip: usbdp: Use guard functions for mutex
phy: rockchip: usbdp: Support going from DP-only mode to USB mode
phy: rockchip: usbdp: Hold mutex in DP PHY configure
phy: rockchip: usbdp: Add some extra debug messages
William Wu (1):
phy: rockchip: usbdp: Fix LFPS detect threshold control
Zhang Yubing (1):
phy: rockchip: usbdp: Support single-lane DP
.../bindings/phy/phy-rockchip-usbdp.yaml | 23 ++
drivers/phy/rockchip/Kconfig | 2 +
drivers/phy/rockchip/phy-rockchip-usbdp.c | 381 ++++++++++-----------
3 files changed, 198 insertions(+), 208 deletions(-)
---
base-commit: 08c7183f5b9ffe4408e74fff848a4cc2105361d4
change-id: 20260203-rockchip-usbdp-cleanup-5b59dfb561a3
Best regards,
--
Sebastian Reichel <sebastian.reichel@collabora.com>
^ permalink raw reply
* [PATCH v6 04/23] phy: rockchip: usbdp: Fix devm_clk_bulk_get_all check
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel, Sashiko
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
If devm_clk_bulk_get_all() returns -EPROBE_DEFER, it is replaced with
-ENODEV, permanently failing the driver probe instead of allowing it to
defer. Avoid masking the error code to fix the issue.
This effectively drops returning -ENODEV in case no clocks are being
described in DT. This special case will now be handled by the follow-up
check searching for "refclk" and exit with -EINVAL.
None of this will be hit in practice, since the driver is only used by
RK3588 and RK3576 - on these platforms the DT is validated to contain
the clocks and the clock driver is force probed early. Thus there is
no need to backport this.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-phy/20260612164107.C7DB21F000E9@smtp.kernel.org/
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 12dfdd470a78..2845a012eafc 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -427,8 +427,8 @@ static int rk_udphy_clk_init(struct rk_udphy *udphy, struct device *dev)
int i;
udphy->num_clks = devm_clk_bulk_get_all(dev, &udphy->clks);
- if (udphy->num_clks < 1)
- return -ENODEV;
+ if (udphy->num_clks < 0)
+ return udphy->num_clks;
/* used for configure phy reference clock frequency */
for (i = 0; i < udphy->num_clks; i++) {
--
2.53.0
^ permalink raw reply related
* [PATCH v6 03/23] phy: rockchip: usbdp: Do not lose USB3 PHY status
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
By default (i.e. without manually enabling runtime PM) DWC3 requests the
USB3 PHY once and keeps it enabled all the time. When DisplayPort is
being requested later on, a mode change is needed. This re-initializes
the PHY. During re-initialization the status variable has incorrectly
been cleared, which means the tracking information for USB3 is lost.
This is not an immediate problem, since the DP side keeps the PHY
enabled. But once DP is toggled off, the whole PHY will be disabled.
This is a problem, because the USB side still needs it powered.
Fix things by not clearing the status flags.
Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index a5ffdf7a6e76..12dfdd470a78 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1008,7 +1008,6 @@ static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
rk_udphy_u3_port_disable(udphy, false);
udphy->mode_change = false;
} else if (udphy->mode_change) {
- udphy->status = UDPHY_MODE_NONE;
if (udphy->mode == UDPHY_MODE_DP)
rk_udphy_u3_port_disable(udphy, true);
--
2.53.0
^ permalink raw reply related
* [PATCH v6 01/23] dt-bindings: phy: rockchip-usbdp: add improved ports scheme
From: Sebastian Reichel @ 2026-06-19 15:28 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner, Frank Wang,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Andy Yan, Dmitry Baryshkov, Yubing Zhang, Alexey Charkov,
linux-phy, linux-arm-kernel, linux-rockchip, linux-kernel, kernel,
devicetree, Sebastian Reichel
In-Reply-To: <20260619-rockchip-usbdp-cleanup-v6-0-3bb1f54b3f35@collabora.com>
Currently the Rockchip USBDP PHY is missing a documented port scheme.
Meanwhile upstream RK3588 DTS files are a bit messy and use different
port schemes. The upstream USBDP PHY Linux kernel driver does not yet
parse the ports at all and thus does not create any implicit ABI either.
But with the current mess it is not possible to properly support USB-C
DP AltMode. Thus this introduces a proper port scheme following roughly
the ports design of the Qualcomm QMP USB4-USB3-DP PHY controller binding
with a slight difference that there is an additional port for the
USB-C SBU port as the Rockchip USB-DP PHY also contains the SBU mux.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
.../bindings/phy/phy-rockchip-usbdp.yaml | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
index 8b7059d5b182..f728acf057e4 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
@@ -114,6 +114,29 @@ properties:
A port node to link the PHY to a TypeC controller for the purpose of
handling orientation switching.
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Output endpoint of the PHY for USB (or DP when configured into 4 lane
+ mode), which should point to the superspeed port of a USB connector.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Incoming endpoint from the USB controller
+
+ port@2:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Incoming endpoint from the DisplayPort controller
+
+ port@3:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Output endpoint of the PHY for DP, which should either point to the
+ SBU port of a USB-C connector or a DisplayPort connector input port.
+
required:
- compatible
- reg
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] docs: arm64: Document that text_offset is always 0
From: Mark Rutland @ 2026-06-19 15:21 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: linux-arm-kernel, Ard Biesheuvel, Will Deacon, Jonathan Corbet,
linux-doc, linux-kernel
In-Reply-To: <20260604140839.1930847-1-linux@rasmusvillemoes.dk>
On Thu, Jun 04, 2026 at 04:08:39PM +0200, Rasmus Villemoes wrote:
> When trying to figure out where to place and call an arm64 Image in
> memory, reading booting.rst should provide the answer. However, it
> requires quite some digging to figure out that text_offset is set via
> ".quad 0" in head.S and is thus actually always 0 since v5.10.
What is the actual problem?
The documentation in booting.rst is accurate; I don't see why it's
necessary to read the source code to look at text_offset. Immediately
above the text in your diff, the documentation has:
| 4. Call the kernel image
| ------------------------
|
| Requirement: MANDATORY
|
| The decompressed kernel image contains a 64-byte header as follows::
|
| u32 code0; /* Executable code */
| u32 code1; /* Executable code */
| u64 text_offset; /* Image load offset, little endian */
| u64 image_size; /* Effective Image size, little endian */
| u64 flags; /* kernel flags, little endian */
| u64 res2 = 0; /* reserved */
| u64 res3 = 0; /* reserved */
| u64 res4 = 0; /* reserved */
| u32 magic = 0x644d5241; /* Magic number, little endian, "ARM\x64" */
| u32 res5; /* reserved (used for PE COFF offset) */
Can you explain the problem you're facing? e.g.
* Is the documentation unclear, in a way that could be better?
* Is there some aspect of the boot protocol that is hard for a
bootloader to follow?
* Is there some problem with *testing* that bootloaders respect the
text_offset requirements?
* Something else?
> Update the documentation and make that explicit. Reword the 2MB
> requirement accordingly, and remove the paragraphs that only apply to
> the ancient versions where text_offset could be non-zero, as they only
> confuse a current reader.
>
> Fixes: 120dc60d0bdb ("arm64: get rid of TEXT_OFFSET")
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> ---
> I've included a Fixes tag since I spent way too much time tracking
> down where that text_offset might be defined. The mentioned commit did
> get rid of all references to TEXT_OFFSET-the-macro, but not
> text_offset-the-concept.
Keeping text_offset as a concept was deliberate. That allows us to keep
the documentation accruate for older kernel versions, and allows for the
possiblity that a non-zero offset is introduced in future (though I
admit that might be a tough sell).
> Documentation/arch/arm64/booting.rst | 20 +++++---------------
> 1 file changed, 5 insertions(+), 15 deletions(-)
>
> diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst
> index 13ef311dace8..f4cc25b1fd56 100644
> --- a/Documentation/arch/arm64/booting.rst
> +++ b/Documentation/arch/arm64/booting.rst
> @@ -55,9 +55,6 @@ not exceed 2 megabytes in size. Since the dtb will be mapped cacheable
> using blocks of up to 2 megabytes in size, it must not be placed within
> any 2M region which must be mapped with any specific attributes.
>
> -NOTE: versions prior to v4.2 also require that the DTB be placed within
> -the 512 MB region starting at text_offset bytes below the kernel Image.
> -
> 3. Decompress the kernel image
> ------------------------------
>
> @@ -93,6 +90,8 @@ Header notes:
>
> - As of v3.17, all fields are little endian unless stated otherwise.
>
> +- As of v5.10, text_offset is always 0.
> +
> - code0/code1 are responsible for branching to stext.
>
> - when booting through EFI, code0/code1 are initially skipped.
> @@ -100,12 +99,6 @@ Header notes:
> entry point (efi_stub_entry). When the stub has done its work, it
> jumps to code0 to resume the normal boot process.
>
> -- Prior to v3.17, the endianness of text_offset was not specified. In
> - these cases image_size is zero and text_offset is 0x80000 in the
> - endianness of the kernel. Where image_size is non-zero image_size is
> - little-endian and must be respected. Where image_size is zero,
> - text_offset can be assumed to be 0x80000.
> -
So far we've tried to ensure that the documentation covers current *and*
older kernel versions. If we're going to drop text covering older
versions we'd need an explciit statemnt as to which kernel versions the
document is accurate for.
I would prefer that we retained documentation regarding the text_offset
field in the header, even if it happens to be zero today.
Mark.
> - The flags field (introduced in v3.17) is a little-endian 64-bit field
> composed as follows:
>
> @@ -135,12 +128,9 @@ Header notes:
> end of the kernel image. The amount of space required will vary
> depending on selected features, and is effectively unbound.
>
> -The Image must be placed text_offset bytes from a 2MB aligned base
> -address anywhere in usable system RAM and called there. The region
> -between the 2 MB aligned base address and the start of the image has no
> -special significance to the kernel, and may be used for other purposes.
> -At least image_size bytes from the start of the image must be free for
> -use by the kernel.
> +The Image must be placed at a 2MB aligned base address anywhere in
> +usable system RAM and called there. At least image_size bytes from
> +the start of the image must be free for use by the kernel.
> NOTE: versions prior to v4.6 cannot make use of memory below the
> physical offset of the Image so it is recommended that the Image be
> placed as close as possible to the start of system RAM.
> --
> 2.54.0
>
^ permalink raw reply
* Re: -next boot failures during KVM setup
From: Ard Biesheuvel @ 2026-06-19 15:06 UTC (permalink / raw)
To: Fuad Tabba, Will Deacon
Cc: Marc Zyngier, Mark Brown, Catalin Marinas, Oliver Upton,
Aishwarya.TCV, linux-arm-kernel
In-Reply-To: <CA+EHjTwymmZqNM9Yf+PQc+7GgmesDFL8UPj-eA2vdrGqrdAufA@mail.gmail.com>
Hi Fuad,
On Fri, 19 Jun 2026, at 17:01, Fuad Tabba wrote:
> Hi,
>
> On Wed, 10 Jun 2026 at 11:42, Will Deacon <will@kernel.org> wrote:
>>
>> On Mon, Jun 08, 2026 at 10:56:12PM +0200, Ard Biesheuvel wrote:
>> > Given we're at -rc7, I'd lean towards dropping the whole branch for now, or
>> > alternatively, only drop/revert "arm64: mm: Unmap kernel data/bss entirely from the
>> > linear map" (and its followup fix "arm64: mm: Defer remap of linear alias of
>> > data/bss") so that the region always remains readable via the linear map.
>>
>> I've reverted those two locally, thanks! I'll push some new branches
>> shortly.
>
> I hit an nVHE boot regression on v7.2 while testing Will's kvmtool
> protected-VM series [1]. I found this thread while debugging, and
> thought this might help. Note that Gemini helped me debug this (it's
> pretty good at debugging).
>
> f2ba877 (the read-only mapping you kept) still breaks nVHE, but only with
> CONFIG_NVHE_EL2_DEBUG / CONFIG_NVHE_EL2_TRACING:
>
> Unable to handle kernel write to read-only memory ... (ESR 0x9600004f)
> pc : kvm_apply_hyp_relocations+0x80/0x8c
>
> kvm_apply_hyp_relocations() writes the .hyp.reloc fixups via lm_alias().
> Most are in .hyp.rodata (whose alias isn't made read-only until
> mark_linear_text_alias_ro(), after the relocs), but five land in .hyp.data
> and now fault. They're all debug-only: __kvm_nvhe_selftest_vm/_vcpu
> (NVHE_EL2_DEBUG) and __kvm_nvhe_trace_buffer (NVHE_EL2_TRACING). A default
> config has none in .hyp.data and boots, which is why this didn't show up
> earlier. VHE skips the relocations entirely.
>
> [1] https://lore.kernel.org/all/20260619115415.5475-1-will@kernel.org/
>
Thanks for the report - I'll investigate. I imagine deferring the R/O remap
should help, but I'll try to reproduce locally and see what we can do about
this.
^ permalink raw reply
* Re: -next boot failures during KVM setup
From: Fuad Tabba @ 2026-06-19 15:01 UTC (permalink / raw)
To: Will Deacon
Cc: Ard Biesheuvel, Marc Zyngier, Mark Brown, Catalin Marinas,
Oliver Upton, Aishwarya.TCV, linux-arm-kernel
In-Reply-To: <aik_oVrNHUrh21MB@willie-the-truck>
Hi,
On Wed, 10 Jun 2026 at 11:42, Will Deacon <will@kernel.org> wrote:
>
> On Mon, Jun 08, 2026 at 10:56:12PM +0200, Ard Biesheuvel wrote:
> > Given we're at -rc7, I'd lean towards dropping the whole branch for now, or
> > alternatively, only drop/revert "arm64: mm: Unmap kernel data/bss entirely from the
> > linear map" (and its followup fix "arm64: mm: Defer remap of linear alias of
> > data/bss") so that the region always remains readable via the linear map.
>
> I've reverted those two locally, thanks! I'll push some new branches
> shortly.
I hit an nVHE boot regression on v7.2 while testing Will's kvmtool
protected-VM series [1]. I found this thread while debugging, and
thought this might help. Note that Gemini helped me debug this (it's
pretty good at debugging).
f2ba877 (the read-only mapping you kept) still breaks nVHE, but only with
CONFIG_NVHE_EL2_DEBUG / CONFIG_NVHE_EL2_TRACING:
Unable to handle kernel write to read-only memory ... (ESR 0x9600004f)
pc : kvm_apply_hyp_relocations+0x80/0x8c
kvm_apply_hyp_relocations() writes the .hyp.reloc fixups via lm_alias().
Most are in .hyp.rodata (whose alias isn't made read-only until
mark_linear_text_alias_ro(), after the relocs), but five land in .hyp.data
and now fault. They're all debug-only: __kvm_nvhe_selftest_vm/_vcpu
(NVHE_EL2_DEBUG) and __kvm_nvhe_trace_buffer (NVHE_EL2_TRACING). A default
config has none in .hyp.data and boots, which is why this didn't show up
earlier. VHE skips the relocations entirely.
[1] https://lore.kernel.org/all/20260619115415.5475-1-will@kernel.org/
Cheers,
/fuad
> Will
>
>
^ permalink raw reply
* Re: [PATCH v3] arm64: errata: Workaround NVIDIA Olympus device store/load ordering erratum
From: Will Deacon @ 2026-06-19 14:58 UTC (permalink / raw)
To: Shanker Donthineni
Cc: Jason Gunthorpe, Catalin Marinas, Vladimir Murzin,
linux-arm-kernel@lists.infradead.org, Mark Rutland,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
Vikram Sethi, Jason Sequeira
In-Reply-To: <25495831-f32d-4332-a7c2-fb1463b96174@nvidia.com>
On Tue, Jun 16, 2026 at 08:22:39AM -0500, Shanker Donthineni wrote:
> On 6/12/2026 7:48 AM, Jason Gunthorpe wrote:
> > On Thu, Jun 11, 2026 at 08:13:48PM -0500, Shanker Donthineni wrote:
> >
> > > For the scalar MMIO helpers, the workaround promotes the raw writes to
> > > store-release on affected CPUs as v1/v2 shown below. For the memcpy-toIO
> > > helpers, could you please clarify the specific reason for adding a dmb despite
> > > the documented no-ordering contract? Is the concern that some drivers may
> > > be relying on ordering across memcpy_toio_*() today even though the API
> > > does not guarantee it, and that we should cover those cases defensively?
> > I think given how arm implements them today the iocopy's are actually
> > the _relaxed variations.. I wonder if this matters to any user?
>
> Following Jason's observation that on arm64 the memcpy_toio()
> /__iowrite{32,64}_copy() helpers are effectively the relaxed
> (write-combining) variants, I'd like to settle one open point before posting
> v4: should the workaround also promote dgh() > dmb on affected CPUs (now
> Olympus core), or leave dgh() as a plain hint?
>
> If you'd still prefer the dmb defensively, to cover drivers that may
> rely on ordering across memcpy_toio() today despite the relaxed contract,
> I'm happy to fold it into v4.
The point is, you're going to have different behaviour to every other
arm64 system out there. You may be able to find vague comments in the
code that imply that you don't need to provide ordering, but at the end
of the day it's a pretty cavalier attitude imo and if a driver ever shows
up that relies on it then you're in trouble.
> Please let me know how you'd like me to proceed.
It's up to you. It's your broken CPU, not mine. You also haven't actually
provided any performance data for others to assess the trade-off.
If it was up to _me_, I'd upgrade dgh() on these CPUs to that I don't
need to worry about this again.
Will
^ permalink raw reply
* Re: [PATCH] Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()
From: Tomasz Figa @ 2026-06-19 14:53 UTC (permalink / raw)
To: Takashi Iwai
Cc: Sean Wang, Sergey Senozhatsky, Marcel Holtmann,
Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang, linux-bluetooth,
linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <87jyruiomq.wl-tiwai@suse.de>
On Fri, Jun 19, 2026 at 11:36 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Fri, 19 Jun 2026 16:17:31 +0200,
> Tomasz Figa wrote:
> >
> >
> > On Fri, Jun 19, 2026 at 10:27 PM Takashi Iwai <tiwai@suse.de> wrote:
> > >
> > > On Wed, 10 Jun 2026 08:52:31 +0200,
> > > Sean Wang wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Tue, Jun 9, 2026 at 7:19 AM Sergey Senozhatsky
> > > > <senozhatsky@chromium.org> wrote:
> > > > >
> > > > > Every once in a while we see a hung btmtksdio_flush() task:
> > > > >
> > > > > INFO: task kworker/u17:0:189 blocked for more than 122 seconds.
> > > > > __cancel_work_timer+0x3f4/0x460
> > > > > cancel_work_sync+0x1c/0x2c
> > > > > btmtksdio_flush+0x2c/0x40
> > > > > hci_dev_open_sync+0x10c4/0x2190
> > > > > [..]
> > > > >
> > > > > It all boils down to incorrect time_is_before_jiffies() usage in
> > > > > btmtksdio_txrx_work(). The btmtksdio_txrx_work() loop is expected
> > > > > to be terminated if running for longer than 5*HZ. However the
> > > > > timeout check is twisted: time_is_before_jiffies(old_jiffies + 5*HZ)
> > > > > evaluates to true when old_jiffies + 5*HZ is in the past i.e. when a
> > > > > timeout has occurred. Using OR with time_is_before_jiffies
> > (txrx_timeout)
> > > > > means that:
> > > > > - before the 5-second timeout: the condition is `int_status || false`,
> > > > > so it loops as long as there are pending interrupts.
> > > > > - after the 5-second timeout: the condition becomes `int_status || true
> > `,
> > > > > which is always true.
> > > > >
> > > > > When the loop becomes infinite btmtksdio_txrx_work() loop never
> > > > > terminates and never releases the SDIO host.
> > > > >
> > > > > Fix loop termination condition to actually enforce a 5*HZ timeout.
> > > > >
> > > > > Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to
> > work")
> > > > > Cc: stable@vger.kernel.org
> > > > > Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> > > > > ---
> > > > > drivers/bluetooth/btmtksdio.c | 2 +-
> > > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/
> > btmtksdio.c
> > > > > index 5b0fab7b89b5..c6f80c419e90 100644
> > > > > --- a/drivers/bluetooth/btmtksdio.c
> > > > > +++ b/drivers/bluetooth/btmtksdio.c
> > > > > @@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct
> > *work)
> > > > > if (btmtksdio_rx_packet(bdev, rx_size) < 0)
> > > > > bdev->hdev->stat.err_rx++;
> > > > > }
> > > > > - } while (int_status || time_is_before_jiffies(txrx_timeout));
> > > > > + } while (int_status && time_is_after_jiffies(txrx_timeout));
> > > >
> > > > yes, loop continues only while there is interrupt work and the timeout
> > > > deadline is still in the future
> > >
> > > I stumbled on this while backporting to distro kernels, and I wonder
> > > whether this change is correct.
> > >
> > > IIUC, this essentially makes the loop exiting right after the first
> > > cycle; the patch changed from time_is_before_jiffies() to *_after_*(),
> > > not only the logical OR to AND, and *_after_*() returns false, so the
> > > whole condition becomes false, too.
> >
> > The intention is for the loop to keep running as long as there is still an
> > interrupt left to handle (int_status != 0) and the timeout has not elapsed
> > (jiffies < txrx_timeout).
> >
> > Note that time_is_after_jiffies(x) returns true if x > jiffies (or jiffies <
> > x):
> >
> > /**
> > * time_is_after_jiffies - return true if a is after jiffies
> > * @a: time (unsigned long) to compare to jiffies
> > *
> > * Return: %true is time a is after jiffies, otherwise %false.
> > */
> > #define time_is_after_jiffies(a) time_before(jiffies, a)
> >
> > Or am I missing something?
>
> Doh, scratch my comment. It's enough confusing about time_after() vs
> time_is_after_jiffies(). Too hot here to review something today :-<
>
> Sorry for the noise!
Haha, no worries, it got me too! (In our internal discussion with
Sergey) I had to look up the definition and think about it for quite a
while to ensure it was really what we needed. ;)
Best,
Tomasz
^ permalink raw reply
* Re: [PATCH] arm64: uapi: Use __u128 instead of __uint128_t in UAPI headers
From: Mark Rutland @ 2026-06-19 14:51 UTC (permalink / raw)
To: Will Deacon
Cc: linux-arm-kernel, Arnd Bergmann, Nick Desaulniers, Steffen Eiden,
Andreas Grapentin, Catalin Marinas, Dave Martin, Marc Zyngier
In-Reply-To: <20260619130835.5678-1-will@kernel.org>
On Fri, Jun 19, 2026 at 02:08:34PM +0100, Will Deacon wrote:
> The arm64 UAPI exposes '__uint128_t' types in the members of
> 'struct user_fpsimd_state', 'struct user_pac_address_keys' and in the
> signal frame via 'struct fpsimd_context'. Since the alignment of such
> a type appears to be non-portable (16 bytes on arm64, 8 bytes on s390),
> prefer the '__u128' typedef from uapi/linux/types.h, which makes the
> alignment explicit and allows the definitions to be reused by other
> host architectures.
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
> Cc: Steffen Eiden <seiden@linux.ibm.com>
> Cc: Andreas Grapentin <gra@linux.ibm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Will Deacon <will@kernel.org>
> ---
>
> This aims to help a little with the s390/arm64 KVM series at:
>
> https://lore.kernel.org/r/20260529155050.2902245-1-seiden@linux.ibm.com
>
> by allowing the relevant parts of the arm64 UAPI to be used directly by
> s390 rather than copied and modified.
>
> I think it's a straightforward change, but the only thing that makes me
> pause for thought is whether there are toolchains out there which accept
> __uint128_t but not __int128. Then again, if that crops up as an issue
> we can probably just tweak the typedef we have in uapi/linux/types.h.
That's all fine to me in concept, so:
Acked-by: Mark Rutland <mark.rutland@arm.com>
A few places in arch/arm64/kernel/fpsimd.c and
arch/arm64/kernel/ptrace.c use __uint128_t to match the uapi headers.
For consistency (and to avoid people accidentally using __uint128_t in
future), I reckon it would be good to fix those up to match, but that
can be a follow-up.
Mark.
> arch/arm64/include/uapi/asm/ptrace.h | 12 ++++++------
> arch/arm64/include/uapi/asm/sigcontext.h | 6 +++---
> 2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
> index 6fed93fb2536..15649a253a57 100644
> --- a/arch/arm64/include/uapi/asm/ptrace.h
> +++ b/arch/arm64/include/uapi/asm/ptrace.h
> @@ -93,7 +93,7 @@ struct user_pt_regs {
> };
>
> struct user_fpsimd_state {
> - __uint128_t vregs[32];
> + __u128 vregs[32];
> __u32 fpsr;
> __u32 fpcr;
> __u32 __reserved[2];
> @@ -258,14 +258,14 @@ struct user_pac_mask {
> /* pointer authentication keys (NT_ARM_PACA_KEYS, NT_ARM_PACG_KEYS) */
>
> struct user_pac_address_keys {
> - __uint128_t apiakey;
> - __uint128_t apibkey;
> - __uint128_t apdakey;
> - __uint128_t apdbkey;
> + __u128 apiakey;
> + __u128 apibkey;
> + __u128 apdakey;
> + __u128 apdbkey;
> };
>
> struct user_pac_generic_keys {
> - __uint128_t apgakey;
> + __u128 apgakey;
> };
>
> /* ZA state (NT_ARM_ZA) */
> diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
> index e29bf3e2d0cc..d250ca7a1d46 100644
> --- a/arch/arm64/include/uapi/asm/sigcontext.h
> +++ b/arch/arm64/include/uapi/asm/sigcontext.h
> @@ -78,7 +78,7 @@ struct fpsimd_context {
> struct _aarch64_ctx head;
> __u32 fpsr;
> __u32 fpcr;
> - __uint128_t vregs[32];
> + __u128 vregs[32];
> };
>
> /*
> @@ -266,8 +266,8 @@ struct gcs_context {
> * - ---- -----------
> * REGS the entire SVE context
> *
> - * ZREGS __uint128_t[SVE_NUM_ZREGS][vq] all Z-registers
> - * ZREG __uint128_t[vq] individual Z-register Zn
> + * ZREGS __u128[SVE_NUM_ZREGS][vq] all Z-registers
> + * ZREG __u128[vq] individual Z-register Zn
> *
> * PREGS uint16_t[SVE_NUM_PREGS][vq] all P-registers
> * PREG uint16_t[vq] individual P-register Pn
> --
> 2.55.0.rc0.738.g0c8ab3ebcc-goog
>
^ permalink raw reply
* Re: [RFC] arm64: early_ioremap fails to map ACPI MADT on 64K pages
From: Will Deacon @ 2026-06-19 14:43 UTC (permalink / raw)
To: Yu Peng
Cc: Catalin Marinas, linux-arm-kernel, Rafael J. Wysocki, Len Brown,
linux-acpi, Andrew Morton, linux-mm, linux-kernel, lpieralisi,
guohanjun, sudeep.holla
In-Reply-To: <20260617060110.2846851-1-pengyu@kylinos.cn>
+arm64 ACPI maintainers
On Wed, Jun 17, 2026 at 02:01:10PM +0800, Yu Peng wrote:
> I hit an early boot failure on an arm64 system built with 64K pages while
> parsing the ACPI MADT.
>
> The failing system reports:
>
> PAGE_SIZE: 64K
> MADT physical address: 0x5a7ae018
> MADT length: 0x32094
The MADT isn't even 4k aligned, so why does the page size matter in this
case?
> The failure happens when acpi_table_parse_madt() calls into early_memremap()
> via __acpi_map_table(). The MADT itself is smaller than 256K, but its
> placement causes the early mapping to require 5 64K pages:
>
> offset within 64K page = 0x5a7ae018 & 0xffff = 0xe018
> mapped range = PAGE_ALIGN(0xe018 + 0x32094)
> = PAGE_ALIGN(0x400ac)
> = 0x50000
> nrpages = 0x50000 / 0x10000 = 5
>
> On arm64, NR_FIX_BTMAPS is currently derived from a 256K per-slot budget:
>
> #define NR_FIX_BTMAPS (SZ_256K / PAGE_SIZE)
>
> So for 64K pages, NR_FIX_BTMAPS is 4. The mapping therefore fails the
> early_ioremap() check:
>
> if (WARN_ON(nrpages > NR_FIX_BTMAPS))
> return NULL;
>
> After that, MADT parsing fails and the boot continues with symptoms such as:
>
> ACPI: APIC not present
> missing boot CPU MPIDR, not enabling secondaries
> Kernel panic - not syncing: No interrupt controller found.
>
> A firmware change can avoid this by placing MADT so that:
>
> (madt_phys & 0xffff) + madt_length <= SZ_256K
>
> However, I do not think ACPI requires such placement, so this looks like a
> kernel-side robustness issue as well, especially on large arm64 systems where
> MADT can grow with CPU topology.
>
> One possible kernel-side change is to increase the boot-time mapping budget for
> CONFIG_ARM64_64K_PAGES, for example using a 512K per-slot budget only in that
> configuration. I do not think this should be applied unconditionally to all
> page sizes, since the arm64 early fixmap code expects the boot-ioremap range
> to stay within one PMD.
>
> Has anyone seen similar failures on arm64 64K systems?
>
> Would maintainers prefer treating this as a firmware layout issue, or would
> increasing the early_ioremap budget for 64K pages be acceptable?
It think it boils down to what ACPI says about the alignment of the MADT.
Lorenzo?
Will
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu-v3: Declare eats_s1chk and eats_trans as host-endian u64
From: Will Deacon @ 2026-06-19 14:38 UTC (permalink / raw)
To: Nicolin Chen
Cc: Robin Murphy, joro, Jason Gunthorpe, Shuai Xue, linux-arm-kernel,
iommu, linux-kernel
In-Reply-To: <20260615194533.3290010-1-nicolinc@nvidia.com>
On Mon, Jun 15, 2026 at 12:45:33PM -0700, Nicolin Chen wrote:
> arm_smmu_get_ste_update_safe() declares the eats_s1chk and eats_trans
> locals as __le64, but initializes them from FIELD_PREP(), which returns a
> host-endian value, and passes them through cpu_to_le64() at the use sites.
>
> Sparse reports the following warnings:
>
> >> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c:1122:38: sparse: sparse: cast from restricted __le64
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c:1124:33: sparse: sparse: cast from restricted __le64
>
> Declare both locals as u64 so the type matches FIELD_PREP() and the
> existing cpu_to_le64() at the use sites performs the host-to-little-endian
> conversion. No functional change.
>
> Fixes: 7cad80048595 ("iommu/arm-smmu-v3: Mark EATS_TRANS safe when computing the update sequence")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/all/202606151017.QU0evpH9-lkp@intel.com/
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 8ce3e801eda3b..4c0f7b17b1f37 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1240,9 +1240,9 @@ VISIBLE_IF_KUNIT
> void arm_smmu_get_ste_update_safe(const __le64 *cur, const __le64 *target,
> __le64 *safe_bits)
> {
> - const __le64 eats_s1chk =
> + const u64 eats_s1chk =
> FIELD_PREP(STRTAB_STE_1_EATS, STRTAB_STE_1_EATS_S1CHK);
> - const __le64 eats_trans =
> + const u64 eats_trans =
> FIELD_PREP(STRTAB_STE_1_EATS, STRTAB_STE_1_EATS_TRANS);
Aha, this is the fix for that sparse report from the kbuild robot. Thanks!
Will
^ permalink raw reply
* Re: [PATCH] Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()
From: Takashi Iwai @ 2026-06-19 14:35 UTC (permalink / raw)
To: Tomasz Figa
Cc: Takashi Iwai, Sean Wang, Sergey Senozhatsky, Marcel Holtmann,
Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang, linux-bluetooth,
linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <CAAFQd5DyDQo9vBH80YYQBW7Bgf64F1m9q44-jhf1cc75XYpftA@mail.gmail.com>
On Fri, 19 Jun 2026 16:17:31 +0200,
Tomasz Figa wrote:
>
>
> On Fri, Jun 19, 2026 at 10:27 PM Takashi Iwai <tiwai@suse.de> wrote:
> >
> > On Wed, 10 Jun 2026 08:52:31 +0200,
> > Sean Wang wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Jun 9, 2026 at 7:19 AM Sergey Senozhatsky
> > > <senozhatsky@chromium.org> wrote:
> > > >
> > > > Every once in a while we see a hung btmtksdio_flush() task:
> > > >
> > > > INFO: task kworker/u17:0:189 blocked for more than 122 seconds.
> > > > __cancel_work_timer+0x3f4/0x460
> > > > cancel_work_sync+0x1c/0x2c
> > > > btmtksdio_flush+0x2c/0x40
> > > > hci_dev_open_sync+0x10c4/0x2190
> > > > [..]
> > > >
> > > > It all boils down to incorrect time_is_before_jiffies() usage in
> > > > btmtksdio_txrx_work(). The btmtksdio_txrx_work() loop is expected
> > > > to be terminated if running for longer than 5*HZ. However the
> > > > timeout check is twisted: time_is_before_jiffies(old_jiffies + 5*HZ)
> > > > evaluates to true when old_jiffies + 5*HZ is in the past i.e. when a
> > > > timeout has occurred. Using OR with time_is_before_jiffies
> (txrx_timeout)
> > > > means that:
> > > > - before the 5-second timeout: the condition is `int_status || false`,
> > > > so it loops as long as there are pending interrupts.
> > > > - after the 5-second timeout: the condition becomes `int_status || true
> `,
> > > > which is always true.
> > > >
> > > > When the loop becomes infinite btmtksdio_txrx_work() loop never
> > > > terminates and never releases the SDIO host.
> > > >
> > > > Fix loop termination condition to actually enforce a 5*HZ timeout.
> > > >
> > > > Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to
> work")
> > > > Cc: stable@vger.kernel.org
> > > > Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> > > > ---
> > > > drivers/bluetooth/btmtksdio.c | 2 +-
> > > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/
> btmtksdio.c
> > > > index 5b0fab7b89b5..c6f80c419e90 100644
> > > > --- a/drivers/bluetooth/btmtksdio.c
> > > > +++ b/drivers/bluetooth/btmtksdio.c
> > > > @@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct
> *work)
> > > > if (btmtksdio_rx_packet(bdev, rx_size) < 0)
> > > > bdev->hdev->stat.err_rx++;
> > > > }
> > > > - } while (int_status || time_is_before_jiffies(txrx_timeout));
> > > > + } while (int_status && time_is_after_jiffies(txrx_timeout));
> > >
> > > yes, loop continues only while there is interrupt work and the timeout
> > > deadline is still in the future
> >
> > I stumbled on this while backporting to distro kernels, and I wonder
> > whether this change is correct.
> >
> > IIUC, this essentially makes the loop exiting right after the first
> > cycle; the patch changed from time_is_before_jiffies() to *_after_*(),
> > not only the logical OR to AND, and *_after_*() returns false, so the
> > whole condition becomes false, too.
>
> The intention is for the loop to keep running as long as there is still an
> interrupt left to handle (int_status != 0) and the timeout has not elapsed
> (jiffies < txrx_timeout).
>
> Note that time_is_after_jiffies(x) returns true if x > jiffies (or jiffies <
> x):
>
> /**
> * time_is_after_jiffies - return true if a is after jiffies
> * @a: time (unsigned long) to compare to jiffies
> *
> * Return: %true is time a is after jiffies, otherwise %false.
> */
> #define time_is_after_jiffies(a) time_before(jiffies, a)
>
> Or am I missing something?
Doh, scratch my comment. It's enough confusing about time_after() vs
time_is_after_jiffies(). Too hot here to review something today :-<
Sorry for the noise!
Takashi
^ permalink raw reply
* Re: [PATCH] docs: arm64: Document that text_offset is always 0
From: Will Deacon @ 2026-06-19 14:33 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: linux-arm-kernel, Ard Biesheuvel, Jonathan Corbet, linux-doc,
linux-kernel
In-Reply-To: <20260604140839.1930847-1-linux@rasmusvillemoes.dk>
On Thu, Jun 04, 2026 at 04:08:39PM +0200, Rasmus Villemoes wrote:
> When trying to figure out where to place and call an arm64 Image in
> memory, reading booting.rst should provide the answer. However, it
> requires quite some digging to figure out that text_offset is set via
> ".quad 0" in head.S and is thus actually always 0 since v5.10.
>
> Update the documentation and make that explicit. Reword the 2MB
> requirement accordingly, and remove the paragraphs that only apply to
> the ancient versions where text_offset could be non-zero, as they only
> confuse a current reader.
Doesn't this needlessly prevent us from having a non-zero offset in future,
if we wanted that for some reason?
Will
^ permalink raw reply
* Re: [PATCH 1/5] dmaengine: sun6i-dma: Refactor to support A733 interrupt and register handling
From: Frank Li @ 2026-06-19 14:26 UTC (permalink / raw)
To: Yuanshen Cao
Cc: Vinod Koul, Frank Li, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Maxime Ripard, dmaengine, linux-arm-kernel, linux-sunxi,
linux-kernel, devicetree
In-Reply-To: <20260619-sun60i-a733-dma-v1-1-da4b649fc72a@gmail.com>
On Fri, Jun 19, 2026 at 04:53:30AM +0000, Yuanshen Cao wrote:
>
> This patch is the first step in a refactoring effort to support the
avoid use "this patch/commit", Just
Refactor ... to support Allwinner A733 DMA controller.
> Allwinner A733 DMA controller. Currently, the `sun6i-dma` driver has
> several functions related to interrupt handling (reading/writing
> interrupt enable and status registers) and register dumping that are
> hardcoded.
>
> To support the A733, which has different register layouts and interrupt
> handling logic, these functions are being moved into the
> `sun6i_dma_config` structure as function pointers. This allows the
> driver to use a polymorphic approach where the specific implementation
> is determined by the hardware configuration assigned during device
> probing.
>
> Changes:
> - Added function pointers to `struct sun6i_dma_config` for:
> - `dump_com_regs`
> - `read_irq_en`
> - `write_irq_en`
> - `read_irq_stat`
> - `write_irq_stat`
> - Implemented generic `sun6i_read/write_irq_*` functions for existing
> hardware.
> - Updated existing `sun6i_dma_config` instances (A31, A23, H3, A64,
> A100, H6, V3S) to use these new function pointers.
>
> Signed-off-by: Yuanshen Cao <alex.caoys@gmail.com>
> ---
> drivers/dma/sun6i-dma.c | 74 +++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 69 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index a9a254dbf8cb..d92e702320d9 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -138,6 +138,11 @@ struct sun6i_dma_config {
> void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst);
> void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq);
> void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode);
> + void (*dump_com_regs)(struct sun6i_dma_dev *sdev);
> + u32 (*read_irq_en)(struct sun6i_dma_dev *sdev, u32 chan_num);
> + void (*write_irq_en)(struct sun6i_dma_dev *sdev, u32 chan_num, u32 irq_val);
> + u32 (*read_irq_stat)(struct sun6i_dma_dev *sdev, u32 chan_num);
> + void (*write_irq_stat)(struct sun6i_dma_dev *sdev, u32 chan_num, u32 status);
> u32 src_burst_lengths;
> u32 dst_burst_lengths;
> u32 src_addr_widths;
> @@ -347,6 +352,25 @@ static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode)
> DMA_CHAN_CFG_DST_MODE_H6(dst_mode);
> }
>
> +static u32 sun6i_read_irq_en(struct sun6i_dma_dev *sdev, u32 chan_num)
> +{
> + return readl(sdev->base + DMA_IRQ_EN(chan_num));
> +}
> +
> +static void sun6i_write_irq_en(struct sun6i_dma_dev *sdev, u32 chan_num, u32 irq_val)
> +{
> + writel(irq_val, sdev->base + DMA_IRQ_EN(chan_num));
> +}
> +static u32 sun6i_read_irq_stat(struct sun6i_dma_dev *sdev, u32 chan_num)
> +{
> + return readl(sdev->base + DMA_IRQ_STAT(chan_num));
> +}
> +
> +static void sun6i_write_irq_stat(struct sun6i_dma_dev *sdev, u32 chan_num, u32 status)
> +{
> + writel(status, sdev->base + DMA_IRQ_STAT(chan_num));
> +}
> +
> static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan)
> {
> struct sun6i_desc *txd = pchan->desc;
> @@ -460,16 +484,16 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
>
> vchan->irq_type = vchan->cyclic ? DMA_IRQ_PKG : DMA_IRQ_QUEUE;
>
> - irq_val = readl(sdev->base + DMA_IRQ_EN(irq_reg));
> + irq_val = sdev->cfg->read_irq_en(sdev, irq_reg);
> irq_val &= ~((DMA_IRQ_HALF | DMA_IRQ_PKG | DMA_IRQ_QUEUE) <<
> (irq_offset * DMA_IRQ_CHAN_WIDTH));
> irq_val |= vchan->irq_type << (irq_offset * DMA_IRQ_CHAN_WIDTH);
> - writel(irq_val, sdev->base + DMA_IRQ_EN(irq_reg));
> + sdev->cfg->write_irq_en(sdev, irq_reg, irq_val);
>
> writel(pchan->desc->p_lli, pchan->base + DMA_CHAN_LLI_ADDR);
> writel(DMA_CHAN_ENABLE_START, pchan->base + DMA_CHAN_ENABLE);
>
> - sun6i_dma_dump_com_regs(sdev);
> + sdev->cfg->dump_com_regs(sdev);
> sun6i_dma_dump_chan_regs(sdev, pchan);
>
> return 0;
> @@ -549,14 +573,14 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
> u32 status;
>
> for (i = 0; i < sdev->num_pchans / DMA_IRQ_CHAN_NR; i++) {
> - status = readl(sdev->base + DMA_IRQ_STAT(i));
> + status = sdev->cfg->read_irq_stat(sdev, i);
> if (!status)
> continue;
>
> dev_dbg(sdev->slave.dev, "DMA irq status %s: 0x%x\n",
> str_high_low(i), status);
>
> - writel(status, sdev->base + DMA_IRQ_STAT(i));
> + sdev->cfg->write_irq_stat(sdev, i, status);
>
> for (j = 0; (j < DMA_IRQ_CHAN_NR) && status; j++) {
> pchan = sdev->pchans + j;
> @@ -1124,6 +1148,11 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_a31,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
Can you define macro like to avoid duplicate these init code. Or set it at
probe if it is NULL.
Frank
> .src_burst_lengths = BIT(1) | BIT(8),
> .dst_burst_lengths = BIT(1) | BIT(8),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1147,6 +1176,11 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_a31,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(8),
> .dst_burst_lengths = BIT(1) | BIT(8),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1165,6 +1199,11 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_a31,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(8),
> .dst_burst_lengths = BIT(1) | BIT(8),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1190,6 +1229,11 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_h3,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1211,6 +1255,11 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_h3,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1232,6 +1281,11 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_h3,
> .set_drq = sun6i_set_drq_h6,
> .set_mode = sun6i_set_mode_h6,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1255,6 +1309,11 @@ static struct sun6i_dma_config sun50i_h6_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_h3,
> .set_drq = sun6i_set_drq_h6,
> .set_mode = sun6i_set_mode_h6,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> @@ -1281,6 +1340,11 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = {
> .set_burst_length = sun6i_set_burst_length_a31,
> .set_drq = sun6i_set_drq_a31,
> .set_mode = sun6i_set_mode_a31,
> + .dump_com_regs = sun6i_dma_dump_com_regs,
> + .read_irq_en = sun6i_read_irq_en,
> + .write_irq_en = sun6i_write_irq_en,
> + .read_irq_stat = sun6i_read_irq_stat,
> + .write_irq_stat = sun6i_write_irq_stat,
> .src_burst_lengths = BIT(1) | BIT(8),
> .dst_burst_lengths = BIT(1) | BIT(8),
> .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>
> --
> 2.54.0
>
^ permalink raw reply
* Re: [PATCH v4 0/4] arm64: cross-CPU NMI via SDEI
From: Marc Zyngier @ 2026-06-19 14:26 UTC (permalink / raw)
To: Catalin Marinas
Cc: Kiryl Shutsemau, Will Deacon, James Morse, Mark Rutland,
Doug Anderson, Petr Mladek, Thomas Gleixner, Andrew Morton,
Baoquan He, Puranjay Mohan, Usama Arif, Breno Leitao,
Julien Thierry, Lecopzer Chen, Sumit Garg, kernel-team, kexec,
linux-arm-kernel, linux-kernel, Kiryl Shutsemau (Meta)
In-Reply-To: <ajVLeseWOZn0XXY2@arm.com>
On Fri, 19 Jun 2026 15:00:26 +0100,
Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> Hi Kiryl,
>
> On Wed, Jun 17, 2026 at 08:20:01PM +0100, Kiryl Shutsemau wrote:
> > - GICv3 pseudo-NMI (interrupt priority masking). Its cost is on the
> > interrupt mask/unmask hot path: local_irq_enable() becomes an
> > ICC_PMR_EL1 write plus a synchronising barrier, and exception
> > entry/exit save and restore the PMR, paid on every CPU whether or not
> > an NMI is ever delivered. In our measurements, enabling pseudo-NMI
> > costs up to ~5% on real workloads, and ~66% on a syscall-in-a-loop
> > microbenchmark. A fleet-wide ~5% regression is not acceptable, so
> > these systems run with pseudo-NMI disabled.
>
> Does your firmware set ICC_CTLR_EL1.PMHE? I'd be curious to see the
> numbers if the DSB was omitted on the enable path.
I certainly don't observe this sort of overhead on the HW I have
access to, and would like to understand where this is coming from with
actual profiling data.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v2 4/5] arm64: defconfig: Drop unused Ethernet vendors
From: Geert Uytterhoeven @ 2026-06-19 14:21 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Krzysztof Kozlowski, linux-kernel, linux-arm-kernel,
Catalin Marinas, Will Deacon, Alexandre Belloni, Linus Walleij,
Drew Fustini, soc
In-Reply-To: <b04972c7-2c5e-40fe-a8a6-7ade300cd4b2@app.fastmail.com>
Hi Arnd,
On Fri, 19 Jun 2026 at 15:54, Arnd Bergmann <arnd@arndb.de> wrote:
> On Fri, Jun 19, 2026, at 15:11, Krzysztof Kozlowski wrote:
> > On 19/06/2026 12:12, Geert Uytterhoeven wrote:
> >>> +# CONFIG_NET_VENDOR_ACTIONS is not set
> >>> +# CONFIG_NET_VENDOR_ADAPTEC is not set
> >>> +# CONFIG_NET_VENDOR_AGERE is not set
> >>> +# CONFIG_NET_VENDOR_ALACRITECH is not set
> >>> +# CONFIG_NET_VENDOR_ALLWINNER is not set
> >>
> >> [...]
> >>
> >> I am not sure this new policy is a good idea: none of this affects
> >
> > I would not call it new policy. Just an idea which got accepted. :)
>
> I think when we originally added the CONFIG_NET_VENDOR_xxx symbols,
> the idea would be that we would one day change them to
> default-disabled, but that never happened, and generally causes
> more problems than it solves.
Yeah. While "make oldconfig" would handle that fine, all defconfigs would
need an update.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox