Add support for PMIC Glink clients to receive notificiation when
the subsystem goes down and comes up again.
Signed-off-by: Anjelique Melendez <anjelique.melendez@oss.qualcomm.com>
---
drivers/soc/qcom/pmic_glink.c | 43 +++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
index 0a6d325b195c..5121f19d63e5 100644
--- a/drivers/soc/qcom/pmic_glink.c
+++ b/drivers/soc/qcom/pmic_glink.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Linaro Ltd
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/auxiliary_bus.h>
#include <linux/cleanup.h>
@@ -9,6 +10,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/remoteproc/qcom_rproc.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
#include <linux/soc/qcom/pdr.h>
@@ -39,10 +41,14 @@ struct pmic_glink {
struct mutex state_lock;
unsigned int client_state;
unsigned int pdr_state;
+ unsigned int ssr_state;
/* serializing clients list updates */
spinlock_t client_lock;
struct list_head clients;
+
+ struct notifier_block ssr_nb;
+ void *ssr_handle;
};
static struct pmic_glink *__pmic_glink;
@@ -205,10 +211,12 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
unsigned long flags;
if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
- if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
+ if ((pg->pdr_state == SERVREG_SERVICE_STATE_UP ||
+ pg->ssr_state == QCOM_SSR_AFTER_POWERUP) && pg->ept)
new_state = SERVREG_SERVICE_STATE_UP;
} else {
- if (pg->pdr_state == SERVREG_SERVICE_STATE_DOWN || !pg->ept)
+ if (pg->pdr_state == SERVREG_SERVICE_STATE_DOWN ||
+ pg->ssr_state == QCOM_SSR_BEFORE_SHUTDOWN || !pg->ept)
new_state = SERVREG_SERVICE_STATE_DOWN;
}
@@ -231,6 +239,18 @@ static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv)
pmic_glink_state_notify_clients(pg);
}
+static int pmic_glink_ssr_callback(struct notifier_block *nb, unsigned long code, void *data)
+{
+ struct pmic_glink *pg = container_of(nb, struct pmic_glink, ssr_nb);
+
+ mutex_lock(&pg->state_lock);
+ pg->ssr_state = code;
+
+ pmic_glink_state_notify_clients(pg);
+ mutex_unlock(&pg->state_lock);
+ return 0;
+}
+
static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct pmic_glink *pg;
@@ -281,6 +301,7 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = {
static int pmic_glink_probe(struct platform_device *pdev)
{
const unsigned long *match_data;
+ const char *subsys_name = NULL;
struct pdr_service *service;
struct pmic_glink *pg;
int ret;
@@ -333,6 +354,22 @@ static int pmic_glink_probe(struct platform_device *pdev)
goto out_release_aux_devices;
}
+ if (device_property_present(&pdev->dev, "qcom,subsys-name")) {
+ device_property_read_string(&pdev->dev, "qcom,subsys-name", &subsys_name);
+ if (!subsys_name) {
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
+ "failed to read subsys_name string from dt\n");
+ goto out_release_aux_devices;
+ }
+ pg->ssr_nb.notifier_call = pmic_glink_ssr_callback;
+ pg->ssr_handle = qcom_register_ssr_notifier(subsys_name, &pg->ssr_nb);
+ if (IS_ERR(pg->ssr_handle)) {
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
+ "failed adding ssr notifier\n");
+ goto out_release_aux_devices;
+ }
+ }
+
mutex_lock(&__pmic_glink_lock);
__pmic_glink = pg;
mutex_unlock(&__pmic_glink_lock);
@@ -360,6 +397,8 @@ static void pmic_glink_remove(struct platform_device *pdev)
pdr_handle_release(pg->pdr);
+ if (pg->ssr_handle)
+ qcom_unregister_ssr_notifier(pg->ssr_handle, &pg->ssr_nb);
if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
pmic_glink_del_aux_device(pg, &pg->ps_aux);
if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
--
2.34.1
Hi Anjelique,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Anjelique-Melendez/dt-bindings-soc-qcom-qcom-pmic-glink-Add-qcom-subsys-name-property/20250625-070209
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link: https://lore.kernel.org/r/20250624225535.2013141-3-anjelique.melendez%40oss.qualcomm.com
patch subject: [PATCH 2/2] soc: qcom: pmic_glink: Add support for subsystem restart (SSR)
config: x86_64-randconfig-161-20250627 (https://download.01.org/0day-ci/archive/20250628/202506280819.vRUvImej-lkp@intel.com/config)
compiler: clang version 20.1.7 (https://github.com/llvm/llvm-project 6146a88f60492b520a36f8f8f3231e15f3cc6082)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202506280819.vRUvImej-lkp@intel.com/
smatch warnings:
drivers/soc/qcom/pmic_glink.c:360 pmic_glink_probe() warn: passing zero to 'PTR_ERR'
vim +/PTR_ERR +360 drivers/soc/qcom/pmic_glink.c
58ef4ece1e41ac Bjorn Andersson 2023-01-31 301 static int pmic_glink_probe(struct platform_device *pdev)
58ef4ece1e41ac Bjorn Andersson 2023-01-31 302 {
ff642773b6b5b8 Neil Armstrong 2023-03-21 303 const unsigned long *match_data;
56e992f9beb5f6 Anjelique Melendez 2025-06-24 304 const char *subsys_name = NULL;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 305 struct pdr_service *service;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 306 struct pmic_glink *pg;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 307 int ret;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 308
58ef4ece1e41ac Bjorn Andersson 2023-01-31 309 pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 310 if (!pg)
58ef4ece1e41ac Bjorn Andersson 2023-01-31 311 return -ENOMEM;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 312
58ef4ece1e41ac Bjorn Andersson 2023-01-31 313 dev_set_drvdata(&pdev->dev, pg);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 314
58ef4ece1e41ac Bjorn Andersson 2023-01-31 315 pg->dev = &pdev->dev;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 316
58ef4ece1e41ac Bjorn Andersson 2023-01-31 317 INIT_LIST_HEAD(&pg->clients);
9329933699b32d Bjorn Andersson 2024-04-30 318 spin_lock_init(&pg->client_lock);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 319 mutex_init(&pg->state_lock);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 320
ff642773b6b5b8 Neil Armstrong 2023-03-21 321 match_data = (unsigned long *)of_device_get_match_data(&pdev->dev);
4db09e7b967b90 Dmitry Baryshkov 2023-10-25 322 if (!match_data)
4db09e7b967b90 Dmitry Baryshkov 2023-10-25 323 return -EINVAL;
4db09e7b967b90 Dmitry Baryshkov 2023-10-25 324
ff642773b6b5b8 Neil Armstrong 2023-03-21 325 pg->client_mask = *match_data;
ff642773b6b5b8 Neil Armstrong 2023-03-21 326
f79ee78767ca60 Rob Clark 2024-02-17 327 pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg);
f79ee78767ca60 Rob Clark 2024-02-17 328 if (IS_ERR(pg->pdr)) {
f79ee78767ca60 Rob Clark 2024-02-17 329 ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr),
f79ee78767ca60 Rob Clark 2024-02-17 330 "failed to initialize pdr\n");
f79ee78767ca60 Rob Clark 2024-02-17 331 return ret;
f79ee78767ca60 Rob Clark 2024-02-17 332 }
f79ee78767ca60 Rob Clark 2024-02-17 333
ff642773b6b5b8 Neil Armstrong 2023-03-21 334 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) {
ff642773b6b5b8 Neil Armstrong 2023-03-21 335 ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi");
58ef4ece1e41ac Bjorn Andersson 2023-01-31 336 if (ret)
f79ee78767ca60 Rob Clark 2024-02-17 337 goto out_release_pdr_handle;
ff642773b6b5b8 Neil Armstrong 2023-03-21 338 }
ff642773b6b5b8 Neil Armstrong 2023-03-21 339 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) {
ff642773b6b5b8 Neil Armstrong 2023-03-21 340 ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode");
ff642773b6b5b8 Neil Armstrong 2023-03-21 341 if (ret)
ff642773b6b5b8 Neil Armstrong 2023-03-21 342 goto out_release_ucsi_aux;
ff642773b6b5b8 Neil Armstrong 2023-03-21 343 }
ff642773b6b5b8 Neil Armstrong 2023-03-21 344 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) {
58ef4ece1e41ac Bjorn Andersson 2023-01-31 345 ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply");
58ef4ece1e41ac Bjorn Andersson 2023-01-31 346 if (ret)
58ef4ece1e41ac Bjorn Andersson 2023-01-31 347 goto out_release_altmode_aux;
ff642773b6b5b8 Neil Armstrong 2023-03-21 348 }
58ef4ece1e41ac Bjorn Andersson 2023-01-31 349
58ef4ece1e41ac Bjorn Andersson 2023-01-31 350 service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd");
58ef4ece1e41ac Bjorn Andersson 2023-01-31 351 if (IS_ERR(service)) {
58ef4ece1e41ac Bjorn Andersson 2023-01-31 352 ret = dev_err_probe(&pdev->dev, PTR_ERR(service),
58ef4ece1e41ac Bjorn Andersson 2023-01-31 353 "failed adding pdr lookup for charger_pd\n");
f79ee78767ca60 Rob Clark 2024-02-17 354 goto out_release_aux_devices;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 355 }
58ef4ece1e41ac Bjorn Andersson 2023-01-31 356
56e992f9beb5f6 Anjelique Melendez 2025-06-24 357 if (device_property_present(&pdev->dev, "qcom,subsys-name")) {
56e992f9beb5f6 Anjelique Melendez 2025-06-24 358 device_property_read_string(&pdev->dev, "qcom,subsys-name", &subsys_name);
56e992f9beb5f6 Anjelique Melendez 2025-06-24 359 if (!subsys_name) {
56e992f9beb5f6 Anjelique Melendez 2025-06-24 @360 ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
s/PTR_ERR(pg->ssr_handle)/-EINVAL/;
56e992f9beb5f6 Anjelique Melendez 2025-06-24 361 "failed to read subsys_name string from dt\n");
56e992f9beb5f6 Anjelique Melendez 2025-06-24 362 goto out_release_aux_devices;
56e992f9beb5f6 Anjelique Melendez 2025-06-24 363 }
56e992f9beb5f6 Anjelique Melendez 2025-06-24 364 pg->ssr_nb.notifier_call = pmic_glink_ssr_callback;
56e992f9beb5f6 Anjelique Melendez 2025-06-24 365 pg->ssr_handle = qcom_register_ssr_notifier(subsys_name, &pg->ssr_nb);
56e992f9beb5f6 Anjelique Melendez 2025-06-24 366 if (IS_ERR(pg->ssr_handle)) {
56e992f9beb5f6 Anjelique Melendez 2025-06-24 367 ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
56e992f9beb5f6 Anjelique Melendez 2025-06-24 368 "failed adding ssr notifier\n");
56e992f9beb5f6 Anjelique Melendez 2025-06-24 369 goto out_release_aux_devices;
56e992f9beb5f6 Anjelique Melendez 2025-06-24 370 }
56e992f9beb5f6 Anjelique Melendez 2025-06-24 371 }
56e992f9beb5f6 Anjelique Melendez 2025-06-24 372
58ef4ece1e41ac Bjorn Andersson 2023-01-31 373 mutex_lock(&__pmic_glink_lock);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 374 __pmic_glink = pg;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 375 mutex_unlock(&__pmic_glink_lock);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 376
58ef4ece1e41ac Bjorn Andersson 2023-01-31 377 return 0;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 378
58ef4ece1e41ac Bjorn Andersson 2023-01-31 379 out_release_aux_devices:
ff642773b6b5b8 Neil Armstrong 2023-03-21 380 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
58ef4ece1e41ac Bjorn Andersson 2023-01-31 381 pmic_glink_del_aux_device(pg, &pg->ps_aux);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 382 out_release_altmode_aux:
ff642773b6b5b8 Neil Armstrong 2023-03-21 383 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
58ef4ece1e41ac Bjorn Andersson 2023-01-31 384 pmic_glink_del_aux_device(pg, &pg->altmode_aux);
ff642773b6b5b8 Neil Armstrong 2023-03-21 385 out_release_ucsi_aux:
ff642773b6b5b8 Neil Armstrong 2023-03-21 386 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI))
ff642773b6b5b8 Neil Armstrong 2023-03-21 387 pmic_glink_del_aux_device(pg, &pg->ucsi_aux);
f79ee78767ca60 Rob Clark 2024-02-17 388 out_release_pdr_handle:
f79ee78767ca60 Rob Clark 2024-02-17 389 pdr_handle_release(pg->pdr);
58ef4ece1e41ac Bjorn Andersson 2023-01-31 390
58ef4ece1e41ac Bjorn Andersson 2023-01-31 391 return ret;
58ef4ece1e41ac Bjorn Andersson 2023-01-31 392 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On 25/06/2025 01:55, Anjelique Melendez wrote:
> Add support for PMIC Glink clients to receive notificiation when
> the subsystem goes down and comes up again.
>
> Signed-off-by: Anjelique Melendez <anjelique.melendez@oss.qualcomm.com>
> ---
> drivers/soc/qcom/pmic_glink.c | 43 +++++++++++++++++++++++++++++++++--
> 1 file changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
> index 0a6d325b195c..5121f19d63e5 100644
> --- a/drivers/soc/qcom/pmic_glink.c
> +++ b/drivers/soc/qcom/pmic_glink.c
> @@ -2,6 +2,7 @@
> /*
> * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
> * Copyright (c) 2022, Linaro Ltd
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> */
> #include <linux/auxiliary_bus.h>
> #include <linux/cleanup.h>
> @@ -9,6 +10,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> +#include <linux/remoteproc/qcom_rproc.h>
> #include <linux/rpmsg.h>
> #include <linux/slab.h>
> #include <linux/soc/qcom/pdr.h>
> @@ -39,10 +41,14 @@ struct pmic_glink {
> struct mutex state_lock;
> unsigned int client_state;
> unsigned int pdr_state;
> + unsigned int ssr_state;
>
> /* serializing clients list updates */
> spinlock_t client_lock;
> struct list_head clients;
> +
> + struct notifier_block ssr_nb;
> + void *ssr_handle;
> };
>
> static struct pmic_glink *__pmic_glink;
> @@ -205,10 +211,12 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
> unsigned long flags;
>
> if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
> - if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
> + if ((pg->pdr_state == SERVREG_SERVICE_STATE_UP ||
> + pg->ssr_state == QCOM_SSR_AFTER_POWERUP) && pg->ept)
carriage return after &&
> new_state = SERVREG_SERVICE_STATE_UP;
> } else {
> - if (pg->pdr_state == SERVREG_SERVICE_STATE_DOWN || !pg->ept)
> + if (pg->pdr_state == SERVREG_SERVICE_STATE_DOWN ||
> + pg->ssr_state == QCOM_SSR_BEFORE_SHUTDOWN || !pg->ept)
carriage return after ||
> new_state = SERVREG_SERVICE_STATE_DOWN;
> }
>
> @@ -231,6 +239,18 @@ static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv)
> pmic_glink_state_notify_clients(pg);
> }
>
> +static int pmic_glink_ssr_callback(struct notifier_block *nb, unsigned long code, void *data)
> +{
> + struct pmic_glink *pg = container_of(nb, struct pmic_glink, ssr_nb);
> +
> + mutex_lock(&pg->state_lock);
> + pg->ssr_state = code;
> +
> + pmic_glink_state_notify_clients(pg);
> + mutex_unlock(&pg->state_lock);
> + return 0;
> +}
> +
> static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev)
> {
> struct pmic_glink *pg;
> @@ -281,6 +301,7 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = {
> static int pmic_glink_probe(struct platform_device *pdev)
> {
> const unsigned long *match_data;
> + const char *subsys_name = NULL;
> struct pdr_service *service;
> struct pmic_glink *pg;
> int ret;
> @@ -333,6 +354,22 @@ static int pmic_glink_probe(struct platform_device *pdev)
> goto out_release_aux_devices;
> }
>
> + if (device_property_present(&pdev->dev, "qcom,subsys-name")) {
> + device_property_read_string(&pdev->dev, "qcom,subsys-name", &subsys_name);
No need to read it from DT. Use a static value here.
If it differs from platform to platform, then add it to platform data
and select it depending on the compat string.
> + if (!subsys_name) {
> + ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
> + "failed to read subsys_name string from dt\n");
> + goto out_release_aux_devices;
> + }
> + pg->ssr_nb.notifier_call = pmic_glink_ssr_callback;
> + pg->ssr_handle = qcom_register_ssr_notifier(subsys_name, &pg->ssr_nb);
> + if (IS_ERR(pg->ssr_handle)) {
> + ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->ssr_handle),
> + "failed adding ssr notifier\n");
> + goto out_release_aux_devices;
> + }
> + }
> +
> mutex_lock(&__pmic_glink_lock);
> __pmic_glink = pg;
> mutex_unlock(&__pmic_glink_lock);
> @@ -360,6 +397,8 @@ static void pmic_glink_remove(struct platform_device *pdev)
>
> pdr_handle_release(pg->pdr);
>
> + if (pg->ssr_handle)
> + qcom_unregister_ssr_notifier(pg->ssr_handle, &pg->ssr_nb);
> if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
> pmic_glink_del_aux_device(pg, &pg->ps_aux);
> if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
--
With best wishes
Dmitry
© 2016 - 2026 Red Hat, Inc.