On 06/06/2026 10:47, Sam Day via B4 Relay wrote:
> From: Sam Day <[email protected]>
>
> 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 <[email protected]>
> ---
> 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)