Re: [RFC PATCH] soc: aspeed: Add B650D4U power passthrough support

From: Prasanth

Date: Fri Oct 02 2026 - 13:28:39 EST


Thanks for the clarification Tan.

For context, I sent this RFC to document the hardware-backed experiment and
request guidance on the correct kernel-facing implementation.

Using the current OpenBMC integration with the B650D4U hardware, the host
can be powered on through the standard D-Bus command, and the OpenBMC web
interface correctly reports the server power and host state. I validated this
on the real board before sending the RFC.

The RFC was therefore intended to obtain feedback on whether this sequence
belongs in the kernel or should instead be expressed through the existing
GPIO and pinctrl configuration. I understand from your review that the
separate SCU passthrough driver is not appropriate, so I will investigate
the GPIO request and pinctrl configuration and withdraw this implementation.


On Fri, Oct 2, 2026 at 10:17 PM Tan Siewert <tan.siewert@xxxxxxxxxxxxx> wrote:
>
> On 10/2/26 3:16 PM, Prasanth Kumar Padarthi wrote:
> > Add the AST2600 SCU passthrough selector support used by the
> > ASRock Rack B650D4U host power-control circuit. This RFC includes
> > the driver, Devicetree binding, and board node to discuss the final
> > kernel-facing interface.
> >
> > Signed-off-by: Prasanth Kumar Padarthi <prasanth.padarthi10@xxxxxxxxx>
>
> This is definitely not the way how to solve this. I've already said on
> linux-aspeed as well as off-the-list, requesting the GPIO lines is
> enough and enabling GPIOP passthrough here does not make any sense, as
> it would be disabled by pinctrl anyways.
> There's a whole implementation in userspace to solve this issue (at
> least if you use OpenBMC). The issue you're facing here is, from my
> point of view, a configuration error, and you'll not solve it with a
> kernel driver that literally just enables GPIOP passthrough...
>
> So my answer to this patch is:
> NACKed-by: Tan Siewert <tan.siewert@xxxxxxxxxxxxx>
>
> > ---
> > .../asrock,b650d4u-power-passthrough.yaml | 23 ++++
> > .../dts/aspeed/aspeed-bmc-asrock-b650d4u.dts | 5 +
> > drivers/soc/aspeed/Kconfig | 9 ++
> > drivers/soc/aspeed/Makefile | 1 +
> > drivers/soc/aspeed/aspeed-b650d4u-power.c | 110 ++++++++++++++++++
> > 5 files changed, 148 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/soc/aspeed/asrock,b650d4u-power-passthrough.yaml
> > create mode 100644 drivers/soc/aspeed/aspeed-b650d4u-power.c
> >
> > diff --git a/Documentation/devicetree/bindings/soc/aspeed/asrock,b650d4u-power-passthrough.yaml b/Documentation/devicetree/bindings/soc/aspeed/asrock,b650d4u-power-passthrough.yaml
> > new file mode 100644
> > index 000000000000..e6451d17955c
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/soc/aspeed/asrock,b650d4u-power-passthrough.yaml
> > @@ -0,0 +1,23 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/soc/aspeed/asrock,b650d4u-power-passthrough.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: ASRock Rack B650D4U power passthrough
> > +
> > +maintainers:
> > + - Prasanth Kumar Padarthi <prasanth.padarthi10@xxxxxxxxx>
> > +
> > +properties:
> > + compatible:
> > + const: asrock,b650d4u-power-passthrough
> > +
> > + aspeed,scu:
> > + $ref: /schemas/types.yaml#/definitions/phandle
> > +
> > +required:
> > + - compatible
> > + - aspeed,scu
> > +
> > +additionalProperties: false
> > diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts
> > index a4e384588a54..86291c250562 100644
> > --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts
> > +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-b650d4u.dts
> > @@ -32,6 +32,11 @@ gfx_memory: framebuffer {
> > size = <0x01000000>;
> > };
> > };
> > +
> > + host-power-passthrough {
> > + compatible = "asrock,b650d4u-power-passthrough";
> > + aspeed,scu = <&syscon>;
> > + };
> > };
> >
> > &fmc {
> > diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
> > index 11e4db998c06..1b0281e0bfb0 100644
> > --- a/drivers/soc/aspeed/Kconfig
> > +++ b/drivers/soc/aspeed/Kconfig
> > @@ -58,6 +58,15 @@ config ASPEED_SBC
> > Say yes to provide information about the secure boot controller in
> > debugfs.
> >
> > +config ASPEED_B650D4U_POWER
> > + tristate "ASRock B650D4U host power passthrough"
> > + select REGMAP
> > + select MFD_SYSCON
> > + default ARCH_ASPEED
> > + help
> > + Enable the AST2600 GPIO passthrough selector used by the
> > + ASRock Rack B650D4U host power-control circuit. This selector routes the host power pulse through the board's passthrough logic during power sequencing.
> > +
> > config ASPEED_XDMA
> > tristate "ASPEED XDMA Engine Driver"
> > select REGMAP
> > diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
> > index 5f61bb4cc36c..3e9618d1eafc 100644
> > --- a/drivers/soc/aspeed/Makefile
> > +++ b/drivers/soc/aspeed/Makefile
> > @@ -5,4 +5,5 @@ obj-$(CONFIG_ASPEED_UART_ROUTING) += aspeed-uart-routing.o
> > obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o
> > obj-$(CONFIG_ASPEED_SOCINFO) += aspeed-socinfo.o
> > obj-$(CONFIG_ASPEED_SBC) += aspeed-sbc.o
> > +obj-$(CONFIG_ASPEED_B650D4U_POWER) += aspeed-b650d4u-power.o
> > obj-$(CONFIG_ASPEED_XDMA) += aspeed-xdma.o
> > diff --git a/drivers/soc/aspeed/aspeed-b650d4u-power.c b/drivers/soc/aspeed/aspeed-b650d4u-power.c
> > new file mode 100644
> > index 000000000000..22a6925539dc
> > --- /dev/null
> > +++ b/drivers/soc/aspeed/aspeed-b650d4u-power.c
> > @@ -0,0 +1,110 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +
> > +#include <linux/device.h>
> > +#include <linux/init.h>
> > +#include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/mutex.h>
> > +#include <linux/kstrtox.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/bits.h>
> > +
> > +#define ASPEED_SCU_PROTECTION 0x000
> > +#define ASPEED_SCU_GPIO_PASSTHROUGH 0x4bc
> > +#define ASPEED_SCU_GPIO_ACTION 0x51c
> > +#define ASPEED_SCU_UNLOCK_KEY 0x1688a8a8
> > +#define ASPEED_B650D4U_POWER_MASK GENMASK(27, 26)
> > +
> > +static struct regmap *b650d4u_scu;
> > +static DEFINE_MUTEX(b650d4u_lock);
> > +
> > +static int b650d4u_set_passthrough(bool enable)
> > +{
> > + int ret;
> > +
> > + mutex_lock(&b650d4u_lock);
> > +
> > + ret = regmap_write(b650d4u_scu, ASPEED_SCU_PROTECTION,
> > + ASPEED_SCU_UNLOCK_KEY);
> > + if (ret) {
> > + pr_err("B650D4U: SCU unlock failed: %d\n", ret);
> > + goto out;
> > + }
> > +
> > + ret = regmap_update_bits(b650d4u_scu,
> > + ASPEED_SCU_GPIO_PASSTHROUGH,
> > + ASPEED_B650D4U_POWER_MASK,
> > + enable ? ASPEED_B650D4U_POWER_MASK : 0);
> > + if (ret) {
> > + pr_err("B650D4U: passthrough update failed: %d\n", ret);
> > + goto out;
> > + }
> > +
> > + if (!enable)
> > + ret = regmap_write(b650d4u_scu,
> > + ASPEED_SCU_GPIO_ACTION, 0);
> > +
> > +out:
> > + mutex_unlock(&b650d4u_lock);
> > + return ret;
> > +}
> > +
> > +static ssize_t passthrough_store(struct device *dev,
> > + struct device_attribute *attr,
> > + const char *buf, size_t count)
> > +{
> > + bool enable;
> > + int ret;
> > +
> > + ret = kstrtobool(buf, &enable);
> > + if (ret)
> > + return ret;
> > +
> > + ret = b650d4u_set_passthrough(enable);
> > + return ret ? ret : count;
> > +}
> > +static DEVICE_ATTR_WO(passthrough);
> > +
> > +static int aspeed_b650d4u_power_probe(struct platform_device *pdev)
> > +{
> > + int ret;
> > +
> > + b650d4u_scu = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
> > + "aspeed,scu");
> > + if (IS_ERR(b650d4u_scu))
> > + return dev_err_probe(&pdev->dev, PTR_ERR(b650d4u_scu),
> > + "failed to get AST2600 SCU regmap\n");
> > +
> > + ret = b650d4u_set_passthrough(true);
> > + if (ret)
> > + return dev_err_probe(&pdev->dev, ret,
> > + "failed to enable power GPIO passthrough\n");
> > +
> > + ret = device_create_file(&pdev->dev, &dev_attr_passthrough);
> > + if (ret)
> > + return dev_err_probe(&pdev->dev, ret,
> > + "failed to create passthrough control\n");
> > +
> > + dev_info(&pdev->dev, "enabled GPIO passthrough selector 1\n");
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id aspeed_b650d4u_power_of_match[] = {
> > + { .compatible = "asrock,b650d4u-power-passthrough" },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(of, aspeed_b650d4u_power_of_match);
> > +
> > +static struct platform_driver aspeed_b650d4u_power_driver = {
> > + .probe = aspeed_b650d4u_power_probe,
> > + .driver = {
> > + .name = "aspeed-b650d4u-power",
> > + .of_match_table = aspeed_b650d4u_power_of_match,
> > + },
> > +};
> > +module_platform_driver(aspeed_b650d4u_power_driver);
> > +
> > +MODULE_DESCRIPTION("ASRock Rack B650D4U host power GPIO passthrough");
> > +MODULE_LICENSE("GPL");
>