xref: /linux/drivers/remoteproc/qcom_q6v5_pas.c (revision 55a42f78ffd386e01a5404419f8c5ded7db70a21)
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