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)

Reply via email to