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/kernel.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/of_address.h> 18 #include <linux/of_reserved_mem.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm_domain.h> 21 #include <linux/pm_runtime.h> 22 #include <linux/firmware/qcom/qcom_scm.h> 23 #include <linux/regulator/consumer.h> 24 #include <linux/remoteproc.h> 25 #include <linux/soc/qcom/mdt_loader.h> 26 #include <linux/soc/qcom/smem.h> 27 #include <linux/soc/qcom/smem_state.h> 28 29 #include "qcom_common.h" 30 #include "qcom_pil_info.h" 31 #include "qcom_q6v5.h" 32 #include "remoteproc_internal.h" 33 34 #define QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS 100 35 36 #define MAX_ASSIGN_COUNT 3 37 38 struct qcom_pas_data { 39 int crash_reason_smem; 40 const char *firmware_name; 41 const char *dtb_firmware_name; 42 int pas_id; 43 int dtb_pas_id; 44 int lite_pas_id; 45 unsigned int minidump_id; 46 bool auto_boot; 47 bool decrypt_shutdown; 48 49 char **proxy_pd_names; 50 51 const char *load_state; 52 const char *ssr_name; 53 const char *sysmon_name; 54 int ssctl_id; 55 unsigned int smem_host_id; 56 57 int region_assign_idx; 58 int region_assign_count; 59 bool region_assign_shared; 60 int region_assign_vmid; 61 }; 62 63 struct qcom_pas { 64 struct device *dev; 65 struct rproc *rproc; 66 67 struct qcom_q6v5 q6v5; 68 69 struct clk *xo; 70 struct clk *aggre2_clk; 71 72 struct regulator *cx_supply; 73 struct regulator *px_supply; 74 75 struct device *proxy_pds[3]; 76 77 int proxy_pd_count; 78 79 const char *dtb_firmware_name; 80 int pas_id; 81 int dtb_pas_id; 82 int lite_pas_id; 83 unsigned int minidump_id; 84 int crash_reason_smem; 85 unsigned int smem_host_id; 86 bool decrypt_shutdown; 87 const char *info_name; 88 89 const struct firmware *firmware; 90 const struct firmware *dtb_firmware; 91 92 struct completion start_done; 93 struct completion stop_done; 94 95 phys_addr_t mem_phys; 96 phys_addr_t dtb_mem_phys; 97 phys_addr_t mem_reloc; 98 phys_addr_t dtb_mem_reloc; 99 phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT]; 100 void *mem_region; 101 void *dtb_mem_region; 102 size_t mem_size; 103 size_t dtb_mem_size; 104 size_t region_assign_size[MAX_ASSIGN_COUNT]; 105 106 int region_assign_idx; 107 int region_assign_count; 108 bool region_assign_shared; 109 int region_assign_vmid; 110 u64 region_assign_owners[MAX_ASSIGN_COUNT]; 111 112 struct qcom_rproc_glink glink_subdev; 113 struct qcom_rproc_subdev smd_subdev; 114 struct qcom_rproc_pdm pdm_subdev; 115 struct qcom_rproc_ssr ssr_subdev; 116 struct qcom_sysmon *sysmon; 117 118 struct qcom_scm_pas_metadata pas_metadata; 119 struct qcom_scm_pas_metadata dtb_pas_metadata; 120 }; 121 122 static void qcom_pas_segment_dump(struct rproc *rproc, 123 struct rproc_dump_segment *segment, 124 void *dest, size_t offset, size_t size) 125 { 126 struct qcom_pas *pas = rproc->priv; 127 int total_offset; 128 129 total_offset = segment->da + segment->offset + offset - pas->mem_phys; 130 if (total_offset < 0 || total_offset + size > pas->mem_size) { 131 dev_err(pas->dev, 132 "invalid copy request for segment %pad with offset %zu and size %zu)\n", 133 &segment->da, offset, size); 134 memset(dest, 0xff, size); 135 return; 136 } 137 138 memcpy_fromio(dest, pas->mem_region + total_offset, size); 139 } 140 141 static void qcom_pas_minidump(struct rproc *rproc) 142 { 143 struct qcom_pas *pas = rproc->priv; 144 145 if (rproc->dump_conf == RPROC_COREDUMP_DISABLED) 146 return; 147 148 qcom_minidump(rproc, pas->minidump_id, qcom_pas_segment_dump); 149 } 150 151 static int qcom_pas_pds_enable(struct qcom_pas *pas, struct device **pds, 152 size_t pd_count) 153 { 154 int ret; 155 int i; 156 157 for (i = 0; i < pd_count; i++) { 158 dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 159 ret = pm_runtime_get_sync(pds[i]); 160 if (ret < 0) { 161 pm_runtime_put_noidle(pds[i]); 162 dev_pm_genpd_set_performance_state(pds[i], 0); 163 goto unroll_pd_votes; 164 } 165 } 166 167 return 0; 168 169 unroll_pd_votes: 170 for (i--; i >= 0; i--) { 171 dev_pm_genpd_set_performance_state(pds[i], 0); 172 pm_runtime_put(pds[i]); 173 } 174 175 return ret; 176 }; 177 178 static void qcom_pas_pds_disable(struct qcom_pas *pas, struct device **pds, 179 size_t pd_count) 180 { 181 int i; 182 183 for (i = 0; i < pd_count; i++) { 184 dev_pm_genpd_set_performance_state(pds[i], 0); 185 pm_runtime_put(pds[i]); 186 } 187 } 188 189 static int qcom_pas_shutdown_poll_decrypt(struct qcom_pas *pas) 190 { 191 unsigned int retry_num = 50; 192 int ret; 193 194 do { 195 msleep(QCOM_PAS_DECRYPT_SHUTDOWN_DELAY_MS); 196 ret = qcom_scm_pas_shutdown(pas->pas_id); 197 } while (ret == -EINVAL && --retry_num); 198 199 return ret; 200 } 201 202 static int qcom_pas_unprepare(struct rproc *rproc) 203 { 204 struct qcom_pas *pas = rproc->priv; 205 206 /* 207 * qcom_pas_load() did pass pas_metadata to the SCM driver for storing 208 * metadata context. It might have been released already if 209 * auth_and_reset() was successful, but in other cases clean it up 210 * here. 211 */ 212 qcom_scm_pas_metadata_release(&pas->pas_metadata); 213 if (pas->dtb_pas_id) 214 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 215 216 return 0; 217 } 218 219 static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) 220 { 221 struct qcom_pas *pas = rproc->priv; 222 int ret; 223 224 /* Store firmware handle to be used in qcom_pas_start() */ 225 pas->firmware = fw; 226 227 if (pas->lite_pas_id) 228 ret = qcom_scm_pas_shutdown(pas->lite_pas_id); 229 230 if (pas->dtb_pas_id) { 231 ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); 232 if (ret) { 233 dev_err(pas->dev, "request_firmware failed for %s: %d\n", 234 pas->dtb_firmware_name, ret); 235 return ret; 236 } 237 238 ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, 239 pas->dtb_pas_id, pas->dtb_mem_phys, 240 &pas->dtb_pas_metadata); 241 if (ret) 242 goto release_dtb_firmware; 243 244 ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name, 245 pas->dtb_mem_region, pas->dtb_mem_phys, 246 pas->dtb_mem_size, &pas->dtb_mem_reloc); 247 if (ret) 248 goto release_dtb_metadata; 249 } 250 251 return 0; 252 253 release_dtb_metadata: 254 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 255 256 release_dtb_firmware: 257 release_firmware(pas->dtb_firmware); 258 259 return ret; 260 } 261 262 static int qcom_pas_start(struct rproc *rproc) 263 { 264 struct qcom_pas *pas = rproc->priv; 265 int ret; 266 267 ret = qcom_q6v5_prepare(&pas->q6v5); 268 if (ret) 269 return ret; 270 271 ret = qcom_pas_pds_enable(pas, pas->proxy_pds, pas->proxy_pd_count); 272 if (ret < 0) 273 goto disable_irqs; 274 275 ret = clk_prepare_enable(pas->xo); 276 if (ret) 277 goto disable_proxy_pds; 278 279 ret = clk_prepare_enable(pas->aggre2_clk); 280 if (ret) 281 goto disable_xo_clk; 282 283 if (pas->cx_supply) { 284 ret = regulator_enable(pas->cx_supply); 285 if (ret) 286 goto disable_aggre2_clk; 287 } 288 289 if (pas->px_supply) { 290 ret = regulator_enable(pas->px_supply); 291 if (ret) 292 goto disable_cx_supply; 293 } 294 295 if (pas->dtb_pas_id) { 296 ret = qcom_scm_pas_auth_and_reset(pas->dtb_pas_id); 297 if (ret) { 298 dev_err(pas->dev, 299 "failed to authenticate dtb image and release reset\n"); 300 goto disable_px_supply; 301 } 302 } 303 304 ret = qcom_mdt_pas_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id, 305 pas->mem_phys, &pas->pas_metadata); 306 if (ret) 307 goto disable_px_supply; 308 309 ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, 310 pas->mem_region, pas->mem_phys, pas->mem_size, 311 &pas->mem_reloc); 312 if (ret) 313 goto release_pas_metadata; 314 315 qcom_pil_info_store(pas->info_name, pas->mem_phys, pas->mem_size); 316 317 ret = qcom_scm_pas_auth_and_reset(pas->pas_id); 318 if (ret) { 319 dev_err(pas->dev, 320 "failed to authenticate image and release reset\n"); 321 goto release_pas_metadata; 322 } 323 324 ret = qcom_q6v5_wait_for_start(&pas->q6v5, msecs_to_jiffies(5000)); 325 if (ret == -ETIMEDOUT) { 326 dev_err(pas->dev, "start timed out\n"); 327 qcom_scm_pas_shutdown(pas->pas_id); 328 goto release_pas_metadata; 329 } 330 331 qcom_scm_pas_metadata_release(&pas->pas_metadata); 332 if (pas->dtb_pas_id) 333 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 334 335 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 336 pas->firmware = NULL; 337 338 return 0; 339 340 release_pas_metadata: 341 qcom_scm_pas_metadata_release(&pas->pas_metadata); 342 if (pas->dtb_pas_id) 343 qcom_scm_pas_metadata_release(&pas->dtb_pas_metadata); 344 disable_px_supply: 345 if (pas->px_supply) 346 regulator_disable(pas->px_supply); 347 disable_cx_supply: 348 if (pas->cx_supply) 349 regulator_disable(pas->cx_supply); 350 disable_aggre2_clk: 351 clk_disable_unprepare(pas->aggre2_clk); 352 disable_xo_clk: 353 clk_disable_unprepare(pas->xo); 354 disable_proxy_pds: 355 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 356 disable_irqs: 357 qcom_q6v5_unprepare(&pas->q6v5); 358 359 /* firmware is used to pass reference from qcom_pas_start(), drop it now */ 360 pas->firmware = NULL; 361 362 return ret; 363 } 364 365 static void qcom_pas_handover(struct qcom_q6v5 *q6v5) 366 { 367 struct qcom_pas *pas = container_of(q6v5, struct qcom_pas, q6v5); 368 369 if (pas->px_supply) 370 regulator_disable(pas->px_supply); 371 if (pas->cx_supply) 372 regulator_disable(pas->cx_supply); 373 clk_disable_unprepare(pas->aggre2_clk); 374 clk_disable_unprepare(pas->xo); 375 qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); 376 } 377 378 static int qcom_pas_stop(struct rproc *rproc) 379 { 380 struct qcom_pas *pas = rproc->priv; 381 int handover; 382 int ret; 383 384 ret = qcom_q6v5_request_stop(&pas->q6v5, pas->sysmon); 385 if (ret == -ETIMEDOUT) 386 dev_err(pas->dev, "timed out on wait\n"); 387 388 ret = qcom_scm_pas_shutdown(pas->pas_id); 389 if (ret && pas->decrypt_shutdown) 390 ret = qcom_pas_shutdown_poll_decrypt(pas); 391 392 if (ret) 393 dev_err(pas->dev, "failed to shutdown: %d\n", ret); 394 395 if (pas->dtb_pas_id) { 396 ret = qcom_scm_pas_shutdown(pas->dtb_pas_id); 397 if (ret) 398 dev_err(pas->dev, "failed to shutdown dtb: %d\n", ret); 399 } 400 401 handover = qcom_q6v5_unprepare(&pas->q6v5); 402 if (handover) 403 qcom_pas_handover(&pas->q6v5); 404 405 if (pas->smem_host_id) 406 ret = qcom_smem_bust_hwspin_lock_by_host(pas->smem_host_id); 407 408 return ret; 409 } 410 411 static void *qcom_pas_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem) 412 { 413 struct qcom_pas *pas = rproc->priv; 414 int offset; 415 416 offset = da - pas->mem_reloc; 417 if (offset < 0 || offset + len > pas->mem_size) 418 return NULL; 419 420 if (is_iomem) 421 *is_iomem = true; 422 423 return pas->mem_region + offset; 424 } 425 426 static unsigned long qcom_pas_panic(struct rproc *rproc) 427 { 428 struct qcom_pas *pas = rproc->priv; 429 430 return qcom_q6v5_panic(&pas->q6v5); 431 } 432 433 static const struct rproc_ops qcom_pas_ops = { 434 .unprepare = qcom_pas_unprepare, 435 .start = qcom_pas_start, 436 .stop = qcom_pas_stop, 437 .da_to_va = qcom_pas_da_to_va, 438 .parse_fw = qcom_register_dump_segments, 439 .load = qcom_pas_load, 440 .panic = qcom_pas_panic, 441 }; 442 443 static const struct rproc_ops qcom_pas_minidump_ops = { 444 .unprepare = qcom_pas_unprepare, 445 .start = qcom_pas_start, 446 .stop = qcom_pas_stop, 447 .da_to_va = qcom_pas_da_to_va, 448 .parse_fw = qcom_register_dump_segments, 449 .load = qcom_pas_load, 450 .panic = qcom_pas_panic, 451 .coredump = qcom_pas_minidump, 452 }; 453 454 static int qcom_pas_init_clock(struct qcom_pas *pas) 455 { 456 pas->xo = devm_clk_get(pas->dev, "xo"); 457 if (IS_ERR(pas->xo)) 458 return dev_err_probe(pas->dev, PTR_ERR(pas->xo), 459 "failed to get xo clock"); 460 461 pas->aggre2_clk = devm_clk_get_optional(pas->dev, "aggre2"); 462 if (IS_ERR(pas->aggre2_clk)) 463 return dev_err_probe(pas->dev, PTR_ERR(pas->aggre2_clk), 464 "failed to get aggre2 clock"); 465 466 return 0; 467 } 468 469 static int qcom_pas_init_regulator(struct qcom_pas *pas) 470 { 471 pas->cx_supply = devm_regulator_get_optional(pas->dev, "cx"); 472 if (IS_ERR(pas->cx_supply)) { 473 if (PTR_ERR(pas->cx_supply) == -ENODEV) 474 pas->cx_supply = NULL; 475 else 476 return PTR_ERR(pas->cx_supply); 477 } 478 479 if (pas->cx_supply) 480 regulator_set_load(pas->cx_supply, 100000); 481 482 pas->px_supply = devm_regulator_get_optional(pas->dev, "px"); 483 if (IS_ERR(pas->px_supply)) { 484 if (PTR_ERR(pas->px_supply) == -ENODEV) 485 pas->px_supply = NULL; 486 else 487 return PTR_ERR(pas->px_supply); 488 } 489 490 return 0; 491 } 492 493 static int qcom_pas_pds_attach(struct device *dev, struct device **devs, char **pd_names) 494 { 495 size_t num_pds = 0; 496 int ret; 497 int i; 498 499 if (!pd_names) 500 return 0; 501 502 while (pd_names[num_pds]) 503 num_pds++; 504 505 /* Handle single power domain */ 506 if (num_pds == 1 && dev->pm_domain) { 507 devs[0] = dev; 508 pm_runtime_enable(dev); 509 return 1; 510 } 511 512 for (i = 0; i < num_pds; i++) { 513 devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 514 if (IS_ERR_OR_NULL(devs[i])) { 515 ret = PTR_ERR(devs[i]) ? : -ENODATA; 516 goto unroll_attach; 517 } 518 } 519 520 return num_pds; 521 522 unroll_attach: 523 for (i--; i >= 0; i--) 524 dev_pm_domain_detach(devs[i], false); 525 526 return ret; 527 }; 528 529 static void qcom_pas_pds_detach(struct qcom_pas *pas, struct device **pds, size_t pd_count) 530 { 531 struct device *dev = pas->dev; 532 int i; 533 534 /* Handle single power domain */ 535 if (pd_count == 1 && dev->pm_domain) { 536 pm_runtime_disable(dev); 537 return; 538 } 539 540 for (i = 0; i < pd_count; i++) 541 dev_pm_domain_detach(pds[i], false); 542 } 543 544 static int qcom_pas_alloc_memory_region(struct qcom_pas *pas) 545 { 546 struct reserved_mem *rmem; 547 struct device_node *node; 548 549 node = of_parse_phandle(pas->dev->of_node, "memory-region", 0); 550 if (!node) { 551 dev_err(pas->dev, "no memory-region specified\n"); 552 return -EINVAL; 553 } 554 555 rmem = of_reserved_mem_lookup(node); 556 of_node_put(node); 557 if (!rmem) { 558 dev_err(pas->dev, "unable to resolve memory-region\n"); 559 return -EINVAL; 560 } 561 562 pas->mem_phys = pas->mem_reloc = rmem->base; 563 pas->mem_size = rmem->size; 564 pas->mem_region = devm_ioremap_wc(pas->dev, pas->mem_phys, pas->mem_size); 565 if (!pas->mem_region) { 566 dev_err(pas->dev, "unable to map memory region: %pa+%zx\n", 567 &rmem->base, pas->mem_size); 568 return -EBUSY; 569 } 570 571 if (!pas->dtb_pas_id) 572 return 0; 573 574 node = of_parse_phandle(pas->dev->of_node, "memory-region", 1); 575 if (!node) { 576 dev_err(pas->dev, "no dtb memory-region specified\n"); 577 return -EINVAL; 578 } 579 580 rmem = of_reserved_mem_lookup(node); 581 of_node_put(node); 582 if (!rmem) { 583 dev_err(pas->dev, "unable to resolve dtb memory-region\n"); 584 return -EINVAL; 585 } 586 587 pas->dtb_mem_phys = pas->dtb_mem_reloc = rmem->base; 588 pas->dtb_mem_size = rmem->size; 589 pas->dtb_mem_region = devm_ioremap_wc(pas->dev, pas->dtb_mem_phys, pas->dtb_mem_size); 590 if (!pas->dtb_mem_region) { 591 dev_err(pas->dev, "unable to map dtb memory region: %pa+%zx\n", 592 &rmem->base, pas->dtb_mem_size); 593 return -EBUSY; 594 } 595 596 return 0; 597 } 598 599 static int qcom_pas_assign_memory_region(struct qcom_pas *pas) 600 { 601 struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT]; 602 struct device_node *node; 603 unsigned int perm_size; 604 int offset; 605 int ret; 606 607 if (!pas->region_assign_idx) 608 return 0; 609 610 for (offset = 0; offset < pas->region_assign_count; ++offset) { 611 struct reserved_mem *rmem = NULL; 612 613 node = of_parse_phandle(pas->dev->of_node, "memory-region", 614 pas->region_assign_idx + offset); 615 if (node) 616 rmem = of_reserved_mem_lookup(node); 617 of_node_put(node); 618 if (!rmem) { 619 dev_err(pas->dev, "unable to resolve shareable memory-region index %d\n", 620 offset); 621 return -EINVAL; 622 } 623 624 if (pas->region_assign_shared) { 625 perm[0].vmid = QCOM_SCM_VMID_HLOS; 626 perm[0].perm = QCOM_SCM_PERM_RW; 627 perm[1].vmid = pas->region_assign_vmid; 628 perm[1].perm = QCOM_SCM_PERM_RW; 629 perm_size = 2; 630 } else { 631 perm[0].vmid = pas->region_assign_vmid; 632 perm[0].perm = QCOM_SCM_PERM_RW; 633 perm_size = 1; 634 } 635 636 pas->region_assign_phys[offset] = rmem->base; 637 pas->region_assign_size[offset] = rmem->size; 638 pas->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS); 639 640 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 641 pas->region_assign_size[offset], 642 &pas->region_assign_owners[offset], 643 perm, perm_size); 644 if (ret < 0) { 645 dev_err(pas->dev, "assign memory %d failed\n", offset); 646 return ret; 647 } 648 } 649 650 return 0; 651 } 652 653 static void qcom_pas_unassign_memory_region(struct qcom_pas *pas) 654 { 655 struct qcom_scm_vmperm perm; 656 int offset; 657 int ret; 658 659 if (!pas->region_assign_idx || pas->region_assign_shared) 660 return; 661 662 for (offset = 0; offset < pas->region_assign_count; ++offset) { 663 perm.vmid = QCOM_SCM_VMID_HLOS; 664 perm.perm = QCOM_SCM_PERM_RW; 665 666 ret = qcom_scm_assign_mem(pas->region_assign_phys[offset], 667 pas->region_assign_size[offset], 668 &pas->region_assign_owners[offset], 669 &perm, 1); 670 if (ret < 0) 671 dev_err(pas->dev, "unassign memory %d failed\n", offset); 672 } 673 } 674 675 static int qcom_pas_probe(struct platform_device *pdev) 676 { 677 const struct qcom_pas_data *desc; 678 struct qcom_pas *pas; 679 struct rproc *rproc; 680 const char *fw_name, *dtb_fw_name = NULL; 681 const struct rproc_ops *ops = &qcom_pas_ops; 682 int ret; 683 684 desc = of_device_get_match_data(&pdev->dev); 685 if (!desc) 686 return -EINVAL; 687 688 if (!qcom_scm_is_available()) 689 return -EPROBE_DEFER; 690 691 fw_name = desc->firmware_name; 692 ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 693 &fw_name); 694 if (ret < 0 && ret != -EINVAL) 695 return ret; 696 697 if (desc->dtb_firmware_name) { 698 dtb_fw_name = desc->dtb_firmware_name; 699 ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1, 700 &dtb_fw_name); 701 if (ret < 0 && ret != -EINVAL) 702 return ret; 703 } 704 705 if (desc->minidump_id) 706 ops = &qcom_pas_minidump_ops; 707 708 rproc = devm_rproc_alloc(&pdev->dev, desc->sysmon_name, ops, fw_name, sizeof(*pas)); 709 710 if (!rproc) { 711 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 712 return -ENOMEM; 713 } 714 715 rproc->auto_boot = desc->auto_boot; 716 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 717 718 pas = rproc->priv; 719 pas->dev = &pdev->dev; 720 pas->rproc = rproc; 721 pas->minidump_id = desc->minidump_id; 722 pas->pas_id = desc->pas_id; 723 pas->lite_pas_id = desc->lite_pas_id; 724 pas->info_name = desc->sysmon_name; 725 pas->smem_host_id = desc->smem_host_id; 726 pas->decrypt_shutdown = desc->decrypt_shutdown; 727 pas->region_assign_idx = desc->region_assign_idx; 728 pas->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); 729 pas->region_assign_vmid = desc->region_assign_vmid; 730 pas->region_assign_shared = desc->region_assign_shared; 731 if (dtb_fw_name) { 732 pas->dtb_firmware_name = dtb_fw_name; 733 pas->dtb_pas_id = desc->dtb_pas_id; 734 } 735 platform_set_drvdata(pdev, pas); 736 737 ret = device_init_wakeup(pas->dev, true); 738 if (ret) 739 goto free_rproc; 740 741 ret = qcom_pas_alloc_memory_region(pas); 742 if (ret) 743 goto free_rproc; 744 745 ret = qcom_pas_assign_memory_region(pas); 746 if (ret) 747 goto free_rproc; 748 749 ret = qcom_pas_init_clock(pas); 750 if (ret) 751 goto unassign_mem; 752 753 ret = qcom_pas_init_regulator(pas); 754 if (ret) 755 goto unassign_mem; 756 757 ret = qcom_pas_pds_attach(&pdev->dev, pas->proxy_pds, desc->proxy_pd_names); 758 if (ret < 0) 759 goto unassign_mem; 760 pas->proxy_pd_count = ret; 761 762 ret = qcom_q6v5_init(&pas->q6v5, pdev, rproc, desc->crash_reason_smem, 763 desc->load_state, qcom_pas_handover); 764 if (ret) 765 goto detach_proxy_pds; 766 767 qcom_add_glink_subdev(rproc, &pas->glink_subdev, desc->ssr_name); 768 qcom_add_smd_subdev(rproc, &pas->smd_subdev); 769 qcom_add_pdm_subdev(rproc, &pas->pdm_subdev); 770 pas->sysmon = qcom_add_sysmon_subdev(rproc, desc->sysmon_name, desc->ssctl_id); 771 if (IS_ERR(pas->sysmon)) { 772 ret = PTR_ERR(pas->sysmon); 773 goto deinit_remove_pdm_smd_glink; 774 } 775 776 qcom_add_ssr_subdev(rproc, &pas->ssr_subdev, desc->ssr_name); 777 ret = rproc_add(rproc); 778 if (ret) 779 goto remove_ssr_sysmon; 780 781 return 0; 782 783 remove_ssr_sysmon: 784 qcom_remove_ssr_subdev(rproc, &pas->ssr_subdev); 785 qcom_remove_sysmon_subdev(pas->sysmon); 786 deinit_remove_pdm_smd_glink: 787 qcom_remove_pdm_subdev(rproc, &pas->pdm_subdev); 788 qcom_remove_smd_subdev(rproc, &pas->smd_subdev); 789 qcom_remove_glink_subdev(rproc, &pas->glink_subdev); 790 qcom_q6v5_deinit(&pas->q6v5); 791 detach_proxy_pds: 792 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 793 unassign_mem: 794 qcom_pas_unassign_memory_region(pas); 795 free_rproc: 796 device_init_wakeup(pas->dev, false); 797 798 return ret; 799 } 800 801 static void qcom_pas_remove(struct platform_device *pdev) 802 { 803 struct qcom_pas *pas = platform_get_drvdata(pdev); 804 805 rproc_del(pas->rproc); 806 807 qcom_q6v5_deinit(&pas->q6v5); 808 qcom_pas_unassign_memory_region(pas); 809 qcom_remove_glink_subdev(pas->rproc, &pas->glink_subdev); 810 qcom_remove_sysmon_subdev(pas->sysmon); 811 qcom_remove_smd_subdev(pas->rproc, &pas->smd_subdev); 812 qcom_remove_pdm_subdev(pas->rproc, &pas->pdm_subdev); 813 qcom_remove_ssr_subdev(pas->rproc, &pas->ssr_subdev); 814 qcom_pas_pds_detach(pas, pas->proxy_pds, pas->proxy_pd_count); 815 device_init_wakeup(pas->dev, false); 816 } 817 818 static const struct qcom_pas_data adsp_resource_init = { 819 .crash_reason_smem = 423, 820 .firmware_name = "adsp.mdt", 821 .pas_id = 1, 822 .auto_boot = true, 823 .ssr_name = "lpass", 824 .sysmon_name = "adsp", 825 .ssctl_id = 0x14, 826 }; 827 828 static const struct qcom_pas_data sa8775p_adsp_resource = { 829 .crash_reason_smem = 423, 830 .firmware_name = "adsp.mbn", 831 .pas_id = 1, 832 .minidump_id = 5, 833 .auto_boot = true, 834 .proxy_pd_names = (char*[]){ 835 "lcx", 836 "lmx", 837 NULL 838 }, 839 .load_state = "adsp", 840 .ssr_name = "lpass", 841 .sysmon_name = "adsp", 842 .ssctl_id = 0x14, 843 }; 844 845 static const struct qcom_pas_data sdm845_adsp_resource_init = { 846 .crash_reason_smem = 423, 847 .firmware_name = "adsp.mdt", 848 .pas_id = 1, 849 .auto_boot = true, 850 .load_state = "adsp", 851 .ssr_name = "lpass", 852 .sysmon_name = "adsp", 853 .ssctl_id = 0x14, 854 }; 855 856 static const struct qcom_pas_data sm6350_adsp_resource = { 857 .crash_reason_smem = 423, 858 .firmware_name = "adsp.mdt", 859 .pas_id = 1, 860 .auto_boot = true, 861 .proxy_pd_names = (char*[]){ 862 "lcx", 863 "lmx", 864 NULL 865 }, 866 .load_state = "adsp", 867 .ssr_name = "lpass", 868 .sysmon_name = "adsp", 869 .ssctl_id = 0x14, 870 }; 871 872 static const struct qcom_pas_data sm6375_mpss_resource = { 873 .crash_reason_smem = 421, 874 .firmware_name = "modem.mdt", 875 .pas_id = 4, 876 .minidump_id = 3, 877 .auto_boot = false, 878 .proxy_pd_names = (char*[]){ 879 "cx", 880 NULL 881 }, 882 .ssr_name = "mpss", 883 .sysmon_name = "modem", 884 .ssctl_id = 0x12, 885 }; 886 887 static const struct qcom_pas_data sm8150_adsp_resource = { 888 .crash_reason_smem = 423, 889 .firmware_name = "adsp.mdt", 890 .pas_id = 1, 891 .auto_boot = true, 892 .proxy_pd_names = (char*[]){ 893 "cx", 894 NULL 895 }, 896 .load_state = "adsp", 897 .ssr_name = "lpass", 898 .sysmon_name = "adsp", 899 .ssctl_id = 0x14, 900 }; 901 902 static const struct qcom_pas_data sm8250_adsp_resource = { 903 .crash_reason_smem = 423, 904 .firmware_name = "adsp.mdt", 905 .pas_id = 1, 906 .minidump_id = 5, 907 .auto_boot = true, 908 .proxy_pd_names = (char*[]){ 909 "lcx", 910 "lmx", 911 NULL 912 }, 913 .load_state = "adsp", 914 .ssr_name = "lpass", 915 .sysmon_name = "adsp", 916 .ssctl_id = 0x14, 917 }; 918 919 static const struct qcom_pas_data sm8350_adsp_resource = { 920 .crash_reason_smem = 423, 921 .firmware_name = "adsp.mdt", 922 .pas_id = 1, 923 .auto_boot = true, 924 .proxy_pd_names = (char*[]){ 925 "lcx", 926 "lmx", 927 NULL 928 }, 929 .load_state = "adsp", 930 .ssr_name = "lpass", 931 .sysmon_name = "adsp", 932 .ssctl_id = 0x14, 933 }; 934 935 static const struct qcom_pas_data msm8996_adsp_resource = { 936 .crash_reason_smem = 423, 937 .firmware_name = "adsp.mdt", 938 .pas_id = 1, 939 .auto_boot = true, 940 .proxy_pd_names = (char*[]){ 941 "cx", 942 NULL 943 }, 944 .ssr_name = "lpass", 945 .sysmon_name = "adsp", 946 .ssctl_id = 0x14, 947 }; 948 949 static const struct qcom_pas_data cdsp_resource_init = { 950 .crash_reason_smem = 601, 951 .firmware_name = "cdsp.mdt", 952 .pas_id = 18, 953 .auto_boot = true, 954 .ssr_name = "cdsp", 955 .sysmon_name = "cdsp", 956 .ssctl_id = 0x17, 957 }; 958 959 static const struct qcom_pas_data sa8775p_cdsp0_resource = { 960 .crash_reason_smem = 601, 961 .firmware_name = "cdsp0.mbn", 962 .pas_id = 18, 963 .minidump_id = 7, 964 .auto_boot = true, 965 .proxy_pd_names = (char*[]){ 966 "cx", 967 "mxc", 968 "nsp", 969 NULL 970 }, 971 .load_state = "cdsp", 972 .ssr_name = "cdsp", 973 .sysmon_name = "cdsp", 974 .ssctl_id = 0x17, 975 }; 976 977 static const struct qcom_pas_data sa8775p_cdsp1_resource = { 978 .crash_reason_smem = 633, 979 .firmware_name = "cdsp1.mbn", 980 .pas_id = 30, 981 .minidump_id = 20, 982 .auto_boot = true, 983 .proxy_pd_names = (char*[]){ 984 "cx", 985 "mxc", 986 "nsp", 987 NULL 988 }, 989 .load_state = "nsp", 990 .ssr_name = "cdsp1", 991 .sysmon_name = "cdsp1", 992 .ssctl_id = 0x20, 993 }; 994 995 static const struct qcom_pas_data sdm845_cdsp_resource_init = { 996 .crash_reason_smem = 601, 997 .firmware_name = "cdsp.mdt", 998 .pas_id = 18, 999 .auto_boot = true, 1000 .load_state = "cdsp", 1001 .ssr_name = "cdsp", 1002 .sysmon_name = "cdsp", 1003 .ssctl_id = 0x17, 1004 }; 1005 1006 static const struct qcom_pas_data sm6350_cdsp_resource = { 1007 .crash_reason_smem = 601, 1008 .firmware_name = "cdsp.mdt", 1009 .pas_id = 18, 1010 .auto_boot = true, 1011 .proxy_pd_names = (char*[]){ 1012 "cx", 1013 "mx", 1014 NULL 1015 }, 1016 .load_state = "cdsp", 1017 .ssr_name = "cdsp", 1018 .sysmon_name = "cdsp", 1019 .ssctl_id = 0x17, 1020 }; 1021 1022 static const struct qcom_pas_data sm8150_cdsp_resource = { 1023 .crash_reason_smem = 601, 1024 .firmware_name = "cdsp.mdt", 1025 .pas_id = 18, 1026 .auto_boot = true, 1027 .proxy_pd_names = (char*[]){ 1028 "cx", 1029 NULL 1030 }, 1031 .load_state = "cdsp", 1032 .ssr_name = "cdsp", 1033 .sysmon_name = "cdsp", 1034 .ssctl_id = 0x17, 1035 }; 1036 1037 static const struct qcom_pas_data sm8250_cdsp_resource = { 1038 .crash_reason_smem = 601, 1039 .firmware_name = "cdsp.mdt", 1040 .pas_id = 18, 1041 .auto_boot = true, 1042 .proxy_pd_names = (char*[]){ 1043 "cx", 1044 NULL 1045 }, 1046 .load_state = "cdsp", 1047 .ssr_name = "cdsp", 1048 .sysmon_name = "cdsp", 1049 .ssctl_id = 0x17, 1050 }; 1051 1052 static const struct qcom_pas_data sc8280xp_nsp0_resource = { 1053 .crash_reason_smem = 601, 1054 .firmware_name = "cdsp.mdt", 1055 .pas_id = 18, 1056 .auto_boot = true, 1057 .proxy_pd_names = (char*[]){ 1058 "nsp", 1059 NULL 1060 }, 1061 .ssr_name = "cdsp0", 1062 .sysmon_name = "cdsp", 1063 .ssctl_id = 0x17, 1064 }; 1065 1066 static const struct qcom_pas_data sc8280xp_nsp1_resource = { 1067 .crash_reason_smem = 633, 1068 .firmware_name = "cdsp.mdt", 1069 .pas_id = 30, 1070 .auto_boot = true, 1071 .proxy_pd_names = (char*[]){ 1072 "nsp", 1073 NULL 1074 }, 1075 .ssr_name = "cdsp1", 1076 .sysmon_name = "cdsp1", 1077 .ssctl_id = 0x20, 1078 }; 1079 1080 static const struct qcom_pas_data x1e80100_adsp_resource = { 1081 .crash_reason_smem = 423, 1082 .firmware_name = "adsp.mdt", 1083 .dtb_firmware_name = "adsp_dtb.mdt", 1084 .pas_id = 1, 1085 .dtb_pas_id = 0x24, 1086 .lite_pas_id = 0x1f, 1087 .minidump_id = 5, 1088 .auto_boot = true, 1089 .proxy_pd_names = (char*[]){ 1090 "lcx", 1091 "lmx", 1092 NULL 1093 }, 1094 .load_state = "adsp", 1095 .ssr_name = "lpass", 1096 .sysmon_name = "adsp", 1097 .ssctl_id = 0x14, 1098 }; 1099 1100 static const struct qcom_pas_data x1e80100_cdsp_resource = { 1101 .crash_reason_smem = 601, 1102 .firmware_name = "cdsp.mdt", 1103 .dtb_firmware_name = "cdsp_dtb.mdt", 1104 .pas_id = 18, 1105 .dtb_pas_id = 0x25, 1106 .minidump_id = 7, 1107 .auto_boot = true, 1108 .proxy_pd_names = (char*[]){ 1109 "cx", 1110 "mxc", 1111 "nsp", 1112 NULL 1113 }, 1114 .load_state = "cdsp", 1115 .ssr_name = "cdsp", 1116 .sysmon_name = "cdsp", 1117 .ssctl_id = 0x17, 1118 }; 1119 1120 static const struct qcom_pas_data sm8350_cdsp_resource = { 1121 .crash_reason_smem = 601, 1122 .firmware_name = "cdsp.mdt", 1123 .pas_id = 18, 1124 .minidump_id = 7, 1125 .auto_boot = true, 1126 .proxy_pd_names = (char*[]){ 1127 "cx", 1128 "mxc", 1129 NULL 1130 }, 1131 .load_state = "cdsp", 1132 .ssr_name = "cdsp", 1133 .sysmon_name = "cdsp", 1134 .ssctl_id = 0x17, 1135 }; 1136 1137 static const struct qcom_pas_data sa8775p_gpdsp0_resource = { 1138 .crash_reason_smem = 640, 1139 .firmware_name = "gpdsp0.mbn", 1140 .pas_id = 39, 1141 .minidump_id = 21, 1142 .auto_boot = true, 1143 .proxy_pd_names = (char*[]){ 1144 "cx", 1145 "mxc", 1146 NULL 1147 }, 1148 .load_state = "gpdsp0", 1149 .ssr_name = "gpdsp0", 1150 .sysmon_name = "gpdsp0", 1151 .ssctl_id = 0x21, 1152 }; 1153 1154 static const struct qcom_pas_data sa8775p_gpdsp1_resource = { 1155 .crash_reason_smem = 641, 1156 .firmware_name = "gpdsp1.mbn", 1157 .pas_id = 40, 1158 .minidump_id = 22, 1159 .auto_boot = true, 1160 .proxy_pd_names = (char*[]){ 1161 "cx", 1162 "mxc", 1163 NULL 1164 }, 1165 .load_state = "gpdsp1", 1166 .ssr_name = "gpdsp1", 1167 .sysmon_name = "gpdsp1", 1168 .ssctl_id = 0x22, 1169 }; 1170 1171 static const struct qcom_pas_data mpss_resource_init = { 1172 .crash_reason_smem = 421, 1173 .firmware_name = "modem.mdt", 1174 .pas_id = 4, 1175 .minidump_id = 3, 1176 .auto_boot = false, 1177 .proxy_pd_names = (char*[]){ 1178 "cx", 1179 "mss", 1180 NULL 1181 }, 1182 .load_state = "modem", 1183 .ssr_name = "mpss", 1184 .sysmon_name = "modem", 1185 .ssctl_id = 0x12, 1186 }; 1187 1188 static const struct qcom_pas_data sc8180x_mpss_resource = { 1189 .crash_reason_smem = 421, 1190 .firmware_name = "modem.mdt", 1191 .pas_id = 4, 1192 .auto_boot = false, 1193 .proxy_pd_names = (char*[]){ 1194 "cx", 1195 NULL 1196 }, 1197 .load_state = "modem", 1198 .ssr_name = "mpss", 1199 .sysmon_name = "modem", 1200 .ssctl_id = 0x12, 1201 }; 1202 1203 static const struct qcom_pas_data msm8996_slpi_resource_init = { 1204 .crash_reason_smem = 424, 1205 .firmware_name = "slpi.mdt", 1206 .pas_id = 12, 1207 .auto_boot = true, 1208 .proxy_pd_names = (char*[]){ 1209 "ssc_cx", 1210 NULL 1211 }, 1212 .ssr_name = "dsps", 1213 .sysmon_name = "slpi", 1214 .ssctl_id = 0x16, 1215 }; 1216 1217 static const struct qcom_pas_data sdm845_slpi_resource_init = { 1218 .crash_reason_smem = 424, 1219 .firmware_name = "slpi.mdt", 1220 .pas_id = 12, 1221 .auto_boot = true, 1222 .proxy_pd_names = (char*[]){ 1223 "lcx", 1224 "lmx", 1225 NULL 1226 }, 1227 .load_state = "slpi", 1228 .ssr_name = "dsps", 1229 .sysmon_name = "slpi", 1230 .ssctl_id = 0x16, 1231 }; 1232 1233 static const struct qcom_pas_data wcss_resource_init = { 1234 .crash_reason_smem = 421, 1235 .firmware_name = "wcnss.mdt", 1236 .pas_id = 6, 1237 .auto_boot = true, 1238 .ssr_name = "mpss", 1239 .sysmon_name = "wcnss", 1240 .ssctl_id = 0x12, 1241 }; 1242 1243 static const struct qcom_pas_data sdx55_mpss_resource = { 1244 .crash_reason_smem = 421, 1245 .firmware_name = "modem.mdt", 1246 .pas_id = 4, 1247 .auto_boot = true, 1248 .proxy_pd_names = (char*[]){ 1249 "cx", 1250 "mss", 1251 NULL 1252 }, 1253 .ssr_name = "mpss", 1254 .sysmon_name = "modem", 1255 .ssctl_id = 0x22, 1256 }; 1257 1258 static const struct qcom_pas_data sm8450_mpss_resource = { 1259 .crash_reason_smem = 421, 1260 .firmware_name = "modem.mdt", 1261 .pas_id = 4, 1262 .minidump_id = 3, 1263 .auto_boot = false, 1264 .decrypt_shutdown = true, 1265 .proxy_pd_names = (char*[]){ 1266 "cx", 1267 "mss", 1268 NULL 1269 }, 1270 .load_state = "modem", 1271 .ssr_name = "mpss", 1272 .sysmon_name = "modem", 1273 .ssctl_id = 0x12, 1274 }; 1275 1276 static const struct qcom_pas_data sm8550_adsp_resource = { 1277 .crash_reason_smem = 423, 1278 .firmware_name = "adsp.mdt", 1279 .dtb_firmware_name = "adsp_dtb.mdt", 1280 .pas_id = 1, 1281 .dtb_pas_id = 0x24, 1282 .minidump_id = 5, 1283 .auto_boot = true, 1284 .proxy_pd_names = (char*[]){ 1285 "lcx", 1286 "lmx", 1287 NULL 1288 }, 1289 .load_state = "adsp", 1290 .ssr_name = "lpass", 1291 .sysmon_name = "adsp", 1292 .ssctl_id = 0x14, 1293 .smem_host_id = 2, 1294 }; 1295 1296 static const struct qcom_pas_data sm8550_cdsp_resource = { 1297 .crash_reason_smem = 601, 1298 .firmware_name = "cdsp.mdt", 1299 .dtb_firmware_name = "cdsp_dtb.mdt", 1300 .pas_id = 18, 1301 .dtb_pas_id = 0x25, 1302 .minidump_id = 7, 1303 .auto_boot = true, 1304 .proxy_pd_names = (char*[]){ 1305 "cx", 1306 "mxc", 1307 "nsp", 1308 NULL 1309 }, 1310 .load_state = "cdsp", 1311 .ssr_name = "cdsp", 1312 .sysmon_name = "cdsp", 1313 .ssctl_id = 0x17, 1314 .smem_host_id = 5, 1315 }; 1316 1317 static const struct qcom_pas_data sm8550_mpss_resource = { 1318 .crash_reason_smem = 421, 1319 .firmware_name = "modem.mdt", 1320 .dtb_firmware_name = "modem_dtb.mdt", 1321 .pas_id = 4, 1322 .dtb_pas_id = 0x26, 1323 .minidump_id = 3, 1324 .auto_boot = false, 1325 .decrypt_shutdown = true, 1326 .proxy_pd_names = (char*[]){ 1327 "cx", 1328 "mss", 1329 NULL 1330 }, 1331 .load_state = "modem", 1332 .ssr_name = "mpss", 1333 .sysmon_name = "modem", 1334 .ssctl_id = 0x12, 1335 .smem_host_id = 1, 1336 .region_assign_idx = 2, 1337 .region_assign_count = 1, 1338 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1339 }; 1340 1341 static const struct qcom_pas_data sc7280_wpss_resource = { 1342 .crash_reason_smem = 626, 1343 .firmware_name = "wpss.mdt", 1344 .pas_id = 6, 1345 .minidump_id = 4, 1346 .auto_boot = false, 1347 .proxy_pd_names = (char*[]){ 1348 "cx", 1349 "mx", 1350 NULL 1351 }, 1352 .load_state = "wpss", 1353 .ssr_name = "wpss", 1354 .sysmon_name = "wpss", 1355 .ssctl_id = 0x19, 1356 }; 1357 1358 static const struct qcom_pas_data sm8650_cdsp_resource = { 1359 .crash_reason_smem = 601, 1360 .firmware_name = "cdsp.mdt", 1361 .dtb_firmware_name = "cdsp_dtb.mdt", 1362 .pas_id = 18, 1363 .dtb_pas_id = 0x25, 1364 .minidump_id = 7, 1365 .auto_boot = true, 1366 .proxy_pd_names = (char*[]){ 1367 "cx", 1368 "mxc", 1369 "nsp", 1370 NULL 1371 }, 1372 .load_state = "cdsp", 1373 .ssr_name = "cdsp", 1374 .sysmon_name = "cdsp", 1375 .ssctl_id = 0x17, 1376 .smem_host_id = 5, 1377 .region_assign_idx = 2, 1378 .region_assign_count = 1, 1379 .region_assign_shared = true, 1380 .region_assign_vmid = QCOM_SCM_VMID_CDSP, 1381 }; 1382 1383 static const struct qcom_pas_data sm8650_mpss_resource = { 1384 .crash_reason_smem = 421, 1385 .firmware_name = "modem.mdt", 1386 .dtb_firmware_name = "modem_dtb.mdt", 1387 .pas_id = 4, 1388 .dtb_pas_id = 0x26, 1389 .minidump_id = 3, 1390 .auto_boot = false, 1391 .decrypt_shutdown = true, 1392 .proxy_pd_names = (char*[]){ 1393 "cx", 1394 "mss", 1395 NULL 1396 }, 1397 .load_state = "modem", 1398 .ssr_name = "mpss", 1399 .sysmon_name = "modem", 1400 .ssctl_id = 0x12, 1401 .smem_host_id = 1, 1402 .region_assign_idx = 2, 1403 .region_assign_count = 3, 1404 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1405 }; 1406 1407 static const struct qcom_pas_data sm8750_mpss_resource = { 1408 .crash_reason_smem = 421, 1409 .firmware_name = "modem.mdt", 1410 .dtb_firmware_name = "modem_dtb.mdt", 1411 .pas_id = 4, 1412 .dtb_pas_id = 0x26, 1413 .minidump_id = 3, 1414 .auto_boot = false, 1415 .decrypt_shutdown = true, 1416 .proxy_pd_names = (char*[]){ 1417 "cx", 1418 "mss", 1419 NULL 1420 }, 1421 .load_state = "modem", 1422 .ssr_name = "mpss", 1423 .sysmon_name = "modem", 1424 .ssctl_id = 0x12, 1425 .smem_host_id = 1, 1426 .region_assign_idx = 2, 1427 .region_assign_count = 2, 1428 .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, 1429 }; 1430 1431 static const struct of_device_id qcom_pas_of_match[] = { 1432 { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource}, 1433 { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, 1434 { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, 1435 { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource}, 1436 { .compatible = "qcom,msm8996-slpi-pil", .data = &msm8996_slpi_resource_init}, 1437 { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8996_adsp_resource}, 1438 { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8996_slpi_resource_init}, 1439 { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, 1440 { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, 1441 { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, 1442 { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource}, 1443 { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource}, 1444 { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, 1445 { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, 1446 { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, 1447 { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource}, 1448 { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, 1449 { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, 1450 { .compatible = "qcom,sc7280-adsp-pas", .data = &sm8350_adsp_resource}, 1451 { .compatible = "qcom,sc7280-cdsp-pas", .data = &sm6350_cdsp_resource}, 1452 { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, 1453 { .compatible = "qcom,sc7280-wpss-pas", .data = &sc7280_wpss_resource}, 1454 { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, 1455 { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, 1456 { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, 1457 { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource}, 1458 { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource}, 1459 { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource}, 1460 { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, 1461 { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init}, 1462 { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init}, 1463 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init}, 1464 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, 1465 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource}, 1466 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init}, 1467 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init}, 1468 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource}, 1469 { .compatible = "qcom,sm6350-adsp-pas", .data = &sm6350_adsp_resource}, 1470 { .compatible = "qcom,sm6350-cdsp-pas", .data = &sm6350_cdsp_resource}, 1471 { .compatible = "qcom,sm6350-mpss-pas", .data = &mpss_resource_init}, 1472 { .compatible = "qcom,sm6375-adsp-pas", .data = &sm6350_adsp_resource}, 1473 { .compatible = "qcom,sm6375-cdsp-pas", .data = &sm8150_cdsp_resource}, 1474 { .compatible = "qcom,sm6375-mpss-pas", .data = &sm6375_mpss_resource}, 1475 { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource}, 1476 { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource}, 1477 { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init}, 1478 { .compatible = "qcom,sm8150-slpi-pas", .data = &sdm845_slpi_resource_init}, 1479 { .compatible = "qcom,sm8250-adsp-pas", .data = &sm8250_adsp_resource}, 1480 { .compatible = "qcom,sm8250-cdsp-pas", .data = &sm8250_cdsp_resource}, 1481 { .compatible = "qcom,sm8250-slpi-pas", .data = &sdm845_slpi_resource_init}, 1482 { .compatible = "qcom,sm8350-adsp-pas", .data = &sm8350_adsp_resource}, 1483 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource}, 1484 { .compatible = "qcom,sm8350-slpi-pas", .data = &sdm845_slpi_resource_init}, 1485 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init}, 1486 { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource}, 1487 { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource}, 1488 { .compatible = "qcom,sm8450-slpi-pas", .data = &sdm845_slpi_resource_init}, 1489 { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource}, 1490 { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource}, 1491 { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource}, 1492 { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource}, 1493 { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, 1494 { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, 1495 { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, 1496 { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource}, 1497 { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource}, 1498 { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource}, 1499 { }, 1500 }; 1501 MODULE_DEVICE_TABLE(of, qcom_pas_of_match); 1502 1503 static struct platform_driver qcom_pas_driver = { 1504 .probe = qcom_pas_probe, 1505 .remove = qcom_pas_remove, 1506 .driver = { 1507 .name = "qcom_q6v5_pas", 1508 .of_match_table = qcom_pas_of_match, 1509 }, 1510 }; 1511 1512 module_platform_driver(qcom_pas_driver); 1513 MODULE_DESCRIPTION("Qualcomm Peripheral Authentication Service remoteproc driver"); 1514 MODULE_LICENSE("GPL v2"); 1515