[PATCH 02/11] drivers: misc: pm8916_pon: add glue driver

Casey Connolly casey.connolly at linaro.org
Wed Jun 17 15:57:17 CEST 2026



On 06/06/2026 10:47, Sam Day via B4 Relay wrote:
> From: Sam Day <me at samcday.com>
> 
> Initially, this driver binds the existing qcom_pwrkey driver to continue
> supporting pwrkey/resin buttons. In follow-up commits it will be further
> extended to bind a reboot-mode driver.
> 
> The "qcom,pm8916-pon" compatible is removed from qcom_pwrkey, since
> pm8916_pon owns it and handles binding qcom_pwrkey.
> 
> Signed-off-by: Sam Day <me at samcday.com>
> ---
>  drivers/button/button-qcom-pmic.c |  1 -
>  drivers/misc/Kconfig              |  7 ++++
>  drivers/misc/Makefile             |  1 +
>  drivers/misc/pm8916_pon.c         | 78 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 86 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/button/button-qcom-pmic.c b/drivers/button/button-qcom-pmic.c
> index d9ac6a51df5..caa47cd9373 100644
> --- a/drivers/button/button-qcom-pmic.c
> +++ b/drivers/button/button-qcom-pmic.c
> @@ -216,7 +216,6 @@ static const struct button_ops button_qcom_pmic_ops = {
>  };
>  
>  static const struct udevice_id qcom_pwrkey_ids[] = {
> -	{ .compatible = "qcom,pm8916-pon" },
>  	{ .compatible = "qcom,pm8941-pon" },
>  	{ .compatible = "qcom,pm8998-pon" },
>  	{ .compatible = "qcom,pmk8350-pon" },
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index ea785793d18..d2e9b833ff7 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -439,6 +439,13 @@ config SPL_PWRSEQ
>  	  device. When the device is started up, its power sequence can be
>  	  initiated.
>  
> +config PM8916_PON
> +	bool "Enable PM8916 PON driver"
> +	depends on PMIC_QCOM && MISC
> +	help
> +	  The PM8916 PMIC is a multifunction device that handles pwr/resin buttons,
> +	  reboot type (soft/hard/poweroff) and reboot mode (recovery/bootloader).
> +
>  config STM32MP_FUSE
>  	bool "Enable STM32MP fuse wrapper providing the fuse API"
>  	depends on ARCH_STM32MP && MISC
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index e2170212e5a..6b979ba4289 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -92,3 +92,4 @@ obj-$(CONFIG_K3_BIST) += k3_bist.o
>  obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
>  obj-$(CONFIG_SL28CPLD) += sl28cpld.o
>  obj-$(CONFIG_SPL_SOCFPGA_DT_REG) += socfpga_dtreg.o
> +obj-$(CONFIG_PM8916_PON) += pm8916_pon.o
> diff --git a/drivers/misc/pm8916_pon.c b/drivers/misc/pm8916_pon.c
> new file mode 100644
> index 00000000000..d65a7cab459
> --- /dev/null
> +++ b/drivers/misc/pm8916_pon.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Qualcomm PM8916 PON glue driver
> + *
> + * The PON device handles pwrkey/resin buttons, as well as setting reboot
> + * type and reboot mode. This glue driver binds the respective drivers.
> + */
> +
> +#include <dm.h>
> +#include <dm/lists.h>
> +#include <dm/device_compat.h>
> +#include <power/pmic.h>
> +#include "button/qcom-pmic.h"
> +
> +#define PON_REV2 0x01
> +
> +struct pm8916_pon_priv {
> +	struct udevice *pmic;
> +	phys_addr_t base;
> +	u32 revision;
> +};
> +
> +static int pm8916_pon_probe(struct udevice *dev)
> +{
> +	int ret;
> +	struct pm8916_pon_priv *priv = dev_get_priv(dev);
> +
> +	priv->pmic = dev->parent;
> +	if (!priv->pmic) {
> +		dev_err(dev, "PMIC driver not found\n");

I don't think this can ever be NULL, this check shouldn't be needed.

> +		return -EINVAL;
> +	}
> +
> +	priv->base = dev_read_addr(dev);
> +
> +	if (!priv->base) {

You should compare this to FDT_ADDR_T_NONE, I'd suggest using
dev_read_addr_ptr() here instead.

Kind regards,

> +		dev_err(dev, "missing reg base\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = pmic_reg_read(priv->pmic, priv->base + PON_REV2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to determine PON rev: %d\n", ret);
> +		return ret;
> +	}
> +
> +	priv->revision = ret;
> +	dev_dbg(dev, "PON rev: %d\n", priv->revision);
> +
> +	return 0;
> +}
> +
> +static int pm8916_pon_bind(struct udevice *dev)
> +{
> +	int ret;
> +
> +	if (CONFIG_IS_ENABLED(BUTTON_QCOM_PMIC)) {
> +		ret = button_qcom_pmic_setup(dev);
> +		if (ret)
> +			dev_warn(dev, "failed to bind qcom_pwrkey: %d\n", ret);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id pm8916_pon_ids[] = {
> +	{ .compatible = "qcom,pm8916-pon" },
> +	{},
> +};
> +
> +U_BOOT_DRIVER(pm8916_pon) = {
> +	.name = "pm8916_pon",
> +	.id = UCLASS_MISC,
> +	.of_match = pm8916_pon_ids,
> +	.bind = pm8916_pon_bind,
> +	.probe = pm8916_pon_probe,
> +	.priv_auto = sizeof(struct pm8916_pon_priv),
> +};
> 

-- 
// Casey (she/her)



More information about the U-Boot mailing list