Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: RD Babiera @ 2026-06-15 18:05 UTC (permalink / raw)
  To: vkoul, peter.griffin, andre.draszik, tudor.ambarus, p.zabel,
	neil.armstrong
  Cc: badhri, linux-arm-kernel, linux-samsung-soc, linux-phy,
	linux-kernel, RD Babiera

Add USB3 PHY support for the Google Tensor G5 USB PHY driver.
This patch adds functionality for the usb3_core and usb3_tca registers,
usb3 clock, and usb3 reset as defined in
google,lga-usb-phy.yaml.

Refactor the probe sequence to initialize the USB2 and USB3 PHYs, and then
initialize clocks and resets for both PHYs afterwards.

Refactor set_vbus_valid to reduce duplicated code.

Implement USB3 phy_ops for phy_init, phy_exit, and phy_power_on.

Signed-off-by: RD Babiera <rdbabiera@google.com>
---
 drivers/phy/phy-google-usb.c | 350 +++++++++++++++++++++++++++++++----
 1 file changed, 317 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
index ab20bc20f19e..a23a9008b521 100644
--- a/drivers/phy/phy-google-usb.c
+++ b/drivers/phy/phy-google-usb.c
@@ -20,6 +20,7 @@
 #include <linux/reset.h>
 #include <linux/usb/typec_mux.h>
 
+/* USB_CFG_CSR */
 #define USBCS_USB2PHY_CFG19_OFFSET 0x0
 #define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
 
@@ -28,11 +29,41 @@
 #define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
 #define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
 
+/* USBDP_TOP */
 #define USBCS_PHY_CFG1_OFFSET 0x28
+#define USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN BIT(1)
+#define USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE GENMASK(11, 10)
+#define SRAM_BYPASS_MODE_BYPASS_FIRMWARE BIT(0)
+#define SRAM_BYPASS_MODE_BYPASS_CONTEXT BIT(1)
 #define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
 
+#define USBDP_TOP_CFG_REG_OFFSET 0x44
+#define USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N BIT(0)
+
+#define PHY_POWER_CONFIG_REG1_OFFSET 0x48
+#define PHY_POWER_CONFIG_REG1_PG_MODE_EN BIT(1)
+#define PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG GENMASK(31, 14)
+#define UPCS_PIPE_CONFIG_ISO_CPM BIT(5)
+#define UPCS_PIPE_CONFIG_PG_MODE_STATIC BIT(6)
+#define UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT BIT(9)
+
+/* USB3_TCA */
+#define TCA_INTR_STS_OFFSET 0x8
+#define TCA_INTR_STS_XA_ACT_EVT BIT(0)
+#define TCA_TCPC_OFFSET 0x14
+#define TCA_TCPC_MUX_CONTROL GENMASK(2, 0)
+#define TCA_TCPC_MUX_CONTROL_USB_ONLY 0x1
+#define TCA_TCPC_CONNECTOR_ORIENTATION BIT(3)
+#define TCA_TCPC_VALID BIT(4)
+#define TCA_PSTATE_0_OFFSET 0x50
+#define TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS BIT(8)
+
+#define GPHY_TCA_DELAY_US 10
+#define GPHY_TCA_TIMEOUT_US 2500000
+
 enum google_usb_phy_id {
 	GOOGLE_USB2_PHY,
+	GOOGLE_USB3_PHY,
 	GOOGLE_USB_PHY_NUM,
 };
 
@@ -46,11 +77,50 @@ struct google_usb_phy_instance {
 	struct reset_control_bulk_data *rsts;
 };
 
+struct google_usb_phy_config {
+	const char * const *clk_names;
+	unsigned int num_clks;
+	const char * const *rst_names;
+	unsigned int num_rsts;
+};
+
+static const char * const u2phy_clk_names[] = {
+	"usb2",
+	"usb2_apb",
+};
+static const char * const u3phy_clk_names[] = {
+	"usb3"
+};
+static const char * const u2phy_rst_names[] = {
+	"usb2",
+	"usb2_apb",
+};
+static const char * const u3phy_rst_names[] = {
+	"usb3"
+};
+
+static const struct google_usb_phy_config phy_configs[GOOGLE_USB_PHY_NUM] = {
+	[GOOGLE_USB2_PHY] = {
+		.clk_names = u2phy_clk_names,
+		.num_clks = ARRAY_SIZE(u2phy_clk_names),
+		.rst_names = u2phy_rst_names,
+		.num_rsts = ARRAY_SIZE(u2phy_rst_names),
+	},
+	[GOOGLE_USB3_PHY] = {
+		.clk_names = u3phy_clk_names,
+		.num_clks = ARRAY_SIZE(u3phy_clk_names),
+		.rst_names = u3phy_rst_names,
+		.num_rsts = ARRAY_SIZE(u3phy_rst_names),
+	},
+};
+
 struct google_usb_phy {
 	struct device *dev;
 	struct regmap *usb_cfg_regmap;
 	unsigned int usb2_cfg_offset;
 	void __iomem *usbdp_top_base;
+	void __iomem *usb3_core_base;
+	void __iomem *usb3_tca_base;
 	struct google_usb_phy_instance *insts;
 	/*
 	 * Protect phy registers from concurrent access, specifically via
@@ -65,15 +135,79 @@ static void set_vbus_valid(struct google_usb_phy *gphy)
 {
 	u32 reg;
 
-	if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
-		reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+	if (gphy->orientation == TYPEC_ORIENTATION_NONE)
 		reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
-		writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
-	} else {
-		reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+	else
 		reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
-		writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
-	}
+	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_sram_bypass(struct google_usb_phy *gphy, u32 bypass)
+{
+	u32 reg;
+
+	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+	reg &= ~USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE;
+	reg |= FIELD_PREP(USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE, bypass);
+	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_pmgt_ref_clk_req_n(struct google_usb_phy *gphy, bool resume)
+{
+	u32 reg;
+
+	reg = readl(gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+	if (resume)
+		reg |= USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+	else
+		reg &= ~USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+	writel(reg, gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+}
+
+static int wait_tca_xa_ack(struct google_usb_phy *gphy)
+{
+	int ret;
+	u32 reg;
+
+	ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET,
+				 reg, !!(reg & TCA_INTR_STS_XA_ACT_EVT),
+				 GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+	if (ret)
+		dev_err(gphy->dev, "tca xa_ack timeout, ret=%d", ret);
+
+	return ret;
+}
+
+static int program_tca_locked(struct google_usb_phy *gphy)
+	   __must_hold(&gphy->phy_mutex)
+{
+	int ret;
+	u32 reg;
+
+	reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+	writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+	reg = readl(gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+	reg &= ~TCA_TCPC_MUX_CONTROL;
+	reg |= FIELD_PREP(TCA_TCPC_MUX_CONTROL, TCA_TCPC_MUX_CONTROL_USB_ONLY);
+	if (gphy->orientation == TYPEC_ORIENTATION_REVERSE)
+		reg |= TCA_TCPC_CONNECTOR_ORIENTATION;
+	else
+		reg &= ~TCA_TCPC_CONNECTOR_ORIENTATION;
+	reg |= TCA_TCPC_VALID;
+	writel(reg, gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+
+	ret = wait_tca_xa_ack(gphy);
+	dev_dbg(gphy->dev, "TCA switch %s, mux %lu, orientation %s",
+		ret ? "failed" : "success",
+		FIELD_GET(TCA_TCPC_MUX_CONTROL, reg),
+		FIELD_GET(TCA_TCPC_CONNECTOR_ORIENTATION, reg) ? "reverse" : "normal");
+
+	reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+	writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+	return ret;
 }
 
 static int google_usb_set_orientation(struct typec_switch_dev *sw,
@@ -161,6 +295,103 @@ static const struct phy_ops google_usb2_phy_ops = {
 	.exit		= google_usb2_phy_exit,
 };
 
+static int google_usb3_phy_init(struct phy *_phy)
+{
+	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+	struct google_usb_phy *gphy = inst->parent;
+	int ret = 0;
+	u32 reg;
+
+	dev_dbg(gphy->dev, "initializing usb3 phy\n");
+
+	guard(mutex)(&gphy->phy_mutex);
+
+	reg = readl(gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+	reg |= PHY_POWER_CONFIG_REG1_PG_MODE_EN;
+	reg &= ~PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG;
+	reg |= FIELD_PREP(PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG,
+			  (UPCS_PIPE_CONFIG_ISO_CPM |
+			   UPCS_PIPE_CONFIG_PG_MODE_STATIC |
+			   UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT));
+	writel(reg, gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+
+	set_vbus_valid(gphy);
+
+	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+	reg |= USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN;
+	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+
+	set_sram_bypass(gphy, SRAM_BYPASS_MODE_BYPASS_FIRMWARE |
+			SRAM_BYPASS_MODE_BYPASS_CONTEXT);
+	set_pmgt_ref_clk_req_n(gphy, true);
+
+	ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
+	if (ret)
+		return ret;
+
+	ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
+	if (ret)
+		goto disable_clocks;
+
+	ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_PSTATE_0_OFFSET,
+				 reg, !(reg & TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS),
+				 GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+	if (ret) {
+		dev_err(gphy->dev, "wait for lane0 phystatus timed out");
+		goto assert_resets;
+	}
+
+	return 0;
+
+assert_resets:
+	reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+disable_clocks:
+	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+	return ret;
+}
+
+static int google_usb3_phy_exit(struct phy *_phy)
+{
+	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+	struct google_usb_phy *gphy = inst->parent;
+
+	dev_dbg(gphy->dev, "exiting usb3 phy\n");
+
+	guard(mutex)(&gphy->phy_mutex);
+
+	set_pmgt_ref_clk_req_n(gphy, false);
+	reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+
+	return 0;
+}
+
+static int google_usb3_phy_power_on(struct phy *_phy)
+{
+	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+	struct google_usb_phy *gphy = inst->parent;
+	int ret;
+
+	dev_dbg(gphy->dev, "power on usb3 phy\n");
+
+	guard(mutex)(&gphy->phy_mutex);
+	ret = wait_tca_xa_ack(gphy);
+	if (ret) {
+		dev_err(gphy->dev, "PoR->NC transition timeout");
+		return ret;
+	}
+
+	ret = program_tca_locked(gphy);
+
+	return ret;
+}
+
+static const struct phy_ops google_usb3_phy_ops = {
+	.init		= google_usb3_phy_init,
+	.exit		= google_usb3_phy_exit,
+	.power_on	= google_usb3_phy_power_on,
+};
+
 static struct phy *google_usb_phy_xlate(struct device *dev,
 					const struct of_phandle_args *args)
 {
@@ -173,14 +404,61 @@ static struct phy *google_usb_phy_xlate(struct device *dev,
 	return gphy->insts[args->args[0]].phy;
 }
 
+static int google_usb_phy_parse_clocks(struct google_usb_phy *gphy)
+{
+	struct device *dev = gphy->dev;
+	int id, i, ret;
+
+	for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+		const struct google_usb_phy_config *cfg = &phy_configs[id];
+		struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+		inst->num_clks = cfg->num_clks;
+		inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
+		if (!inst->clks)
+			return -ENOMEM;
+
+		for (i = 0; i < inst->num_clks; i++)
+			inst->clks[i].id = cfg->clk_names[i];
+
+		ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to get phy%d clks\n", id);
+	}
+
+	return 0;
+}
+
+static int google_usb_phy_parse_resets(struct google_usb_phy *gphy)
+{
+	struct device *dev = gphy->dev;
+	int id, i, ret;
+
+	for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+		const struct google_usb_phy_config *cfg = &phy_configs[id];
+		struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+		inst->num_rsts = cfg->num_rsts;
+		inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
+		if (!inst->rsts)
+			return -ENOMEM;
+
+		for (i = 0; i < inst->num_rsts; i++)
+			inst->rsts[i].id = cfg->rst_names[i];
+		ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+		if (ret)
+			return dev_err_probe(dev, ret, "failed to get phy%d resets\n", id);
+	}
+
+	return 0;
+}
+
 static int google_usb_phy_probe(struct platform_device *pdev)
 {
 	struct typec_switch_desc sw_desc = { };
-	struct google_usb_phy_instance *inst;
 	struct phy_provider *phy_provider;
 	struct device *dev = &pdev->dev;
 	struct google_usb_phy *gphy;
-	struct phy *phy;
 	u32 args[1];
 	int ret;
 
@@ -212,39 +490,45 @@ static int google_usb_phy_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base),
 				    "invalid usbdp top\n");
 
+	gphy->usb3_core_base = devm_platform_ioremap_resource_byname(pdev,
+								     "usb3_core");
+	if (IS_ERR(gphy->usb3_core_base))
+		return dev_err_probe(dev, PTR_ERR(gphy->usb3_core_base),
+				    "invalid usb3 core\n");
+
+	gphy->usb3_tca_base = devm_platform_ioremap_resource_byname(pdev,
+								    "usb3_tca");
+	if (IS_ERR(gphy->usb3_tca_base))
+		return dev_err_probe(dev, PTR_ERR(gphy->usb3_tca_base),
+				    "invalid usb3 tca\n");
+
 	gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL);
 	if (!gphy->insts)
 		return -ENOMEM;
 
-	inst = &gphy->insts[GOOGLE_USB2_PHY];
-	inst->parent = gphy;
-	inst->index = GOOGLE_USB2_PHY;
-	phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
-	if (IS_ERR(phy))
-		return dev_err_probe(dev, PTR_ERR(phy),
+	gphy->insts[GOOGLE_USB2_PHY].phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
+	gphy->insts[GOOGLE_USB2_PHY].index = GOOGLE_USB2_PHY;
+	gphy->insts[GOOGLE_USB2_PHY].parent = gphy;
+	if (IS_ERR(gphy->insts[GOOGLE_USB2_PHY].phy))
+		return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB2_PHY].phy),
 				     "failed to create usb2 phy instance\n");
-	inst->phy = phy;
-	phy_set_drvdata(phy, inst);
+	phy_set_drvdata(gphy->insts[GOOGLE_USB2_PHY].phy, &gphy->insts[GOOGLE_USB2_PHY]);
 
-	inst->num_clks = 2;
-	inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
-	if (!inst->clks)
-		return -ENOMEM;
-	inst->clks[0].id = "usb2";
-	inst->clks[1].id = "usb2_apb";
-	ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+	gphy->insts[GOOGLE_USB3_PHY].phy = devm_phy_create(dev, NULL, &google_usb3_phy_ops);
+	gphy->insts[GOOGLE_USB3_PHY].index = GOOGLE_USB3_PHY;
+	gphy->insts[GOOGLE_USB3_PHY].parent = gphy;
+	if (IS_ERR(gphy->insts[GOOGLE_USB3_PHY].phy))
+		return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB3_PHY].phy),
+				     "failed to create usb3 phy instance\n");
+	phy_set_drvdata(gphy->insts[GOOGLE_USB3_PHY].phy, &gphy->insts[GOOGLE_USB3_PHY]);
+
+	ret = google_usb_phy_parse_clocks(gphy);
 	if (ret)
-		return dev_err_probe(dev, ret, "failed to get u2 phy clks\n");
+		return ret;
 
-	inst->num_rsts = 2;
-	inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
-	if (!inst->rsts)
-		return -ENOMEM;
-	inst->rsts[0].id = "usb2";
-	inst->rsts[1].id = "usb2_apb";
-	ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+	ret = google_usb_phy_parse_resets(gphy);
 	if (ret)
-		return dev_err_probe(dev, ret, "failed to get u2 phy resets\n");
+		return ret;
 
 	phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
 	if (IS_ERR(phy_provider))

base-commit: 2ace2e949979b82f82f12dd76d7c5a6145246ca3
-- 
2.54.0.1189.g8c84645362-goog



^ permalink raw reply related

* Re: [PATCH 7/7] clk: sunxi-ng: Add Allwinner A733 RTC CCU support
From: Jerome Brunet @ 2026-06-15 17:56 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Junhui Liu, Michael Turquette, Stephen Boyd, Jernej Skrabec,
	Samuel Holland, Alexandre Belloni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Maxime Ripard, linux-clk,
	linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
	devicetree, André Przywara
In-Reply-To: <CAGb2v64euL+QNXiJdTn0JygYLXg0WoguPSprKT4sKGZGVZbwug@mail.gmail.com>

On sam. 28 mars 2026 at 22:41, Chen-Yu Tsai <wens@kernel.org> wrote:

> On Wed, Jan 21, 2026 at 7:04 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>
>> Add support for the internal CCU found in the RTC module of the Allwinner
>> A733 SoC. While the basic 16MHz (IOSC) and 32kHz logic remains compatible
>> with older SoCs like the sun6i, the A733 introduces several new features.
>>
>> The A733 RTC CCU supports choosing one of three external crystal
>> frequencies: 19.2MHz, 24MHz, and 26MHz. It features hardware detection
>> logic to automatically identify the frequency used on the board and
>> exports this DCXO signal as the "hosc" clock.
>>
>> Furthermore, the driver implements logic to derive a 32kHz reference
>> from the HOSC. This is achieved through a muxed clock path using fixed
>> pre-dividers to normalize the different crystal frequencies to ~32kHz.
>
> Have you tested whether the actually normalizes the frequency, i.e.
> selects a different divider based on the DCXO frequency? Otherwise
> we're just lying about the frequency.
>
>> This path reuses the same hardware mux registers as the HOSC clock.
>>
>> Additionally, this CCU provides several gate clocks for specific
>> peripherals, including SerDes, HDMI, and UFS. The driver is implemented
>> as an auxiliary driver to be bound to the sun6i-rtc driver.
>>
>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>> ---

[...]

>> +};
>> +
>> +static const struct clk_parent_data hosc_parents[] = {
>> +       { .fw_name = "osc24M" },
>> +       { .fw_name = "osc19M" },
>> +       { .fw_name = "osc26M" },
>> +       { .fw_name = "osc24M" },
>> +};
>
> As mentioned in my reply to the binding, this is wrong. There is only
> one input.
>
> The most you can do is check the rate of the parent clock against the
> detected one, and _scream_ that the DT is wrong. And maybe override
> the reported frequency.
>
> If you want to do the latter, you could add a new fixed rate gated
> clock type to our library. You would fill in the rate before the
> clocks get registered. I probably wouldn't go that far. We want people
> to have correct hardware descriptions.
>
> Funnily enough Allwinner's BSP actually implements a fixed rate gate
> for the next 24M-to-32k divider clock.

What about implementing the register bellow as a read-only (and
non-cached) divider using the factors provided by Junhui ? That would be
an accurate description of the HW I think.

The oscillator gets set in DT and if the output reported past the
divider is not 32728Hz, you know you've got a problem (bad DT or HW gone
bad)

With a fixed-rate gate, you may actually end up lying about what
actually happen, if the HW does not behave as expected.

Do you prefer a fixed-rate gate still or should I try the RO divider
approach ?

>
>> +
>> +struct ccu_mux hosc_clk = {
>> +       .enable = DCXO_CTRL_DCXO_EN,
>> +       .mux    = _SUNXI_CCU_MUX(14, 2),
>> +       .common = {
>> +               .reg            = DCXO_CTRL_REG,
>> +               .hw.init        = CLK_HW_INIT_PARENTS_DATA("hosc",
>> +                                                          hosc_parents,
>> +                                                          &ccu_mux_ro_ops,
>> +                                                          0),
>> +       },
>> +};
>
> So this is wrong.
>
>> +
>> +static const struct ccu_mux_fixed_prediv hosc_32k_predivs[] = {
>> +       { .index = 0, .div = 732 },
>
> Why is it 732 instead of 750?
>
>> +       { .index = 1, .div = 586 },
>> +       { .index = 2, .div = 793 },
>> +       { .index = 3, .div = 732 },
>> +};
>> +
>> +static struct ccu_mux hosc_32k_mux_clk = {
>> +       .enable         = DCXO_CTRL_DCXO_EN,
>


^ permalink raw reply

* [GIT PULL] CRC updates for 7.2
From: Eric Biggers @ 2026-06-15 17:48 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-crypto, linux-arm-kernel, linux-kernel, Ard Biesheuvel,
	Christoph Hellwig

The following changes since commit e7ae89a0c97ce2b68b0983cd01eda67cf373517d:

  Linux 7.1-rc5 (2026-05-24 13:48:06 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git tags/crc-for-linus

for you to fetch changes up to cbe44c389ae80362e72696ac08f7c55a83f2a050:

  crypto: aegis128 - Use neon-intrinsics.h on ARM too (2026-05-28 13:14:25 -0700)

----------------------------------------------------------------

Accelerate CRC64-NVME for 32-bit ARM by refactoring the arm64 NEON
intrinsics implementation to be shared by 32-bit and 64-bit.

Also apply a similar cleanup to the 32-bit ARM NEON implementation of
xor_gen(), where it now reuses code from the 64-bit implementation.

----------------------------------------------------------------
Ard Biesheuvel (6):
      ARM: Add a neon-intrinsics.h header like on arm64
      xor/arm: Replace vectorized implementation with arm64's intrinsics
      xor/arm64: Use shared NEON intrinsics implementation from 32-bit ARM
      lib/crc: Turn NEON intrinsics crc64 implementation into common code
      lib/crc: arm: Enable arm64's NEON intrinsics implementation of crc64
      crypto: aegis128 - Use neon-intrinsics.h on ARM too

 Documentation/arch/arm/kernel_mode_neon.rst        |   4 +-
 arch/arm/include/asm/neon-intrinsics.h             |  60 +++++++++
 crypto/Makefile                                    |  10 +-
 crypto/aegis128-neon-inner.c                       |   4 +-
 lib/crc/Kconfig                                    |   1 +
 lib/crc/Makefile                                   |   9 +-
 lib/crc/arm/crc64-neon.h                           |  34 +++++
 lib/crc/arm/crc64.h                                |  36 +++++
 lib/crc/arm64/crc64-neon.h                         |  21 +++
 lib/crc/arm64/crc64.h                              |   4 +-
 lib/crc/{arm64/crc64-neon-inner.c => crc64-neon.c} |  26 +---
 lib/raid/xor/Makefile                              |  13 +-
 lib/raid/xor/arm/xor-neon.c                        |  26 ----
 lib/raid/xor/arm/xor-neon.h                        |   7 +
 lib/raid/xor/arm/xor_arch.h                        |   7 +-
 lib/raid/xor/arm64/xor-eor3.c                      | 146 +++++++++++++++++++++
 lib/raid/xor/xor-8regs.c                           |   2 -
 lib/raid/xor/{arm64 => }/xor-neon.c                | 143 +-------------------
 18 files changed, 338 insertions(+), 215 deletions(-)
 create mode 100644 arch/arm/include/asm/neon-intrinsics.h
 create mode 100644 lib/crc/arm/crc64-neon.h
 create mode 100644 lib/crc/arm/crc64.h
 create mode 100644 lib/crc/arm64/crc64-neon.h
 rename lib/crc/{arm64/crc64-neon-inner.c => crc64-neon.c} (62%)
 delete mode 100644 lib/raid/xor/arm/xor-neon.c
 create mode 100644 lib/raid/xor/arm/xor-neon.h
 create mode 100644 lib/raid/xor/arm64/xor-eor3.c
 rename lib/raid/xor/{arm64 => }/xor-neon.c (56%)


^ permalink raw reply

* Re: [PATCH 1/7] dt-bindings: rtc: sun6i: Add Allwinner A733 support
From: Jerome Brunet @ 2026-06-15 17:46 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Junhui Liu, Michael Turquette, Stephen Boyd, Jernej Skrabec,
	Samuel Holland, Alexandre Belloni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Maxime Ripard, linux-clk,
	linux-arm-kernel, linux-sunxi, linux-kernel, linux-rtc,
	devicetree
In-Reply-To: <CAGb2v67844OPwE6VJ0PAs5LsmCa2h0FvXOBUomZ50dM5tZ0Zow@mail.gmail.com>

On sam. 28 mars 2026 at 20:37, Chen-Yu Tsai <wens@kernel.org> wrote:

> On Wed, Jan 21, 2026 at 7:03 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>
>> The RTC module in the Allwinner A733 SoC is functionally compatible with
>> the sun6i RTC, but its internal Clock Control Unit (CCU) has significant
>> changes.
>>
>> The A733 supports selecting the oscillator between three frequencies:
>> 19.2MHz, 24MHz, and 26MHz. The RTC CCU relies on hardware to detect
>> which frequency is actually used on the board. By defining all three
>> frequencies as fixed-clocks in the device tree, the driver can identify
>> the hardware-detected frequency and expose it to the rest of the system.
>
> No. The board device tree shall have the exact and correct frequency
> defined in the external crystal device node. The operating system can
> use the hardware-detected frequency to "fix" the in-system representation
> if it is off.
>
>> Additionally, the A733 RTC CCU provides several new DCXO gate clocks for
>> specific modules, including SerDes, HDMI, and UFS.
>>
>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>> ---
>>  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 38 ++++++++++++++++++++--
>>  include/dt-bindings/clock/sun60i-a733-rtc.h        | 16 +++++++++
>>  2 files changed, 52 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>> index 9df5cdb6f63f..b18431955783 100644
>> --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>> +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>> @@ -26,6 +26,7 @@ properties:
>>            - allwinner,sun50i-h6-rtc
>>            - allwinner,sun50i-h616-rtc
>>            - allwinner,sun50i-r329-rtc
>> +          - allwinner,sun60i-a733-rtc
>>        - items:
>>            - const: allwinner,sun50i-a64-rtc
>>            - const: allwinner,sun8i-h3-rtc
>> @@ -46,11 +47,11 @@ properties:
>>
>>    clocks:
>>      minItems: 1
>> -    maxItems: 4
>> +    maxItems: 6
>>
>>    clock-names:
>>      minItems: 1
>> -    maxItems: 4
>> +    maxItems: 6
>>
>>    clock-output-names:
>>      minItems: 1
>> @@ -156,6 +157,38 @@ allOf:
>>          - clocks
>>          - clock-names
>>
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: allwinner,sun60i-a733-rtc
>> +
>> +    then:
>> +      properties:
>> +        clocks:
>> +          minItems: 5
>> +          items:
>> +            - description: Bus clock for register access
>
>> +            - description: 19.2 MHz oscillator
>> +            - description: 24 MHz oscillator
>> +            - description: 26 MHz oscillator
>
> No. There is only one input. As in there is only one set of pins for the
> DCXO. The inputs are the same as on R329 / A523. Just use that list.
>
>> +            - description: AHB parent for internal SPI clock
>> +            - description: External 32768 Hz oscillator
>> +
>> +        clock-names:
>> +          minItems: 5
>> +          items:
>> +            - const: bus
>> +            - const: osc19M
>> +            - const: osc24M
>> +            - const: osc26M
>> +            - const: ahb
>> +            - const: ext-osc32k
>> +
>> +      required:
>> +        - clocks
>> +        - clock-names
>> +
>>    - if:
>>        properties:
>>          compatible:
>> @@ -164,6 +197,7 @@ allOf:
>>                - allwinner,sun8i-r40-rtc
>>                - allwinner,sun50i-h616-rtc
>>                - allwinner,sun50i-r329-rtc
>> +              - allwinner,sun60i-a733-rtc
>>
>>      then:
>>        properties:
>> diff --git a/include/dt-bindings/clock/sun60i-a733-rtc.h b/include/dt-bindings/clock/sun60i-a733-rtc.h
>> new file mode 100644
>> index 000000000000..8a2b5facad73
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/sun60i-a733-rtc.h
>> @@ -0,0 +1,16 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
>> +
>> +#ifndef _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_
>> +#define _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_
>> +
>> +#define CLK_IOSC               0
>> +#define CLK_OSC32K             1
>> +#define CLK_HOSC               2
>
> The DCXO enable control has been present since at least the H6. We just
> never added it, as we would never disable it anyway.
>
> If you compare the RTC clock trees of the A733 and A523, the only addition
> besides the new gates seems to be the LOSC auto selection. But even that
> is just an illusion, as the A523 has the same registers for that.
>
> One could say the A733 RTC is almost backward compatible to the A523, if
> not for the two fastboot registers the A523 has at 0x120 and 0x124.
>
> So I ask that you try to integrate the differences into the existing
> driver and bindings. You can tweak and export internal clks if you
> need.

I'd like to help with that. I think it is doable but I have a question
regarding the binding of the existing driver, more precisely their usage
here:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c?h=v7.1#n370

Clock indexes are supposed to be stable in DT (AFAIK) but with the code
linked the external 32k is at:

* "ext-32k" - so index 3 - if "clock-names" is present
* index 0 if clock names is not present

... but index 0 is supposed to be the bus clock according the binding
doc, whether "clock-names" is there or not :/

So what are those old r329 bindings ? is there a documentation defining
them somewhere ?

Cleaning that part would help with A733 addition in the existing driver
I think

>
>> +#define CLK_RTC_32K            3
>
> AFAICT besides being an internal clock, this is also fed to GPIO for
> debounce? We probably need to expose this on the A523 as well.
>
>
> Thanks
> ChenYu
>
>
>> +#define CLK_OSC32K_FANOUT      4
>> +#define CLK_HOSC_SERDES1       5
>> +#define CLK_HOSC_SERDES0       6
>> +#define CLK_HOSC_HDMI          7
>> +#define CLK_HOSC_UFS           8
>> +
>> +#endif /* _DT_BINDINGS_CLK_SUN60I_A733_RTC_H_ */
>>
>> --
>> 2.52.0
>>
>>

-- 
Jerome


^ permalink raw reply

* [PATCH v1] ARM: imx: avic: Fix OF node reference leaks
From: Yuho Choi @ 2026-06-15 17:45 UTC (permalink / raw)
  To: Frank Li, Sascha Hauer, Russell King, Pengutronix Kernel Team
  Cc: Fabio Estevam, linux-arm-kernel, imx, linux-kernel, Yuho Choi

of_find_compatible_node() returns a device node with its reference count
incremented. mxc_init_irq() looks up the i.MX25 CCM node for of_iomap()
and the AVIC node for irq_domain_create_legacy(), but does not release
either temporary reference.

of_iomap() does not consume the node reference, and
irq_domain_create_legacy() takes its own fwnode reference for the domain.
Drop the temporary OF node references after each use.

Fixes: 9b454d16e57d ("ARM: imx: avic: set low-power interrupt mask for imx25")
Fixes: 544496ab5cbd ("ARM: imx: move irq_domain_add_legacy call into avic driver")
Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
---
 arch/arm/mach-imx/avic.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 3067c06b4b8e..6873a50bbe2c 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -173,6 +173,7 @@ static void __init mxc_init_irq(void __iomem *irqbase)
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
 	mx25_ccm_base = of_iomap(np, 0);
+	of_node_put(np);
 
 	if (mx25_ccm_base) {
 		/*
@@ -203,6 +204,7 @@ static void __init mxc_init_irq(void __iomem *irqbase)
 	np = of_find_compatible_node(NULL, NULL, "fsl,avic");
 	domain = irq_domain_create_legacy(of_fwnode_handle(np), AVIC_NUM_IRQS, irq_base, 0,
 					  &irq_domain_simple_ops, NULL);
+	of_node_put(np);
 	WARN_ON(!domain);
 
 	for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32)
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH v8 04/12] iommu/tegra241-cmdqv: Restore PROD and CONS after resume
From: Pranjal Shrivastava @ 2026-06-15 17:43 UTC (permalink / raw)
  To: Mostafa Saleh
  Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
	Nicolin Chen, Daniel Mentz, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <ajAv7pvRlAgLR7cn@google.com>

On Mon, Jun 15, 2026 at 05:01:34PM +0000, Mostafa Saleh wrote:
> On Mon, Jun 01, 2026 at 09:59:01PM +0000, Pranjal Shrivastava wrote:
> > From: Ashish Mhetre <amhetre@nvidia.com>
> > 
> > PROD and CONS indices for vcmdqs are getting set to 0 after resume.
> > Because of this the vcmdq is not consuming commands after resume.
> > Fix this by restoring PROD and CONS indices after resume from
> > saved pointers.
> 
> What commands are exisiting at resume? Won't
> tegra241_cmdqv_drain_vintf0_lvcmdqs() drain the queues and make the
> PROD and CONS equal each other anyway?

The SW prod / cons are indeed equal because of the queue drain before
suspend. However, the HW registers in vCMDQ reset to 0 on a power-cycle

Now, if we resume with the software prod/cons at 100/100, since the HW
prod/cons is at 0/0, when the driver then issues a new command and only
updates the PROD register to 101, the HW will see (CONS=0, PROD=101).

The arm-smmu-v3 driver restores these indices correctly in device_reset
but the Tegra VMDQV driver doesn't. Thus, this patch was added to
restore both indices ensuring the HW doesn't de-sync.

This was added after Ashish tested an older version of the series [1]
with Tegra,

Thanks,
Praan

[1] https://lore.kernel.org/all/6afc3e46-489e-4741-96d5-8a2f72a8b431@nvidia.com/


^ permalink raw reply

* Re: [PATCH 1/8] mm: Add ptep_try_set() for lockless empty-slot installs
From: Tejun Heo @ 2026-06-15 17:40 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: Will Deacon, David Vernet, Andrea Righi, Changwoo Min,
	Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Martin KaFai Lau, Kumar Kartikeya Dwivedi, Peter Zijlstra,
	Catalin Marinas, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Andrew Morton, Mike Rapoport, Emil Tsalapatis,
	sched-ext, bpf, x86, linux-arm-kernel, linux-mm, linux-kernel
In-Reply-To: <79338662-e637-412b-84b4-71cef3883b3d@kernel.org>

Hello,

On Mon, Jun 15, 2026 at 07:36:19PM +0200, David Hildenbrand (Arm) wrote:
> On 6/15/26 18:27, Tejun Heo wrote:
> > Hello, David.
> > 
> >> Is BPF maybe picking up patches from other subsystems up too early
> >> without waiting for acks?
> > 
> > Do you mean the comment cleanup I just sent, or the original
> > ptep_try_set() merge?
> 
> I am talking about any patch that touches arch code without an ACK from the
> maintainer.
> 
> Maybe arm64 and x86 people are fine with that, but I heard other voices
> recently, thus my question.

I see. I don't know the dynamics here. I'll leave it for bpf folks.

Thanks.

-- 
tejun


^ permalink raw reply

* Re: [PATCH 1/8] mm: Add ptep_try_set() for lockless empty-slot installs
From: David Hildenbrand (Arm) @ 2026-06-15 17:36 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Will Deacon, David Vernet, Andrea Righi, Changwoo Min,
	Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Martin KaFai Lau, Kumar Kartikeya Dwivedi, Peter Zijlstra,
	Catalin Marinas, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Andrew Morton, Mike Rapoport, Emil Tsalapatis,
	sched-ext, bpf, x86, linux-arm-kernel, linux-mm, linux-kernel
In-Reply-To: <31d1ac68dc230564301fc1e7dc748a1d@kernel.org>

On 6/15/26 18:27, Tejun Heo wrote:
> Hello, David.
> 
>> Is BPF maybe picking up patches from other subsystems up too early
>> without waiting for acks?
> 
> Do you mean the comment cleanup I just sent, or the original
> ptep_try_set() merge?

I am talking about any patch that touches arch code without an ACK from the
maintainer.

Maybe arm64 and x86 people are fine with that, but I heard other voices
recently, thus my question.

> 
> The original went through several rounds, and you acked the patch that
> introduced both problems (258df8fce42f) before it landed.

I am not an arm64 maintainer although working for the company :)

-- 
Cheers,

David


^ permalink raw reply

* Re: [PATCH 1/8] mm: Add ptep_try_set() for lockless empty-slot installs
From: Tejun Heo @ 2026-06-15 16:27 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: Will Deacon, David Vernet, Andrea Righi, Changwoo Min,
	Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Martin KaFai Lau, Kumar Kartikeya Dwivedi, Peter Zijlstra,
	Catalin Marinas, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, Andrew Morton, Mike Rapoport, Emil Tsalapatis,
	sched-ext, bpf, x86, linux-arm-kernel, linux-mm, linux-kernel
In-Reply-To: <f6e87467-2fa1-4edc-a739-9899be36196c@kernel.org>

Hello, David.

> Is BPF maybe picking up patches from other subsystems up too early
> without waiting for acks?

Do you mean the comment cleanup I just sent, or the original
ptep_try_set() merge?

The original went through several rounds, and you acked the patch that
introduced both problems (258df8fce42f) before it landed.

The barriers fix came from Catalin, he raised the issue and reviewed the
fix. The comment cleanup got picked up quickly. Maybe that's the bpf
folks wanting it in ahead of the merge window.

Thanks.

--
tejun


^ permalink raw reply

* Re: [PATCH] arm64/entry: Don't disable preemption in debug_exception_enter() with RT kernel
From: Sebastian Andrzej Siewior @ 2026-06-15 17:21 UTC (permalink / raw)
  To: Luis Claudio R. Goncalves
  Cc: Waiman Long, Catalin Marinas, Will Deacon, Mark Rutland,
	Clark Williams, Steven Rostedt, linux-arm-kernel, linux-kernel,
	linux-rt-devel
In-Reply-To: <aho0eqjMESuHxECr@redhat.com>

On 2026-05-29 21:51:06 [-0300], Luis Claudio R. Goncalves wrote:
> On Thu, May 28, 2026 at 05:35:54PM +0200, Sebastian Andrzej Siewior wrote:
> > On 2026-05-28 16:51:24 [+0200], To Waiman Long wrote:
> > > > The kernel backtrace is produced using the latest v7.1-rc4 kernel. There are
> > > > a number of changes to the debug_exception_enter() and
> > > > debug_exception_exit() functions over the years, but the preemption disable
> > > > code remains since its introduction in v5.3.
> > > 
> > > Let me look at this again.
> > 
> > So how do you reproduce this? The calls within debug_exception_enter()/
> > exit() look harmless or I miss the big thing here.
> > From your backtrace, you have brk_handler() and this is gone since
> > commit 31575e11ecf7e ("arm64: debug: split brk64 exception entry") which
> > is v6.17-rc1. I can use gdb with breakpoint handling.
> 
> Sebastian, in the original series Ada provided a few tests, including the
> two files I list below. Running that test in a v7.1-rc5 kernel with
> PREEMPT_RT and DEBUG_ATOMIC_SLEEP enabled, I get this backtrace:

This is a reminder to myself that I need to look at this since it does
not look solved with the breakpoint patches. But this is also perf.

Sebastian


^ permalink raw reply

* [RESEND] arm64: dts: mediatek: mt8516: remove cpu3 armpll clock-name
From: Luca Leonardo Scorcia @ 2026-06-15 17:21 UTC (permalink / raw)
  To: linux-mediatek
  Cc: Luca Leonardo Scorcia, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	devicetree, linux-kernel, linux-arm-kernel

The armpll clock in cpu3 clock-names property comes from MediaTek sources,
but it's unused in the kernel and not populated in the clocks property.
Let's remove it and align the node with other cpu nodes of the same SoC.

Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
 arch/arm64/boot/dts/mediatek/mt8516.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index b5e753759465..596f673a0d88 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -95,7 +95,7 @@ cpu3: cpu@3 {
 				<&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>;
 			clocks = <&infracfg CLK_IFR_MUX1_SEL>,
 				 <&topckgen CLK_TOP_MAINPLL_D2>;
-			clock-names = "cpu", "intermediate", "armpll";
+			clock-names = "cpu", "intermediate";
 			operating-points-v2 = <&cluster0_opp>;
 		};
 
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH] clk: mvebu: ap-cpu: fix missing clk_put() in ap_cpu_clock_probe()
From: Brian Masney @ 2026-06-15 17:18 UTC (permalink / raw)
  To: Wentao Liang
  Cc: andrew, gregory.clement, sebastian.hesselbarth, mturquette, sboyd,
	linux-arm-kernel, linux-clk, linux-kernel, stable
In-Reply-To: <20260604025115.3763823-1-vulab@iscas.ac.cn>

On Thu, Jun 04, 2026 at 02:51:15AM +0000, Wentao Liang wrote:
> The function ap_cpu_clock_probe() calls of_clk_get() to obtain a
> reference to the parent clock for each CPU cluster, but it never
> releases it with clk_put().  The returned clk is used only to read
> the parent's name via __clk_get_name(), and the reference is leaked
> on every successful cluster initialization as well as on the error
> path when devm_clk_hw_register() fails.
> 
> Add the missing clk_put() after the name has been extracted and
> before returning on error to fix the leak.
> 
> Fixes: af9617b419f7 ("clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>

This calls:

                parent = of_clk_get(np, cluster_index);
                if (IS_ERR(parent)) {
			...
                }
                parent_name =  __clk_get_name(parent);

Can this all be replaced with a call to of_clk_get_parent_name() ?

Brian



^ permalink raw reply

* Re: [PATCH v6 1/7] dt-bindings: mfd: mt6397: Add MT6392 PMIC
From: Luca Leonardo Scorcia @ 2026-06-15 17:09 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-mediatek, Fabien Parent, Val Packett, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sen Chu,
	Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	AngeloGioacchino Del Regno, Linus Walleij, Julien Massot,
	Louis-Alexis Eyraud, Akari Tsuyukusa, Chen Zhong, linux-input,
	devicetree, linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260615-palatable-aerobics-3091229b6ada@spud>

Hi,
yes, sorry about that, series v6 has been superseded by v7 (I replied
to the thread and marked it as archived in patchwork, please let me
know if I have to do something else to mark it as obsolete).
Sashiko was correct, the regulators node is required for this device.

Sashiko also has suggestions for v7, a few pre existing issues and a
few nits here and there but some are actual improvements. One bit that
caught my eye is the use of the modeset register in the
mt6392_ldo_get_mode function. I have to double check that with the
data sheet and the android kernel sources. Not sure if I can do that
before next week though.

Is there any way I can trigger a Sashiko review before sending patches
to the ML?

Thank you,
Luca


^ permalink raw reply

* Re: [PATCH 00/19] init: discoverable root partitions, a.k.a. an omittable "root=" cmdline option
From: Al Viro @ 2026-06-15 17:04 UTC (permalink / raw)
  To: Vincent Mailhol
  Cc: Jens Axboe, Davidlohr Bueso, Christian Brauner, Jan Kara,
	linux-kernel, linux-block, linux-efi, linux-fsdevel,
	Richard Henderson, Matt Turner, Magnus Lindholm, linux-alpha,
	Vineet Gupta, linux-snps-arc, Russell King, linux-arm-kernel,
	Catalin Marinas, Will Deacon, Huacai Chen, WANG Xuerui, loongarch,
	Thomas Bogendoerfer, linux-mips, James E.J. Bottomley,
	Helge Deller, linux-parisc, Madhavan Srinivasan, Michael Ellerman,
	linuxppc-dev, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-riscv, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	linux-s390, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, Jonathan Corbet, Shuah Khan, linux-doc
In-Reply-To: <20260615-discoverable-root_partitions-v1-0-39c78fac42e2@kernel.org>

On Mon, Jun 15, 2026 at 06:08:56PM +0200, Vincent Mailhol wrote:

> Tested with GRUB, which implements the LoaderDevicePartUUID EFI variable
> in its bli module [3]. With this, I was able to boot a kernel with a
> completely empty cmdline and no initrd.
> 
> [1] The Discoverable Partitions Specification (DPS)
> Link: https://uapi-group.org/specifications/specs/discoverable_partitions_specification/
> 
> [2] systemd-gpt-auto-generator
> Link: https://www.freedesktop.org/software/systemd/man/latest/systemd-gpt-auto-generator.html
> 
> [3] GRUB -- §16.2 bli
> Link: https://www.gnu.org/software/grub/manual/grub/html_node/bli_005fmodule.html

So what does that thing, tied to EFI as it is, have to do with architectures where
	* firmware is rather unlike EFI
	* firmware wouldn't know what to do with GPT
	* GRUB is *not* ported to, let alone used
such as, say it, the very first one mentioned at your [1]?

Or is that conditional upon "if anyone wants to design replacement firmware
for those, and if they agree to follow our wishlist"?


^ permalink raw reply

* Re: [PATCH v8 05/12] iommu/arm-smmu-v3: Cache and restore MSI config
From: Mostafa Saleh @ 2026-06-15 17:04 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
	Nicolin Chen, Daniel Mentz, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <20260601215909.3958732-6-praan@google.com>

On Mon, Jun 01, 2026 at 09:59:02PM +0000, Pranjal Shrivastava wrote:
> The SMMU's MSI configuration registers (*_IRQ_CFGn) containing target
> address, data and memory attributes lose their state when the SMMU is
> powered down. We'll need to cache and restore their contents to ensure
> that MSIs work after the system resumes.
> 
> To address this, cache the original `msi_msg` within the `msi_desc`
> when the configuration is first written by `arm_smmu_write_msi_msg`.
> This primarily includes the target address and data since the memory
> attributes are fixed.
> 
> Introduce a new helper `arm_smmu_resume_msis` which will later be called
> during the driver's resume callback. The helper would retrieve the
> cached MSI message for each relevant interrupt (evtq, gerr, priq) via
> get_cached_msi_msg & re-config the registers via arm_smmu_write_msi_msg.
> 
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Pranjal Shrivastava <praan@google.com>

Reviewed-by: Mostafa Saleh <smostafa@google.com>

Thanks,
Mostafa

> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 37 +++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> 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 8682be5060ed..93cee32f6c99 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -4551,6 +4551,9 @@ static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
>  	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
>  	phys_addr_t *cfg = arm_smmu_msi_cfg[desc->msi_index];
>  
> +	/* Cache the msi_msg for resume */
> +	desc->msg = *msg;
> +
>  	doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;
>  	doorbell &= MSI_CFG0_ADDR_MASK;
>  
> @@ -4559,6 +4562,40 @@ static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
>  	writel_relaxed(ARM_SMMU_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);
>  }
>  
> +static void arm_smmu_resume_msi(struct arm_smmu_device *smmu,
> +				unsigned int irq, const char *name)
> +{
> +	struct msi_desc *desc;
> +	struct msi_msg msg;
> +
> +	if (!irq)
> +		return;
> +
> +	desc = irq_get_msi_desc(irq);
> +	if (!desc) {
> +		dev_err(smmu->dev, "Failed to resume msi: %s", name);
> +		return;
> +	}
> +
> +	get_cached_msi_msg(irq, &msg);
> +	arm_smmu_write_msi_msg(desc, &msg);
> +}
> +
> +static void arm_smmu_resume_msis(struct arm_smmu_device *smmu)
> +{
> +	if (!(smmu->features & ARM_SMMU_FEAT_MSI))
> +		return;
> +
> +	if (!dev_get_msi_domain(smmu->dev))
> +		return;
> +
> +	arm_smmu_resume_msi(smmu, smmu->gerr_irq, "gerror");
> +	arm_smmu_resume_msi(smmu, smmu->evtq.q.irq, "evtq");
> +
> +	if (smmu->features & ARM_SMMU_FEAT_PRI)
> +		arm_smmu_resume_msi(smmu, smmu->priq.q.irq, "priq");
> +}
> +
>  static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
>  {
>  	int ret, nvec = ARM_SMMU_MAX_MSIS;
> -- 
> 2.54.0.1013.g208068f2d8-goog
> 
> 


^ permalink raw reply

* Re: [PATCH v8 04/12] iommu/tegra241-cmdqv: Restore PROD and CONS after resume
From: Mostafa Saleh @ 2026-06-15 17:01 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
	Nicolin Chen, Daniel Mentz, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <20260601215909.3958732-5-praan@google.com>

On Mon, Jun 01, 2026 at 09:59:01PM +0000, Pranjal Shrivastava wrote:
> From: Ashish Mhetre <amhetre@nvidia.com>
> 
> PROD and CONS indices for vcmdqs are getting set to 0 after resume.
> Because of this the vcmdq is not consuming commands after resume.
> Fix this by restoring PROD and CONS indices after resume from
> saved pointers.

What commands are exisiting at resume? Won't
tegra241_cmdqv_drain_vintf0_lvcmdqs() drain the queues and make the
PROD and CONS equal each other anyway?

Thanks,
Mostafa

> 
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
> Signed-off-by: Pranjal Shrivastava <praan@google.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> index cb1e75e4ee91..866cae7b73e5 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> @@ -511,6 +511,8 @@ static int tegra241_vcmdq_hw_init(struct tegra241_vcmdq *vcmdq)
>  
>  	/* Configure and enable VCMDQ */
>  	writeq_relaxed(vcmdq->cmdq.q.q_base, REG_VCMDQ_PAGE1(vcmdq, BASE));
> +	writel_relaxed(vcmdq->cmdq.q.llq.prod, REG_VCMDQ_PAGE0(vcmdq, PROD));
> +	writel_relaxed(vcmdq->cmdq.q.llq.cons, REG_VCMDQ_PAGE0(vcmdq, CONS));
>  
>  	ret = vcmdq_write_config(vcmdq, VCMDQ_EN);
>  	if (ret) {
> -- 
> 2.54.0.1013.g208068f2d8-goog
> 
> 


^ permalink raw reply

* Re: [PATCH v8 03/12] iommu/tegra241-cmdqv: Add a helper to drain VCMDQs
From: Mostafa Saleh @ 2026-06-15 16:58 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: iommu, Will Deacon, Joerg Roedel, Robin Murphy, Jason Gunthorpe,
	Nicolin Chen, Daniel Mentz, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <20260601215909.3958732-4-praan@google.com>

On Mon, Jun 01, 2026 at 09:59:00PM +0000, Pranjal Shrivastava wrote:
> The tegra241-cmdqv driver supports vCMDQs which need to be drained
> before suspending the SMMU. The current driver implementation only uses
> VINTF0 for vCMDQs owned by the kernel which need to be drained. Add a
> helper that drains all the enabled vCMDQs under VINTF0.
> 
> Add another function ptr to arm_smmu_impl_ops to drain implementation
> specified queues and call it within `arm_smmu_drain_queues`.
> 
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Signed-off-by: Pranjal Shrivastava <praan@google.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  7 +++++
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  1 +
>  .../iommu/arm/arm-smmu-v3/tegra241-cmdqv.c    | 27 +++++++++++++++++++
>  3 files changed, 35 insertions(+)
> 
> 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 0e77ef1e4523..8682be5060ed 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -915,6 +915,13 @@ static int arm_smmu_drain_queues(struct arm_smmu_device *smmu)
>  	 */
>  	ret = arm_smmu_queue_poll_until_empty(smmu, &smmu->cmdq.q);
>  
> +	if (ret)
> +		goto out;
> +
> +	/* Drain all implementation-specific queues */
> +	if (smmu->impl_ops && smmu->impl_ops->drain_queues)
> +		ret = smmu->impl_ops->drain_queues(smmu);
> +out:
>  	return ret;
>  }
>  
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index c855ab4962ed..24d5e28eea88 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -885,6 +885,7 @@ struct arm_smmu_impl_ops {
>  	size_t (*get_viommu_size)(enum iommu_viommu_type viommu_type);
>  	int (*vsmmu_init)(struct arm_vsmmu *vsmmu,
>  			  const struct iommu_user_data *user_data);
> +	int (*drain_queues)(struct arm_smmu_device *smmu);
>  };
>  
>  /* An SMMUv3 instance */
> diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> index 67be62a6e764..cb1e75e4ee91 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
> @@ -414,6 +414,32 @@ tegra241_cmdqv_get_cmdq(struct arm_smmu_device *smmu,
>  	return &vcmdq->cmdq;
>  }
>  
> +static int tegra241_cmdqv_drain_vintf0_lvcmdqs(struct arm_smmu_device *smmu)
> +{
> +	struct tegra241_cmdqv *cmdqv =
> +		container_of(smmu, struct tegra241_cmdqv, smmu);
> +	struct tegra241_vintf *vintf = cmdqv->vintfs[0];
> +	int ret = 0;
> +	u16 lidx;
> +
> +	/* Kernel only uses VINTF0. Return if it's disabled */
> +	if (!READ_ONCE(vintf->enabled))
> +		return 0;

I am not familiar with this driver, but the READ_ONCE() caught my eye,
I see that’s already what is the existing code is doing, but it is not
clear to me why, it seems to be an attempt to make this path lockless.

However, won’t we need some aquire/release semantics?

For example in tegra241_vintf_hw_deinit() it WRITE_ONCE() cmdq and then
vintf and finally writel() with a write memory barrier.

While in tegra241_cmdqv_drain_vintf0_lvcmdqs() (or in
tegra241_cmdqv_get_cmdq()) it checks READ_ONCE(vintf->enabled) then
READ_ONCE(vcmdq->enabled)

Now it is possible that this executes in any order, due to the lack
of barriers,which means you can see:
Thread#1: READ_ONCE(vintf->enabled) => TRUE
Thread#2: Writes both vintf->enabled and vcmdq->enabled to FALSE
Thread#1: Still sees vcmdq->enabled as TRUE because it was speculated.

Am I missing something?

Thanks,
Mostafa

> +
> +	for (lidx = 0; lidx < cmdqv->num_lvcmdqs_per_vintf; lidx++) {
> +		struct tegra241_vcmdq *vcmdq = vintf->lvcmdqs[lidx];
> +
> +		if (!vcmdq || !READ_ONCE(vcmdq->enabled))
> +			continue;
> +
> +		ret = arm_smmu_queue_poll_until_empty(smmu, &vcmdq->cmdq.q);
> +		if (ret)
> +			break;
> +	}
> +
> +	return ret;
> +}
> +
>  /* HW Reset Functions */
>  
>  /*
> @@ -845,6 +871,7 @@ static struct arm_smmu_impl_ops tegra241_cmdqv_impl_ops = {
>  	.get_secondary_cmdq = tegra241_cmdqv_get_cmdq,
>  	.device_reset = tegra241_cmdqv_hw_reset,
>  	.device_remove = tegra241_cmdqv_remove,
> +	.drain_queues = tegra241_cmdqv_drain_vintf0_lvcmdqs,
>  	/* For user-space use */
>  	.hw_info = tegra241_cmdqv_hw_info,
>  	.get_viommu_size = tegra241_cmdqv_get_vintf_size,
> -- 
> 2.54.0.1013.g208068f2d8-goog
> 
> 


^ permalink raw reply

* Re: [PATCH RFC 1/2] dt-bindings: pinctl: amlogic,pinctrl-a4: Add gpio irq property
From: Conor Dooley @ 2026-06-15 16:52 UTC (permalink / raw)
  To: xianwei.zhao
  Cc: Linus Walleij, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	linux-amlogic, linux-gpio, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260611-gpio-to-irq-v1-1-12201716f23f@amlogic.com>

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

Given Linus' comments on the cover letter,
pw-bot: changes-requested

Thanks,
Conor.

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

^ permalink raw reply

* Re: [PATCH v6 1/7] dt-bindings: mfd: mt6397: Add MT6392 PMIC
From: Conor Dooley @ 2026-06-15 16:50 UTC (permalink / raw)
  To: Luca Leonardo Scorcia
  Cc: linux-mediatek, Fabien Parent, Val Packett, Dmitry Torokhov,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sen Chu,
	Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
	AngeloGioacchino Del Regno, Linus Walleij, Julien Massot,
	Louis-Alexis Eyraud, Akari Tsuyukusa, Chen Zhong, linux-input,
	devicetree, linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260612200717.361018-2-l.scorcia@gmail.com>

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

On Fri, Jun 12, 2026 at 10:04:06PM +0200, Luca Leonardo Scorcia wrote:
> From: Fabien Parent <parent.f@gmail.com>
> 
> Add the initial bindings for the MT6392 PMIC and its RTC device.
> 
> Signed-off-by: Fabien Parent <parent.f@gmail.com>
> Signed-off-by: Val Packett <val@packett.cool>
> Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>

Sashiko complaint about missing regulators looks valid.
Is it?

Cheers,
Conor.

> ---
>  .../devicetree/bindings/mfd/mediatek,mt6397.yaml          | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml
> index 3cbc0dc12c31..e39e81aa9924 100644
> --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml
> +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml
> @@ -40,6 +40,10 @@ properties:
>            - mediatek,mt6358
>            - mediatek,mt6359
>            - mediatek,mt6397
> +      - items:
> +          - enum:
> +              - mediatek,mt6392
> +          - const: mediatek,mt6323
>        - items:
>            - enum:
>                - mediatek,mt6366
> @@ -72,6 +76,10 @@ properties:
>                - mediatek,mt6331-rtc
>                - mediatek,mt6358-rtc
>                - mediatek,mt6397-rtc
> +          - items:
> +              - enum:
> +                  - mediatek,mt6392-rtc
> +              - const: mediatek,mt6323-rtc
>            - items:
>                - enum:
>                    - mediatek,mt6359-rtc
> -- 
> 2.43.0
> 

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

^ permalink raw reply

* Re: [PATCH RFC 3/9] net: stmmac: qcom-ethqos: fix RGMII_ID mode to use DLL bypass
From: Andrew Lunn @ 2026-06-15 16:48 UTC (permalink / raw)
  To: Mohd Ayaan Anwar
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Richard Cochran, Bjorn Andersson, Konrad Dybcio, Maxime Coquelin,
	Alexandre Torgue, Russell King, linux-arm-msm, netdev, devicetree,
	linux-kernel, linux-stm32, linux-arm-kernel
In-Reply-To: <ai93X/cNWHtEQsDt@oss.qualcomm.com>

On Mon, Jun 15, 2026 at 09:24:07AM +0530, Mohd Ayaan Anwar wrote:
> Hello Andrew,
> On Thu, Jun 11, 2026 at 10:54:37PM +0200, Andrew Lunn wrote:
> > On Fri, Jun 12, 2026 at 12:06:59AM +0530, Mohd Ayaan Anwar wrote:
> > > When "rgmii-id" is selected the PHY supplies both TX and RX delays, so
> > > the MAC must not add its own.  The driver currently falls through to the
> > > generic DLL initialisation path which programs it to add a delay.
> > > 
> > > Power down the DLL and set DDR bypass mode for RGMII_ID, then program
> > > the IO_MACRO via a new ethqos_rgmii_id_macro_init() helper.  Also fix
> > > ethqos_set_clk_tx_rate() to not double the clock rate in bypass mode at
> > > 100M/10M, and remove RGMII_ID from the phase-shift suppression in
> > > ethqos_rgmii_macro_init() since RGMII_ID no longer reaches that path.
> > 
> > I'm curious how this works at the moment? Do no boards make use of
> > RGMII ID? Are all current boards broken?
> 
> Searching through the DTS, I found that we have two boards using "rgmii"
> (qcs404-evb-4000.dts and sa8155-adp.dts) and another board using
> "rgmii-txid" (sa8540p-ride.dts). No board which uses RGMII ID.

So this causes problems. We cannot break existing boards, yet it would
be good to fix the current broken behaviour.

> I don't think any of these boards have extra long wires which would add
> PCB level delay. They are against the netdev definitions for "rgmii" and
> "rgmii-txid".
> 
> But the first two boards should still be working fine since the current
> driver programs the IO_MACRO to add the delay when operating in RGMII
> mode.

Which is wrong, given the current definition. No delays should be
added, by either the MAC or the PHY.

Please could you contact the Maintainers of these boards and find out
the real situation with the hardware.

It could be the best way forward is that you issue a warning when
"rgmii" is found and pass rgmii-id to the PHY. And you also change the
two boards to use rgmii-id. Lets think about the rgmii-txid case once
we better understand it.

	Andrew


^ permalink raw reply

* Re: [RFC PATCH v4 6/9] dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
From: Conor Dooley @ 2026-06-15 16:49 UTC (permalink / raw)
  To: MidG971
  Cc: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson,
	dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
	iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
	jonas
In-Reply-To: <20260613070116.438906-7-midgy971@gmail.com>

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

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

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

^ permalink raw reply

* Re: [PATCH v1 11/11] KVM: arm64: Implement lazy vCPU state sync for non-protected guests
From: Fuad Tabba @ 2026-06-15 16:44 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: Marc Zyngier, Oliver Upton, Will Deacon, Catalin Marinas,
	Quentin Perret, Sebastian Ene, Per Larsen, Suzuki K Poulose,
	Zenghui Yu, Joey Gouly, Steffen Eiden, Mark Rutland,
	Jonathan Cameron, Hyunwoo Kim, linux-arm-kernel, kvmarm,
	linux-kernel
In-Reply-To: <ajAncPp3nOGcWD1U@google.com>

On Mon, 15 Jun 2026 at 17:25, Vincent Donnefort <vdonnefort@google.com> wrote:
>
> On Fri, Jun 12, 2026 at 07:59:25AM +0100, tabba@google.com wrote:
> > pKVM copies a non-protected guest's register context between the host
> > and the hypervisor on every world switch, even when the host never
> > inspects it. Defer the copy: on entry, flush the host context into the
> > hyp vCPU only when the host marked it dirty (PKVM_HOST_STATE_DIRTY); on
> > exit, leave it in the hyp vCPU and copy it back only when the host needs
> > it, via a __pkvm_vcpu_sync_state hypercall on trap handling or at vcpu
> > put. A protected guest's context is copied as before, since lazy sync
> > only helps where the host is trusted to see the guest's registers.
> >
> > The PC is the exception: it is copied back on every exit so the
> > kvm_exit tracepoint reports the guest's real exit PC rather than the
> > value left by the previous sync.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_asm.h   |  1 +
> >  arch/arm64/include/asm/kvm_host.h  |  2 +
> >  arch/arm64/kvm/arm.c               |  7 +++
> >  arch/arm64/kvm/handle_exit.c       | 22 ++++++++
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c | 88 ++++++++++++++++++++++++++++--
> >  5 files changed, 115 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 043495f7fc78..6e1135b3ded4 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -113,6 +113,7 @@ enum __kvm_host_smccc_func {
> >       __KVM_HOST_SMCCC_FUNC___pkvm_finalize_teardown_vm,
> >       __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
> >       __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
> > +     __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_sync_state,
> >       __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
> >
> >       MARKER(__KVM_HOST_SMCCC_FUNC_MAX)
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index a49042bfa801..1ef660774adc 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -1113,6 +1113,8 @@ struct kvm_vcpu_arch {
> >  /* SError pending for nested guest */
> >  #define NESTED_SERROR_PENDING        __vcpu_single_flag(sflags, BIT(8))
> >
> > +/* pKVM host vcpu state is dirty, needs resync (nVHE-only) */
>
> nit: with hVHE, I guess we can just drop that nVHE-only?

Ack.


>
> > +#define PKVM_HOST_STATE_DIRTY        __vcpu_single_flag(iflags, BIT(4))
> >
> >  /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
> >  #define vcpu_sve_pffr(vcpu) (kern_hyp_va((vcpu)->arch.sve_state) +   \
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index c9f36932c980..a5c54e37778b 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -734,6 +734,10 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >       if (is_protected_kvm_enabled()) {
> >               kvm_call_hyp(__vgic_v3_save_aprs, &vcpu->arch.vgic_cpu.vgic_v3);
> >               kvm_call_hyp_nvhe(__pkvm_vcpu_put);
> > +
> > +             /* __pkvm_vcpu_put implies a sync of the state */
> > +             if (!kvm_vm_is_protected(vcpu->kvm))
> > +                     vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> >       }
> >
> >       kvm_vcpu_put_debug(vcpu);
> > @@ -961,6 +965,9 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> >               return ret;
> >
> >       if (is_protected_kvm_enabled()) {
> > +             /* Start with the vcpu in a dirty state */
> > +             if (!kvm_vm_is_protected(vcpu->kvm))
> > +                     vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> >               ret = pkvm_create_hyp_vm(kvm);
> >               if (ret)
> >                       return ret;
> > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> > index 54aedf93c78b..dccc3786548b 100644
> > --- a/arch/arm64/kvm/handle_exit.c
> > +++ b/arch/arm64/kvm/handle_exit.c
> > @@ -422,6 +422,21 @@ static int handle_trap_exceptions(struct kvm_vcpu *vcpu)
> >  {
> >       int handled;
> >
> > +     /*
> > +      * If we run a non-protected VM when protection is enabled
> > +      * system-wide, resync the state from the hypervisor and mark
> > +      * it as dirty on the host side if it wasn't dirty already
> > +      * (which could happen if preemption has taken place).
> > +      */
> > +     if (is_protected_kvm_enabled() && !kvm_vm_is_protected(vcpu->kvm)) {
> > +             preempt_disable();
>
> nit: since we are introducing guard() with that series, this one could be
> guard(preempt)().

Nice one :) Done.


>
> > +             if (!(vcpu_get_flag(vcpu, PKVM_HOST_STATE_DIRTY))) {
> > +                     kvm_call_hyp_nvhe(__pkvm_vcpu_sync_state);
> > +                     vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> > +             }
> > +             preempt_enable();
> > +     }
> > +
> >       /*
> >        * See ARM ARM B1.14.1: "Hyp traps on instructions
> >        * that fail their condition code check"
> > @@ -489,6 +504,13 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
> >  /* For exit types that need handling before we can be preempted */
> >  void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index)
> >  {
> > +     /*
> > +      * We just exited, so the state is clean from a hypervisor
> > +      * perspective.
> > +      */
> > +     if (is_protected_kvm_enabled())
> > +             vcpu_clear_flag(vcpu, PKVM_HOST_STATE_DIRTY);
> > +
> >       if (ARM_SERROR_PENDING(exception_index)) {
> >               if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN)) {
> >                       u64 disr = kvm_vcpu_get_disr(vcpu);
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index 23e644c24a03..02383b372258 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -139,6 +139,49 @@ static void sync_hyp_vgic_state(struct pkvm_hyp_vcpu *hyp_vcpu)
> >               host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
> >  }
> >
> > +
> > +static void __copy_vcpu_state(const struct kvm_vcpu *from_vcpu,
> > +                           struct kvm_vcpu *to_vcpu)
> > +{
> > +     int i;
> > +
> > +     to_vcpu->arch.ctxt.regs         = from_vcpu->arch.ctxt.regs;
> > +     to_vcpu->arch.ctxt.spsr_abt     = from_vcpu->arch.ctxt.spsr_abt;
> > +     to_vcpu->arch.ctxt.spsr_und     = from_vcpu->arch.ctxt.spsr_und;
> > +     to_vcpu->arch.ctxt.spsr_irq     = from_vcpu->arch.ctxt.spsr_irq;
> > +     to_vcpu->arch.ctxt.spsr_fiq     = from_vcpu->arch.ctxt.spsr_fiq;
> > +     to_vcpu->arch.ctxt.fp_regs      = from_vcpu->arch.ctxt.fp_regs;
> > +
> > +     /*
> > +      * Copy the sysregs, but don't mess with the timer state which
> > +      * is directly handled by EL1 and is expected to be preserved.
> > +      * enum vcpu_sysreg is sparse: VNCR-mapped registers take values
> > +      * derived from their VNCR page offset, so the timer registers do
> > +      * not form a contiguous numeric range and must be skipped by name.
> > +      */
> > +     for (i = 1; i < NR_SYS_REGS; i++) {
> > +             switch (i) {
> > +             case CNTVOFF_EL2:
> > +             case CNTV_CVAL_EL0:
> > +             case CNTV_CTL_EL0:
> > +             case CNTP_CVAL_EL0:
> > +             case CNTP_CTL_EL0:
> > +                     continue;
> > +             }
> > +             to_vcpu->arch.ctxt.sys_regs[i] = from_vcpu->arch.ctxt.sys_regs[i];
> > +     }
> > +}
> > +
> > +static void __sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
> > +{
> > +     __copy_vcpu_state(&hyp_vcpu->vcpu, hyp_vcpu->host_vcpu);
> > +}
> > +
> > +static void __flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
> > +{
> > +     __copy_vcpu_state(hyp_vcpu->host_vcpu, &hyp_vcpu->vcpu);
> > +}
>
> nit: Could that be flush/sync_hyp_vcpu_state? as everything this is called
> "state" and we already have flush_debug_state() below ?

Good point, renamed to flush_hyp_vcpu_state()/sync_hyp_vcpu_state().

>
> > +
> >  static void flush_debug_state(struct pkvm_hyp_vcpu *hyp_vcpu)
> >  {
> >       struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> > @@ -168,7 +211,17 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
> >       fpsimd_sve_flush();
> >       flush_debug_state(hyp_vcpu);
> >
> > -     hyp_vcpu->vcpu.arch.ctxt        = host_vcpu->arch.ctxt;
> > +     /*
> > +      * If we deal with a non-protected guest and the state is potentially
> > +      * dirty (from a host perspective), copy the state back into the hyp
> > +      * vcpu.
> > +      */
> > +     if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
> > +             if (vcpu_get_flag(host_vcpu, PKVM_HOST_STATE_DIRTY))
> > +                     __flush_hyp_vcpu(hyp_vcpu);
> > +     } else {
> > +             hyp_vcpu->vcpu.arch.ctxt = host_vcpu->arch.ctxt;
> > +     }
> >
> >       hyp_vcpu->vcpu.arch.mdcr_el2    = host_vcpu->arch.mdcr_el2;
> >       hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
> > @@ -191,9 +244,11 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
> >       fpsimd_sve_sync(&hyp_vcpu->vcpu);
> >       sync_debug_state(hyp_vcpu);
> >
> > -     host_vcpu->arch.ctxt            = hyp_vcpu->vcpu.arch.ctxt;
> > -
> > -     host_vcpu->arch.hcr_el2         = hyp_vcpu->vcpu.arch.hcr_el2;
> > +     if (pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> > +             host_vcpu->arch.ctxt = hyp_vcpu->vcpu.arch.ctxt;
> > +     else
> > +             /* Keep the PC current for the kvm_exit tracepoint (lazy ctxt sync). */
> > +             host_vcpu->arch.ctxt.regs.pc = hyp_vcpu->vcpu.arch.ctxt.regs.pc;
> >
> >       host_vcpu->arch.fault           = hyp_vcpu->vcpu.arch.fault;
> >
> > @@ -227,8 +282,30 @@ static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
> >  {
> >       struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> >
> > -     if (hyp_vcpu)
> > +     if (hyp_vcpu) {
> > +             struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> > +
> > +             if (!pkvm_hyp_vcpu_is_protected(hyp_vcpu) &&
> > +                 !vcpu_get_flag(host_vcpu, PKVM_HOST_STATE_DIRTY)) {
> > +                     __sync_hyp_vcpu(hyp_vcpu);
> > +             }
> > +
> >               pkvm_put_hyp_vcpu(hyp_vcpu);
> > +     }
> > +}
> > +
> > +static void handle___pkvm_vcpu_sync_state(struct kvm_cpu_context *host_ctxt)
> > +{
> > +     struct pkvm_hyp_vcpu *hyp_vcpu;
> > +
> > +     if (!is_protected_kvm_enabled())
> > +             return;
>
> Since "KVM: arm64: Remove is_protected_kvm_enabled() checks from hypercalls" we
> got rid of those is_protected_kvm_enabled() for pKVM-only HVCs. (also, it is
> declared in the pKVM-only section of the HVCs)

Dropped.

Thanks a lot for the reviews!
/fuad
>
> > +
> > +     hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> > +     if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> > +             return;
> > +
> > +     __sync_hyp_vcpu(hyp_vcpu);
> >  }
> >
> >  static struct kvm_vcpu *__get_host_hyp_vcpus(struct kvm_vcpu *arg,
> > @@ -859,6 +936,7 @@ static const hcall_t host_hcall[] = {
> >       HANDLE_FUNC(__pkvm_finalize_teardown_vm),
> >       HANDLE_FUNC(__pkvm_vcpu_load),
> >       HANDLE_FUNC(__pkvm_vcpu_put),
> > +     HANDLE_FUNC(__pkvm_vcpu_sync_state),
> >       HANDLE_FUNC(__pkvm_tlb_flush_vmid),
> >  };
> >
> > --
> > 2.54.0.1136.gdb2ca164c4-goog
> >


^ permalink raw reply

* Re: [PATCH 3/8] dt-bindings: clock: clocking-wizard: Make s_axi_aclk optional for static-config
From: Conor Dooley @ 2026-06-15 16:44 UTC (permalink / raw)
  To: Shubhrajyoti Datta
  Cc: linux-clk, linux-kernel, git, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Michal Simek,
	devicetree, linux-arm-kernel
In-Reply-To: <20260615-squid-showy-435c9cf780a0@spud>

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

On Mon, Jun 15, 2026 at 05:42:17PM +0100, Conor Dooley wrote:
> 
> 
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> pw-bot: not-applicable

Actually, I take this back. Patch 1 seems to be what's adding the static
configurations in the first place and then patches 2 and 3 complete that
effort. Instead, please add this static config support as one patch.

Thanks,
Conor.

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

^ permalink raw reply

* Re: [PATCH] clk: at91: Read "reg" with helper
From: Brian Masney @ 2026-06-15 16:42 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Michael Turquette, Stephen Boyd, Nicolas Ferre, Alexandre Belloni,
	Claudiu Beznea, linux-clk, linux-arm-kernel, linux-kernel
In-Reply-To: <20260612215251.1888345-1-robh@kernel.org>

On Fri, Jun 12, 2026 at 04:52:51PM -0500, Rob Herring (Arm) wrote:
> The "reg" property is an address-sized DT cell property. The AT91
> compat clock parser only uses a small bus id from it, but reading it
> with the u8 helper does not match the property encoding.
> 
> Use of_property_read_reg() so the code goes through the helper for
> "reg" properties, then keep the existing range check before passing
> the bus id to the clock registration code.
> 
> Assisted-by: Codex:gpt-5-5
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>

Reviewed-by: Brian Masney <bmasney@redhat.com>



^ permalink raw reply

* Re: [PATCH 3/8] dt-bindings: clock: clocking-wizard: Make s_axi_aclk optional for static-config
From: Conor Dooley @ 2026-06-15 16:42 UTC (permalink / raw)
  To: Shubhrajyoti Datta
  Cc: linux-clk, linux-kernel, git, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Michal Simek,
	devicetree, linux-arm-kernel
In-Reply-To: <20260615034845.3320286-4-shubhrajyoti.datta@amd.com>

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



Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

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

^ 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