apr.c (17103B)
1// SPDX-License-Identifier: GPL-2.0 2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. 3// Copyright (c) 2018, Linaro Limited 4 5#include <linux/kernel.h> 6#include <linux/module.h> 7#include <linux/device.h> 8#include <linux/spinlock.h> 9#include <linux/idr.h> 10#include <linux/slab.h> 11#include <linux/workqueue.h> 12#include <linux/of_device.h> 13#include <linux/soc/qcom/apr.h> 14#include <linux/soc/qcom/pdr.h> 15#include <linux/rpmsg.h> 16#include <linux/of.h> 17 18enum { 19 PR_TYPE_APR = 0, 20 PR_TYPE_GPR, 21}; 22 23/* Some random values tbh which does not collide with static modules */ 24#define GPR_DYNAMIC_PORT_START 0x10000000 25#define GPR_DYNAMIC_PORT_END 0x20000000 26 27struct packet_router { 28 struct rpmsg_endpoint *ch; 29 struct device *dev; 30 spinlock_t svcs_lock; 31 spinlock_t rx_lock; 32 struct idr svcs_idr; 33 int dest_domain_id; 34 int type; 35 struct pdr_handle *pdr; 36 struct workqueue_struct *rxwq; 37 struct work_struct rx_work; 38 struct list_head rx_list; 39}; 40 41struct apr_rx_buf { 42 struct list_head node; 43 int len; 44 uint8_t buf[]; 45}; 46 47/** 48 * apr_send_pkt() - Send a apr message from apr device 49 * 50 * @adev: Pointer to previously registered apr device. 51 * @pkt: Pointer to apr packet to send 52 * 53 * Return: Will be an negative on packet size on success. 54 */ 55int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt) 56{ 57 struct packet_router *apr = dev_get_drvdata(adev->dev.parent); 58 struct apr_hdr *hdr; 59 unsigned long flags; 60 int ret; 61 62 spin_lock_irqsave(&adev->svc.lock, flags); 63 64 hdr = &pkt->hdr; 65 hdr->src_domain = APR_DOMAIN_APPS; 66 hdr->src_svc = adev->svc.id; 67 hdr->dest_domain = adev->domain_id; 68 hdr->dest_svc = adev->svc.id; 69 70 ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size); 71 spin_unlock_irqrestore(&adev->svc.lock, flags); 72 73 return ret ? ret : hdr->pkt_size; 74} 75EXPORT_SYMBOL_GPL(apr_send_pkt); 76 77void gpr_free_port(gpr_port_t *port) 78{ 79 struct packet_router *gpr = port->pr; 80 unsigned long flags; 81 82 spin_lock_irqsave(&gpr->svcs_lock, flags); 83 idr_remove(&gpr->svcs_idr, port->id); 84 spin_unlock_irqrestore(&gpr->svcs_lock, flags); 85 86 kfree(port); 87} 88EXPORT_SYMBOL_GPL(gpr_free_port); 89 90gpr_port_t *gpr_alloc_port(struct apr_device *gdev, struct device *dev, 91 gpr_port_cb cb, void *priv) 92{ 93 struct packet_router *pr = dev_get_drvdata(gdev->dev.parent); 94 gpr_port_t *port; 95 struct pkt_router_svc *svc; 96 int id; 97 98 port = kzalloc(sizeof(*port), GFP_KERNEL); 99 if (!port) 100 return ERR_PTR(-ENOMEM); 101 102 svc = port; 103 svc->callback = cb; 104 svc->pr = pr; 105 svc->priv = priv; 106 svc->dev = dev; 107 spin_lock_init(&svc->lock); 108 109 spin_lock(&pr->svcs_lock); 110 id = idr_alloc_cyclic(&pr->svcs_idr, svc, GPR_DYNAMIC_PORT_START, 111 GPR_DYNAMIC_PORT_END, GFP_ATOMIC); 112 if (id < 0) { 113 dev_err(dev, "Unable to allocate dynamic GPR src port\n"); 114 kfree(port); 115 spin_unlock(&pr->svcs_lock); 116 return ERR_PTR(id); 117 } 118 119 svc->id = id; 120 spin_unlock(&pr->svcs_lock); 121 122 return port; 123} 124EXPORT_SYMBOL_GPL(gpr_alloc_port); 125 126static int pkt_router_send_svc_pkt(struct pkt_router_svc *svc, struct gpr_pkt *pkt) 127{ 128 struct packet_router *pr = svc->pr; 129 struct gpr_hdr *hdr; 130 unsigned long flags; 131 int ret; 132 133 hdr = &pkt->hdr; 134 135 spin_lock_irqsave(&svc->lock, flags); 136 ret = rpmsg_trysend(pr->ch, pkt, hdr->pkt_size); 137 spin_unlock_irqrestore(&svc->lock, flags); 138 139 return ret ? ret : hdr->pkt_size; 140} 141 142int gpr_send_pkt(struct apr_device *gdev, struct gpr_pkt *pkt) 143{ 144 return pkt_router_send_svc_pkt(&gdev->svc, pkt); 145} 146EXPORT_SYMBOL_GPL(gpr_send_pkt); 147 148int gpr_send_port_pkt(gpr_port_t *port, struct gpr_pkt *pkt) 149{ 150 return pkt_router_send_svc_pkt(port, pkt); 151} 152EXPORT_SYMBOL_GPL(gpr_send_port_pkt); 153 154static void apr_dev_release(struct device *dev) 155{ 156 struct apr_device *adev = to_apr_device(dev); 157 158 kfree(adev); 159} 160 161static int apr_callback(struct rpmsg_device *rpdev, void *buf, 162 int len, void *priv, u32 addr) 163{ 164 struct packet_router *apr = dev_get_drvdata(&rpdev->dev); 165 struct apr_rx_buf *abuf; 166 unsigned long flags; 167 168 if (len <= APR_HDR_SIZE) { 169 dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n", 170 buf, len); 171 return -EINVAL; 172 } 173 174 abuf = kzalloc(sizeof(*abuf) + len, GFP_ATOMIC); 175 if (!abuf) 176 return -ENOMEM; 177 178 abuf->len = len; 179 memcpy(abuf->buf, buf, len); 180 181 spin_lock_irqsave(&apr->rx_lock, flags); 182 list_add_tail(&abuf->node, &apr->rx_list); 183 spin_unlock_irqrestore(&apr->rx_lock, flags); 184 185 queue_work(apr->rxwq, &apr->rx_work); 186 187 return 0; 188} 189 190static int apr_do_rx_callback(struct packet_router *apr, struct apr_rx_buf *abuf) 191{ 192 uint16_t hdr_size, msg_type, ver, svc_id; 193 struct pkt_router_svc *svc; 194 struct apr_device *adev; 195 struct apr_driver *adrv = NULL; 196 struct apr_resp_pkt resp; 197 struct apr_hdr *hdr; 198 unsigned long flags; 199 void *buf = abuf->buf; 200 int len = abuf->len; 201 202 hdr = buf; 203 ver = APR_HDR_FIELD_VER(hdr->hdr_field); 204 if (ver > APR_PKT_VER + 1) 205 return -EINVAL; 206 207 hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field); 208 if (hdr_size < APR_HDR_SIZE) { 209 dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size); 210 return -EINVAL; 211 } 212 213 if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) { 214 dev_err(apr->dev, "APR: Wrong packet size\n"); 215 return -EINVAL; 216 } 217 218 msg_type = APR_HDR_FIELD_MT(hdr->hdr_field); 219 if (msg_type >= APR_MSG_TYPE_MAX) { 220 dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type); 221 return -EINVAL; 222 } 223 224 if (hdr->src_domain >= APR_DOMAIN_MAX || 225 hdr->dest_domain >= APR_DOMAIN_MAX || 226 hdr->src_svc >= APR_SVC_MAX || 227 hdr->dest_svc >= APR_SVC_MAX) { 228 dev_err(apr->dev, "APR: Wrong APR header\n"); 229 return -EINVAL; 230 } 231 232 svc_id = hdr->dest_svc; 233 spin_lock_irqsave(&apr->svcs_lock, flags); 234 svc = idr_find(&apr->svcs_idr, svc_id); 235 if (svc && svc->dev->driver) { 236 adev = svc_to_apr_device(svc); 237 adrv = to_apr_driver(adev->dev.driver); 238 } 239 spin_unlock_irqrestore(&apr->svcs_lock, flags); 240 241 if (!adrv || !adev) { 242 dev_err(apr->dev, "APR: service is not registered (%d)\n", 243 svc_id); 244 return -EINVAL; 245 } 246 247 resp.hdr = *hdr; 248 resp.payload_size = hdr->pkt_size - hdr_size; 249 250 /* 251 * NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include 252 * optional headers in to apr_hdr which should be ignored 253 */ 254 if (resp.payload_size > 0) 255 resp.payload = buf + hdr_size; 256 257 adrv->callback(adev, &resp); 258 259 return 0; 260} 261 262static int gpr_do_rx_callback(struct packet_router *gpr, struct apr_rx_buf *abuf) 263{ 264 uint16_t hdr_size, ver; 265 struct pkt_router_svc *svc = NULL; 266 struct gpr_resp_pkt resp; 267 struct gpr_hdr *hdr; 268 unsigned long flags; 269 void *buf = abuf->buf; 270 int len = abuf->len; 271 272 hdr = buf; 273 ver = hdr->version; 274 if (ver > GPR_PKT_VER + 1) 275 return -EINVAL; 276 277 hdr_size = hdr->hdr_size; 278 if (hdr_size < GPR_PKT_HEADER_WORD_SIZE) { 279 dev_err(gpr->dev, "GPR: Wrong hdr size:%d\n", hdr_size); 280 return -EINVAL; 281 } 282 283 if (hdr->pkt_size < GPR_PKT_HEADER_BYTE_SIZE || hdr->pkt_size != len) { 284 dev_err(gpr->dev, "GPR: Wrong packet size\n"); 285 return -EINVAL; 286 } 287 288 resp.hdr = *hdr; 289 resp.payload_size = hdr->pkt_size - (hdr_size * 4); 290 291 /* 292 * NOTE: hdr_size is not same as GPR_HDR_SIZE as remote can include 293 * optional headers in to gpr_hdr which should be ignored 294 */ 295 if (resp.payload_size > 0) 296 resp.payload = buf + (hdr_size * 4); 297 298 299 spin_lock_irqsave(&gpr->svcs_lock, flags); 300 svc = idr_find(&gpr->svcs_idr, hdr->dest_port); 301 spin_unlock_irqrestore(&gpr->svcs_lock, flags); 302 303 if (!svc) { 304 dev_err(gpr->dev, "GPR: Port(%x) is not registered\n", 305 hdr->dest_port); 306 return -EINVAL; 307 } 308 309 if (svc->callback) 310 svc->callback(&resp, svc->priv, 0); 311 312 return 0; 313} 314 315static void apr_rxwq(struct work_struct *work) 316{ 317 struct packet_router *apr = container_of(work, struct packet_router, rx_work); 318 struct apr_rx_buf *abuf, *b; 319 unsigned long flags; 320 321 if (!list_empty(&apr->rx_list)) { 322 list_for_each_entry_safe(abuf, b, &apr->rx_list, node) { 323 switch (apr->type) { 324 case PR_TYPE_APR: 325 apr_do_rx_callback(apr, abuf); 326 break; 327 case PR_TYPE_GPR: 328 gpr_do_rx_callback(apr, abuf); 329 break; 330 default: 331 break; 332 } 333 spin_lock_irqsave(&apr->rx_lock, flags); 334 list_del(&abuf->node); 335 spin_unlock_irqrestore(&apr->rx_lock, flags); 336 kfree(abuf); 337 } 338 } 339} 340 341static int apr_device_match(struct device *dev, struct device_driver *drv) 342{ 343 struct apr_device *adev = to_apr_device(dev); 344 struct apr_driver *adrv = to_apr_driver(drv); 345 const struct apr_device_id *id = adrv->id_table; 346 347 /* Attempt an OF style match first */ 348 if (of_driver_match_device(dev, drv)) 349 return 1; 350 351 if (!id) 352 return 0; 353 354 while (id->domain_id != 0 || id->svc_id != 0) { 355 if (id->domain_id == adev->domain_id && 356 id->svc_id == adev->svc.id) 357 return 1; 358 id++; 359 } 360 361 return 0; 362} 363 364static int apr_device_probe(struct device *dev) 365{ 366 struct apr_device *adev = to_apr_device(dev); 367 struct apr_driver *adrv = to_apr_driver(dev->driver); 368 int ret; 369 370 ret = adrv->probe(adev); 371 if (!ret) 372 adev->svc.callback = adrv->gpr_callback; 373 374 return ret; 375} 376 377static void apr_device_remove(struct device *dev) 378{ 379 struct apr_device *adev = to_apr_device(dev); 380 struct apr_driver *adrv; 381 struct packet_router *apr = dev_get_drvdata(adev->dev.parent); 382 383 if (dev->driver) { 384 adrv = to_apr_driver(dev->driver); 385 if (adrv->remove) 386 adrv->remove(adev); 387 spin_lock(&apr->svcs_lock); 388 idr_remove(&apr->svcs_idr, adev->svc.id); 389 spin_unlock(&apr->svcs_lock); 390 } 391} 392 393static int apr_uevent(struct device *dev, struct kobj_uevent_env *env) 394{ 395 struct apr_device *adev = to_apr_device(dev); 396 int ret; 397 398 ret = of_device_uevent_modalias(dev, env); 399 if (ret != -ENODEV) 400 return ret; 401 402 return add_uevent_var(env, "MODALIAS=apr:%s", adev->name); 403} 404 405struct bus_type aprbus = { 406 .name = "aprbus", 407 .match = apr_device_match, 408 .probe = apr_device_probe, 409 .uevent = apr_uevent, 410 .remove = apr_device_remove, 411}; 412EXPORT_SYMBOL_GPL(aprbus); 413 414static int apr_add_device(struct device *dev, struct device_node *np, 415 u32 svc_id, u32 domain_id) 416{ 417 struct packet_router *apr = dev_get_drvdata(dev); 418 struct apr_device *adev = NULL; 419 struct pkt_router_svc *svc; 420 int ret; 421 422 adev = kzalloc(sizeof(*adev), GFP_KERNEL); 423 if (!adev) 424 return -ENOMEM; 425 426 adev->svc_id = svc_id; 427 svc = &adev->svc; 428 429 svc->id = svc_id; 430 svc->pr = apr; 431 svc->priv = adev; 432 svc->dev = dev; 433 spin_lock_init(&svc->lock); 434 435 adev->domain_id = domain_id; 436 437 if (np) 438 snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np); 439 440 switch (apr->type) { 441 case PR_TYPE_APR: 442 dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, 443 domain_id, svc_id); 444 break; 445 case PR_TYPE_GPR: 446 dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name, 447 domain_id, svc_id); 448 break; 449 default: 450 break; 451 } 452 453 adev->dev.bus = &aprbus; 454 adev->dev.parent = dev; 455 adev->dev.of_node = np; 456 adev->dev.release = apr_dev_release; 457 adev->dev.driver = NULL; 458 459 spin_lock(&apr->svcs_lock); 460 idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC); 461 spin_unlock(&apr->svcs_lock); 462 463 of_property_read_string_index(np, "qcom,protection-domain", 464 1, &adev->service_path); 465 466 dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev)); 467 468 ret = device_register(&adev->dev); 469 if (ret) { 470 dev_err(dev, "device_register failed: %d\n", ret); 471 put_device(&adev->dev); 472 } 473 474 return ret; 475} 476 477static int of_apr_add_pd_lookups(struct device *dev) 478{ 479 const char *service_name, *service_path; 480 struct packet_router *apr = dev_get_drvdata(dev); 481 struct device_node *node; 482 struct pdr_service *pds; 483 int ret; 484 485 for_each_child_of_node(dev->of_node, node) { 486 ret = of_property_read_string_index(node, "qcom,protection-domain", 487 0, &service_name); 488 if (ret < 0) 489 continue; 490 491 ret = of_property_read_string_index(node, "qcom,protection-domain", 492 1, &service_path); 493 if (ret < 0) { 494 dev_err(dev, "pdr service path missing: %d\n", ret); 495 of_node_put(node); 496 return ret; 497 } 498 499 pds = pdr_add_lookup(apr->pdr, service_name, service_path); 500 if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { 501 dev_err(dev, "pdr add lookup failed: %ld\n", PTR_ERR(pds)); 502 of_node_put(node); 503 return PTR_ERR(pds); 504 } 505 } 506 507 return 0; 508} 509 510static void of_register_apr_devices(struct device *dev, const char *svc_path) 511{ 512 struct packet_router *apr = dev_get_drvdata(dev); 513 struct device_node *node; 514 const char *service_path; 515 int ret; 516 517 for_each_child_of_node(dev->of_node, node) { 518 u32 svc_id; 519 u32 domain_id; 520 521 /* 522 * This function is called with svc_path NULL during 523 * apr_probe(), in which case we register any apr devices 524 * without a qcom,protection-domain specified. 525 * 526 * Then as the protection domains becomes available 527 * (if applicable) this function is again called, but with 528 * svc_path representing the service becoming available. In 529 * this case we register any apr devices with a matching 530 * qcom,protection-domain. 531 */ 532 533 ret = of_property_read_string_index(node, "qcom,protection-domain", 534 1, &service_path); 535 if (svc_path) { 536 /* skip APR services that are PD independent */ 537 if (ret) 538 continue; 539 540 /* skip APR services whose PD paths don't match */ 541 if (strcmp(service_path, svc_path)) 542 continue; 543 } else { 544 /* skip APR services whose PD lookups are registered */ 545 if (ret == 0) 546 continue; 547 } 548 549 if (of_property_read_u32(node, "reg", &svc_id)) 550 continue; 551 552 domain_id = apr->dest_domain_id; 553 554 if (apr_add_device(dev, node, svc_id, domain_id)) 555 dev_err(dev, "Failed to add apr %d svc\n", svc_id); 556 } 557} 558 559static int apr_remove_device(struct device *dev, void *svc_path) 560{ 561 struct apr_device *adev = to_apr_device(dev); 562 563 if (svc_path && adev->service_path) { 564 if (!strcmp(adev->service_path, (char *)svc_path)) 565 device_unregister(&adev->dev); 566 } else { 567 device_unregister(&adev->dev); 568 } 569 570 return 0; 571} 572 573static void apr_pd_status(int state, char *svc_path, void *priv) 574{ 575 struct packet_router *apr = (struct packet_router *)priv; 576 577 switch (state) { 578 case SERVREG_SERVICE_STATE_UP: 579 of_register_apr_devices(apr->dev, svc_path); 580 break; 581 case SERVREG_SERVICE_STATE_DOWN: 582 device_for_each_child(apr->dev, svc_path, apr_remove_device); 583 break; 584 } 585} 586 587static int apr_probe(struct rpmsg_device *rpdev) 588{ 589 struct device *dev = &rpdev->dev; 590 struct packet_router *apr; 591 int ret; 592 593 apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL); 594 if (!apr) 595 return -ENOMEM; 596 597 ret = of_property_read_u32(dev->of_node, "qcom,domain", &apr->dest_domain_id); 598 599 if (of_device_is_compatible(dev->of_node, "qcom,gpr")) { 600 apr->type = PR_TYPE_GPR; 601 } else { 602 if (ret) /* try deprecated apr-domain property */ 603 ret = of_property_read_u32(dev->of_node, "qcom,apr-domain", 604 &apr->dest_domain_id); 605 apr->type = PR_TYPE_APR; 606 } 607 608 if (ret) { 609 dev_err(dev, "Domain ID not specified in DT\n"); 610 return ret; 611 } 612 613 dev_set_drvdata(dev, apr); 614 apr->ch = rpdev->ept; 615 apr->dev = dev; 616 apr->rxwq = create_singlethread_workqueue("qcom_apr_rx"); 617 if (!apr->rxwq) { 618 dev_err(apr->dev, "Failed to start Rx WQ\n"); 619 return -ENOMEM; 620 } 621 INIT_WORK(&apr->rx_work, apr_rxwq); 622 623 apr->pdr = pdr_handle_alloc(apr_pd_status, apr); 624 if (IS_ERR(apr->pdr)) { 625 dev_err(dev, "Failed to init PDR handle\n"); 626 ret = PTR_ERR(apr->pdr); 627 goto destroy_wq; 628 } 629 630 INIT_LIST_HEAD(&apr->rx_list); 631 spin_lock_init(&apr->rx_lock); 632 spin_lock_init(&apr->svcs_lock); 633 idr_init(&apr->svcs_idr); 634 635 ret = of_apr_add_pd_lookups(dev); 636 if (ret) 637 goto handle_release; 638 639 of_register_apr_devices(dev, NULL); 640 641 return 0; 642 643handle_release: 644 pdr_handle_release(apr->pdr); 645destroy_wq: 646 destroy_workqueue(apr->rxwq); 647 return ret; 648} 649 650static void apr_remove(struct rpmsg_device *rpdev) 651{ 652 struct packet_router *apr = dev_get_drvdata(&rpdev->dev); 653 654 pdr_handle_release(apr->pdr); 655 device_for_each_child(&rpdev->dev, NULL, apr_remove_device); 656 destroy_workqueue(apr->rxwq); 657} 658 659/* 660 * __apr_driver_register() - Client driver registration with aprbus 661 * 662 * @drv:Client driver to be associated with client-device. 663 * @owner: owning module/driver 664 * 665 * This API will register the client driver with the aprbus 666 * It is called from the driver's module-init function. 667 */ 668int __apr_driver_register(struct apr_driver *drv, struct module *owner) 669{ 670 drv->driver.bus = &aprbus; 671 drv->driver.owner = owner; 672 673 return driver_register(&drv->driver); 674} 675EXPORT_SYMBOL_GPL(__apr_driver_register); 676 677/* 678 * apr_driver_unregister() - Undo effect of apr_driver_register 679 * 680 * @drv: Client driver to be unregistered 681 */ 682void apr_driver_unregister(struct apr_driver *drv) 683{ 684 driver_unregister(&drv->driver); 685} 686EXPORT_SYMBOL_GPL(apr_driver_unregister); 687 688static const struct of_device_id pkt_router_of_match[] = { 689 { .compatible = "qcom,apr"}, 690 { .compatible = "qcom,apr-v2"}, 691 { .compatible = "qcom,gpr"}, 692 {} 693}; 694MODULE_DEVICE_TABLE(of, pkt_router_of_match); 695 696static struct rpmsg_driver packet_router_driver = { 697 .probe = apr_probe, 698 .remove = apr_remove, 699 .callback = apr_callback, 700 .drv = { 701 .name = "qcom,apr", 702 .of_match_table = pkt_router_of_match, 703 }, 704}; 705 706static int __init apr_init(void) 707{ 708 int ret; 709 710 ret = bus_register(&aprbus); 711 if (!ret) 712 ret = register_rpmsg_driver(&packet_router_driver); 713 else 714 bus_unregister(&aprbus); 715 716 return ret; 717} 718 719static void __exit apr_exit(void) 720{ 721 bus_unregister(&aprbus); 722 unregister_rpmsg_driver(&packet_router_driver); 723} 724 725subsys_initcall(apr_init); 726module_exit(apr_exit); 727 728MODULE_LICENSE("GPL v2"); 729MODULE_DESCRIPTION("Qualcomm APR Bus");