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