1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2022, Linaro Ltd 5 */ 6 #include <linux/auxiliary_bus.h> 7 #include <linux/cleanup.h> 8 #include <linux/delay.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/rpmsg.h> 13 #include <linux/slab.h> 14 #include <linux/soc/qcom/pdr.h> 15 #include <linux/soc/qcom/pmic_glink.h> 16 #include <linux/spinlock.h> 17 18 #define PMIC_GLINK_SEND_TIMEOUT (5 * HZ) 19 20 enum { 21 PMIC_GLINK_CLIENT_BATT = 0, 22 PMIC_GLINK_CLIENT_ALTMODE, 23 PMIC_GLINK_CLIENT_UCSI, 24 }; 25 26 struct pmic_glink { 27 struct device *dev; 28 struct pdr_handle *pdr; 29 30 struct rpmsg_endpoint *ept; 31 32 unsigned long client_mask; 33 34 struct auxiliary_device altmode_aux; 35 struct auxiliary_device ps_aux; 36 struct auxiliary_device ucsi_aux; 37 38 /* serializing client_state and pdr_state updates */ 39 struct mutex state_lock; 40 unsigned int client_state; 41 unsigned int pdr_state; 42 43 /* serializing clients list updates */ 44 spinlock_t client_lock; 45 struct list_head clients; 46 }; 47 48 static struct pmic_glink *__pmic_glink; 49 static DEFINE_MUTEX(__pmic_glink_lock); 50 51 struct pmic_glink_client { 52 struct list_head node; 53 54 struct pmic_glink *pg; 55 unsigned int id; 56 57 void (*cb)(const void *data, size_t len, void *priv); 58 void (*pdr_notify)(void *priv, int state); 59 void *priv; 60 }; 61 62 static void _devm_pmic_glink_release_client(struct device *dev, void *res) 63 { 64 struct pmic_glink_client *client = (struct pmic_glink_client *)res; 65 struct pmic_glink *pg = client->pg; 66 unsigned long flags; 67 68 spin_lock_irqsave(&pg->client_lock, flags); 69 list_del(&client->node); 70 spin_unlock_irqrestore(&pg->client_lock, flags); 71 } 72 73 struct pmic_glink_client *devm_pmic_glink_client_alloc(struct device *dev, 74 unsigned int id, 75 void (*cb)(const void *, size_t, void *), 76 void (*pdr)(void *, int), 77 void *priv) 78 { 79 struct pmic_glink_client *client; 80 struct pmic_glink *pg = dev_get_drvdata(dev->parent); 81 82 client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL); 83 if (!client) 84 return ERR_PTR(-ENOMEM); 85 86 client->pg = pg; 87 client->id = id; 88 client->cb = cb; 89 client->pdr_notify = pdr; 90 client->priv = priv; 91 INIT_LIST_HEAD(&client->node); 92 93 devres_add(dev, client); 94 95 return client; 96 } 97 EXPORT_SYMBOL_GPL(devm_pmic_glink_client_alloc); 98 99 void pmic_glink_client_register(struct pmic_glink_client *client) 100 { 101 struct pmic_glink *pg = client->pg; 102 unsigned long flags; 103 104 guard(mutex)(&pg->state_lock); 105 spin_lock_irqsave(&pg->client_lock, flags); 106 107 list_add(&client->node, &pg->clients); 108 client->pdr_notify(client->priv, pg->client_state); 109 110 spin_unlock_irqrestore(&pg->client_lock, flags); 111 } 112 EXPORT_SYMBOL_GPL(pmic_glink_client_register); 113 114 int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len) 115 { 116 struct pmic_glink *pg = client->pg; 117 bool timeout_reached = false; 118 unsigned long start; 119 int ret; 120 121 guard(mutex)(&pg->state_lock); 122 if (!pg->ept) { 123 return -ECONNRESET; 124 } 125 126 start = jiffies; 127 for (;;) { 128 ret = rpmsg_send(pg->ept, data, len); 129 if (ret != -EAGAIN) 130 break; 131 132 if (timeout_reached) { 133 ret = -ETIMEDOUT; 134 break; 135 } 136 137 usleep_range(1000, 5000); 138 timeout_reached = time_after(jiffies, start + PMIC_GLINK_SEND_TIMEOUT); 139 } 140 141 return ret; 142 } 143 EXPORT_SYMBOL_GPL(pmic_glink_send); 144 145 static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data, 146 int len, void *priv, u32 addr) 147 { 148 struct pmic_glink_client *client; 149 struct pmic_glink_hdr *hdr; 150 struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev); 151 unsigned long flags; 152 153 if (len < sizeof(*hdr)) { 154 dev_warn(pg->dev, "ignoring truncated message\n"); 155 return 0; 156 } 157 158 hdr = data; 159 160 spin_lock_irqsave(&pg->client_lock, flags); 161 list_for_each_entry(client, &pg->clients, node) { 162 if (client->id == le32_to_cpu(hdr->owner)) 163 client->cb(data, len, client->priv); 164 } 165 spin_unlock_irqrestore(&pg->client_lock, flags); 166 167 return 0; 168 } 169 170 static void pmic_glink_aux_release(struct device *dev) 171 { 172 of_node_put(dev->of_node); 173 } 174 175 static int pmic_glink_add_aux_device(struct pmic_glink *pg, 176 struct auxiliary_device *aux, 177 const char *name) 178 { 179 struct device *parent = pg->dev; 180 int ret; 181 182 aux->name = name; 183 aux->dev.parent = parent; 184 aux->dev.release = pmic_glink_aux_release; 185 device_set_of_node_from_dev(&aux->dev, parent); 186 ret = auxiliary_device_init(aux); 187 if (ret) { 188 of_node_put(aux->dev.of_node); 189 return ret; 190 } 191 192 ret = auxiliary_device_add(aux); 193 if (ret) 194 auxiliary_device_uninit(aux); 195 196 return ret; 197 } 198 199 static void pmic_glink_del_aux_device(struct pmic_glink *pg, 200 struct auxiliary_device *aux) 201 { 202 auxiliary_device_delete(aux); 203 auxiliary_device_uninit(aux); 204 } 205 206 static void pmic_glink_state_notify_clients(struct pmic_glink *pg) 207 { 208 struct pmic_glink_client *client; 209 unsigned int new_state = pg->client_state; 210 unsigned long flags; 211 212 if (pg->client_state != SERVREG_SERVICE_STATE_UP) { 213 if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept) 214 new_state = SERVREG_SERVICE_STATE_UP; 215 } else { 216 if (pg->pdr_state == SERVREG_SERVICE_STATE_DOWN || !pg->ept) 217 new_state = SERVREG_SERVICE_STATE_DOWN; 218 } 219 220 if (new_state != pg->client_state) { 221 spin_lock_irqsave(&pg->client_lock, flags); 222 list_for_each_entry(client, &pg->clients, node) 223 client->pdr_notify(client->priv, new_state); 224 spin_unlock_irqrestore(&pg->client_lock, flags); 225 pg->client_state = new_state; 226 } 227 } 228 229 static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv) 230 { 231 struct pmic_glink *pg = priv; 232 233 guard(mutex)(&pg->state_lock); 234 pg->pdr_state = state; 235 236 pmic_glink_state_notify_clients(pg); 237 } 238 239 static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev) 240 { 241 struct pmic_glink *pg; 242 243 guard(mutex)(&__pmic_glink_lock); 244 pg = __pmic_glink; 245 if (!pg) 246 return dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n"); 247 248 dev_set_drvdata(&rpdev->dev, pg); 249 250 guard(mutex)(&pg->state_lock); 251 pg->ept = rpdev->ept; 252 pmic_glink_state_notify_clients(pg); 253 254 return 0; 255 } 256 257 static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev) 258 { 259 struct pmic_glink *pg; 260 261 guard(mutex)(&__pmic_glink_lock); 262 pg = __pmic_glink; 263 if (!pg) 264 return; 265 266 guard(mutex)(&pg->state_lock); 267 pg->ept = NULL; 268 pmic_glink_state_notify_clients(pg); 269 } 270 271 static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = { 272 { "PMIC_RTR_ADSP_APPS" }, 273 {} 274 }; 275 276 static struct rpmsg_driver pmic_glink_rpmsg_driver = { 277 .probe = pmic_glink_rpmsg_probe, 278 .remove = pmic_glink_rpmsg_remove, 279 .callback = pmic_glink_rpmsg_callback, 280 .id_table = pmic_glink_rpmsg_id_match, 281 .drv = { 282 .name = "qcom_pmic_glink_rpmsg", 283 }, 284 }; 285 286 static int pmic_glink_probe(struct platform_device *pdev) 287 { 288 const unsigned long *match_data; 289 struct pdr_service *service; 290 struct pmic_glink *pg; 291 int ret; 292 293 pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL); 294 if (!pg) 295 return -ENOMEM; 296 297 dev_set_drvdata(&pdev->dev, pg); 298 299 pg->dev = &pdev->dev; 300 301 INIT_LIST_HEAD(&pg->clients); 302 spin_lock_init(&pg->client_lock); 303 mutex_init(&pg->state_lock); 304 305 match_data = (unsigned long *)of_device_get_match_data(&pdev->dev); 306 if (!match_data) 307 return -EINVAL; 308 309 pg->client_mask = *match_data; 310 311 pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg); 312 if (IS_ERR(pg->pdr)) { 313 ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr), 314 "failed to initialize pdr\n"); 315 return ret; 316 } 317 318 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) { 319 ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi"); 320 if (ret) 321 goto out_release_pdr_handle; 322 } 323 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) { 324 ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode"); 325 if (ret) 326 goto out_release_ucsi_aux; 327 } 328 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) { 329 ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply"); 330 if (ret) 331 goto out_release_altmode_aux; 332 } 333 334 service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd"); 335 if (IS_ERR(service)) { 336 ret = dev_err_probe(&pdev->dev, PTR_ERR(service), 337 "failed adding pdr lookup for charger_pd\n"); 338 goto out_release_aux_devices; 339 } 340 341 mutex_lock(&__pmic_glink_lock); 342 __pmic_glink = pg; 343 mutex_unlock(&__pmic_glink_lock); 344 345 return 0; 346 347 out_release_aux_devices: 348 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 349 pmic_glink_del_aux_device(pg, &pg->ps_aux); 350 out_release_altmode_aux: 351 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 352 pmic_glink_del_aux_device(pg, &pg->altmode_aux); 353 out_release_ucsi_aux: 354 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 355 pmic_glink_del_aux_device(pg, &pg->ucsi_aux); 356 out_release_pdr_handle: 357 pdr_handle_release(pg->pdr); 358 359 return ret; 360 } 361 362 static void pmic_glink_remove(struct platform_device *pdev) 363 { 364 struct pmic_glink *pg = dev_get_drvdata(&pdev->dev); 365 366 pdr_handle_release(pg->pdr); 367 368 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) 369 pmic_glink_del_aux_device(pg, &pg->ps_aux); 370 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) 371 pmic_glink_del_aux_device(pg, &pg->altmode_aux); 372 if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) 373 pmic_glink_del_aux_device(pg, &pg->ucsi_aux); 374 375 guard(mutex)(&__pmic_glink_lock); 376 __pmic_glink = NULL; 377 } 378 379 static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | 380 BIT(PMIC_GLINK_CLIENT_ALTMODE) | 381 BIT(PMIC_GLINK_CLIENT_UCSI); 382 383 static const struct of_device_id pmic_glink_of_match[] = { 384 { .compatible = "qcom,pmic-glink", .data = &pmic_glink_sm8450_client_mask }, 385 {} 386 }; 387 MODULE_DEVICE_TABLE(of, pmic_glink_of_match); 388 389 static struct platform_driver pmic_glink_driver = { 390 .probe = pmic_glink_probe, 391 .remove = pmic_glink_remove, 392 .driver = { 393 .name = "qcom_pmic_glink", 394 .of_match_table = pmic_glink_of_match, 395 }, 396 }; 397 398 static int pmic_glink_init(void) 399 { 400 int ret; 401 402 ret = platform_driver_register(&pmic_glink_driver); 403 if (ret < 0) 404 return ret; 405 406 ret = register_rpmsg_driver(&pmic_glink_rpmsg_driver); 407 if (ret < 0) { 408 platform_driver_unregister(&pmic_glink_driver); 409 return ret; 410 } 411 412 return 0; 413 } 414 module_init(pmic_glink_init); 415 416 static void pmic_glink_exit(void) 417 { 418 unregister_rpmsg_driver(&pmic_glink_rpmsg_driver); 419 platform_driver_unregister(&pmic_glink_driver); 420 } 421 module_exit(pmic_glink_exit); 422 423 MODULE_DESCRIPTION("Qualcomm PMIC GLINK driver"); 424 MODULE_LICENSE("GPL"); 425