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