1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Qualcomm Peripheral Authentication Service remoteproc driver 4 * 5 * Copyright (C) 2016 Linaro Ltd 6 * Copyright (C) 2014 Sony Mobile Communications AB 7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/firmware.h> 13 #include <linux/interrupt.h> 14 #include <linux/iommu.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/of_address.h> 19 #include <linux/of_platform.h> 20 #include <linux/of_reserved_mem.h> 21 #include <linux/platform_device.h> 22 #include <linux/pm_domain.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/firmware/qcom/qcom_pas.h> 25 #include <linux/firmware/qcom/qcom_scm.h> 26 #include <linux/regulator/consumer.h> 27 #include <linux/remoteproc.h> 28 #include <linux/soc/qcom/mdt_loader.h> 29 #include <linux/soc/qcom/smem.h> 30 #include <linux/soc/qcom/smem_state.h> 31 32 #include "qcom_common.h" 33 #include "qcom_pil_info.h" 34 #include "qcom_q6v5.h" 35 #include "remoteproc_internal.h" 36 37 #define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS 100 38 39 #define MAX_ASSIGN_COUNT 3 40 41 struct qcom_pas_data { 42 int crash_reason_smem; 43 const char *firmware_name; 44 const char *dtb_firmware_name; 45 int pas_id; 46 int dtb_pas_id; 47 int lite_pas_id; 48 int lite_dtb_pas_id; 49 unsigned int minidump_id; 50 bool auto_boot; 51 bool decrypt_shutdown; 52 53 char **proxy_pd_names; 54 55 const char *load_state; 56 const char *ssr_name; 57 const char *sysmon_name; 58 int ssctl_id; 59 unsigned int smem_host_id; 60 61 int region_assign_idx; 62 int region_assign_count; 63 bool region_assign_shared; 64 int region_assign_vmid; 65 bool early_boot; 66 bool needs_tzmem; 67 }; 68 69 struct qcom_pas { 70 struct device *dev; 71 struct rproc *rproc; 72 73 struct qcom_q6v5 q6v5; 74 75 struct clk *xo; 76 struct clk *aggre2_clk; 77 78 struct regulator *cx_supply; 79 struct regulator *px_supply; 80 81 struct device *proxy_pds[3]; 82 83 int proxy_pd_count; 84 85 const char *dtb_firmware_name; 86 int pas_id; 87 int dtb_pas_id; 88 int lite_pas_id; 89 int lite_dtb_pas_id; 90 unsigned int minidump_id; 91 int crash_reason_smem; 92 unsigned int smem_host_id; 93 bool decrypt_shutdown; 94 const char *info_name; 95 96 const struct firmware *firmware; 97 const struct firmware *dtb_firmware; 98 99 phys_addr_t mem_phys; 100 phys_addr_t dtb_mem_phys; 101 phys_addr_t mem_reloc; 102 phys_addr_t dtb_mem_reloc; 103 phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT]; 104 105 void __iomem *mem_region; 106 107 size_t mem_size; 108 size_t dtb_mem_size; 109 size_t region_assign_size[MAX_ASSIGN_COUNT]; 110 111 int region_assign_idx; 112 int region_assign_count; 113 bool region_assign_shared; 114 int region_assign_vmid; 115 u64 region_assign_owners[MAX_ASSIGN_COUNT]; 116 117 struct qcom_rproc_glink glink_subdev; 118 struct qcom_rproc_subdev smd_subdev; 119 struct qcom_rproc_pdm pdm_subdev; 120 struct qcom_rproc_ssr ssr_subdev; 121 struct qcom_sysmon *sysmon; 122 struct platform_device *bam_dmux; 123 124 struct qcom_pas_context *pas_ctx; 125 struct qcom_pas_context *dtb_pas_ctx; 126 }; 127 128 static void qcom_pas_segment_dump(struct rproc *rproc, 129 struct rproc_dump_segment *segment, 130 void *dest, size_t offset, size_t size) 131 { 132 struct qcom_pas *pas = rproc->priv; 133 int total_offset; 134 135 total_offset = segment->da + segment->offset + offset - pas->mem_phys; 136 if (total_offset < 0 || total_offset + size > pas->mem_size) { 137 dev_err(pas->dev, 138 "invalid copy request for segment %pad with offset %zu and size %zu)\n", 139 &segment->da, offset, size); 140 memset(dest, 0xff, size); 141 return; 142 } 143 144 memcpy_fromio(dest, pas->mem_region + total_offset, size); 145 } 146 147 static void qcom_pas_minidump(struct rproc *rproc) 148 { 149 struct qcom_pas *pas = rproc->priv; 150 151 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) 152 return; 153 154 pas->mem_region = qcom_pas_ctx_map(pas->pas_ctx); 155 if (!pas->mem_region) 156 return; 157 158 qcom_minidump(rproc, pas->minidump_id, qcom_pas_segment_dump); 159 iounmap(pas->mem_region); 160 pas->mem_region = NULL; 161 } 162 163 static int qcom_pas_pds_enable(struct qcom_pas *pas, struct device **pds, 164 size_t pd_count) 165 { 166 int ret; 167 int i; 168 169 for (i = 0; i < pd_count; i++) { 170 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 171 ret = pm_runtime_get_sync(pds[i]); 172 if (ret < 0) { 173 pm_runtime_put_noidle(pds[i]); 174 dev_pm_genpd_set_performance_state(pds[i], 0); 175 goto unroll_pd_votes; 176 } 177 } 178 179 return 0; 180 181 unroll_pd_votes: 182 for (i--; i >= 0; i--) { 183 dev_pm_genpd_set_performance_state(pds[i], 0); 184 pm_runtime_put(pds[i]); 185 } 186 187 return ret; 188 }; 189 190 static void qcom_pas_pds_disable(struct qcom_pas *pas, struct device **pds, 191 size_t pd_count) 192 { 193 int i; 194 195 for (i = 0; i < pd_count; i++) { 196 dev_pm_genpd_set_performance_state(pds[i], 0); 197 pm_runtime_put(pds[i]); 198 } 199 } 200 201 static int qcom_pas_shutdown_poll_decrypt(struct qcom_pas *pas) 202 { 203 unsigned int retry_num = 50; 204 int ret; 205 206 do { 207 msleep(QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS); 208 ret = qcom_pas_shutdown(pas->pas_id); 209 } while (ret == -EINVAL && --retry_num); 210 211 return ret; 212 } 213 214 static int qcom_pas_unprepare(struct rproc *rproc) 215 { 216 struct qcom_pas *pas = rproc->priv; 217 218 /* 219 * qcom_pas_load() did pass pas_metadata to the SCM driver for storing 220 * metadata context. It might have been released already if 221 * auth_and_reset() was successful, but in other cases clean it up 222 * here. 223 */ 224 qcom_pas_metadata_release(pas->pas_ctx); 225 if (pas->dtb_pas_id) 226 qcom_pas_metadata_release(pas->dtb_pas_ctx); 227 228 return 0; 229 } 230 231 static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) 232 { 233 struct qcom_pas *pas = rproc->priv; 234 int ret; 235 236 /* Store firmware handle to be used in qcom_pas_start() */ 237 pas->firmware = fw; 238 239 if (pas->lite_pas_id) 240 qcom_pas_shutdown(pas->lite_pas_id); 241 if (pas->lite_dtb_pas_id) 242 qcom_pas_shutdown(pas->lite_dtb_pas_id); 243 244 if (pas->dtb_pas_id) { 245 ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); 246 if (ret) { 247 dev_err(pas->dev, "request_firmware failed for %s: %d\n", 248 pas->dtb_firmware_name, ret); 249 return ret; 250 } 251 252 ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, 253 pas->dtb_firmware_name, &pas->dtb_mem_reloc); 254 if (ret) { 255 qcom_pas_metadata_release(pas->dtb_pas_ctx); 256 release_firmware(pas->dtb_firmware); 257 return ret; 258 } 259 } 260 261 return 0; 262 } 263 264 static void qcom_pas_unmap_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size) 265 { 266 if (rproc->has_iommu) 267 iommu_unmap(rproc->domain, mem_phys, size); 268 } 269 270 static int qcom_pas_map_carveout(struct rproc *rproc, phys_addr_t mem_phys, size_t size) 271 { 272 int ret = 0; 273 274 if (rproc->has_iommu) 275 ret = iommu_map(rproc->domain, mem_phys, mem_phys, size, 276 IOMMU_READ | IOMMU_WRITE, GFP_KERNEL); 277 return ret; 278 } 279 280 static int qcom_pas_start(struct rproc *rproc) 281 { 282 struct qcom_pas *pas = rproc->priv; 283 int ret; 284 285 ret = qcom_q6v5_prepare(&pas->q6v5); 286 if (ret) 287 return ret; 288 289 ret = qcom_pas_pds_enable(pas, pas->proxy_pds, pas->proxy_pd_count); 290 if (ret < 0) 291 goto disable_irqs; 292 293 ret = clk_prepare_enable(pas->xo); 294 if (ret) 295 goto disable_proxy_pds; 296 297 ret = clk_prepare_enable(pas->aggre2_clk); 298 if (ret) 299 goto disable_xo_clk; 300 301 if (pas->cx_supply) { 302 ret = regulator_enable(pas->cx_supply); 303 if (ret) 304 goto disable_aggre2_clk; 305 } 306 307 if (pas->px_supply) { 308 ret = regulator_enable(pas->px_supply); 309 if (ret) 310 goto disable_cx_supply; 311 } 312 313 if (pas->dtb_pas_id) { 314 ret = qcom_pas_map_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); 315 if (ret) 316 goto disable_px_supply; 317 318 ret = qcom_pas_prepare_and_auth_reset(pas->dtb_pas_ctx); 319 if (ret) { 320 dev_err(pas->dev, 321 "failed to authenticate dtb image and release reset\n"); 322 goto unmap_dtb_carveout; 323 } 324 } 325 326 ret = qcom_mdt_pas_load(pas->pas_ctx, pas->firmware, rproc->firmware, 327 &pas->mem_reloc); 328 if (ret) 329 goto release_pas_metadata; 330 331 qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size); 332 333 ret = qcom_pas_map_carveout(rproc, pas->mem_phys, pas->mem_size); 334 if (ret) 335 goto release_pas_metadata; 336 337 ret = qcom_pas_prepare_and_auth_reset(pas->pas_ctx); 338 if (ret) { 339 dev_err(pas->dev, 340 "failed to authenticate image and release reset\n"); 341 goto unmap_carveout; 342 } 343 344 ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000)); 345 if (ret == -ETIMEDOUT) { 346 dev_err(pas->dev, "start timed out\n"); 347 qcom_pas_shutdown(pas->pas_id); 348 goto unmap_carveout; 349 } 350 351 qcom_pas_metadata_release(pas->pas_ctx); 352 if (pas->dtb_pas_id) 353 qcom_pas_metadata_release(pas->dtb_pas_ctx); 354 355 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 356 pas->firmware = NULL; 357 358 return 0; 359 360 unmap_carveout: 361 qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size); 362 release_pas_metadata: 363 qcom_pas_metadata_release(pas->pas_ctx); 364 if (pas->dtb_pas_id) 365 qcom_pas_metadata_release(pas->dtb_pas_ctx); 366 367 unmap_dtb_carveout: 368 if (pas->dtb_pas_id) 369 qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); 370 disable_px_supply: 371 if (pas->px_supply) 372 regulator_disable(pas->px_supply); 373 disable_cx_supply: 374 if (pas->cx_supply) 375 regulator_disable(pas->cx_supply); 376 disable_aggre2_clk: 377 clk_disable_unprepare(pas->aggre2_clk); 378 disable_xo_clk: 379 clk_disable_unprepare(pas->xo); 380 disable_proxy_pds: 381 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 382 disable_irqs: 383 qcom_q6v5_unprepare(&pas->q6v5); 384 385 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 386 pas->firmware = NULL; 387 388 return ret; 389 } 390 391 static void qcom_pas_handover(struct qcom_q6v5 *q6v5) 392 { 393 struct qcom_pas *pas = container_of(q6v5, struct qcom_pas, q6v5); 394 395 if (pas->px_supply) 396 regulator_disable(pas->px_supply); 397 if (pas->cx_supply) 398 regulator_disable(pas->cx_supply); 399 clk_disable_unprepare(pas->aggre2_clk); 400 clk_disable_unprepare(pas->xo); 401 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 402 } 403 404 static int qcom_pas_stop(struct rproc *rproc) 405 { 406 struct qcom_pas *pas = rproc->priv; 407 int handover; 408 int ret; 409 410 ret = qcom_q6v5_request_stop(&pas->q6v5, pas->sysmon); 411 if (ret == -ETIMEDOUT) 412 dev_err(pas->dev, "timed out on wait\n"); 413 414 ret = qcom_pas_shutdown(pas->pas_id); 415 if (ret && pas->decrypt_shutdown) 416 ret = qcom_pas_shutdown_poll_decrypt(pas); 417 418 if (ret) 419 dev_err(pas->dev, "failed to shutdown: %d\n", ret); 420 421 if (pas->dtb_pas_id) { 422 ret = qcom_pas_shutdown(pas->dtb_pas_id); 423 if (ret) 424 dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret); 425 426 qcom_pas_unmap_carveout(rproc, pas->dtb_mem_phys, pas->dtb_mem_size); 427 } 428 429 qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size); 430 431 handover = qcom_q6v5_unprepare(&pas->q6v5); 432 if (handover) 433 qcom_pas_handover(&pas->q6v5); 434 435 if (pas->smem_host_id) 436 ret = qcom_smem_bust_hwspin_lock_by_host(pas->smem_host_id); 437 438 return ret; 439 } 440 441 static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 442 { 443 struct qcom_pas *pas = rproc->priv; 444 int offset; 445 446 offset = da - pas->mem_reloc; 447 if (offset < 0 || offset + len > pas->mem_size) 448 return NULL; 449 450 if (is_iomem) 451 *is_iomem = true; 452 453 return (__force void *)pas->mem_region + offset; 454 } 455 456 static int qcom_pas_parse_firmware(struct rproc *rproc, const struct firmware *fw) 457 { 458 struct qcom_pas *pas = rproc->priv; 459 struct resource_table *table = NULL; 460 size_t output_rt_size; 461 void *output_rt; 462 size_t table_sz; 463 int ret; 464 465 ret = qcom_register_dump_segments(rproc, fw); 466 if (ret) { 467 dev_err(pas->dev, "Error in registering dump segments\n"); 468 return ret; 469 } 470 471 if (!rproc->has_iommu) 472 return 0; 473 474 ret = rproc_elf_load_rsc_table(rproc, fw); 475 if (ret) 476 dev_dbg(&rproc->dev, "Failed to load resource table from firmware\n"); 477 478 table = rproc->table_ptr; 479 table_sz = rproc->table_sz; 480 481 /* 482 * The resources consumed by Qualcomm remote processors fall into two categories: 483 * static (such as the memory carveouts for the rproc firmware) and dynamic (like 484 * shared memory pools). Both are managed by a Qualcomm hypervisor (such as QHEE 485 * or Gunyah), if one is present. Otherwise, a resource table must be retrieved 486 * via an SCM call. That table will list all dynamic resources (if any) and possibly 487 * the static ones. The static resources may also come from a resource table embedded 488 * in the rproc firmware instead. 489 * 490 * Here, we call rproc_elf_load_rsc_table() to check firmware binary has resources 491 * or not and if it is not having then we pass NULL and zero as input resource 492 * table pointer and size respectively to the argument of qcom_pas_get_rsc_table() 493 * and this is even true for Qualcomm remote processor who does follow remoteproc 494 * framework. 495 */ 496 output_rt = qcom_pas_get_rsc_table(pas->pas_ctx, table, table_sz, &output_rt_size); 497 ret = IS_ERR(output_rt) ? PTR_ERR(output_rt) : 0; 498 if (ret) { 499 dev_err(pas->dev, "Error in getting resource table: %d\n", ret); 500 return ret; 501 } 502 503 kfree(rproc->cached_table); 504 rproc->cached_table = output_rt; 505 rproc->table_ptr = rproc->cached_table; 506 rproc->table_sz = output_rt_size; 507 508 return ret; 509 } 510 511 static unsigned long qcom_pas_panic(struct rproc *rproc) 512 { 513 struct qcom_pas *pas = rproc->priv; 514 515 return qcom_q6v5_panic(&pas->q6v5); 516 } 517 518 static int qcom_pas_attach(struct rproc *rproc) 519 { 520 struct qcom_pas *pas = rproc->priv; 521 bool ready_state; 522 bool crash_state; 523 bool stop_state; 524 int ret; 525 526 pas->q6v5.handover_issued = true; 527 enable_irq(pas->q6v5.handover_irq); 528 529 pas->q6v5.running = true; 530 ret = irq_get_irqchip_state(pas->q6v5.fatal_irq, 531 IRQCHIP_STATE_LINE_LEVEL, &crash_state); 532 if (ret) 533 goto disable_running; 534 535 if (crash_state) { 536 dev_err(pas->dev, "Subsystem has crashed before driver probe\n"); 537 rproc_report_crash(rproc, RPROC_FATAL_ERROR); 538 ret = -EINVAL; 539 goto disable_running; 540 } 541 542 ret = irq_get_irqchip_state(pas->q6v5.stop_irq, 543 IRQCHIP_STATE_LINE_LEVEL, &stop_state); 544 if (ret) 545 goto disable_running; 546 547 if (stop_state || qcom_sysmon_shutdown_irq_state(pas->sysmon)) { 548 dev_info(pas->dev, "Subsystem found stop state set. Falling back to start.\n"); 549 goto unroll_attach; 550 } 551 552 ret = irq_get_irqchip_state(pas->q6v5.ready_irq, 553 IRQCHIP_STATE_LINE_LEVEL, &ready_state); 554 if (ret) 555 goto disable_running; 556 557 if (unlikely(!ready_state)) { 558 /* 559 * The bootloader may not support early boot, mark the state as 560 * RPROC_OFFLINE so that the PAS driver can load the firmware and 561 * start the remoteproc. 562 */ 563 dev_err(pas->dev, "Failed to get subsystem ready interrupt\n"); 564 goto unroll_attach; 565 } 566 567 return 0; 568 569 unroll_attach: 570 pas->rproc->state = RPROC_OFFLINE; 571 ret = -EINVAL; 572 disable_running: 573 disable_irq(pas->q6v5.handover_irq); 574 pas->q6v5.running = false; 575 576 return ret; 577 } 578 579 static void qcom_pas_coredump(struct rproc *rproc) 580 { 581 struct qcom_pas *pas = rproc->priv; 582 583 pas->mem_region = qcom_pas_ctx_map(pas->pas_ctx); 584 if (!pas->mem_region) 585 return; 586 587 rproc_coredump(rproc); 588 iounmap(pas->mem_region); 589 pas->mem_region = NULL; 590 } 591 592 static const struct rproc_ops qcom_pas_ops = { 593 .unprepare = qcom_pas_unprepare, 594 .start = qcom_pas_start, 595 .stop = qcom_pas_stop, 596 .da_to_va = qcom_pas_da_to_va, 597 .parse_fw = qcom_pas_parse_firmware, 598 .load = qcom_pas_load, 599 .panic = qcom_pas_panic, 600 .attach = qcom_pas_attach, 601 .coredump = qcom_pas_coredump, 602 }; 603 604 static const struct rproc_ops qcom_pas_minidump_ops = { 605 .unprepare = qcom_pas_unprepare, 606 .start = qcom_pas_start, 607 .stop = qcom_pas_stop, 608 .da_to_va = qcom_pas_da_to_va, 609 .parse_fw = qcom_pas_parse_firmware, 610 .load = qcom_pas_load, 611 .panic = qcom_pas_panic, 612 .coredump = qcom_pas_minidump, 613 .attach = qcom_pas_attach, 614 }; 615 616 static int qcom_pas_init_clock(struct qcom_pas *pas) 617 { 618 pas->xo = devm_clk_get(pas->dev, "xo"); 619 if (IS_ERR(pas->xo)) 620 return dev_err_probe(pas->dev, PTR_ERR(pas->xo), 621 "failed to get xo clock"); 622 623 pas->aggre2_clk = devm_clk_get_optional(pas->dev, "aggre2"); 624 if (IS_ERR(pas->aggre2_clk)) 625 return dev_err_probe(pas->dev, PTR_ERR(pas->aggre2_clk), 626 "failed to get aggre2 clock"); 627 628 return 0; 629 } 630 631 static int qcom_pas_init_regulator(struct qcom_pas *pas) 632 { 633 pas->cx_supply = devm_regulator_get_optional(pas->dev, "cx"); 634 if (IS_ERR(pas->cx_supply)) { 635 if (PTR_ERR(pas->cx_supply) == -ENODEV) 636 pas->cx_supply = NULL; 637 else 638 return PTR_ERR(pas->cx_supply); 639 } 640 641 if (pas->cx_supply) 642 regulator_set_load(pas->cx_supply, 100000); 643 644 pas->px_supply = devm_regulator_get_optional(pas->dev, "px"); 645 if (IS_ERR(pas->px_supply)) { 646 if (PTR_ERR(pas->px_supply) == -ENODEV) 647 pas->px_supply = NULL; 648 else 649 return PTR_ERR(pas->px_supply); 650 } 651 652 return 0; 653 } 654 655 static int qcom_pas_pds_attach(struct device *dev, struct device **devs, char **pd_names) 656 { 657 size_t num_pds = 0; 658 int ret; 659 int i; 660 661 if (!pd_names) 662 return 0; 663 664 while (pd_names[num_pds]) 665 num_pds++; 666 667 /* Handle single power domain */ 668 if (num_pds == 1 && dev->pm_domain) { 669 devs[0] = dev; 670 pm_runtime_enable(dev); 671 return 1; 672 } 673 674 for (i = 0; i < num_pds; i++) { 675 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 676 if (IS_ERR_OR_NULL(devs[i])) { 677 ret = PTR_ERR(devs[i]) ? : -ENODATA; 678 goto unroll_attach; 679 } 680 } 681 682 return num_pds; 683 684 unroll_attach: 685 for (i--; i >= 0; i--) 686 dev_pm_domain_detach(devs[i], false); 687 688 return ret; 689 }; 690 691 static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_t pd_count) 692 { 693 struct device *dev = pas->dev; 694 int i; 695 696 /* Handle single power domain */ 697 if (pd_count == 1 && dev->pm_domain) { 698 pm_runtime_disable(dev); 699 return; 700 } 701 702 for (i = 0; i < pd_count; i++) 703 dev_pm_domain_detach(pds[i], false); 704 } 705 706 static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) 707 { 708 struct resource res; 709 int ret; 710 711 ret = of_reserved_mem_region_to_resource(pas->dev->of_node, 0, &res); 712 if (ret) { 713 dev_err(pas->dev, "unable to resolve memory-region\n"); 714 return ret; 715 } 716 717 pas->mem_phys = pas->mem_reloc = res.start; 718 pas->mem_size = resource_size(&res); 719 720 pas->pas_ctx = devm_qcom_pas_context_alloc(pas->dev, pas->pas_id, 721 pas->mem_phys, pas->mem_size); 722 if (IS_ERR(pas->pas_ctx)) 723 return PTR_ERR(pas->pas_ctx); 724 725 if (!pas->dtb_pas_id) 726 return 0; 727 728 ret = of_reserved_mem_region_to_resource(pas->dev->of_node, 1, &res); 729 if (ret) { 730 dev_err(pas->dev, "unable to resolve dtb memory-region\n"); 731 return ret; 732 } 733 734 pas->dtb_mem_phys = pas->dtb_mem_reloc = res.start; 735 pas->dtb_mem_size = resource_size(&res); 736 737 pas->dtb_pas_ctx = devm_qcom_pas_context_alloc(pas->dev, pas->dtb_pas_id, 738 pas->dtb_mem_phys, 739 pas->dtb_mem_size); 740 if (IS_ERR(pas->dtb_pas_ctx)) 741 return PTR_ERR(pas->dtb_pas_ctx); 742 743 return 0; 744 } 745 746 static int qcom_pas_assign_memory_region(struct qcom_pas *pas) 747 { 748 struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT]; 749 unsigned int perm_size; 750 int offset; 751 int ret; 752 753 if (!pas->region_assign_idx) 754 return 0; 755 756 for (offset = 0; offset < pas->region_assign_count; ++offset) { 757 struct resource res; 758 759 ret = of_reserved_mem_region_to_resource(pas->dev->of_node, 760 pas->region_assign_idx + offset, 761 &res); 762 if (ret) { 763 dev_err(pas->dev, "unable to resolve shareable memory-region index %d\n", 764 offset); 765 return ret; 766 } 767 768 if (pas->region_assign_shared) { 769 perm[0].vmid = QCOM_SCM_VMID_HLOS; 770 perm[0].perm = QCOM_SCM_PERM_RW; 771 perm[1].vmid = pas->region_assign_vmid; 772 perm[1].perm = QCOM_SCM_PERM_RW; 773 perm_size = 2; 774 } else { 775 perm[0].vmid = pas->region_assign_vmid; 776 perm[0].perm = QCOM_SCM_PERM_RW; 777 perm_size = 1; 778 } 779 780 pas->region_assign_phys[offset] = res.start; 781 pas->region_assign_size[offset] = resource_size(&res); 782 pas->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS); 783 784 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 785 pas->region_assign_size[offset], 786 &pas->region_assign_owners[offset], 787 perm, perm_size); 788 if (ret < 0) { 789 dev_err(pas->dev, "assign memory %d failed\n", offset); 790 return ret; 791 } 792 } 793 794 return 0; 795 } 796 797 static void qcom_pas_unassign_memory_region(struct qcom_pas *pas) 798 { 799 struct qcom_scm_vmperm perm; 800 int offset; 801 int ret; 802 803 if (!pas->region_assign_idx || pas->region_assign_shared) 804 return; 805 806 for (offset = 0; offset < pas->region_assign_count; ++offset) { 807 perm.vmid = QCOM_SCM_VMID_HLOS; 808 perm.perm = QCOM_SCM_PERM_RW; 809 810 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 811 pas->region_assign_size[offset], 812 &pas->region_assign_owners[offset], 813 &perm, 1); 814 if (ret < 0) 815 dev_err(pas->dev, "unassign memory %d failed\n", offset); 816 } 817 } 818 819 static int qcom_pas_probe(struct platform_device *pdev) 820 { 821 const struct qcom_pas_data *desc; 822 struct qcom_pas *pas; 823 struct rproc *rproc; 824 struct device_node *node; 825 const char *fw_name, *dtb_fw_name = NULL; 826 const struct rproc_ops *ops = &qcom_pas_ops; 827 int ret; 828 829 desc = of_device_get_match_data(&pdev->dev); 830 if (!desc) 831 return -EINVAL; 832 833 if (!qcom_pas_is_available()) 834 return -EPROBE_DEFER; 835 836 fw_name = desc->firmware_name; 837 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 838 &fw_name); 839 if (ret < 0 && ret != -EINVAL) 840 return ret; 841 842 if (desc->dtb_firmware_name) { 843 dtb_fw_name = desc->dtb_firmware_name; 844 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1, 845 &dtb_fw_name); 846 if (ret < 0 && ret != -EINVAL) 847 return ret; 848 } 849 850 if (desc->minidump_id) 851 ops = &qcom_pas_minidump_ops; 852 853 rproc = devm_rproc_alloc(&pdev->dev, desc->sysmon_name, ops, fw_name, sizeof(*pas)); 854 855 if (!rproc) { 856 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 857 return -ENOMEM; 858 } 859 860 rproc->has_iommu = of_property_present(pdev->dev.of_node, "iommus"); 861 rproc->auto_boot = desc->auto_boot; 862 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 863 864 pas = rproc->priv; 865 pas->dev = &pdev->dev; 866 pas->rproc = rproc; 867 pas->minidump_id = desc->minidump_id; 868 pas->pas_id = desc->pas_id; 869 pas->lite_pas_id = desc->lite_pas_id; 870 pas->lite_dtb_pas_id = desc->lite_dtb_pas_id; 871 pas->info_name = desc->sysmon_name; 872 pas->smem_host_id = desc->smem_host_id; 873 pas->decrypt_shutdown = desc->decrypt_shutdown; 874 pas->region_assign_idx = desc->region_assign_idx; 875 pas->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); 876 pas->region_assign_vmid = desc->region_assign_vmid; 877 pas->region_assign_shared = desc->region_assign_shared; 878 if (dtb_fw_name) { 879 pas->dtb_firmware_name = dtb_fw_name; 880 pas->dtb_pas_id = desc->dtb_pas_id; 881 } 882 platform_set_drvdata(pdev, pas); 883 884 ret = device_init_wakeup(pas->dev, true); 885 if (ret) 886 goto free_rproc; 887 888 ret = qcom_pas_alloc_memory_region(pas); 889 if (ret) 890 goto free_rproc; 891 892 ret = qcom_pas_assign_memory_region(pas); 893 if (ret) 894 goto free_rproc; 895 896 ret = qcom_pas_init_clock(pas); 897 if (ret) 898 goto unassign_mem; 899 900 ret = qcom_pas_init_regulator(pas); 901 if (ret) 902 goto unassign_mem; 903 904 ret = qcom_pas_pds_attach(&pdev->dev, pas->proxy_pds, desc->proxy_pd_names); 905 if (ret < 0) 906 goto unassign_mem; 907 pas->proxy_pd_count = ret; 908 909 ret = qcom_q6v5_init(&pas->q6v5, pdev, rproc, desc->crash_reason_smem, 910 desc->load_state, qcom_pas_handover); 911 if (ret) 912 goto detach_proxy_pds; 913 914 qcom_add_glink_subdev(rproc, &pas->glink_subdev, desc->ssr_name); 915 qcom_add_smd_subdev(rproc, &pas->smd_subdev); 916 qcom_add_pdm_subdev(rproc, &pas->pdm_subdev); 917 pas->sysmon = qcom_add_sysmon_subdev(rproc, desc->sysmon_name, desc->ssctl_id); 918 if (IS_ERR(pas->sysmon)) { 919 ret = PTR_ERR(pas->sysmon); 920 goto deinit_remove_pdm_smd_glink; 921 } 922 923 qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); 924 925 pas->pas_ctx->use_tzmem = desc->needs_tzmem || rproc->has_iommu; 926 if (pas->dtb_pas_id) 927 pas->dtb_pas_ctx->use_tzmem = desc->needs_tzmem || rproc->has_iommu; 928 929 if (desc->early_boot) 930 pas->rproc->state = RPROC_DETACHED; 931 932 ret = rproc_add(rproc); 933 if (ret) 934 goto remove_ssr_sysmon; 935 936 node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux"); 937 pas->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev); 938 of_node_put(node); 939 940 return 0; 941 942 remove_ssr_sysmon: 943 qcom_remove_ssr_subdev(rproc, &pas->ssr_subdev); 944 qcom_remove_sysmon_subdev(pas->sysmon); 945 deinit_remove_pdm_smd_glink: 946 qcom_remove_pdm_subdev(rproc, &pas->pdm_subdev); 947 qcom_remove_smd_subdev(rproc, &pas->smd_subdev); 948 qcom_remove_glink_subdev(rproc, &pas->glink_subdev); 949 qcom_q6v5_deinit(&pas->q6v5); 950 detach_proxy_pds: 951 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 952 unassign_mem: 953 qcom_pas_unassign_memory_region(pas); 954 free_rproc: 955 device_init_wakeup(pas->dev, false); 956 957 return ret; 958 } 959 960 static void qcom_pas_remove(struct platform_device *pdev) 961 { 962 struct qcom_pas *pas = platform_get_drvdata(pdev); 963 964 if (pas->bam_dmux) 965 of_platform_device_destroy(&pas->bam_dmux->dev, NULL); 966 967 rproc_del(pas->rproc); 968 969 qcom_q6v5_deinit(&pas->q6v5); 970 qcom_pas_unassign_memory_region(pas); 971 qcom_remove_glink_subdev(pas->rproc, &pas->glink_subdev); 972 qcom_remove_sysmon_subdev(pas->sysmon); 973 qcom_remove_smd_subdev(pas->rproc, &pas->smd_subdev); 974 qcom_remove_pdm_subdev(pas->rproc, &pas->pdm_subdev); 975 qcom_remove_ssr_subdev(pas->rproc, &pas->ssr_subdev); 976 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 977 device_init_wakeup(pas->dev, false); 978 } 979 980 static const struct qcom_pas_data adsp_resource_init = { 981 .crash_reason_smem = 423, 982 .firmware_name = "adsp.mdt", 983 .pas_id = 1, 984 .auto_boot = true, 985 .ssr_name = "lpass", 986 .sysmon_name = "adsp", 987 .ssctl_id = 0x14, 988 }; 989 990 static const struct qcom_pas_data sa8775p_adsp_resource = { 991 .crash_reason_smem = 423, 992 .firmware_name = "adsp.mbn", 993 .pas_id = 1, 994 .minidump_id = 5, 995 .auto_boot = true, 996 .proxy_pd_names = (char*[]){ 997 "lcx", 998 "lmx", 999 NULL 1000 }, 1001 .load_state = "adsp", 1002 .ssr_name = "lpass", 1003 .sysmon_name = "adsp", 1004 .ssctl_id = 0x14, 1005 }; 1006 1007 static const struct qcom_pas_data sdm845_adsp_resource_init = { 1008 .crash_reason_smem = 423, 1009 .firmware_name = "adsp.mdt", 1010 .pas_id = 1, 1011 .auto_boot = true, 1012 .load_state = "adsp", 1013 .ssr_name = "lpass", 1014 .sysmon_name = "adsp", 1015 .ssctl_id = 0x14, 1016 }; 1017 1018 static const struct qcom_pas_data sm6350_adsp_resource = { 1019 .crash_reason_smem = 423, 1020 .firmware_name = "adsp.mdt", 1021 .pas_id = 1, 1022 .auto_boot = true, 1023 .proxy_pd_names = (char*[]){ 1024 "lcx", 1025 "lmx", 1026 NULL 1027 }, 1028 .load_state = "adsp", 1029 .ssr_name = "lpass", 1030 .sysmon_name = "adsp", 1031 .ssctl_id = 0x14, 1032 }; 1033 1034 static const struct qcom_pas_data sm6375_mpss_resource = { 1035 .crash_reason_smem = 421, 1036 .firmware_name = "modem.mdt", 1037 .pas_id = 4, 1038 .minidump_id = 3, 1039 .auto_boot = false, 1040 .proxy_pd_names = (char*[]){ 1041 "cx", 1042 NULL 1043 }, 1044 .ssr_name = "mpss", 1045 .sysmon_name = "modem", 1046 .ssctl_id = 0x12, 1047 }; 1048 1049 static const struct qcom_pas_data sm8150_adsp_resource = { 1050 .crash_reason_smem = 423, 1051 .firmware_name = "adsp.mdt", 1052 .pas_id = 1, 1053 .auto_boot = true, 1054 .proxy_pd_names = (char*[]){ 1055 "cx", 1056 NULL 1057 }, 1058 .load_state = "adsp", 1059 .ssr_name = "lpass", 1060 .sysmon_name = "adsp", 1061 .ssctl_id = 0x14, 1062 }; 1063 1064 static const struct qcom_pas_data sm8250_adsp_resource = { 1065 .crash_reason_smem = 423, 1066 .firmware_name = "adsp.mdt", 1067 .pas_id = 1, 1068 .minidump_id = 5, 1069 .auto_boot = true, 1070 .proxy_pd_names = (char*[]){ 1071 "lcx", 1072 "lmx", 1073 NULL 1074 }, 1075 .load_state = "adsp", 1076 .ssr_name = "lpass", 1077 .sysmon_name = "adsp", 1078 .ssctl_id = 0x14, 1079 }; 1080 1081 static const struct qcom_pas_data sm8350_adsp_resource = { 1082 .crash_reason_smem = 423, 1083 .firmware_name = "adsp.mdt", 1084 .pas_id = 1, 1085 .auto_boot = true, 1086 .proxy_pd_names = (char*[]){ 1087 "lcx", 1088 "lmx", 1089 NULL 1090 }, 1091 .load_state = "adsp", 1092 .ssr_name = "lpass", 1093 .sysmon_name = "adsp", 1094 .ssctl_id = 0x14, 1095 }; 1096 1097 static const struct qcom_pas_data msm8996_adsp_resource = { 1098 .crash_reason_smem = 423, 1099 .firmware_name = "adsp.mdt", 1100 .pas_id = 1, 1101 .auto_boot = true, 1102 .proxy_pd_names = (char*[]){ 1103 "cx", 1104 NULL 1105 }, 1106 .ssr_name = "lpass", 1107 .sysmon_name = "adsp", 1108 .ssctl_id = 0x14, 1109 }; 1110 1111 static const struct qcom_pas_data cdsp_resource_init = { 1112 .crash_reason_smem = 601, 1113 .firmware_name = "cdsp.mdt", 1114 .pas_id = 18, 1115 .auto_boot = true, 1116 .ssr_name = "cdsp", 1117 .sysmon_name = "cdsp", 1118 .ssctl_id = 0x17, 1119 }; 1120 1121 static const struct qcom_pas_data sa8775p_cdsp0_resource = { 1122 .crash_reason_smem = 601, 1123 .firmware_name = "cdsp0.mbn", 1124 .pas_id = 18, 1125 .minidump_id = 7, 1126 .auto_boot = true, 1127 .proxy_pd_names = (char*[]){ 1128 "cx", 1129 "mxc", 1130 "nsp", 1131 NULL 1132 }, 1133 .load_state = "cdsp", 1134 .ssr_name = "cdsp", 1135 .sysmon_name = "cdsp", 1136 .ssctl_id = 0x17, 1137 }; 1138 1139 static const struct qcom_pas_data sa8775p_cdsp1_resource = { 1140 .crash_reason_smem = 633, 1141 .firmware_name = "cdsp1.mbn", 1142 .pas_id = 30, 1143 .minidump_id = 20, 1144 .auto_boot = true, 1145 .proxy_pd_names = (char*[]){ 1146 "cx", 1147 "mxc", 1148 "nsp", 1149 NULL 1150 }, 1151 .load_state = "nsp", 1152 .ssr_name = "cdsp1", 1153 .sysmon_name = "cdsp1", 1154 .ssctl_id = 0x20, 1155 }; 1156 1157 static const struct qcom_pas_data sdm845_cdsp_resource_init = { 1158 .crash_reason_smem = 601, 1159 .firmware_name = "cdsp.mdt", 1160 .pas_id = 18, 1161 .auto_boot = true, 1162 .load_state = "cdsp", 1163 .ssr_name = "cdsp", 1164 .sysmon_name = "cdsp", 1165 .ssctl_id = 0x17, 1166 }; 1167 1168 static const struct qcom_pas_data sm6350_cdsp_resource = { 1169 .crash_reason_smem = 601, 1170 .firmware_name = "cdsp.mdt", 1171 .pas_id = 18, 1172 .auto_boot = true, 1173 .proxy_pd_names = (char*[]){ 1174 "cx", 1175 "mx", 1176 NULL 1177 }, 1178 .load_state = "cdsp", 1179 .ssr_name = "cdsp", 1180 .sysmon_name = "cdsp", 1181 .ssctl_id = 0x17, 1182 }; 1183 1184 static const struct qcom_pas_data sm8150_cdsp_resource = { 1185 .crash_reason_smem = 601, 1186 .firmware_name = "cdsp.mdt", 1187 .pas_id = 18, 1188 .auto_boot = true, 1189 .proxy_pd_names = (char*[]){ 1190 "cx", 1191 NULL 1192 }, 1193 .load_state = "cdsp", 1194 .ssr_name = "cdsp", 1195 .sysmon_name = "cdsp", 1196 .ssctl_id = 0x17, 1197 }; 1198 1199 static const struct qcom_pas_data sm8250_cdsp_resource = { 1200 .crash_reason_smem = 601, 1201 .firmware_name = "cdsp.mdt", 1202 .pas_id = 18, 1203 .auto_boot = true, 1204 .proxy_pd_names = (char*[]){ 1205 "cx", 1206 NULL 1207 }, 1208 .load_state = "cdsp", 1209 .ssr_name = "cdsp", 1210 .sysmon_name = "cdsp", 1211 .ssctl_id = 0x17, 1212 }; 1213 1214 static const struct qcom_pas_data sc8280xp_nsp0_resource = { 1215 .crash_reason_smem = 601, 1216 .firmware_name = "cdsp.mdt", 1217 .pas_id = 18, 1218 .auto_boot = true, 1219 .proxy_pd_names = (char*[]){ 1220 "nsp", 1221 NULL 1222 }, 1223 .ssr_name = "cdsp0", 1224 .sysmon_name = "cdsp", 1225 .ssctl_id = 0x17, 1226 }; 1227 1228 static const struct qcom_pas_data sc8280xp_nsp1_resource = { 1229 .crash_reason_smem = 633, 1230 .firmware_name = "cdsp.mdt", 1231 .pas_id = 30, 1232 .auto_boot = true, 1233 .proxy_pd_names = (char*[]){ 1234 "nsp", 1235 NULL 1236 }, 1237 .ssr_name = "cdsp1", 1238 .sysmon_name = "cdsp1", 1239 .ssctl_id = 0x20, 1240 }; 1241 1242 static const struct qcom_pas_data x1e80100_adsp_resource = { 1243 .crash_reason_smem = 423, 1244 .firmware_name = "adsp.mdt", 1245 .dtb_firmware_name = "adsp_dtb.mdt", 1246 .pas_id = 1, 1247 .dtb_pas_id = 0x24, 1248 .lite_pas_id = 0x1f, 1249 .lite_dtb_pas_id = 0x29, 1250 .minidump_id = 5, 1251 .auto_boot = true, 1252 .proxy_pd_names = (char*[]){ 1253 "lcx", 1254 "lmx", 1255 NULL 1256 }, 1257 .load_state = "adsp", 1258 .ssr_name = "lpass", 1259 .sysmon_name = "adsp", 1260 .ssctl_id = 0x14, 1261 }; 1262 1263 static const struct qcom_pas_data x1e80100_cdsp_resource = { 1264 .crash_reason_smem = 601, 1265 .firmware_name = "cdsp.mdt", 1266 .dtb_firmware_name = "cdsp_dtb.mdt", 1267 .pas_id = 18, 1268 .dtb_pas_id = 0x25, 1269 .minidump_id = 7, 1270 .auto_boot = true, 1271 .proxy_pd_names = (char*[]){ 1272 "cx", 1273 "mxc", 1274 "nsp", 1275 NULL 1276 }, 1277 .load_state = "cdsp", 1278 .ssr_name = "cdsp", 1279 .sysmon_name = "cdsp", 1280 .ssctl_id = 0x17, 1281 }; 1282 1283 static const struct qcom_pas_data sm8350_cdsp_resource = { 1284 .crash_reason_smem = 601, 1285 .firmware_name = "cdsp.mdt", 1286 .pas_id = 18, 1287 .minidump_id = 7, 1288 .auto_boot = true, 1289 .proxy_pd_names = (char*[]){ 1290 "cx", 1291 "mxc", 1292 NULL 1293 }, 1294 .load_state = "cdsp", 1295 .ssr_name = "cdsp", 1296 .sysmon_name = "cdsp", 1297 .ssctl_id = 0x17, 1298 }; 1299 1300 static const struct qcom_pas_data sa8775p_gpdsp0_resource = { 1301 .crash_reason_smem = 640, 1302 .firmware_name = "gpdsp0.mbn", 1303 .pas_id = 39, 1304 .minidump_id = 21, 1305 .auto_boot = true, 1306 .proxy_pd_names = (char*[]){ 1307 "cx", 1308 "mxc", 1309 NULL 1310 }, 1311 .load_state = "gpdsp0", 1312 .ssr_name = "gpdsp0", 1313 .sysmon_name = "gpdsp0", 1314 .ssctl_id = 0x21, 1315 }; 1316 1317 static const struct qcom_pas_data sa8775p_gpdsp1_resource = { 1318 .crash_reason_smem = 641, 1319 .firmware_name = "gpdsp1.mbn", 1320 .pas_id = 40, 1321 .minidump_id = 22, 1322 .auto_boot = true, 1323 .proxy_pd_names = (char*[]){ 1324 "cx", 1325 "mxc", 1326 NULL 1327 }, 1328 .load_state = "gpdsp1", 1329 .ssr_name = "gpdsp1", 1330 .sysmon_name = "gpdsp1", 1331 .ssctl_id = 0x22, 1332 }; 1333 1334 static const struct qcom_pas_data mpss_resource_init = { 1335 .crash_reason_smem = 421, 1336 .firmware_name = "modem.mdt", 1337 .pas_id = 4, 1338 .minidump_id = 3, 1339 .auto_boot = false, 1340 .proxy_pd_names = (char*[]){ 1341 "cx", 1342 "mss", 1343 NULL 1344 }, 1345 .load_state = "modem", 1346 .ssr_name = "mpss", 1347 .sysmon_name = "modem", 1348 .ssctl_id = 0x12, 1349 }; 1350 1351 static const struct qcom_pas_data sc8180x_mpss_resource = { 1352 .crash_reason_smem = 421, 1353 .firmware_name = "modem.mdt", 1354 .pas_id = 4, 1355 .auto_boot = false, 1356 .proxy_pd_names = (char*[]){ 1357 "cx", 1358 NULL 1359 }, 1360 .load_state = "modem", 1361 .ssr_name = "mpss", 1362 .sysmon_name = "modem", 1363 .ssctl_id = 0x12, 1364 }; 1365 1366 static const struct qcom_pas_data msm8996_slpi_resource_init = { 1367 .crash_reason_smem = 424, 1368 .firmware_name = "slpi.mdt", 1369 .pas_id = 12, 1370 .auto_boot = true, 1371 .proxy_pd_names = (char*[]){ 1372 "ssc_cx", 1373 NULL 1374 }, 1375 .ssr_name = "dsps", 1376 .sysmon_name = "slpi", 1377 .ssctl_id = 0x16, 1378 }; 1379 1380 static const struct qcom_pas_data sdm845_slpi_resource_init = { 1381 .crash_reason_smem = 424, 1382 .firmware_name = "slpi.mdt", 1383 .pas_id = 12, 1384 .auto_boot = true, 1385 .proxy_pd_names = (char*[]){ 1386 "lcx", 1387 "lmx", 1388 NULL 1389 }, 1390 .load_state = "slpi", 1391 .ssr_name = "dsps", 1392 .sysmon_name = "slpi", 1393 .ssctl_id = 0x16, 1394 }; 1395 1396 static const struct qcom_pas_data wcss_resource_init = { 1397 .crash_reason_smem = 421, 1398 .firmware_name = "wcnss.mdt", 1399 .pas_id = 6, 1400 .auto_boot = true, 1401 .ssr_name = "mpss", 1402 .sysmon_name = "wcnss", 1403 .ssctl_id = 0x12, 1404 }; 1405 1406 static const struct qcom_pas_data sdx55_mpss_resource = { 1407 .crash_reason_smem = 421, 1408 .firmware_name = "modem.mdt", 1409 .pas_id = 4, 1410 .auto_boot = true, 1411 .proxy_pd_names = (char*[]){ 1412 "cx", 1413 "mss", 1414 NULL 1415 }, 1416 .ssr_name = "mpss", 1417 .sysmon_name = "modem", 1418 .ssctl_id = 0x22, 1419 }; 1420 1421 static const struct qcom_pas_data milos_cdsp_resource = { 1422 .crash_reason_smem = 601, 1423 .firmware_name = "cdsp.mbn", 1424 .dtb_firmware_name = "cdsp_dtb.mbn", 1425 .pas_id = 18, 1426 .dtb_pas_id = 0x25, 1427 .minidump_id = 7, 1428 .auto_boot = true, 1429 .proxy_pd_names = (char*[]){ 1430 "cx", 1431 "mx", 1432 NULL 1433 }, 1434 .load_state = "cdsp", 1435 .ssr_name = "cdsp", 1436 .sysmon_name = "cdsp", 1437 .ssctl_id = 0x17, 1438 .smem_host_id = 5, 1439 }; 1440 1441 static const struct qcom_pas_data nord_adsp_resource = { 1442 .crash_reason_smem = 423, 1443 .firmware_name = "adsp.mbn", 1444 .dtb_firmware_name = "adsp_dtb.mbn", 1445 .pas_id = 1, 1446 .dtb_pas_id = 36, 1447 .minidump_id = 5, 1448 .auto_boot = true, 1449 .early_boot = true, 1450 .proxy_pd_names = (char*[]){ 1451 "cx", 1452 "mx", 1453 NULL 1454 }, 1455 .load_state = "adsp", 1456 .ssr_name = "lpass", 1457 .sysmon_name = "adsp", 1458 .ssctl_id = 0x14, 1459 .smem_host_id = 2, 1460 }; 1461 1462 static const struct qcom_pas_data nord_cdsp0_resource = { 1463 .crash_reason_smem = 601, 1464 .firmware_name = "cdsp.mbn", 1465 .dtb_firmware_name = "cdsp_dtb.mbn", 1466 .pas_id = 18, 1467 .dtb_pas_id = 37, 1468 .minidump_id = 7, 1469 .auto_boot = true, 1470 .proxy_pd_names = (char*[]){ 1471 "cx", 1472 "mx", 1473 "nsp", 1474 NULL 1475 }, 1476 .load_state = "cdsp", 1477 .ssr_name = "cdsp0", 1478 .sysmon_name = "cdsp0", 1479 .ssctl_id = 0x17, 1480 .smem_host_id = 5, 1481 }; 1482 1483 static const struct qcom_pas_data nord_cdsp1_resource = { 1484 .crash_reason_smem = 633, 1485 .firmware_name = "cdsp1.mbn", 1486 .dtb_firmware_name = "cdsp1_dtb.mbn", 1487 .pas_id = 30, 1488 .dtb_pas_id = 59, 1489 .minidump_id = 20, 1490 .auto_boot = true, 1491 .proxy_pd_names = (char*[]){ 1492 "cx", 1493 "mx", 1494 "nsp", 1495 NULL 1496 }, 1497 .load_state = "cdsp1", 1498 .ssr_name = "cdsp1", 1499 .sysmon_name = "cdsp1", 1500 .ssctl_id = 0x20, 1501 .smem_host_id = 69, 1502 }; 1503 1504 static const struct qcom_pas_data nord_cdsp2_resource = { 1505 .crash_reason_smem = 665, 1506 .firmware_name = "cdsp2.mbn", 1507 .dtb_firmware_name = "cdsp2_dtb.mbn", 1508 .pas_id = 57, 1509 .dtb_pas_id = 60, 1510 .minidump_id = 29, 1511 .auto_boot = true, 1512 .proxy_pd_names = (char*[]){ 1513 "cx", 1514 "mx", 1515 "nsp", 1516 NULL 1517 }, 1518 .load_state = "cdsp2", 1519 .ssr_name = "cdsp2", 1520 .sysmon_name = "cdsp2", 1521 .ssctl_id = 0x1f, 1522 .smem_host_id = 133, 1523 }; 1524 1525 static const struct qcom_pas_data nord_cdsp3_resource = { 1526 .crash_reason_smem = 666, 1527 .firmware_name = "cdsp3.mbn", 1528 .dtb_firmware_name = "cdsp3_dtb.mbn", 1529 .pas_id = 58, 1530 .dtb_pas_id = 61, 1531 .minidump_id = 30, 1532 .auto_boot = true, 1533 .proxy_pd_names = (char*[]){ 1534 "cx", 1535 "mx", 1536 "nsp", 1537 NULL 1538 }, 1539 .load_state = "cdsp3", 1540 .ssr_name = "cdsp3", 1541 .sysmon_name = "cdsp3", 1542 .ssctl_id = 0x1a, 1543 .smem_host_id = 197, 1544 }; 1545 1546 static const struct qcom_pas_data sm8450_mpss_resource = { 1547 .crash_reason_smem = 421, 1548 .firmware_name = "modem.mdt", 1549 .pas_id = 4, 1550 .minidump_id = 3, 1551 .auto_boot = false, 1552 .decrypt_shutdown = true, 1553 .proxy_pd_names = (char*[]){ 1554 "cx", 1555 "mss", 1556 NULL 1557 }, 1558 .load_state = "modem", 1559 .ssr_name = "mpss", 1560 .sysmon_name = "modem", 1561 .ssctl_id = 0x12, 1562 }; 1563 1564 static const struct qcom_pas_data sm8550_adsp_resource = { 1565 .crash_reason_smem = 423, 1566 .firmware_name = "adsp.mdt", 1567 .dtb_firmware_name = "adsp_dtb.mdt", 1568 .pas_id = 1, 1569 .dtb_pas_id = 0x24, 1570 .minidump_id = 5, 1571 .auto_boot = true, 1572 .proxy_pd_names = (char*[]){ 1573 "lcx", 1574 "lmx", 1575 NULL 1576 }, 1577 .load_state = "adsp", 1578 .ssr_name = "lpass", 1579 .sysmon_name = "adsp", 1580 .ssctl_id = 0x14, 1581 .smem_host_id = 2, 1582 }; 1583 1584 static const struct qcom_pas_data sm8550_cdsp_resource = { 1585 .crash_reason_smem = 601, 1586 .firmware_name = "cdsp.mdt", 1587 .dtb_firmware_name = "cdsp_dtb.mdt", 1588 .pas_id = 18, 1589 .dtb_pas_id = 0x25, 1590 .minidump_id = 7, 1591 .auto_boot = true, 1592 .proxy_pd_names = (char*[]){ 1593 "cx", 1594 "mxc", 1595 "nsp", 1596 NULL 1597 }, 1598 .load_state = "cdsp", 1599 .ssr_name = "cdsp", 1600 .sysmon_name = "cdsp", 1601 .ssctl_id = 0x17, 1602 .smem_host_id = 5, 1603 }; 1604 1605 static const struct qcom_pas_data sm8550_mpss_resource = { 1606 .crash_reason_smem = 421, 1607 .firmware_name = "modem.mdt", 1608 .dtb_firmware_name = "modem_dtb.mdt", 1609 .pas_id = 4, 1610 .dtb_pas_id = 0x26, 1611 .minidump_id = 3, 1612 .auto_boot = false, 1613 .decrypt_shutdown = true, 1614 .proxy_pd_names = (char*[]){ 1615 "cx", 1616 "mss", 1617 NULL 1618 }, 1619 .load_state = "modem", 1620 .ssr_name = "mpss", 1621 .sysmon_name = "modem", 1622 .ssctl_id = 0x12, 1623 .smem_host_id = 1, 1624 .region_assign_idx = 2, 1625 .region_assign_count = 1, 1626 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1627 }; 1628 1629 static const struct qcom_pas_data sc7280_wpss_resource = { 1630 .crash_reason_smem = 626, 1631 .firmware_name = "wpss.mdt", 1632 .pas_id = 6, 1633 .minidump_id = 4, 1634 .auto_boot = false, 1635 .proxy_pd_names = (char*[]){ 1636 "cx", 1637 "mx", 1638 NULL 1639 }, 1640 .load_state = "wpss", 1641 .ssr_name = "wpss", 1642 .sysmon_name = "wpss", 1643 .ssctl_id = 0x19, 1644 }; 1645 1646 static const struct qcom_pas_data shikra_cdsp_resource = { 1647 .crash_reason_smem = 601, 1648 .firmware_name = "cdsp.mbn", 1649 .pas_id = 18, 1650 .minidump_id = 7, 1651 .auto_boot = true, 1652 .proxy_pd_names = (char *[]){ 1653 "cx", 1654 NULL 1655 }, 1656 .load_state = "cdsp", 1657 .ssr_name = "cdsp", 1658 .sysmon_name = "cdsp", 1659 .ssctl_id = 0x17, 1660 .smem_host_id = 5, 1661 }; 1662 1663 static const struct qcom_pas_data shikra_lpaicp_resource = { 1664 .crash_reason_smem = 682, 1665 .firmware_name = "lpaicp.mbn", 1666 .dtb_firmware_name = "lpaicp_dtb.mbn", 1667 .pas_id = 0x56, 1668 .dtb_pas_id = 0x57, 1669 .minidump_id = 0, 1670 .auto_boot = true, 1671 .ssr_name = "lpaicp", 1672 .sysmon_name = "lpaicp", 1673 }; 1674 1675 static const struct qcom_pas_data shikra_mpss_resource = { 1676 .crash_reason_smem = 421, 1677 .firmware_name = "qdsp6sw.mbn", 1678 .pas_id = 4, 1679 .minidump_id = 3, 1680 .auto_boot = false, 1681 .proxy_pd_names = (char *[]){ 1682 "cx", 1683 NULL 1684 }, 1685 .load_state = "modem", 1686 .ssr_name = "mpss", 1687 .sysmon_name = "modem", 1688 .ssctl_id = 0x12, 1689 }; 1690 1691 static const struct qcom_pas_data sm8650_cdsp_resource = { 1692 .crash_reason_smem = 601, 1693 .firmware_name = "cdsp.mdt", 1694 .dtb_firmware_name = "cdsp_dtb.mdt", 1695 .pas_id = 18, 1696 .dtb_pas_id = 0x25, 1697 .minidump_id = 7, 1698 .auto_boot = true, 1699 .proxy_pd_names = (char*[]){ 1700 "cx", 1701 "mxc", 1702 "nsp", 1703 NULL 1704 }, 1705 .load_state = "cdsp", 1706 .ssr_name = "cdsp", 1707 .sysmon_name = "cdsp", 1708 .ssctl_id = 0x17, 1709 .smem_host_id = 5, 1710 .region_assign_idx = 2, 1711 .region_assign_count = 1, 1712 .region_assign_shared = true, 1713 .region_assign_vmid = QCOM_SCM_VMID_CDSP, 1714 }; 1715 1716 static const struct qcom_pas_data sm8650_mpss_resource = { 1717 .crash_reason_smem = 421, 1718 .firmware_name = "modem.mdt", 1719 .dtb_firmware_name = "modem_dtb.mdt", 1720 .pas_id = 4, 1721 .dtb_pas_id = 0x26, 1722 .minidump_id = 3, 1723 .auto_boot = false, 1724 .decrypt_shutdown = true, 1725 .proxy_pd_names = (char*[]){ 1726 "cx", 1727 "mss", 1728 NULL 1729 }, 1730 .load_state = "modem", 1731 .ssr_name = "mpss", 1732 .sysmon_name = "modem", 1733 .ssctl_id = 0x12, 1734 .smem_host_id = 1, 1735 .region_assign_idx = 2, 1736 .region_assign_count = 3, 1737 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1738 }; 1739 1740 static const struct qcom_pas_data sm8750_mpss_resource = { 1741 .crash_reason_smem = 421, 1742 .firmware_name = "modem.mdt", 1743 .dtb_firmware_name = "modem_dtb.mdt", 1744 .pas_id = 4, 1745 .dtb_pas_id = 0x26, 1746 .minidump_id = 3, 1747 .auto_boot = false, 1748 .decrypt_shutdown = true, 1749 .proxy_pd_names = (char*[]){ 1750 "cx", 1751 "mss", 1752 NULL 1753 }, 1754 .load_state = "modem", 1755 .ssr_name = "mpss", 1756 .sysmon_name = "modem", 1757 .ssctl_id = 0x12, 1758 .smem_host_id = 1, 1759 .region_assign_idx = 2, 1760 .region_assign_count = 2, 1761 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1762 }; 1763 1764 static const struct qcom_pas_data kaanapali_soccp_resource = { 1765 .crash_reason_smem = 656, 1766 .firmware_name = "soccp.mbn", 1767 .dtb_firmware_name = "soccp_dtb.mbn", 1768 .pas_id = 51, 1769 .dtb_pas_id = 0x41, 1770 .proxy_pd_names = (char*[]){ 1771 "cx", 1772 "mx", 1773 NULL 1774 }, 1775 .ssr_name = "soccp", 1776 .sysmon_name = "soccp", 1777 .auto_boot = true, 1778 .early_boot = true, 1779 }; 1780 1781 static const struct qcom_pas_data glymur_soccp_resource = { 1782 .crash_reason_smem = 656, 1783 .firmware_name = "soccp.mbn", 1784 .dtb_firmware_name = "soccp_dtb.mbn", 1785 .pas_id = 51, 1786 .dtb_pas_id = 0x41, 1787 .proxy_pd_names = (char*[]){ 1788 "cx", 1789 "mx", 1790 NULL 1791 }, 1792 .ssr_name = "soccp", 1793 .sysmon_name = "soccp", 1794 .auto_boot = true, 1795 .early_boot = true, 1796 .needs_tzmem = true, 1797 }; 1798 1799 static const struct qcom_pas_data eliza_cdsp_resource = { 1800 .crash_reason_smem = 601, 1801 .firmware_name = "cdsp.mbn", 1802 .dtb_firmware_name = "cdsp_dtb.mbn", 1803 .pas_id = 18, 1804 .dtb_pas_id = 0x25, 1805 .minidump_id = 7, 1806 .auto_boot = true, 1807 .proxy_pd_names = (char*[]){ 1808 "cx", 1809 "mx", 1810 "nsp", 1811 NULL 1812 }, 1813 .load_state = "cdsp", 1814 .ssr_name = "cdsp", 1815 .sysmon_name = "cdsp", 1816 .ssctl_id = 0x17, 1817 .smem_host_id = 5, 1818 .region_assign_idx = 2, 1819 .region_assign_count = 1, 1820 .region_assign_shared = true, 1821 .region_assign_vmid = QCOM_SCM_VMID_CDSP, 1822 }; 1823 1824 static const struct of_device_id qcom_pas_of_match[] = { 1825 { .compatible = "qcom,eliza-adsp-pas", .data = &sm8550_adsp_resource }, 1826 { .compatible = "qcom,eliza-cdsp-pas", .data = &eliza_cdsp_resource }, 1827 { .compatible = "qcom,glymur-soccp-pas", .data = &glymur_soccp_resource }, 1828 { .compatible = "qcom,kaanapali-soccp-pas", .data = &kaanapali_soccp_resource }, 1829 { .compatible = "qcom,milos-adsp-pas", .data = &sm8550_adsp_resource }, 1830 { .compatible = "qcom,milos-cdsp-pas", .data = &milos_cdsp_resource }, 1831 { .compatible = "qcom,milos-mpss-pas", .data = &sm8450_mpss_resource }, 1832 { .compatible = "qcom,milos-wpss-pas", .data = &sc7280_wpss_resource }, 1833 { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource }, 1834 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource }, 1835 { .compatible = "qcom,msm8974-adsp-pil", .data = &msm8996_adsp_resource }, 1836 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource }, 1837 { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init }, 1838 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource }, 1839 { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init }, 1840 { .compatible = "qcom,nord-adsp-pas", .data = &nord_adsp_resource }, 1841 { .compatible = "qcom,nord-cdsp0-pas", .data = &nord_cdsp0_resource }, 1842 { .compatible = "qcom,nord-cdsp1-pas", .data = &nord_cdsp1_resource }, 1843 { .compatible = "qcom,nord-cdsp2-pas", .data = &nord_cdsp2_resource }, 1844 { .compatible = "qcom,nord-cdsp3-pas", .data = &nord_cdsp3_resource }, 1845 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, 1846 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, 1847 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, 1848 { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource }, 1849 { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource }, 1850 { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource }, 1851 { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource }, 1852 { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource }, 1853 { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource }, 1854 { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource }, 1855 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init }, 1856 { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource }, 1857 { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource }, 1858 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init }, 1859 { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource }, 1860 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource }, 1861 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource }, 1862 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource }, 1863 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource }, 1864 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource }, 1865 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource }, 1866 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init }, 1867 { .compatible = "qcom,sdm660-cdsp-pas", .data = &cdsp_resource_init }, 1868 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init }, 1869 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init }, 1870 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init }, 1871 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource }, 1872 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource }, 1873 { .compatible = "qcom,shikra-cdsp-pas", .data = &shikra_cdsp_resource }, 1874 { .compatible = "qcom,shikra-lpaicp-pas", .data = &shikra_lpaicp_resource }, 1875 { .compatible = "qcom,shikra-mpss-pas", .data = &shikra_mpss_resource }, 1876 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init }, 1877 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init }, 1878 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource }, 1879 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource }, 1880 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource }, 1881 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init }, 1882 { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource }, 1883 { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource }, 1884 { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource }, 1885 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource }, 1886 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource }, 1887 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init }, 1888 { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init }, 1889 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource }, 1890 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource }, 1891 { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init }, 1892 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource }, 1893 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource }, 1894 { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init }, 1895 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init }, 1896 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource }, 1897 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource }, 1898 { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init }, 1899 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource }, 1900 { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource }, 1901 { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource }, 1902 { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource }, 1903 { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource }, 1904 { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource }, 1905 { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource }, 1906 { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource }, 1907 { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource }, 1908 { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource }, 1909 { }, 1910 }; 1911 MODULE_DEVICE_TABLE(of, qcom_pas_of_match); 1912 1913 static struct platform_driver qcom_pas_driver = { 1914 .probe = qcom_pas_probe, 1915 .remove = qcom_pas_remove, 1916 .driver = { 1917 .name = "qcom_q6v5_pas", 1918 .of_match_table = qcom_pas_of_match, 1919 }, 1920 }; 1921 1922 module_platform_driver(qcom_pas_driver); 1923 MODULE_DESCRIPTION("Qualcomm Peripheral Authentication Service remoteproc driver"); 1924 MODULE_LICENSE("GPL v2"); 1925