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 - 2025 Red Hat, Inc.