File Index
Files and directories
Sign in
FILE

qcom_q6v5_pas.c

File preview with syntax highlighting.

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