xref: /wlan-dirver/platform/cnss2/main.c (revision 48cfe543c66903e6d5c687c4a394b09b314631a5)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/delay.h>
8 #include <linux/devcoredump.h>
9 #include <linux/elf.h>
10 #include <linux/jiffies.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_device.h>
14 #include <linux/of_gpio.h>
15 #include <linux/pm_wakeup.h>
16 #include <linux/reboot.h>
17 #include <linux/rwsem.h>
18 #include <linux/suspend.h>
19 #include <linux/timer.h>
20 #include <linux/version.h>
21 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
22 #include <linux/panic_notifier.h>
23 #endif
24 #if IS_ENABLED(CONFIG_QCOM_MINIDUMP)
25 #include <soc/qcom/minidump.h>
26 #endif
27 
28 #include "cnss_plat_ipc_qmi.h"
29 #include "cnss_utils.h"
30 #include "main.h"
31 #include "bus.h"
32 #include "debug.h"
33 #include "genl.h"
34 #include "reg.h"
35 
36 #ifdef CONFIG_CNSS_HW_SECURE_DISABLE
37 #include "smcinvoke.h"
38 #include "smcinvoke_object.h"
39 #include "IClientEnv.h"
40 
41 #define HW_STATE_UID 0x108
42 #define HW_OP_GET_STATE 1
43 #define HW_WIFI_UID 0x508
44 #define FEATURE_NOT_SUPPORTED 12
45 #define PERIPHERAL_NOT_FOUND 10
46 #endif
47 
48 #define CNSS_DUMP_FORMAT_VER		0x11
49 #define CNSS_DUMP_FORMAT_VER_V2		0x22
50 #define CNSS_DUMP_MAGIC_VER_V2		0x42445953
51 #define CNSS_DUMP_NAME			"CNSS_WLAN"
52 #define CNSS_DUMP_DESC_SIZE		0x1000
53 #define CNSS_DUMP_SEG_VER		0x1
54 #define FILE_SYSTEM_READY		1
55 #define FW_READY_TIMEOUT		20000
56 #define FW_ASSERT_TIMEOUT		5000
57 #define CNSS_EVENT_PENDING		2989
58 #define POWER_RESET_MIN_DELAY_MS	100
59 
60 #define CNSS_QUIRKS_DEFAULT		0
61 #ifdef CONFIG_CNSS_EMULATION
62 #define CNSS_MHI_TIMEOUT_DEFAULT	90000
63 #define CNSS_MHI_M2_TIMEOUT_DEFAULT	2000
64 #define CNSS_QMI_TIMEOUT_DEFAULT	90000
65 #else
66 #define CNSS_MHI_TIMEOUT_DEFAULT	0
67 #define CNSS_MHI_M2_TIMEOUT_DEFAULT	25
68 #define CNSS_QMI_TIMEOUT_DEFAULT	10000
69 #endif
70 #define CNSS_BDF_TYPE_DEFAULT		CNSS_BDF_ELF
71 #define CNSS_TIME_SYNC_PERIOD_DEFAULT	900000
72 #define CNSS_MIN_TIME_SYNC_PERIOD	2000
73 #define CNSS_DMS_QMI_CONNECTION_WAIT_MS 50
74 #define CNSS_DMS_QMI_CONNECTION_WAIT_RETRY 200
75 #define CNSS_DAEMON_CONNECT_TIMEOUT_MS  30000
76 #define CNSS_CAL_DB_FILE_NAME "wlfw_cal_db.bin"
77 #define CNSS_CAL_START_PROBE_WAIT_RETRY_MAX 100
78 #define CNSS_CAL_START_PROBE_WAIT_MS	500
79 
80 enum cnss_cal_db_op {
81 	CNSS_CAL_DB_UPLOAD,
82 	CNSS_CAL_DB_DOWNLOAD,
83 	CNSS_CAL_DB_INVALID_OP,
84 };
85 
86 enum cnss_recovery_type {
87 	CNSS_WLAN_RECOVERY = 0x1,
88 	CNSS_PCSS_RECOVERY = 0x2,
89 };
90 
91 static struct cnss_plat_data *plat_env;
92 
93 static bool cnss_allow_driver_loading;
94 
95 static DECLARE_RWSEM(cnss_pm_sem);
96 
97 static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = {
98 	"qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin",
99 	"utfbd30.bin", "epping30.bin", "evicted30.bin"
100 };
101 
102 static struct cnss_fw_files FW_FILES_DEFAULT = {
103 	"qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin",
104 	"utfbd.bin", "epping.bin", "evicted.bin"
105 };
106 
107 struct cnss_driver_event {
108 	struct list_head list;
109 	enum cnss_driver_event_type type;
110 	bool sync;
111 	struct completion complete;
112 	int ret;
113 	void *data;
114 };
115 
116 static void cnss_set_plat_priv(struct platform_device *plat_dev,
117 			       struct cnss_plat_data *plat_priv)
118 {
119 	plat_env = plat_priv;
120 }
121 
122 bool cnss_check_driver_loading_allowed(void)
123 {
124 	return cnss_allow_driver_loading;
125 }
126 
127 struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev)
128 {
129 	return plat_env;
130 }
131 
132 /**
133  * cnss_get_mem_seg_count - Get segment count of memory
134  * @type: memory type
135  * @seg: segment count
136  *
137  * Return: 0 on success, negative value on failure
138  */
139 int cnss_get_mem_seg_count(enum cnss_remote_mem_type type, u32 *seg)
140 {
141 	struct cnss_plat_data *plat_priv;
142 
143 	plat_priv = cnss_get_plat_priv(NULL);
144 	if (!plat_priv)
145 		return -ENODEV;
146 
147 	switch (type) {
148 	case CNSS_REMOTE_MEM_TYPE_FW:
149 		*seg = plat_priv->fw_mem_seg_len;
150 		break;
151 	case CNSS_REMOTE_MEM_TYPE_QDSS:
152 		*seg = plat_priv->qdss_mem_seg_len;
153 		break;
154 	default:
155 		return -EINVAL;
156 	}
157 
158 	return 0;
159 }
160 EXPORT_SYMBOL(cnss_get_mem_seg_count);
161 
162 /**
163  * cnss_get_wifi_kobject -return wifi kobject
164  * Return: Null, to maintain driver comnpatibilty
165  */
166 struct kobject *cnss_get_wifi_kobj(struct device *dev)
167 {
168 	struct cnss_plat_data *plat_priv;
169 
170 	plat_priv = cnss_get_plat_priv(NULL);
171 	if (!plat_priv)
172 		return NULL;
173 
174 	return plat_priv->wifi_kobj;
175 }
176 EXPORT_SYMBOL(cnss_get_wifi_kobj);
177 
178 /**
179  * cnss_get_mem_segment_info - Get memory info of different type
180  * @type: memory type
181  * @segment: array to save the segment info
182  * @seg: segment count
183  *
184  * Return: 0 on success, negative value on failure
185  */
186 int cnss_get_mem_segment_info(enum cnss_remote_mem_type type,
187 			      struct cnss_mem_segment segment[],
188 			      u32 segment_count)
189 {
190 	struct cnss_plat_data *plat_priv;
191 	u32 i;
192 
193 	plat_priv = cnss_get_plat_priv(NULL);
194 	if (!plat_priv)
195 		return -ENODEV;
196 
197 	switch (type) {
198 	case CNSS_REMOTE_MEM_TYPE_FW:
199 		if (segment_count > plat_priv->fw_mem_seg_len)
200 			segment_count = plat_priv->fw_mem_seg_len;
201 		for (i = 0; i < segment_count; i++) {
202 			segment[i].size = plat_priv->fw_mem[i].size;
203 			segment[i].va = plat_priv->fw_mem[i].va;
204 			segment[i].pa = plat_priv->fw_mem[i].pa;
205 		}
206 		break;
207 	case CNSS_REMOTE_MEM_TYPE_QDSS:
208 		if (segment_count > plat_priv->qdss_mem_seg_len)
209 			segment_count = plat_priv->qdss_mem_seg_len;
210 		for (i = 0; i < segment_count; i++) {
211 			segment[i].size = plat_priv->qdss_mem[i].size;
212 			segment[i].va = plat_priv->qdss_mem[i].va;
213 			segment[i].pa = plat_priv->qdss_mem[i].pa;
214 		}
215 		break;
216 	default:
217 		return -EINVAL;
218 	}
219 
220 	return 0;
221 }
222 EXPORT_SYMBOL(cnss_get_mem_segment_info);
223 
224 int cnss_set_feature_list(struct cnss_plat_data *plat_priv,
225 			  enum cnss_feature_v01 feature)
226 {
227 	if (unlikely(!plat_priv || feature >= CNSS_MAX_FEATURE_V01))
228 		return -EINVAL;
229 
230 	plat_priv->feature_list |= 1 << feature;
231 	return 0;
232 }
233 
234 int cnss_clear_feature_list(struct cnss_plat_data *plat_priv,
235 			    enum cnss_feature_v01 feature)
236 {
237 	if (unlikely(!plat_priv || feature >= CNSS_MAX_FEATURE_V01))
238 		return -EINVAL;
239 
240 	plat_priv->feature_list &= ~(1 << feature);
241 	return 0;
242 }
243 
244 int cnss_get_feature_list(struct cnss_plat_data *plat_priv,
245 			  u64 *feature_list)
246 {
247 	if (unlikely(!plat_priv))
248 		return -EINVAL;
249 
250 	*feature_list = plat_priv->feature_list;
251 	return 0;
252 }
253 
254 static int cnss_pm_notify(struct notifier_block *b,
255 			  unsigned long event, void *p)
256 {
257 	switch (event) {
258 	case PM_SUSPEND_PREPARE:
259 		down_write(&cnss_pm_sem);
260 		break;
261 	case PM_POST_SUSPEND:
262 		up_write(&cnss_pm_sem);
263 		break;
264 	}
265 
266 	return NOTIFY_DONE;
267 }
268 
269 static struct notifier_block cnss_pm_notifier = {
270 	.notifier_call = cnss_pm_notify,
271 };
272 
273 void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv)
274 {
275 	if (atomic_inc_return(&plat_priv->pm_count) != 1)
276 		return;
277 
278 	cnss_pr_dbg("PM stay awake, state: 0x%lx, count: %d\n",
279 		    plat_priv->driver_state,
280 		    atomic_read(&plat_priv->pm_count));
281 	pm_stay_awake(&plat_priv->plat_dev->dev);
282 }
283 
284 void cnss_pm_relax(struct cnss_plat_data *plat_priv)
285 {
286 	int r = atomic_dec_return(&plat_priv->pm_count);
287 
288 	WARN_ON(r < 0);
289 
290 	if (r != 0)
291 		return;
292 
293 	cnss_pr_dbg("PM relax, state: 0x%lx, count: %d\n",
294 		    plat_priv->driver_state,
295 		    atomic_read(&plat_priv->pm_count));
296 	pm_relax(&plat_priv->plat_dev->dev);
297 }
298 
299 void cnss_lock_pm_sem(struct device *dev)
300 {
301 	down_read(&cnss_pm_sem);
302 }
303 EXPORT_SYMBOL(cnss_lock_pm_sem);
304 
305 void cnss_release_pm_sem(struct device *dev)
306 {
307 	up_read(&cnss_pm_sem);
308 }
309 EXPORT_SYMBOL(cnss_release_pm_sem);
310 
311 int cnss_get_fw_files_for_target(struct device *dev,
312 				 struct cnss_fw_files *pfw_files,
313 				 u32 target_type, u32 target_version)
314 {
315 	if (!pfw_files)
316 		return -ENODEV;
317 
318 	switch (target_version) {
319 	case QCA6174_REV3_VERSION:
320 	case QCA6174_REV3_2_VERSION:
321 		memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files));
322 		break;
323 	default:
324 		memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files));
325 		cnss_pr_err("Unknown target version, type: 0x%X, version: 0x%X",
326 			    target_type, target_version);
327 		break;
328 	}
329 
330 	return 0;
331 }
332 EXPORT_SYMBOL(cnss_get_fw_files_for_target);
333 
334 int cnss_get_platform_cap(struct device *dev, struct cnss_platform_cap *cap)
335 {
336 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
337 
338 	if (!plat_priv)
339 		return -ENODEV;
340 
341 	if (!cap)
342 		return -EINVAL;
343 
344 	*cap = plat_priv->cap;
345 	cnss_pr_dbg("Platform cap_flag is 0x%x\n", cap->cap_flag);
346 
347 	return 0;
348 }
349 EXPORT_SYMBOL(cnss_get_platform_cap);
350 
351 void cnss_request_pm_qos(struct device *dev, u32 qos_val)
352 {
353 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
354 
355 	if (!plat_priv)
356 		return;
357 
358 	cpu_latency_qos_add_request(&plat_priv->qos_request, qos_val);
359 }
360 EXPORT_SYMBOL(cnss_request_pm_qos);
361 
362 void cnss_remove_pm_qos(struct device *dev)
363 {
364 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
365 
366 	if (!plat_priv)
367 		return;
368 
369 	cpu_latency_qos_remove_request(&plat_priv->qos_request);
370 }
371 EXPORT_SYMBOL(cnss_remove_pm_qos);
372 
373 int cnss_wlan_enable(struct device *dev,
374 		     struct cnss_wlan_enable_cfg *config,
375 		     enum cnss_driver_mode mode,
376 		     const char *host_version)
377 {
378 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
379 	int ret = 0;
380 
381 	if (!plat_priv)
382 		return -ENODEV;
383 
384 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
385 		return 0;
386 
387 	if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks))
388 		return 0;
389 
390 	if (!config || !host_version) {
391 		cnss_pr_err("Invalid config or host_version pointer\n");
392 		return -EINVAL;
393 	}
394 
395 	cnss_pr_dbg("Mode: %d, config: %pK, host_version: %s\n",
396 		    mode, config, host_version);
397 
398 	if (mode == CNSS_WALTEST || mode == CNSS_CCPM)
399 		goto skip_cfg;
400 
401 	ret = cnss_wlfw_wlan_cfg_send_sync(plat_priv, config, host_version);
402 	if (ret)
403 		goto out;
404 
405 skip_cfg:
406 	ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, mode);
407 out:
408 	return ret;
409 }
410 EXPORT_SYMBOL(cnss_wlan_enable);
411 
412 int cnss_wlan_disable(struct device *dev, enum cnss_driver_mode mode)
413 {
414 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
415 	int ret = 0;
416 
417 	if (!plat_priv)
418 		return -ENODEV;
419 
420 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
421 		return 0;
422 
423 	if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks))
424 		return 0;
425 
426 	ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
427 	cnss_bus_free_qdss_mem(plat_priv);
428 
429 	return ret;
430 }
431 EXPORT_SYMBOL(cnss_wlan_disable);
432 
433 int cnss_athdiag_read(struct device *dev, u32 offset, u32 mem_type,
434 		      u32 data_len, u8 *output)
435 {
436 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
437 	int ret = 0;
438 
439 	if (!plat_priv) {
440 		cnss_pr_err("plat_priv is NULL!\n");
441 		return -EINVAL;
442 	}
443 
444 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
445 		return 0;
446 
447 	if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
448 		cnss_pr_err("Invalid state for athdiag read: 0x%lx\n",
449 			    plat_priv->driver_state);
450 		ret = -EINVAL;
451 		goto out;
452 	}
453 
454 	ret = cnss_wlfw_athdiag_read_send_sync(plat_priv, offset, mem_type,
455 					       data_len, output);
456 
457 out:
458 	return ret;
459 }
460 EXPORT_SYMBOL(cnss_athdiag_read);
461 
462 int cnss_athdiag_write(struct device *dev, u32 offset, u32 mem_type,
463 		       u32 data_len, u8 *input)
464 {
465 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
466 	int ret = 0;
467 
468 	if (!plat_priv) {
469 		cnss_pr_err("plat_priv is NULL!\n");
470 		return -EINVAL;
471 	}
472 
473 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
474 		return 0;
475 
476 	if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
477 		cnss_pr_err("Invalid state for athdiag write: 0x%lx\n",
478 			    plat_priv->driver_state);
479 		ret = -EINVAL;
480 		goto out;
481 	}
482 
483 	ret = cnss_wlfw_athdiag_write_send_sync(plat_priv, offset, mem_type,
484 						data_len, input);
485 
486 out:
487 	return ret;
488 }
489 EXPORT_SYMBOL(cnss_athdiag_write);
490 
491 int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
492 {
493 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
494 
495 	if (!plat_priv)
496 		return -ENODEV;
497 
498 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
499 		return 0;
500 
501 	return cnss_wlfw_ini_send_sync(plat_priv, fw_log_mode);
502 }
503 EXPORT_SYMBOL(cnss_set_fw_log_mode);
504 
505 int cnss_set_pcie_gen_speed(struct device *dev, u8 pcie_gen_speed)
506 {
507 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
508 
509 	if (!plat_priv)
510 		return -EINVAL;
511 
512 	if (!plat_priv->fw_pcie_gen_switch) {
513 		cnss_pr_err("Firmware does not support PCIe gen switch\n");
514 		return -EOPNOTSUPP;
515 	}
516 
517 	if (pcie_gen_speed < QMI_PCIE_GEN_SPEED_1_V01 ||
518 	    pcie_gen_speed > QMI_PCIE_GEN_SPEED_3_V01)
519 		return -EINVAL;
520 
521 	cnss_pr_dbg("WLAN provided PCIE gen speed: %d\n", pcie_gen_speed);
522 	plat_priv->pcie_gen_speed = pcie_gen_speed;
523 	return 0;
524 }
525 EXPORT_SYMBOL(cnss_set_pcie_gen_speed);
526 
527 static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
528 {
529 	int ret = 0;
530 
531 	if (!plat_priv)
532 		return -ENODEV;
533 
534 	set_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
535 
536 	ret = cnss_wlfw_tgt_cap_send_sync(plat_priv);
537 	if (ret)
538 		goto out;
539 
540 	if (plat_priv->hds_enabled)
541 		cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_HDS);
542 
543 	cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_REGDB);
544 
545 	cnss_wlfw_ini_file_send_sync(plat_priv, WLFW_CONN_ROAM_INI_V01);
546 
547 	ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv,
548 					   plat_priv->ctrl_params.bdf_type);
549 	if (ret)
550 		goto out;
551 
552 	ret = cnss_bus_load_m3(plat_priv);
553 	if (ret)
554 		goto out;
555 
556 	ret = cnss_wlfw_m3_dnld_send_sync(plat_priv);
557 	if (ret)
558 		goto out;
559 
560 	cnss_wlfw_qdss_dnld_send_sync(plat_priv);
561 
562 	return 0;
563 out:
564 	return ret;
565 }
566 
567 static int cnss_request_antenna_sharing(struct cnss_plat_data *plat_priv)
568 {
569 	int ret = 0;
570 
571 	if (!plat_priv->antenna) {
572 		ret = cnss_wlfw_antenna_switch_send_sync(plat_priv);
573 		if (ret)
574 			goto out;
575 	}
576 
577 	if (test_bit(CNSS_COEX_CONNECTED, &plat_priv->driver_state)) {
578 		ret = coex_antenna_switch_to_wlan_send_sync_msg(plat_priv);
579 		if (ret)
580 			goto out;
581 	}
582 
583 	ret = cnss_wlfw_antenna_grant_send_sync(plat_priv);
584 	if (ret)
585 		goto out;
586 
587 	return 0;
588 
589 out:
590 	return ret;
591 }
592 
593 static void cnss_release_antenna_sharing(struct cnss_plat_data *plat_priv)
594 {
595 	if (test_bit(CNSS_COEX_CONNECTED, &plat_priv->driver_state))
596 		coex_antenna_switch_to_mdm_send_sync_msg(plat_priv);
597 }
598 
599 static int cnss_setup_dms_mac(struct cnss_plat_data *plat_priv)
600 {
601 	u32 i;
602 	int ret = 0;
603 	struct cnss_plat_ipc_daemon_config *cfg;
604 
605 	ret = cnss_qmi_get_dms_mac(plat_priv);
606 	if (ret == 0 && plat_priv->dms.mac_valid)
607 		goto qmi_send;
608 
609 	/* DTSI property use-nv-mac is used to force DMS MAC address for WLAN.
610 	 * Thus assert on failure to get MAC from DMS even after retries
611 	 */
612 	if (plat_priv->use_nv_mac) {
613 		/* Check if Daemon says platform support DMS MAC provisioning */
614 		cfg = cnss_plat_ipc_qmi_daemon_config();
615 		if (cfg) {
616 			if (!cfg->dms_mac_addr_supported) {
617 				cnss_pr_err("DMS MAC address not supported\n");
618 				CNSS_ASSERT(0);
619 				return -EINVAL;
620 			}
621 		}
622 		for (i = 0; i < CNSS_DMS_QMI_CONNECTION_WAIT_RETRY; i++) {
623 			if (plat_priv->dms.mac_valid)
624 				break;
625 
626 			ret = cnss_qmi_get_dms_mac(plat_priv);
627 			if (ret == 0)
628 				break;
629 			msleep(CNSS_DMS_QMI_CONNECTION_WAIT_MS);
630 		}
631 		if (!plat_priv->dms.mac_valid) {
632 			cnss_pr_err("Unable to get MAC from DMS after retries\n");
633 			CNSS_ASSERT(0);
634 			return -EINVAL;
635 		}
636 	}
637 qmi_send:
638 	if (plat_priv->dms.mac_valid)
639 		ret =
640 		cnss_wlfw_wlan_mac_req_send_sync(plat_priv, plat_priv->dms.mac,
641 						 ARRAY_SIZE(plat_priv->dms.mac));
642 
643 	return ret;
644 }
645 
646 static int cnss_cal_db_mem_update(struct cnss_plat_data *plat_priv,
647 				  enum cnss_cal_db_op op, u32 *size)
648 {
649 	int ret = 0;
650 	u32 timeout = cnss_get_timeout(plat_priv,
651 				       CNSS_TIMEOUT_DAEMON_CONNECTION);
652 	enum cnss_plat_ipc_qmi_client_id_v01 client_id =
653 					CNSS_PLAT_IPC_DAEMON_QMI_CLIENT_V01;
654 
655 	if (op >= CNSS_CAL_DB_INVALID_OP)
656 		return -EINVAL;
657 
658 	if (!plat_priv->cbc_file_download) {
659 		cnss_pr_info("CAL DB file not required as per BDF\n");
660 		return 0;
661 	}
662 	if (*size == 0) {
663 		cnss_pr_err("Invalid cal file size\n");
664 		return -EINVAL;
665 	}
666 	if (!test_bit(CNSS_DAEMON_CONNECTED, &plat_priv->driver_state)) {
667 		cnss_pr_info("Waiting for CNSS Daemon connection\n");
668 		ret = wait_for_completion_timeout(&plat_priv->daemon_connected,
669 						  msecs_to_jiffies(timeout));
670 		if (!ret) {
671 			cnss_pr_err("Daemon not yet connected\n");
672 			CNSS_ASSERT(0);
673 			return ret;
674 		}
675 	}
676 	if (!plat_priv->cal_mem->va) {
677 		cnss_pr_err("CAL DB Memory not setup for FW\n");
678 		return -EINVAL;
679 	}
680 
681 	/* Copy CAL DB file contents to/from CAL_TYPE_DDR mem allocated to FW */
682 	if (op == CNSS_CAL_DB_DOWNLOAD) {
683 		cnss_pr_dbg("Initiating Calibration file download to mem\n");
684 		ret = cnss_plat_ipc_qmi_file_download(client_id,
685 						      CNSS_CAL_DB_FILE_NAME,
686 						      plat_priv->cal_mem->va,
687 						      size);
688 	} else {
689 		cnss_pr_dbg("Initiating Calibration mem upload to file\n");
690 		ret = cnss_plat_ipc_qmi_file_upload(client_id,
691 						    CNSS_CAL_DB_FILE_NAME,
692 						    plat_priv->cal_mem->va,
693 						    *size);
694 	}
695 
696 	if (ret)
697 		cnss_pr_err("Cal DB file %s %s failure\n",
698 			    CNSS_CAL_DB_FILE_NAME,
699 			    op == CNSS_CAL_DB_DOWNLOAD ? "download" : "upload");
700 	else
701 		cnss_pr_dbg("Cal DB file %s %s size %d done\n",
702 			    CNSS_CAL_DB_FILE_NAME,
703 			    op == CNSS_CAL_DB_DOWNLOAD ? "download" : "upload",
704 			    *size);
705 
706 	return ret;
707 }
708 
709 static int cnss_cal_mem_upload_to_file(struct cnss_plat_data *plat_priv)
710 {
711 	if (plat_priv->cal_file_size > plat_priv->cal_mem->size) {
712 		cnss_pr_err("Cal file size is larger than Cal DB Mem size\n");
713 		return -EINVAL;
714 	}
715 	return cnss_cal_db_mem_update(plat_priv, CNSS_CAL_DB_UPLOAD,
716 				      &plat_priv->cal_file_size);
717 }
718 
719 static int cnss_cal_file_download_to_mem(struct cnss_plat_data *plat_priv,
720 					 u32 *cal_file_size)
721 {
722 	/* To download pass the total size of cal DB mem allocated.
723 	 * After cal file is download to mem, its size is updated in
724 	 * return pointer
725 	 */
726 	*cal_file_size = plat_priv->cal_mem->size;
727 	return cnss_cal_db_mem_update(plat_priv, CNSS_CAL_DB_DOWNLOAD,
728 				      cal_file_size);
729 }
730 
731 static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
732 {
733 	int ret = 0;
734 	u32 cal_file_size = 0;
735 
736 	if (!plat_priv)
737 		return -ENODEV;
738 
739 	if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
740 		cnss_pr_err("Reboot is in progress, ignore FW ready\n");
741 		return -EINVAL;
742 	}
743 
744 	cnss_pr_dbg("Processing FW Init Done..\n");
745 	del_timer(&plat_priv->fw_boot_timer);
746 	set_bit(CNSS_FW_READY, &plat_priv->driver_state);
747 	clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
748 
749 	cnss_wlfw_send_pcie_gen_speed_sync(plat_priv);
750 
751 	if (test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state)) {
752 		clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
753 		clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
754 	}
755 
756 	if (test_bit(ENABLE_WALTEST, &plat_priv->ctrl_params.quirks)) {
757 		ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
758 						    CNSS_WALTEST);
759 	} else if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state)) {
760 		cnss_request_antenna_sharing(plat_priv);
761 		cnss_cal_file_download_to_mem(plat_priv, &cal_file_size);
762 		cnss_wlfw_cal_report_req_send_sync(plat_priv, cal_file_size);
763 		plat_priv->cal_time = jiffies;
764 		ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
765 						    CNSS_CALIBRATION);
766 	} else {
767 		ret = cnss_setup_dms_mac(plat_priv);
768 		ret = cnss_bus_call_driver_probe(plat_priv);
769 	}
770 
771 	if (ret && test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
772 		goto out;
773 	else if (ret)
774 		goto shutdown;
775 
776 	cnss_vreg_unvote_type(plat_priv, CNSS_VREG_PRIM);
777 
778 	return 0;
779 
780 shutdown:
781 	cnss_bus_dev_shutdown(plat_priv);
782 
783 	clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
784 	clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
785 
786 out:
787 	return ret;
788 }
789 
790 static char *cnss_driver_event_to_str(enum cnss_driver_event_type type)
791 {
792 	switch (type) {
793 	case CNSS_DRIVER_EVENT_SERVER_ARRIVE:
794 		return "SERVER_ARRIVE";
795 	case CNSS_DRIVER_EVENT_SERVER_EXIT:
796 		return "SERVER_EXIT";
797 	case CNSS_DRIVER_EVENT_REQUEST_MEM:
798 		return "REQUEST_MEM";
799 	case CNSS_DRIVER_EVENT_FW_MEM_READY:
800 		return "FW_MEM_READY";
801 	case CNSS_DRIVER_EVENT_FW_READY:
802 		return "FW_READY";
803 	case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START:
804 		return "COLD_BOOT_CAL_START";
805 	case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE:
806 		return "COLD_BOOT_CAL_DONE";
807 	case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
808 		return "REGISTER_DRIVER";
809 	case CNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
810 		return "UNREGISTER_DRIVER";
811 	case CNSS_DRIVER_EVENT_RECOVERY:
812 		return "RECOVERY";
813 	case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
814 		return "FORCE_FW_ASSERT";
815 	case CNSS_DRIVER_EVENT_POWER_UP:
816 		return "POWER_UP";
817 	case CNSS_DRIVER_EVENT_POWER_DOWN:
818 		return "POWER_DOWN";
819 	case CNSS_DRIVER_EVENT_IDLE_RESTART:
820 		return "IDLE_RESTART";
821 	case CNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
822 		return "IDLE_SHUTDOWN";
823 	case CNSS_DRIVER_EVENT_IMS_WFC_CALL_IND:
824 		return "IMS_WFC_CALL_IND";
825 	case CNSS_DRIVER_EVENT_WLFW_TWT_CFG_IND:
826 		return "WLFW_TWC_CFG_IND";
827 	case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
828 		return "QDSS_TRACE_REQ_MEM";
829 	case CNSS_DRIVER_EVENT_FW_MEM_FILE_SAVE:
830 		return "FW_MEM_FILE_SAVE";
831 	case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
832 		return "QDSS_TRACE_FREE";
833 	case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA:
834 		return "QDSS_TRACE_REQ_DATA";
835 	case CNSS_DRIVER_EVENT_MAX:
836 		return "EVENT_MAX";
837 	}
838 
839 	return "UNKNOWN";
840 };
841 
842 int cnss_driver_event_post(struct cnss_plat_data *plat_priv,
843 			   enum cnss_driver_event_type type,
844 			   u32 flags, void *data)
845 {
846 	struct cnss_driver_event *event;
847 	unsigned long irq_flags;
848 	int gfp = GFP_KERNEL;
849 	int ret = 0;
850 
851 	if (!plat_priv)
852 		return -ENODEV;
853 
854 	cnss_pr_dbg("Posting event: %s(%d)%s, state: 0x%lx flags: 0x%0x\n",
855 		    cnss_driver_event_to_str(type), type,
856 		    flags ? "-sync" : "", plat_priv->driver_state, flags);
857 
858 	if (type >= CNSS_DRIVER_EVENT_MAX) {
859 		cnss_pr_err("Invalid Event type: %d, can't post", type);
860 		return -EINVAL;
861 	}
862 
863 	if (in_interrupt() || irqs_disabled())
864 		gfp = GFP_ATOMIC;
865 
866 	event = kzalloc(sizeof(*event), gfp);
867 	if (!event)
868 		return -ENOMEM;
869 
870 	cnss_pm_stay_awake(plat_priv);
871 
872 	event->type = type;
873 	event->data = data;
874 	init_completion(&event->complete);
875 	event->ret = CNSS_EVENT_PENDING;
876 	event->sync = !!(flags & CNSS_EVENT_SYNC);
877 
878 	spin_lock_irqsave(&plat_priv->event_lock, irq_flags);
879 	list_add_tail(&event->list, &plat_priv->event_list);
880 	spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
881 
882 	queue_work(plat_priv->event_wq, &plat_priv->event_work);
883 
884 	if (!(flags & CNSS_EVENT_SYNC))
885 		goto out;
886 
887 	if (flags & CNSS_EVENT_UNKILLABLE)
888 		wait_for_completion(&event->complete);
889 	else if (flags & CNSS_EVENT_UNINTERRUPTIBLE)
890 		ret = wait_for_completion_killable(&event->complete);
891 	else
892 		ret = wait_for_completion_interruptible(&event->complete);
893 
894 	cnss_pr_dbg("Completed event: %s(%d), state: 0x%lx, ret: %d/%d\n",
895 		    cnss_driver_event_to_str(type), type,
896 		    plat_priv->driver_state, ret, event->ret);
897 	spin_lock_irqsave(&plat_priv->event_lock, irq_flags);
898 	if (ret == -ERESTARTSYS && event->ret == CNSS_EVENT_PENDING) {
899 		event->sync = false;
900 		spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
901 		ret = -EINTR;
902 		goto out;
903 	}
904 	spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
905 
906 	ret = event->ret;
907 	kfree(event);
908 
909 out:
910 	cnss_pm_relax(plat_priv);
911 	return ret;
912 }
913 
914 /**
915  * cnss_get_timeout - Get timeout for corresponding type.
916  * @plat_priv: Pointer to platform driver context.
917  * @cnss_timeout_type: Timeout type.
918  *
919  * Return: Timeout in milliseconds.
920  */
921 unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv,
922 			      enum cnss_timeout_type timeout_type)
923 {
924 	unsigned int qmi_timeout = cnss_get_qmi_timeout(plat_priv);
925 
926 	switch (timeout_type) {
927 	case CNSS_TIMEOUT_QMI:
928 		return qmi_timeout;
929 	case CNSS_TIMEOUT_POWER_UP:
930 		return (qmi_timeout << 2);
931 	case CNSS_TIMEOUT_IDLE_RESTART:
932 		/* In idle restart power up sequence, we have fw_boot_timer to
933 		 * handle FW initialization failure.
934 		 * It uses WLAN_MISSION_MODE_TIMEOUT, so setup 3x that time to
935 		 * account for FW dump collection and FW re-initialization on
936 		 * retry.
937 		 */
938 		return (qmi_timeout + WLAN_MISSION_MODE_TIMEOUT * 3);
939 	case CNSS_TIMEOUT_CALIBRATION:
940 		/* Similar to mission mode, in CBC if FW init fails
941 		 * fw recovery is tried. Thus return 2x the CBC timeout.
942 		 */
943 		return (qmi_timeout + WLAN_COLD_BOOT_CAL_TIMEOUT * 2);
944 	case CNSS_TIMEOUT_WLAN_WATCHDOG:
945 		return ((qmi_timeout << 1) + WLAN_WD_TIMEOUT_MS);
946 	case CNSS_TIMEOUT_RDDM:
947 		return CNSS_RDDM_TIMEOUT_MS;
948 	case CNSS_TIMEOUT_RECOVERY:
949 		return RECOVERY_TIMEOUT;
950 	case CNSS_TIMEOUT_DAEMON_CONNECTION:
951 		return qmi_timeout + CNSS_DAEMON_CONNECT_TIMEOUT_MS;
952 	default:
953 		return qmi_timeout;
954 	}
955 }
956 
957 unsigned int cnss_get_boot_timeout(struct device *dev)
958 {
959 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
960 
961 	if (!plat_priv) {
962 		cnss_pr_err("plat_priv is NULL\n");
963 		return 0;
964 	}
965 
966 	return cnss_get_timeout(plat_priv, CNSS_TIMEOUT_QMI);
967 }
968 EXPORT_SYMBOL(cnss_get_boot_timeout);
969 
970 int cnss_power_up(struct device *dev)
971 {
972 	int ret = 0;
973 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
974 	unsigned int timeout;
975 
976 	if (!plat_priv) {
977 		cnss_pr_err("plat_priv is NULL\n");
978 		return -ENODEV;
979 	}
980 
981 	cnss_pr_dbg("Powering up device\n");
982 
983 	ret = cnss_driver_event_post(plat_priv,
984 				     CNSS_DRIVER_EVENT_POWER_UP,
985 				     CNSS_EVENT_SYNC, NULL);
986 	if (ret)
987 		goto out;
988 
989 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
990 		goto out;
991 
992 	timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_POWER_UP);
993 
994 	reinit_completion(&plat_priv->power_up_complete);
995 	ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
996 					  msecs_to_jiffies(timeout));
997 	if (!ret) {
998 		cnss_pr_err("Timeout (%ums) waiting for power up to complete\n",
999 			    timeout);
1000 		ret = -EAGAIN;
1001 		goto out;
1002 	}
1003 
1004 	return 0;
1005 
1006 out:
1007 	return ret;
1008 }
1009 EXPORT_SYMBOL(cnss_power_up);
1010 
1011 int cnss_power_down(struct device *dev)
1012 {
1013 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1014 
1015 	if (!plat_priv) {
1016 		cnss_pr_err("plat_priv is NULL\n");
1017 		return -ENODEV;
1018 	}
1019 
1020 	cnss_pr_dbg("Powering down device\n");
1021 
1022 	return cnss_driver_event_post(plat_priv,
1023 				      CNSS_DRIVER_EVENT_POWER_DOWN,
1024 				      CNSS_EVENT_SYNC, NULL);
1025 }
1026 EXPORT_SYMBOL(cnss_power_down);
1027 
1028 int cnss_idle_restart(struct device *dev)
1029 {
1030 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1031 	unsigned int timeout;
1032 	int ret = 0;
1033 
1034 	if (!plat_priv) {
1035 		cnss_pr_err("plat_priv is NULL\n");
1036 		return -ENODEV;
1037 	}
1038 
1039 	if (!mutex_trylock(&plat_priv->driver_ops_lock)) {
1040 		cnss_pr_dbg("Another driver operation is in progress, ignore idle restart\n");
1041 		return -EBUSY;
1042 	}
1043 
1044 	cnss_pr_dbg("Doing idle restart\n");
1045 
1046 	reinit_completion(&plat_priv->power_up_complete);
1047 
1048 	if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
1049 		cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n");
1050 		ret = -EINVAL;
1051 		goto out;
1052 	}
1053 
1054 	ret = cnss_driver_event_post(plat_priv,
1055 				     CNSS_DRIVER_EVENT_IDLE_RESTART,
1056 				     CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
1057 	if (ret)
1058 		goto out;
1059 
1060 	if (plat_priv->device_id == QCA6174_DEVICE_ID) {
1061 		ret = cnss_bus_call_driver_probe(plat_priv);
1062 		goto out;
1063 	}
1064 
1065 	timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_IDLE_RESTART);
1066 	ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
1067 					  msecs_to_jiffies(timeout));
1068 	if (plat_priv->power_up_error) {
1069 		ret = plat_priv->power_up_error;
1070 		clear_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state);
1071 		cnss_pr_dbg("Power up error:%d, exiting\n",
1072 			    plat_priv->power_up_error);
1073 		goto out;
1074 	}
1075 
1076 	if (!ret) {
1077 		/* This exception occurs after attempting retry of FW recovery.
1078 		 * Thus we can safely power off the device.
1079 		 */
1080 		cnss_fatal_err("Timeout (%ums) waiting for idle restart to complete\n",
1081 			       timeout);
1082 		ret = -ETIMEDOUT;
1083 		cnss_power_down(dev);
1084 		CNSS_ASSERT(0);
1085 		goto out;
1086 	}
1087 
1088 	if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
1089 		cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n");
1090 		del_timer(&plat_priv->fw_boot_timer);
1091 		ret = -EINVAL;
1092 		goto out;
1093 	}
1094 
1095 	/* In non-DRV mode, remove MHI satellite configuration. Switching to
1096 	 * non-DRV is supported only once after device reboots and before wifi
1097 	 * is turned on. We do not allow switching back to DRV.
1098 	 * To bring device back into DRV, user needs to reboot device.
1099 	 */
1100 	if (test_bit(DISABLE_DRV, &plat_priv->ctrl_params.quirks)) {
1101 		cnss_pr_dbg("DRV is disabled\n");
1102 		cnss_bus_disable_mhi_satellite_cfg(plat_priv);
1103 	}
1104 
1105 	mutex_unlock(&plat_priv->driver_ops_lock);
1106 	return 0;
1107 
1108 out:
1109 	mutex_unlock(&plat_priv->driver_ops_lock);
1110 	return ret;
1111 }
1112 EXPORT_SYMBOL(cnss_idle_restart);
1113 
1114 int cnss_idle_shutdown(struct device *dev)
1115 {
1116 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1117 	unsigned int timeout;
1118 	int ret;
1119 
1120 	if (!plat_priv) {
1121 		cnss_pr_err("plat_priv is NULL\n");
1122 		return -ENODEV;
1123 	}
1124 
1125 	if (test_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state)) {
1126 		cnss_pr_dbg("System suspend or resume in progress, ignore idle shutdown\n");
1127 		return -EAGAIN;
1128 	}
1129 
1130 	cnss_pr_dbg("Doing idle shutdown\n");
1131 
1132 	if (!test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
1133 	    !test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
1134 		goto skip_wait;
1135 
1136 	reinit_completion(&plat_priv->recovery_complete);
1137 	timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_RECOVERY);
1138 	ret = wait_for_completion_timeout(&plat_priv->recovery_complete,
1139 					  msecs_to_jiffies(timeout));
1140 	if (!ret) {
1141 		cnss_pr_err("Timeout (%ums) waiting for recovery to complete\n",
1142 			    timeout);
1143 		CNSS_ASSERT(0);
1144 	}
1145 
1146 skip_wait:
1147 	return cnss_driver_event_post(plat_priv,
1148 				      CNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
1149 				      CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
1150 }
1151 EXPORT_SYMBOL(cnss_idle_shutdown);
1152 
1153 static int cnss_get_resources(struct cnss_plat_data *plat_priv)
1154 {
1155 	int ret = 0;
1156 
1157 	ret = cnss_get_vreg_type(plat_priv, CNSS_VREG_PRIM);
1158 	if (ret) {
1159 		cnss_pr_err("Failed to get vreg, err = %d\n", ret);
1160 		goto out;
1161 	}
1162 
1163 	ret = cnss_get_clk(plat_priv);
1164 	if (ret) {
1165 		cnss_pr_err("Failed to get clocks, err = %d\n", ret);
1166 		goto put_vreg;
1167 	}
1168 
1169 	ret = cnss_get_pinctrl(plat_priv);
1170 	if (ret) {
1171 		cnss_pr_err("Failed to get pinctrl, err = %d\n", ret);
1172 		goto put_clk;
1173 	}
1174 
1175 	return 0;
1176 
1177 put_clk:
1178 	cnss_put_clk(plat_priv);
1179 put_vreg:
1180 	cnss_put_vreg_type(plat_priv, CNSS_VREG_PRIM);
1181 out:
1182 	return ret;
1183 }
1184 
1185 static void cnss_put_resources(struct cnss_plat_data *plat_priv)
1186 {
1187 	cnss_put_clk(plat_priv);
1188 	cnss_put_vreg_type(plat_priv, CNSS_VREG_PRIM);
1189 }
1190 
1191 #if IS_ENABLED(CONFIG_ESOC) && IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
1192 static int cnss_modem_notifier_nb(struct notifier_block *nb,
1193 				  unsigned long code,
1194 				  void *ss_handle)
1195 {
1196 	struct cnss_plat_data *plat_priv =
1197 		container_of(nb, struct cnss_plat_data, modem_nb);
1198 	struct cnss_esoc_info *esoc_info;
1199 
1200 	cnss_pr_dbg("Modem notifier: event %lu\n", code);
1201 
1202 	if (!plat_priv)
1203 		return NOTIFY_DONE;
1204 
1205 	esoc_info = &plat_priv->esoc_info;
1206 
1207 	if (code == SUBSYS_AFTER_POWERUP)
1208 		esoc_info->modem_current_status = 1;
1209 	else if (code == SUBSYS_BEFORE_SHUTDOWN)
1210 		esoc_info->modem_current_status = 0;
1211 	else
1212 		return NOTIFY_DONE;
1213 
1214 	if (!cnss_bus_call_driver_modem_status(plat_priv,
1215 					       esoc_info->modem_current_status))
1216 		return NOTIFY_DONE;
1217 
1218 	return NOTIFY_OK;
1219 }
1220 
1221 static int cnss_register_esoc(struct cnss_plat_data *plat_priv)
1222 {
1223 	int ret = 0;
1224 	struct device *dev;
1225 	struct cnss_esoc_info *esoc_info;
1226 	struct esoc_desc *esoc_desc;
1227 	const char *client_desc;
1228 
1229 	dev = &plat_priv->plat_dev->dev;
1230 	esoc_info = &plat_priv->esoc_info;
1231 
1232 	esoc_info->notify_modem_status =
1233 		of_property_read_bool(dev->of_node,
1234 				      "qcom,notify-modem-status");
1235 
1236 	if (!esoc_info->notify_modem_status)
1237 		goto out;
1238 
1239 	ret = of_property_read_string_index(dev->of_node, "esoc-names", 0,
1240 					    &client_desc);
1241 	if (ret) {
1242 		cnss_pr_dbg("esoc-names is not defined in DT, skip!\n");
1243 	} else {
1244 		esoc_desc = devm_register_esoc_client(dev, client_desc);
1245 		if (IS_ERR_OR_NULL(esoc_desc)) {
1246 			ret = PTR_RET(esoc_desc);
1247 			cnss_pr_err("Failed to register esoc_desc, err = %d\n",
1248 				    ret);
1249 			goto out;
1250 		}
1251 		esoc_info->esoc_desc = esoc_desc;
1252 	}
1253 
1254 	plat_priv->modem_nb.notifier_call = cnss_modem_notifier_nb;
1255 	esoc_info->modem_current_status = 0;
1256 	esoc_info->modem_notify_handler =
1257 		subsys_notif_register_notifier(esoc_info->esoc_desc ?
1258 					       esoc_info->esoc_desc->name :
1259 					       "modem", &plat_priv->modem_nb);
1260 	if (IS_ERR(esoc_info->modem_notify_handler)) {
1261 		ret = PTR_ERR(esoc_info->modem_notify_handler);
1262 		cnss_pr_err("Failed to register esoc notifier, err = %d\n",
1263 			    ret);
1264 		goto unreg_esoc;
1265 	}
1266 
1267 	return 0;
1268 unreg_esoc:
1269 	if (esoc_info->esoc_desc)
1270 		devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
1271 out:
1272 	return ret;
1273 }
1274 
1275 static void cnss_unregister_esoc(struct cnss_plat_data *plat_priv)
1276 {
1277 	struct device *dev;
1278 	struct cnss_esoc_info *esoc_info;
1279 
1280 	dev = &plat_priv->plat_dev->dev;
1281 	esoc_info = &plat_priv->esoc_info;
1282 
1283 	if (esoc_info->notify_modem_status)
1284 		subsys_notif_unregister_notifier
1285 		(esoc_info->modem_notify_handler,
1286 		 &plat_priv->modem_nb);
1287 	if (esoc_info->esoc_desc)
1288 		devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
1289 }
1290 #else
1291 static inline int cnss_register_esoc(struct cnss_plat_data *plat_priv)
1292 {
1293 	return 0;
1294 }
1295 
1296 static inline void cnss_unregister_esoc(struct cnss_plat_data *plat_priv) {}
1297 #endif
1298 
1299 int cnss_enable_dev_sol_irq(struct cnss_plat_data *plat_priv)
1300 {
1301 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1302 	int ret = 0;
1303 
1304 	if (sol_gpio->dev_sol_gpio < 0 || sol_gpio->dev_sol_irq <= 0)
1305 		return 0;
1306 
1307 	enable_irq(sol_gpio->dev_sol_irq);
1308 	ret = enable_irq_wake(sol_gpio->dev_sol_irq);
1309 	if (ret)
1310 		cnss_pr_err("Failed to enable device SOL as wake IRQ, err = %d\n",
1311 			    ret);
1312 
1313 	return ret;
1314 }
1315 
1316 int cnss_disable_dev_sol_irq(struct cnss_plat_data *plat_priv)
1317 {
1318 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1319 	int ret = 0;
1320 
1321 	if (sol_gpio->dev_sol_gpio < 0 || sol_gpio->dev_sol_irq <= 0)
1322 		return 0;
1323 
1324 	ret = disable_irq_wake(sol_gpio->dev_sol_irq);
1325 	if (ret)
1326 		cnss_pr_err("Failed to disable device SOL as wake IRQ, err = %d\n",
1327 			    ret);
1328 	disable_irq(sol_gpio->dev_sol_irq);
1329 
1330 	return ret;
1331 }
1332 
1333 int cnss_get_dev_sol_value(struct cnss_plat_data *plat_priv)
1334 {
1335 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1336 
1337 	if (sol_gpio->dev_sol_gpio < 0)
1338 		return -EINVAL;
1339 
1340 	return gpio_get_value(sol_gpio->dev_sol_gpio);
1341 }
1342 
1343 static irqreturn_t cnss_dev_sol_handler(int irq, void *data)
1344 {
1345 	struct cnss_plat_data *plat_priv = data;
1346 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1347 
1348 	sol_gpio->dev_sol_counter++;
1349 	cnss_pr_dbg("WLAN device SOL IRQ (%u) is asserted #%u\n",
1350 		    irq, sol_gpio->dev_sol_counter);
1351 
1352 	/* Make sure abort current suspend */
1353 	cnss_pm_stay_awake(plat_priv);
1354 	cnss_pm_relax(plat_priv);
1355 	pm_system_wakeup();
1356 
1357 	cnss_bus_handle_dev_sol_irq(plat_priv);
1358 
1359 	return IRQ_HANDLED;
1360 }
1361 
1362 static int cnss_init_dev_sol_gpio(struct cnss_plat_data *plat_priv)
1363 {
1364 	struct device *dev = &plat_priv->plat_dev->dev;
1365 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1366 	int ret = 0;
1367 
1368 	sol_gpio->dev_sol_gpio = of_get_named_gpio(dev->of_node,
1369 						   "wlan-dev-sol-gpio", 0);
1370 	if (sol_gpio->dev_sol_gpio < 0)
1371 		goto out;
1372 
1373 	cnss_pr_dbg("Get device SOL GPIO (%d) from device node\n",
1374 		    sol_gpio->dev_sol_gpio);
1375 
1376 	ret = gpio_request(sol_gpio->dev_sol_gpio, "wlan_dev_sol_gpio");
1377 	if (ret) {
1378 		cnss_pr_err("Failed to request device SOL GPIO, err = %d\n",
1379 			    ret);
1380 		goto out;
1381 	}
1382 
1383 	gpio_direction_input(sol_gpio->dev_sol_gpio);
1384 	sol_gpio->dev_sol_irq = gpio_to_irq(sol_gpio->dev_sol_gpio);
1385 
1386 	ret = request_irq(sol_gpio->dev_sol_irq, cnss_dev_sol_handler,
1387 			  IRQF_TRIGGER_FALLING, "wlan_dev_sol_irq", plat_priv);
1388 	if (ret) {
1389 		cnss_pr_err("Failed to request device SOL IRQ, err = %d\n", ret);
1390 		goto free_gpio;
1391 	}
1392 
1393 	return 0;
1394 
1395 free_gpio:
1396 	gpio_free(sol_gpio->dev_sol_gpio);
1397 out:
1398 	return ret;
1399 }
1400 
1401 static void cnss_deinit_dev_sol_gpio(struct cnss_plat_data *plat_priv)
1402 {
1403 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1404 
1405 	if (sol_gpio->dev_sol_gpio < 0)
1406 		return;
1407 
1408 	free_irq(sol_gpio->dev_sol_irq, plat_priv);
1409 	gpio_free(sol_gpio->dev_sol_gpio);
1410 }
1411 
1412 int cnss_set_host_sol_value(struct cnss_plat_data *plat_priv, int value)
1413 {
1414 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1415 
1416 	if (sol_gpio->host_sol_gpio < 0)
1417 		return -EINVAL;
1418 
1419 	if (value)
1420 		cnss_pr_dbg("Assert host SOL GPIO\n");
1421 	gpio_set_value(sol_gpio->host_sol_gpio, value);
1422 
1423 	return 0;
1424 }
1425 
1426 int cnss_get_host_sol_value(struct cnss_plat_data *plat_priv)
1427 {
1428 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1429 
1430 	if (sol_gpio->host_sol_gpio < 0)
1431 		return -EINVAL;
1432 
1433 	return gpio_get_value(sol_gpio->host_sol_gpio);
1434 }
1435 
1436 static int cnss_init_host_sol_gpio(struct cnss_plat_data *plat_priv)
1437 {
1438 	struct device *dev = &plat_priv->plat_dev->dev;
1439 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1440 	int ret = 0;
1441 
1442 	sol_gpio->host_sol_gpio = of_get_named_gpio(dev->of_node,
1443 						    "wlan-host-sol-gpio", 0);
1444 	if (sol_gpio->host_sol_gpio < 0)
1445 		goto out;
1446 
1447 	cnss_pr_dbg("Get host SOL GPIO (%d) from device node\n",
1448 		    sol_gpio->host_sol_gpio);
1449 
1450 	ret = gpio_request(sol_gpio->host_sol_gpio, "wlan_host_sol_gpio");
1451 	if (ret) {
1452 		cnss_pr_err("Failed to request host SOL GPIO, err = %d\n",
1453 			    ret);
1454 		goto out;
1455 	}
1456 
1457 	gpio_direction_output(sol_gpio->host_sol_gpio, 0);
1458 
1459 	return 0;
1460 
1461 out:
1462 	return ret;
1463 }
1464 
1465 static void cnss_deinit_host_sol_gpio(struct cnss_plat_data *plat_priv)
1466 {
1467 	struct cnss_sol_gpio *sol_gpio = &plat_priv->sol_gpio;
1468 
1469 	if (sol_gpio->host_sol_gpio < 0)
1470 		return;
1471 
1472 	gpio_free(sol_gpio->host_sol_gpio);
1473 }
1474 
1475 static int cnss_init_sol_gpio(struct cnss_plat_data *plat_priv)
1476 {
1477 	int ret;
1478 
1479 	ret = cnss_init_dev_sol_gpio(plat_priv);
1480 	if (ret)
1481 		goto out;
1482 
1483 	ret = cnss_init_host_sol_gpio(plat_priv);
1484 	if (ret)
1485 		goto deinit_dev_sol;
1486 
1487 	return 0;
1488 
1489 deinit_dev_sol:
1490 	cnss_deinit_dev_sol_gpio(plat_priv);
1491 out:
1492 	return ret;
1493 }
1494 
1495 static void cnss_deinit_sol_gpio(struct cnss_plat_data *plat_priv)
1496 {
1497 	cnss_deinit_host_sol_gpio(plat_priv);
1498 	cnss_deinit_dev_sol_gpio(plat_priv);
1499 }
1500 
1501 #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
1502 static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
1503 {
1504 	struct cnss_plat_data *plat_priv;
1505 	int ret = 0;
1506 
1507 	if (!subsys_desc->dev) {
1508 		cnss_pr_err("dev from subsys_desc is NULL\n");
1509 		return -ENODEV;
1510 	}
1511 
1512 	plat_priv = dev_get_drvdata(subsys_desc->dev);
1513 	if (!plat_priv) {
1514 		cnss_pr_err("plat_priv is NULL\n");
1515 		return -ENODEV;
1516 	}
1517 
1518 	if (!plat_priv->driver_state) {
1519 		cnss_pr_dbg("subsys powerup is ignored\n");
1520 		return 0;
1521 	}
1522 
1523 	ret = cnss_bus_dev_powerup(plat_priv);
1524 	if (ret)
1525 		__pm_relax(plat_priv->recovery_ws);
1526 	return ret;
1527 }
1528 
1529 static int cnss_subsys_shutdown(const struct subsys_desc *subsys_desc,
1530 				bool force_stop)
1531 {
1532 	struct cnss_plat_data *plat_priv;
1533 
1534 	if (!subsys_desc->dev) {
1535 		cnss_pr_err("dev from subsys_desc is NULL\n");
1536 		return -ENODEV;
1537 	}
1538 
1539 	plat_priv = dev_get_drvdata(subsys_desc->dev);
1540 	if (!plat_priv) {
1541 		cnss_pr_err("plat_priv is NULL\n");
1542 		return -ENODEV;
1543 	}
1544 
1545 	if (!plat_priv->driver_state) {
1546 		cnss_pr_dbg("subsys shutdown is ignored\n");
1547 		return 0;
1548 	}
1549 
1550 	return cnss_bus_dev_shutdown(plat_priv);
1551 }
1552 
1553 void cnss_device_crashed(struct device *dev)
1554 {
1555 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1556 	struct cnss_subsys_info *subsys_info;
1557 
1558 	if (!plat_priv)
1559 		return;
1560 
1561 	subsys_info = &plat_priv->subsys_info;
1562 	if (subsys_info->subsys_device) {
1563 		set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1564 		subsys_set_crash_status(subsys_info->subsys_device, true);
1565 		subsystem_restart_dev(subsys_info->subsys_device);
1566 	}
1567 }
1568 EXPORT_SYMBOL(cnss_device_crashed);
1569 
1570 static void cnss_subsys_crash_shutdown(const struct subsys_desc *subsys_desc)
1571 {
1572 	struct cnss_plat_data *plat_priv = dev_get_drvdata(subsys_desc->dev);
1573 
1574 	if (!plat_priv) {
1575 		cnss_pr_err("plat_priv is NULL\n");
1576 		return;
1577 	}
1578 
1579 	cnss_bus_dev_crash_shutdown(plat_priv);
1580 }
1581 
1582 static int cnss_subsys_ramdump(int enable,
1583 			       const struct subsys_desc *subsys_desc)
1584 {
1585 	struct cnss_plat_data *plat_priv = dev_get_drvdata(subsys_desc->dev);
1586 
1587 	if (!plat_priv) {
1588 		cnss_pr_err("plat_priv is NULL\n");
1589 		return -ENODEV;
1590 	}
1591 
1592 	if (!enable)
1593 		return 0;
1594 
1595 	return cnss_bus_dev_ramdump(plat_priv);
1596 }
1597 
1598 static void cnss_recovery_work_handler(struct work_struct *work)
1599 {
1600 }
1601 #else
1602 static void cnss_recovery_work_handler(struct work_struct *work)
1603 {
1604 	int ret;
1605 
1606 	struct cnss_plat_data *plat_priv =
1607 		container_of(work, struct cnss_plat_data, recovery_work);
1608 
1609 	if (!plat_priv->recovery_enabled)
1610 		panic("subsys-restart: Resetting the SoC wlan crashed\n");
1611 
1612 	cnss_bus_dev_shutdown(plat_priv);
1613 	cnss_bus_dev_ramdump(plat_priv);
1614 	msleep(POWER_RESET_MIN_DELAY_MS);
1615 
1616 	ret = cnss_bus_dev_powerup(plat_priv);
1617 	if (ret)
1618 		__pm_relax(plat_priv->recovery_ws);
1619 
1620 	return;
1621 }
1622 
1623 void cnss_device_crashed(struct device *dev)
1624 {
1625 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1626 
1627 	if (!plat_priv)
1628 		return;
1629 
1630 	set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1631 	schedule_work(&plat_priv->recovery_work);
1632 }
1633 EXPORT_SYMBOL(cnss_device_crashed);
1634 #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
1635 
1636 void *cnss_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
1637 {
1638 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1639 	struct cnss_ramdump_info *ramdump_info;
1640 
1641 	if (!plat_priv)
1642 		return NULL;
1643 
1644 	ramdump_info = &plat_priv->ramdump_info;
1645 	*size = ramdump_info->ramdump_size;
1646 
1647 	return ramdump_info->ramdump_va;
1648 }
1649 EXPORT_SYMBOL(cnss_get_virt_ramdump_mem);
1650 
1651 static const char *cnss_recovery_reason_to_str(enum cnss_recovery_reason reason)
1652 {
1653 	switch (reason) {
1654 	case CNSS_REASON_DEFAULT:
1655 		return "DEFAULT";
1656 	case CNSS_REASON_LINK_DOWN:
1657 		return "LINK_DOWN";
1658 	case CNSS_REASON_RDDM:
1659 		return "RDDM";
1660 	case CNSS_REASON_TIMEOUT:
1661 		return "TIMEOUT";
1662 	}
1663 
1664 	return "UNKNOWN";
1665 };
1666 
1667 static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
1668 			    enum cnss_recovery_reason reason)
1669 {
1670 	plat_priv->recovery_count++;
1671 
1672 	if (plat_priv->device_id == QCA6174_DEVICE_ID)
1673 		goto self_recovery;
1674 
1675 	if (test_bit(SKIP_RECOVERY, &plat_priv->ctrl_params.quirks)) {
1676 		cnss_pr_dbg("Skip device recovery\n");
1677 		return 0;
1678 	}
1679 
1680 	/* FW recovery sequence has multiple steps and firmware load requires
1681 	 * linux PM in awake state. Thus hold the cnss wake source until
1682 	 * WLAN MISSION enabled. CNSS_TIMEOUT_RECOVERY option should cover all
1683 	 * time taken in this process.
1684 	 */
1685 	pm_wakeup_ws_event(plat_priv->recovery_ws,
1686 			   cnss_get_timeout(plat_priv, CNSS_TIMEOUT_RECOVERY),
1687 			   true);
1688 
1689 	switch (reason) {
1690 	case CNSS_REASON_LINK_DOWN:
1691 		if (!cnss_bus_check_link_status(plat_priv)) {
1692 			cnss_pr_dbg("Skip link down recovery as link is already up\n");
1693 			return 0;
1694 		}
1695 		if (test_bit(LINK_DOWN_SELF_RECOVERY,
1696 			     &plat_priv->ctrl_params.quirks))
1697 			goto self_recovery;
1698 		if (!cnss_bus_recover_link_down(plat_priv)) {
1699 			/* clear recovery bit here to avoid skipping
1700 			 * the recovery work for RDDM later
1701 			 */
1702 			clear_bit(CNSS_DRIVER_RECOVERY,
1703 				  &plat_priv->driver_state);
1704 			return 0;
1705 		}
1706 		break;
1707 	case CNSS_REASON_RDDM:
1708 		cnss_bus_collect_dump_info(plat_priv, false);
1709 		break;
1710 	case CNSS_REASON_DEFAULT:
1711 	case CNSS_REASON_TIMEOUT:
1712 		break;
1713 	default:
1714 		cnss_pr_err("Unsupported recovery reason: %s(%d)\n",
1715 			    cnss_recovery_reason_to_str(reason), reason);
1716 		break;
1717 	}
1718 	cnss_bus_device_crashed(plat_priv);
1719 
1720 	return 0;
1721 
1722 self_recovery:
1723 	cnss_pr_dbg("Going for self recovery\n");
1724 	cnss_bus_dev_shutdown(plat_priv);
1725 
1726 	if (test_bit(LINK_DOWN_SELF_RECOVERY, &plat_priv->ctrl_params.quirks))
1727 		clear_bit(LINK_DOWN_SELF_RECOVERY,
1728 			  &plat_priv->ctrl_params.quirks);
1729 
1730 	cnss_bus_dev_powerup(plat_priv);
1731 
1732 	return 0;
1733 }
1734 
1735 static int cnss_driver_recovery_hdlr(struct cnss_plat_data *plat_priv,
1736 				     void *data)
1737 {
1738 	struct cnss_recovery_data *recovery_data = data;
1739 	int ret = 0;
1740 
1741 	cnss_pr_dbg("Driver recovery is triggered with reason: %s(%d)\n",
1742 		    cnss_recovery_reason_to_str(recovery_data->reason),
1743 		    recovery_data->reason);
1744 
1745 	if (!plat_priv->driver_state) {
1746 		cnss_pr_err("Improper driver state, ignore recovery\n");
1747 		ret = -EINVAL;
1748 		goto out;
1749 	}
1750 
1751 	if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
1752 		cnss_pr_err("Reboot is in progress, ignore recovery\n");
1753 		ret = -EINVAL;
1754 		goto out;
1755 	}
1756 
1757 	if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1758 		cnss_pr_err("Recovery is already in progress\n");
1759 		CNSS_ASSERT(0);
1760 		ret = -EINVAL;
1761 		goto out;
1762 	}
1763 
1764 	if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
1765 	    test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
1766 		cnss_pr_err("Driver unload or idle shutdown is in progress, ignore recovery\n");
1767 		ret = -EINVAL;
1768 		goto out;
1769 	}
1770 
1771 	switch (plat_priv->device_id) {
1772 	case QCA6174_DEVICE_ID:
1773 		if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
1774 		    test_bit(CNSS_DRIVER_IDLE_RESTART,
1775 			     &plat_priv->driver_state)) {
1776 			cnss_pr_err("Driver load or idle restart is in progress, ignore recovery\n");
1777 			ret = -EINVAL;
1778 			goto out;
1779 		}
1780 		break;
1781 	default:
1782 		if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
1783 			set_bit(CNSS_FW_BOOT_RECOVERY,
1784 				&plat_priv->driver_state);
1785 		}
1786 		break;
1787 	}
1788 
1789 	set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1790 	ret = cnss_do_recovery(plat_priv, recovery_data->reason);
1791 
1792 out:
1793 	kfree(data);
1794 	return ret;
1795 }
1796 
1797 int cnss_self_recovery(struct device *dev,
1798 		       enum cnss_recovery_reason reason)
1799 {
1800 	cnss_schedule_recovery(dev, reason);
1801 	return 0;
1802 }
1803 EXPORT_SYMBOL(cnss_self_recovery);
1804 
1805 void cnss_schedule_recovery(struct device *dev,
1806 			    enum cnss_recovery_reason reason)
1807 {
1808 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1809 	struct cnss_recovery_data *data;
1810 	int gfp = GFP_KERNEL;
1811 
1812 	if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
1813 		cnss_bus_update_status(plat_priv, CNSS_FW_DOWN);
1814 
1815 	if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
1816 	    test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
1817 		cnss_pr_dbg("Driver unload or idle shutdown is in progress, ignore schedule recovery\n");
1818 		return;
1819 	}
1820 
1821 	if (in_interrupt() || irqs_disabled())
1822 		gfp = GFP_ATOMIC;
1823 
1824 	data = kzalloc(sizeof(*data), gfp);
1825 	if (!data)
1826 		return;
1827 
1828 	data->reason = reason;
1829 	cnss_driver_event_post(plat_priv,
1830 			       CNSS_DRIVER_EVENT_RECOVERY,
1831 			       0, data);
1832 }
1833 EXPORT_SYMBOL(cnss_schedule_recovery);
1834 
1835 int cnss_force_fw_assert(struct device *dev)
1836 {
1837 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1838 
1839 	if (!plat_priv) {
1840 		cnss_pr_err("plat_priv is NULL\n");
1841 		return -ENODEV;
1842 	}
1843 
1844 	if (plat_priv->device_id == QCA6174_DEVICE_ID) {
1845 		cnss_pr_info("Forced FW assert is not supported\n");
1846 		return -EOPNOTSUPP;
1847 	}
1848 
1849 	if (cnss_bus_is_device_down(plat_priv)) {
1850 		cnss_pr_info("Device is already in bad state, ignore force assert\n");
1851 		return 0;
1852 	}
1853 
1854 	if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1855 		cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n");
1856 		return 0;
1857 	}
1858 
1859 	if (in_interrupt() || irqs_disabled())
1860 		cnss_driver_event_post(plat_priv,
1861 				       CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
1862 				       0, NULL);
1863 	else
1864 		cnss_bus_force_fw_assert_hdlr(plat_priv);
1865 
1866 	return 0;
1867 }
1868 EXPORT_SYMBOL(cnss_force_fw_assert);
1869 
1870 int cnss_force_collect_rddm(struct device *dev)
1871 {
1872 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1873 	unsigned int timeout;
1874 	int ret = 0;
1875 
1876 	if (!plat_priv) {
1877 		cnss_pr_err("plat_priv is NULL\n");
1878 		return -ENODEV;
1879 	}
1880 
1881 	if (plat_priv->device_id == QCA6174_DEVICE_ID) {
1882 		cnss_pr_info("Force collect rddm is not supported\n");
1883 		return -EOPNOTSUPP;
1884 	}
1885 
1886 	if (cnss_bus_is_device_down(plat_priv)) {
1887 		cnss_pr_info("Device is already in bad state, wait to collect rddm\n");
1888 		goto wait_rddm;
1889 	}
1890 
1891 	if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1892 		cnss_pr_info("Recovery is already in progress, wait to collect rddm\n");
1893 		goto wait_rddm;
1894 	}
1895 
1896 	if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
1897 	    test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
1898 	    test_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state) ||
1899 	    test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
1900 		cnss_pr_info("Loading/Unloading/idle restart/shutdown is in progress, ignore forced collect rddm\n");
1901 		return 0;
1902 	}
1903 
1904 	ret = cnss_bus_force_fw_assert_hdlr(plat_priv);
1905 	if (ret)
1906 		return ret;
1907 
1908 wait_rddm:
1909 	reinit_completion(&plat_priv->rddm_complete);
1910 	timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_RDDM);
1911 	ret = wait_for_completion_timeout(&plat_priv->rddm_complete,
1912 					  msecs_to_jiffies(timeout));
1913 	if (!ret) {
1914 		cnss_pr_err("Timeout (%ums) waiting for RDDM to complete\n",
1915 			    timeout);
1916 		ret = -ETIMEDOUT;
1917 	} else if (ret > 0) {
1918 		ret = 0;
1919 	}
1920 
1921 	return ret;
1922 }
1923 EXPORT_SYMBOL(cnss_force_collect_rddm);
1924 
1925 int cnss_qmi_send_get(struct device *dev)
1926 {
1927 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1928 
1929 	if (!test_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state))
1930 		return 0;
1931 
1932 	return cnss_bus_qmi_send_get(plat_priv);
1933 }
1934 EXPORT_SYMBOL(cnss_qmi_send_get);
1935 
1936 int cnss_qmi_send_put(struct device *dev)
1937 {
1938 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1939 
1940 	if (!test_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state))
1941 		return 0;
1942 
1943 	return cnss_bus_qmi_send_put(plat_priv);
1944 }
1945 EXPORT_SYMBOL(cnss_qmi_send_put);
1946 
1947 int cnss_qmi_send(struct device *dev, int type, void *cmd,
1948 		  int cmd_len, void *cb_ctx,
1949 		  int (*cb)(void *ctx, void *event, int event_len))
1950 {
1951 	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1952 	int ret;
1953 
1954 	if (!plat_priv)
1955 		return -ENODEV;
1956 
1957 	if (!test_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state))
1958 		return -EINVAL;
1959 
1960 	plat_priv->get_info_cb = cb;
1961 	plat_priv->get_info_cb_ctx = cb_ctx;
1962 
1963 	ret = cnss_wlfw_get_info_send_sync(plat_priv, type, cmd, cmd_len);
1964 	if (ret) {
1965 		plat_priv->get_info_cb = NULL;
1966 		plat_priv->get_info_cb_ctx = NULL;
1967 	}
1968 
1969 	return ret;
1970 }
1971 EXPORT_SYMBOL(cnss_qmi_send);
1972 
1973 static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
1974 {
1975 	int ret = 0;
1976 	u32 retry = 0, timeout;
1977 
1978 	if (test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state)) {
1979 		cnss_pr_dbg("Calibration complete. Ignore calibration req\n");
1980 		goto out;
1981 	} else if (test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state)) {
1982 		cnss_pr_dbg("Calibration in progress. Ignore new calibration req\n");
1983 		goto out;
1984 	} else if (test_bit(CNSS_WLAN_HW_DISABLED, &plat_priv->driver_state)) {
1985 		cnss_pr_dbg("Calibration deferred as WLAN device disabled\n");
1986 		goto out;
1987 	}
1988 
1989 	if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
1990 	    test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state) ||
1991 	    test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
1992 		cnss_pr_err("WLAN in mission mode before cold boot calibration\n");
1993 		CNSS_ASSERT(0);
1994 		return -EINVAL;
1995 	}
1996 
1997 	while (retry++ < CNSS_CAL_START_PROBE_WAIT_RETRY_MAX) {
1998 		if (test_bit(CNSS_PCI_PROBE_DONE, &plat_priv->driver_state))
1999 			break;
2000 		msleep(CNSS_CAL_START_PROBE_WAIT_MS);
2001 
2002 		if (retry == CNSS_CAL_START_PROBE_WAIT_RETRY_MAX) {
2003 			cnss_pr_err("Calibration start failed as PCI probe not complete\n");
2004 			CNSS_ASSERT(0);
2005 			ret = -EINVAL;
2006 			goto mark_cal_fail;
2007 		}
2008 	}
2009 
2010 	switch (plat_priv->device_id) {
2011 	case QCA6290_DEVICE_ID:
2012 	case QCA6390_DEVICE_ID:
2013 	case QCA6490_DEVICE_ID:
2014 	case KIWI_DEVICE_ID:
2015 	case MANGO_DEVICE_ID:
2016 		break;
2017 	default:
2018 		cnss_pr_err("Not supported for device ID 0x%lx\n",
2019 			    plat_priv->device_id);
2020 		ret = -EINVAL;
2021 		goto mark_cal_fail;
2022 	}
2023 
2024 	set_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
2025 	if (test_bit(CNSS_DRIVER_REGISTER, &plat_priv->driver_state)) {
2026 		timeout = cnss_get_timeout(plat_priv,
2027 					   CNSS_TIMEOUT_CALIBRATION);
2028 		cnss_pr_dbg("Restarting calibration %ds timeout\n",
2029 			    timeout / 1000);
2030 		if (cancel_delayed_work_sync(&plat_priv->wlan_reg_driver_work))
2031 			schedule_delayed_work(&plat_priv->wlan_reg_driver_work,
2032 					      msecs_to_jiffies(timeout));
2033 	}
2034 	reinit_completion(&plat_priv->cal_complete);
2035 	ret = cnss_bus_dev_powerup(plat_priv);
2036 mark_cal_fail:
2037 	if (ret) {
2038 		complete(&plat_priv->cal_complete);
2039 		clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
2040 		/* Set CBC done in driver state to mark attempt and note error
2041 		 * since calibration cannot be retried at boot.
2042 		 */
2043 		plat_priv->cal_done = CNSS_CAL_FAILURE;
2044 		set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
2045 	}
2046 
2047 out:
2048 	return ret;
2049 }
2050 
2051 static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
2052 					void *data)
2053 {
2054 	struct cnss_cal_info *cal_info = data;
2055 
2056 	if (!test_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state) ||
2057 	    test_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state))
2058 		goto out;
2059 
2060 	switch (cal_info->cal_status) {
2061 	case CNSS_CAL_DONE:
2062 		cnss_pr_dbg("Calibration completed successfully\n");
2063 		plat_priv->cal_done = true;
2064 		break;
2065 	case CNSS_CAL_TIMEOUT:
2066 	case CNSS_CAL_FAILURE:
2067 		cnss_pr_dbg("Calibration failed. Status: %d, force shutdown\n",
2068 			    cal_info->cal_status);
2069 		break;
2070 	default:
2071 		cnss_pr_err("Unknown calibration status: %u\n",
2072 			    cal_info->cal_status);
2073 		break;
2074 	}
2075 
2076 	cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
2077 	cnss_bus_free_qdss_mem(plat_priv);
2078 	cnss_release_antenna_sharing(plat_priv);
2079 	cnss_bus_dev_shutdown(plat_priv);
2080 	msleep(POWER_RESET_MIN_DELAY_MS);
2081 	complete(&plat_priv->cal_complete);
2082 	clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
2083 	set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
2084 
2085 	if (cal_info->cal_status == CNSS_CAL_DONE) {
2086 		cnss_cal_mem_upload_to_file(plat_priv);
2087 		if (!test_bit(CNSS_DRIVER_REGISTER, &plat_priv->driver_state))
2088 			goto out;
2089 
2090 		cnss_pr_dbg("Schedule WLAN driver load\n");
2091 		if (cancel_delayed_work_sync(&plat_priv->wlan_reg_driver_work))
2092 			schedule_delayed_work(&plat_priv->wlan_reg_driver_work,
2093 					      0);
2094 	}
2095 out:
2096 	kfree(data);
2097 	return 0;
2098 }
2099 
2100 static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv)
2101 {
2102 	int ret;
2103 
2104 	ret = cnss_bus_dev_powerup(plat_priv);
2105 	if (ret)
2106 		clear_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state);
2107 
2108 	return ret;
2109 }
2110 
2111 static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv)
2112 {
2113 	cnss_bus_dev_shutdown(plat_priv);
2114 
2115 	return 0;
2116 }
2117 
2118 static int cnss_qdss_trace_req_mem_hdlr(struct cnss_plat_data *plat_priv)
2119 {
2120 	int ret = 0;
2121 
2122 	ret = cnss_bus_alloc_qdss_mem(plat_priv);
2123 	if (ret < 0)
2124 		return ret;
2125 
2126 	return cnss_wlfw_qdss_trace_mem_info_send_sync(plat_priv);
2127 }
2128 
2129 static void *cnss_get_fw_mem_pa_to_va(struct cnss_fw_mem *fw_mem,
2130 				      u32 mem_seg_len, u64 pa, u32 size)
2131 {
2132 	int i = 0;
2133 	u64 offset = 0;
2134 	void *va = NULL;
2135 	u64 local_pa;
2136 	u32 local_size;
2137 
2138 	for (i = 0; i < mem_seg_len; i++) {
2139 		local_pa = (u64)fw_mem[i].pa;
2140 		local_size = (u32)fw_mem[i].size;
2141 		if (pa == local_pa && size <= local_size) {
2142 			va = fw_mem[i].va;
2143 			break;
2144 		}
2145 		if (pa > local_pa &&
2146 		    pa < local_pa + local_size &&
2147 		    pa + size <= local_pa + local_size) {
2148 			offset = pa - local_pa;
2149 			va = fw_mem[i].va + offset;
2150 			break;
2151 		}
2152 	}
2153 	return va;
2154 }
2155 
2156 static int cnss_fw_mem_file_save_hdlr(struct cnss_plat_data *plat_priv,
2157 				      void *data)
2158 {
2159 	struct cnss_qmi_event_fw_mem_file_save_data *event_data = data;
2160 	struct cnss_fw_mem *fw_mem_seg;
2161 	int ret = 0L;
2162 	void *va = NULL;
2163 	u32 i, fw_mem_seg_len;
2164 
2165 	switch (event_data->mem_type) {
2166 	case QMI_WLFW_MEM_TYPE_DDR_V01:
2167 		if (!plat_priv->fw_mem_seg_len)
2168 			goto invalid_mem_save;
2169 
2170 		fw_mem_seg = plat_priv->fw_mem;
2171 		fw_mem_seg_len = plat_priv->fw_mem_seg_len;
2172 		break;
2173 	case QMI_WLFW_MEM_QDSS_V01:
2174 		if (!plat_priv->qdss_mem_seg_len)
2175 			goto invalid_mem_save;
2176 
2177 		fw_mem_seg = plat_priv->qdss_mem;
2178 		fw_mem_seg_len = plat_priv->qdss_mem_seg_len;
2179 		break;
2180 	default:
2181 		goto invalid_mem_save;
2182 	}
2183 
2184 	for (i = 0; i < event_data->mem_seg_len; i++) {
2185 		va = cnss_get_fw_mem_pa_to_va(fw_mem_seg, fw_mem_seg_len,
2186 					      event_data->mem_seg[i].addr,
2187 					      event_data->mem_seg[i].size);
2188 		if (!va) {
2189 			cnss_pr_err("Fail to find matching va of pa %pa for mem type: %d\n",
2190 				    &event_data->mem_seg[i].addr,
2191 				    event_data->mem_type);
2192 			ret = -EINVAL;
2193 			break;
2194 		}
2195 		ret = cnss_genl_send_msg(va, CNSS_GENL_MSG_TYPE_QDSS,
2196 					 event_data->file_name,
2197 					 event_data->mem_seg[i].size);
2198 		if (ret < 0) {
2199 			cnss_pr_err("Fail to save fw mem data: %d\n",
2200 				    ret);
2201 			break;
2202 		}
2203 	}
2204 	kfree(data);
2205 	return ret;
2206 
2207 invalid_mem_save:
2208 	cnss_pr_err("FW Mem type %d not allocated. Invalid save request\n",
2209 		    event_data->mem_type);
2210 	kfree(data);
2211 	return -EINVAL;
2212 }
2213 
2214 static int cnss_qdss_trace_free_hdlr(struct cnss_plat_data *plat_priv)
2215 {
2216 	cnss_bus_free_qdss_mem(plat_priv);
2217 
2218 	return 0;
2219 }
2220 
2221 static int cnss_qdss_trace_req_data_hdlr(struct cnss_plat_data *plat_priv,
2222 					 void *data)
2223 {
2224 	int ret = 0;
2225 	struct cnss_qmi_event_fw_mem_file_save_data *event_data = data;
2226 
2227 	if (!plat_priv)
2228 		return -ENODEV;
2229 
2230 	ret = cnss_wlfw_qdss_data_send_sync(plat_priv, event_data->file_name,
2231 					    event_data->total_size);
2232 
2233 	kfree(data);
2234 	return ret;
2235 }
2236 
2237 static void cnss_driver_event_work(struct work_struct *work)
2238 {
2239 	struct cnss_plat_data *plat_priv =
2240 		container_of(work, struct cnss_plat_data, event_work);
2241 	struct cnss_driver_event *event;
2242 	unsigned long flags;
2243 	int ret = 0;
2244 
2245 	if (!plat_priv) {
2246 		cnss_pr_err("plat_priv is NULL!\n");
2247 		return;
2248 	}
2249 
2250 	cnss_pm_stay_awake(plat_priv);
2251 
2252 	spin_lock_irqsave(&plat_priv->event_lock, flags);
2253 
2254 	while (!list_empty(&plat_priv->event_list)) {
2255 		event = list_first_entry(&plat_priv->event_list,
2256 					 struct cnss_driver_event, list);
2257 		list_del(&event->list);
2258 		spin_unlock_irqrestore(&plat_priv->event_lock, flags);
2259 
2260 		cnss_pr_dbg("Processing driver event: %s%s(%d), state: 0x%lx\n",
2261 			    cnss_driver_event_to_str(event->type),
2262 			    event->sync ? "-sync" : "", event->type,
2263 			    plat_priv->driver_state);
2264 
2265 		switch (event->type) {
2266 		case CNSS_DRIVER_EVENT_SERVER_ARRIVE:
2267 			ret = cnss_wlfw_server_arrive(plat_priv, event->data);
2268 			break;
2269 		case CNSS_DRIVER_EVENT_SERVER_EXIT:
2270 			ret = cnss_wlfw_server_exit(plat_priv);
2271 			break;
2272 		case CNSS_DRIVER_EVENT_REQUEST_MEM:
2273 			ret = cnss_bus_alloc_fw_mem(plat_priv);
2274 			if (ret)
2275 				break;
2276 			ret = cnss_wlfw_respond_mem_send_sync(plat_priv);
2277 			break;
2278 		case CNSS_DRIVER_EVENT_FW_MEM_READY:
2279 			ret = cnss_fw_mem_ready_hdlr(plat_priv);
2280 			break;
2281 		case CNSS_DRIVER_EVENT_FW_READY:
2282 			ret = cnss_fw_ready_hdlr(plat_priv);
2283 			break;
2284 		case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START:
2285 			ret = cnss_cold_boot_cal_start_hdlr(plat_priv);
2286 			break;
2287 		case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE:
2288 			ret = cnss_cold_boot_cal_done_hdlr(plat_priv,
2289 							   event->data);
2290 			break;
2291 		case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
2292 			ret = cnss_bus_register_driver_hdlr(plat_priv,
2293 							    event->data);
2294 			break;
2295 		case CNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
2296 			ret = cnss_bus_unregister_driver_hdlr(plat_priv);
2297 			break;
2298 		case CNSS_DRIVER_EVENT_RECOVERY:
2299 			ret = cnss_driver_recovery_hdlr(plat_priv,
2300 							event->data);
2301 			break;
2302 		case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
2303 			ret = cnss_bus_force_fw_assert_hdlr(plat_priv);
2304 			break;
2305 		case CNSS_DRIVER_EVENT_IDLE_RESTART:
2306 			set_bit(CNSS_DRIVER_IDLE_RESTART,
2307 				&plat_priv->driver_state);
2308 			fallthrough;
2309 		case CNSS_DRIVER_EVENT_POWER_UP:
2310 			ret = cnss_power_up_hdlr(plat_priv);
2311 			break;
2312 		case CNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
2313 			set_bit(CNSS_DRIVER_IDLE_SHUTDOWN,
2314 				&plat_priv->driver_state);
2315 			fallthrough;
2316 		case CNSS_DRIVER_EVENT_POWER_DOWN:
2317 			ret = cnss_power_down_hdlr(plat_priv);
2318 			break;
2319 		case CNSS_DRIVER_EVENT_IMS_WFC_CALL_IND:
2320 			ret = cnss_process_wfc_call_ind_event(plat_priv,
2321 							      event->data);
2322 			break;
2323 		case CNSS_DRIVER_EVENT_WLFW_TWT_CFG_IND:
2324 			ret = cnss_process_twt_cfg_ind_event(plat_priv,
2325 							     event->data);
2326 			break;
2327 		case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
2328 			ret = cnss_qdss_trace_req_mem_hdlr(plat_priv);
2329 			break;
2330 		case CNSS_DRIVER_EVENT_FW_MEM_FILE_SAVE:
2331 			ret = cnss_fw_mem_file_save_hdlr(plat_priv,
2332 							 event->data);
2333 			break;
2334 		case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
2335 			ret = cnss_qdss_trace_free_hdlr(plat_priv);
2336 			break;
2337 		case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA:
2338 			ret = cnss_qdss_trace_req_data_hdlr(plat_priv,
2339 							    event->data);
2340 			break;
2341 		default:
2342 			cnss_pr_err("Invalid driver event type: %d",
2343 				    event->type);
2344 			kfree(event);
2345 			spin_lock_irqsave(&plat_priv->event_lock, flags);
2346 			continue;
2347 		}
2348 
2349 		spin_lock_irqsave(&plat_priv->event_lock, flags);
2350 		if (event->sync) {
2351 			event->ret = ret;
2352 			complete(&event->complete);
2353 			continue;
2354 		}
2355 		spin_unlock_irqrestore(&plat_priv->event_lock, flags);
2356 
2357 		kfree(event);
2358 
2359 		spin_lock_irqsave(&plat_priv->event_lock, flags);
2360 	}
2361 	spin_unlock_irqrestore(&plat_priv->event_lock, flags);
2362 
2363 	cnss_pm_relax(plat_priv);
2364 }
2365 
2366 #if IS_ENABLED(CONFIG_MSM_SUBSYSTEM_RESTART)
2367 int cnss_register_subsys(struct cnss_plat_data *plat_priv)
2368 {
2369 	int ret = 0;
2370 	struct cnss_subsys_info *subsys_info;
2371 
2372 	subsys_info = &plat_priv->subsys_info;
2373 
2374 	subsys_info->subsys_desc.name = "wlan";
2375 	subsys_info->subsys_desc.owner = THIS_MODULE;
2376 	subsys_info->subsys_desc.powerup = cnss_subsys_powerup;
2377 	subsys_info->subsys_desc.shutdown = cnss_subsys_shutdown;
2378 	subsys_info->subsys_desc.ramdump = cnss_subsys_ramdump;
2379 	subsys_info->subsys_desc.crash_shutdown = cnss_subsys_crash_shutdown;
2380 	subsys_info->subsys_desc.dev = &plat_priv->plat_dev->dev;
2381 
2382 	subsys_info->subsys_device = subsys_register(&subsys_info->subsys_desc);
2383 	if (IS_ERR(subsys_info->subsys_device)) {
2384 		ret = PTR_ERR(subsys_info->subsys_device);
2385 		cnss_pr_err("Failed to register subsys, err = %d\n", ret);
2386 		goto out;
2387 	}
2388 
2389 	subsys_info->subsys_handle =
2390 		subsystem_get(subsys_info->subsys_desc.name);
2391 	if (!subsys_info->subsys_handle) {
2392 		cnss_pr_err("Failed to get subsys_handle!\n");
2393 		ret = -EINVAL;
2394 		goto unregister_subsys;
2395 	} else if (IS_ERR(subsys_info->subsys_handle)) {
2396 		ret = PTR_ERR(subsys_info->subsys_handle);
2397 		cnss_pr_err("Failed to do subsystem_get, err = %d\n", ret);
2398 		goto unregister_subsys;
2399 	}
2400 
2401 	return 0;
2402 
2403 unregister_subsys:
2404 	subsys_unregister(subsys_info->subsys_device);
2405 out:
2406 	return ret;
2407 }
2408 
2409 void cnss_unregister_subsys(struct cnss_plat_data *plat_priv)
2410 {
2411 	struct cnss_subsys_info *subsys_info;
2412 
2413 	subsys_info = &plat_priv->subsys_info;
2414 	subsystem_put(subsys_info->subsys_handle);
2415 	subsys_unregister(subsys_info->subsys_device);
2416 }
2417 
2418 static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv)
2419 {
2420 	struct cnss_subsys_info *subsys_info = &plat_priv->subsys_info;
2421 
2422 	return create_ramdump_device(subsys_info->subsys_desc.name,
2423 				     subsys_info->subsys_desc.dev);
2424 }
2425 
2426 static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv,
2427 					void *ramdump_dev)
2428 {
2429 	destroy_ramdump_device(ramdump_dev);
2430 }
2431 
2432 int cnss_do_ramdump(struct cnss_plat_data *plat_priv)
2433 {
2434 	struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info;
2435 	struct ramdump_segment segment;
2436 
2437 	memset(&segment, 0, sizeof(segment));
2438 	segment.v_address = (void __iomem *)ramdump_info->ramdump_va;
2439 	segment.size = ramdump_info->ramdump_size;
2440 
2441 	return qcom_ramdump(ramdump_info->ramdump_dev, &segment, 1);
2442 }
2443 
2444 int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv)
2445 {
2446 	struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
2447 	struct cnss_dump_data *dump_data = &info_v2->dump_data;
2448 	struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr;
2449 	struct ramdump_segment *ramdump_segs, *s;
2450 	struct cnss_dump_meta_info meta_info = {0};
2451 	int i, ret = 0;
2452 
2453 	ramdump_segs = kcalloc(dump_data->nentries + 1,
2454 			       sizeof(*ramdump_segs),
2455 			       GFP_KERNEL);
2456 	if (!ramdump_segs)
2457 		return -ENOMEM;
2458 
2459 	s = ramdump_segs + 1;
2460 	for (i = 0; i < dump_data->nentries; i++) {
2461 		if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) {
2462 			cnss_pr_err("Unsupported dump type: %d",
2463 				    dump_seg->type);
2464 			continue;
2465 		}
2466 
2467 		if (meta_info.entry[dump_seg->type].entry_start == 0) {
2468 			meta_info.entry[dump_seg->type].type = dump_seg->type;
2469 			meta_info.entry[dump_seg->type].entry_start = i + 1;
2470 		}
2471 		meta_info.entry[dump_seg->type].entry_num++;
2472 
2473 		s->address = dump_seg->address;
2474 		s->v_address = (void __iomem *)dump_seg->v_address;
2475 		s->size = dump_seg->size;
2476 		s++;
2477 		dump_seg++;
2478 	}
2479 
2480 	meta_info.magic = CNSS_RAMDUMP_MAGIC;
2481 	meta_info.version = CNSS_RAMDUMP_VERSION;
2482 	meta_info.chipset = plat_priv->device_id;
2483 	meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX;
2484 
2485 	ramdump_segs->v_address = (void __iomem *)(&meta_info);
2486 	ramdump_segs->size = sizeof(meta_info);
2487 
2488 	ret = qcom_elf_ramdump(info_v2->ramdump_dev, ramdump_segs,
2489 			       dump_data->nentries + 1);
2490 	kfree(ramdump_segs);
2491 
2492 	return ret;
2493 }
2494 #else
2495 static int cnss_panic_handler(struct notifier_block *nb, unsigned long action,
2496 			      void *data)
2497 {
2498 	struct cnss_plat_data *plat_priv =
2499 		container_of(nb, struct cnss_plat_data, panic_nb);
2500 
2501 	cnss_bus_dev_crash_shutdown(plat_priv);
2502 
2503 	return NOTIFY_DONE;
2504 }
2505 
2506 int cnss_register_subsys(struct cnss_plat_data *plat_priv)
2507 {
2508 	int ret;
2509 
2510 	if (!plat_priv)
2511 		return -ENODEV;
2512 
2513 	plat_priv->panic_nb.notifier_call = cnss_panic_handler;
2514 	ret = atomic_notifier_chain_register(&panic_notifier_list,
2515 					     &plat_priv->panic_nb);
2516 	if (ret) {
2517 		cnss_pr_err("Failed to register panic handler\n");
2518 		return -EINVAL;
2519 	}
2520 
2521 	return 0;
2522 }
2523 
2524 void cnss_unregister_subsys(struct cnss_plat_data *plat_priv)
2525 {
2526 	int ret;
2527 
2528 	ret = atomic_notifier_chain_unregister(&panic_notifier_list,
2529 					       &plat_priv->panic_nb);
2530 	if (ret)
2531 		cnss_pr_err("Failed to unregister panic handler\n");
2532 }
2533 
2534 #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2)
2535 static void *cnss_create_ramdump_device(struct cnss_plat_data *plat_priv)
2536 {
2537 	return &plat_priv->plat_dev->dev;
2538 }
2539 
2540 static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv,
2541 					void *ramdump_dev)
2542 {
2543 }
2544 #endif
2545 
2546 #if IS_ENABLED(CONFIG_QCOM_RAMDUMP)
2547 int cnss_do_ramdump(struct cnss_plat_data *plat_priv)
2548 {
2549 	struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info;
2550 	struct qcom_dump_segment segment;
2551 	struct list_head head;
2552 
2553 	INIT_LIST_HEAD(&head);
2554 	memset(&segment, 0, sizeof(segment));
2555 	segment.va = ramdump_info->ramdump_va;
2556 	segment.size = ramdump_info->ramdump_size;
2557 	list_add(&segment.node, &head);
2558 
2559 	return qcom_dump(&head, ramdump_info->ramdump_dev);
2560 }
2561 #else
2562 int cnss_do_ramdump(struct cnss_plat_data *plat_priv)
2563 {
2564 	return 0;
2565 }
2566 
2567 /* Using completion event inside dynamically allocated ramdump_desc
2568  * may result a race between freeing the event after setting it to
2569  * complete inside dev coredump free callback and the thread that is
2570  * waiting for completion.
2571  */
2572 DECLARE_COMPLETION(dump_done);
2573 #define TIMEOUT_SAVE_DUMP_MS 30000
2574 
2575 #define SIZEOF_ELF_STRUCT(__xhdr)					\
2576 static inline size_t sizeof_elf_##__xhdr(unsigned char class)		\
2577 {									\
2578 	if (class == ELFCLASS32)					\
2579 		return sizeof(struct elf32_##__xhdr);			\
2580 	else								\
2581 		return sizeof(struct elf64_##__xhdr);			\
2582 }
2583 
2584 SIZEOF_ELF_STRUCT(phdr)
2585 SIZEOF_ELF_STRUCT(hdr)
2586 
2587 #define set_xhdr_property(__xhdr, arg, class, member, value)		\
2588 do {									\
2589 	if (class == ELFCLASS32)					\
2590 		((struct elf32_##__xhdr *)arg)->member = value;		\
2591 	else								\
2592 		((struct elf64_##__xhdr *)arg)->member = value;		\
2593 } while (0)
2594 
2595 #define set_ehdr_property(arg, class, member, value) \
2596 	set_xhdr_property(hdr, arg, class, member, value)
2597 #define set_phdr_property(arg, class, member, value) \
2598 	set_xhdr_property(phdr, arg, class, member, value)
2599 
2600 /* These replace qcom_ramdump driver APIs called from common API
2601  * cnss_do_elf_dump() by the ones defined here.
2602  */
2603 #define qcom_dump_segment cnss_qcom_dump_segment
2604 #define qcom_elf_dump cnss_qcom_elf_dump
2605 #define dump_enabled cnss_dump_enabled
2606 
2607 struct cnss_qcom_dump_segment {
2608 	struct list_head node;
2609 	dma_addr_t da;
2610 	void *va;
2611 	size_t size;
2612 };
2613 
2614 struct cnss_qcom_ramdump_desc {
2615 	void *data;
2616 	struct completion dump_done;
2617 };
2618 
2619 static ssize_t cnss_qcom_devcd_readv(char *buffer, loff_t offset, size_t count,
2620 				     void *data, size_t datalen)
2621 {
2622 	struct cnss_qcom_ramdump_desc *desc = data;
2623 
2624 	return memory_read_from_buffer(buffer, count, &offset, desc->data,
2625 				       datalen);
2626 }
2627 
2628 static void cnss_qcom_devcd_freev(void *data)
2629 {
2630 	struct cnss_qcom_ramdump_desc *desc = data;
2631 
2632 	cnss_pr_dbg("Free dump data for dev coredump\n");
2633 
2634 	complete(&dump_done);
2635 	vfree(desc->data);
2636 	kfree(desc);
2637 }
2638 
2639 static int cnss_qcom_devcd_dump(struct device *dev, void *data, size_t datalen,
2640 				gfp_t gfp)
2641 {
2642 	struct cnss_qcom_ramdump_desc *desc;
2643 	unsigned int timeout = TIMEOUT_SAVE_DUMP_MS;
2644 	int ret;
2645 
2646 	desc = kmalloc(sizeof(*desc), GFP_KERNEL);
2647 	if (!desc)
2648 		return -ENOMEM;
2649 
2650 	desc->data = data;
2651 	reinit_completion(&dump_done);
2652 
2653 	dev_coredumpm(dev, NULL, desc, datalen, gfp,
2654 		      cnss_qcom_devcd_readv, cnss_qcom_devcd_freev);
2655 
2656 	ret = wait_for_completion_timeout(&dump_done,
2657 					  msecs_to_jiffies(timeout));
2658 	if (!ret)
2659 		cnss_pr_err("Timeout waiting (%dms) for saving dump to file system\n",
2660 			    timeout);
2661 
2662 	return ret ? 0 : -ETIMEDOUT;
2663 }
2664 
2665 /* Since the elf32 and elf64 identification is identical apart from
2666  * the class, use elf32 by default.
2667  */
2668 static void init_elf_identification(struct elf32_hdr *ehdr, unsigned char class)
2669 {
2670 	memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
2671 	ehdr->e_ident[EI_CLASS] = class;
2672 	ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
2673 	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
2674 	ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
2675 }
2676 
2677 int cnss_qcom_elf_dump(struct list_head *segs, struct device *dev,
2678 		       unsigned char class)
2679 {
2680 	struct cnss_qcom_dump_segment *segment;
2681 	void *phdr, *ehdr;
2682 	size_t data_size, offset;
2683 	int phnum = 0;
2684 	void *data;
2685 	void __iomem *ptr;
2686 
2687 	if (!segs || list_empty(segs))
2688 		return -EINVAL;
2689 
2690 	data_size = sizeof_elf_hdr(class);
2691 	list_for_each_entry(segment, segs, node) {
2692 		data_size += sizeof_elf_phdr(class) + segment->size;
2693 		phnum++;
2694 	}
2695 
2696 	data = vmalloc(data_size);
2697 	if (!data)
2698 		return -ENOMEM;
2699 
2700 	cnss_pr_dbg("Creating ELF file with size %d\n", data_size);
2701 
2702 	ehdr = data;
2703 	memset(ehdr, 0, sizeof_elf_hdr(class));
2704 	init_elf_identification(ehdr, class);
2705 	set_ehdr_property(ehdr, class, e_type, ET_CORE);
2706 	set_ehdr_property(ehdr, class, e_machine, EM_NONE);
2707 	set_ehdr_property(ehdr, class, e_version, EV_CURRENT);
2708 	set_ehdr_property(ehdr, class, e_phoff, sizeof_elf_hdr(class));
2709 	set_ehdr_property(ehdr, class, e_ehsize, sizeof_elf_hdr(class));
2710 	set_ehdr_property(ehdr, class, e_phentsize, sizeof_elf_phdr(class));
2711 	set_ehdr_property(ehdr, class, e_phnum, phnum);
2712 
2713 	phdr = data + sizeof_elf_hdr(class);
2714 	offset = sizeof_elf_hdr(class) + sizeof_elf_phdr(class) * phnum;
2715 	list_for_each_entry(segment, segs, node) {
2716 		memset(phdr, 0, sizeof_elf_phdr(class));
2717 		set_phdr_property(phdr, class, p_type, PT_LOAD);
2718 		set_phdr_property(phdr, class, p_offset, offset);
2719 		set_phdr_property(phdr, class, p_vaddr, segment->da);
2720 		set_phdr_property(phdr, class, p_paddr, segment->da);
2721 		set_phdr_property(phdr, class, p_filesz, segment->size);
2722 		set_phdr_property(phdr, class, p_memsz, segment->size);
2723 		set_phdr_property(phdr, class, p_flags, PF_R | PF_W | PF_X);
2724 		set_phdr_property(phdr, class, p_align, 0);
2725 
2726 		if (segment->va) {
2727 			memcpy(data + offset, segment->va, segment->size);
2728 		} else {
2729 			ptr = devm_ioremap(dev, segment->da, segment->size);
2730 			if (!ptr) {
2731 				cnss_pr_err("Invalid coredump segment (%pad, %zu)\n",
2732 					    &segment->da, segment->size);
2733 				memset(data + offset, 0xff, segment->size);
2734 			} else {
2735 				memcpy_fromio(data + offset, ptr,
2736 					      segment->size);
2737 			}
2738 		}
2739 
2740 		offset += segment->size;
2741 		phdr += sizeof_elf_phdr(class);
2742 	}
2743 
2744 	return cnss_qcom_devcd_dump(dev, data, data_size, GFP_KERNEL);
2745 }
2746 
2747 /* Saving dump to file system is always needed in this case. */
2748 static bool cnss_dump_enabled(void)
2749 {
2750 	return true;
2751 }
2752 #endif /* CONFIG_QCOM_RAMDUMP */
2753 
2754 int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv)
2755 {
2756 	struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
2757 	struct cnss_dump_data *dump_data = &info_v2->dump_data;
2758 	struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr;
2759 	struct qcom_dump_segment *seg;
2760 	struct cnss_dump_meta_info meta_info = {0};
2761 	struct list_head head;
2762 	int i, ret = 0;
2763 
2764 	if (!dump_enabled()) {
2765 		cnss_pr_info("Dump collection is not enabled\n");
2766 		return ret;
2767 	}
2768 
2769 	INIT_LIST_HEAD(&head);
2770 	for (i = 0; i < dump_data->nentries; i++) {
2771 		if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) {
2772 			cnss_pr_err("Unsupported dump type: %d",
2773 				    dump_seg->type);
2774 			continue;
2775 		}
2776 
2777 		seg = kcalloc(1, sizeof(*seg), GFP_KERNEL);
2778 		if (!seg)
2779 			continue;
2780 
2781 		if (meta_info.entry[dump_seg->type].entry_start == 0) {
2782 			meta_info.entry[dump_seg->type].type = dump_seg->type;
2783 			meta_info.entry[dump_seg->type].entry_start = i + 1;
2784 		}
2785 		meta_info.entry[dump_seg->type].entry_num++;
2786 		seg->da = dump_seg->address;
2787 		seg->va = dump_seg->v_address;
2788 		seg->size = dump_seg->size;
2789 		list_add_tail(&seg->node, &head);
2790 		dump_seg++;
2791 	}
2792 
2793 	seg = kcalloc(1, sizeof(*seg), GFP_KERNEL);
2794 	if (!seg)
2795 		goto do_elf_dump;
2796 
2797 	meta_info.magic = CNSS_RAMDUMP_MAGIC;
2798 	meta_info.version = CNSS_RAMDUMP_VERSION;
2799 	meta_info.chipset = plat_priv->device_id;
2800 	meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX;
2801 	seg->va = &meta_info;
2802 	seg->size = sizeof(meta_info);
2803 	list_add(&seg->node, &head);
2804 
2805 do_elf_dump:
2806 	ret = qcom_elf_dump(&head, info_v2->ramdump_dev, ELF_CLASS);
2807 
2808 	while (!list_empty(&head)) {
2809 		seg = list_first_entry(&head, struct qcom_dump_segment, node);
2810 		list_del(&seg->node);
2811 		kfree(seg);
2812 	}
2813 
2814 	return ret;
2815 }
2816 #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
2817 
2818 #if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2)
2819 static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv)
2820 {
2821 	struct cnss_ramdump_info *ramdump_info;
2822 	struct msm_dump_entry dump_entry;
2823 
2824 	ramdump_info = &plat_priv->ramdump_info;
2825 	ramdump_info->dump_data.addr = ramdump_info->ramdump_pa;
2826 	ramdump_info->dump_data.len = ramdump_info->ramdump_size;
2827 	ramdump_info->dump_data.version = CNSS_DUMP_FORMAT_VER;
2828 	ramdump_info->dump_data.magic = CNSS_DUMP_MAGIC_VER_V2;
2829 	strlcpy(ramdump_info->dump_data.name, CNSS_DUMP_NAME,
2830 		sizeof(ramdump_info->dump_data.name));
2831 	dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
2832 	dump_entry.addr = virt_to_phys(&ramdump_info->dump_data);
2833 
2834 	return msm_dump_data_register_nominidump(MSM_DUMP_TABLE_APPS,
2835 						&dump_entry);
2836 }
2837 
2838 static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
2839 {
2840 	int ret = 0;
2841 	struct device *dev;
2842 	struct cnss_ramdump_info *ramdump_info;
2843 	u32 ramdump_size = 0;
2844 
2845 	dev = &plat_priv->plat_dev->dev;
2846 	ramdump_info = &plat_priv->ramdump_info;
2847 
2848 	if (plat_priv->dt_type != CNSS_DTT_MULTIEXCHG) {
2849 		/* dt type: legacy or converged */
2850 		ret = of_property_read_u32(dev->of_node,
2851 					   "qcom,wlan-ramdump-dynamic",
2852 					   &ramdump_size);
2853 	} else {
2854 		ret = of_property_read_u32(plat_priv->dev_node,
2855 					   "qcom,wlan-ramdump-dynamic",
2856 					   &ramdump_size);
2857 	}
2858 	if (ret == 0) {
2859 		ramdump_info->ramdump_va =
2860 			dma_alloc_coherent(dev, ramdump_size,
2861 					   &ramdump_info->ramdump_pa,
2862 					   GFP_KERNEL);
2863 
2864 		if (ramdump_info->ramdump_va)
2865 			ramdump_info->ramdump_size = ramdump_size;
2866 	}
2867 
2868 	cnss_pr_dbg("ramdump va: %pK, pa: %pa\n",
2869 		    ramdump_info->ramdump_va, &ramdump_info->ramdump_pa);
2870 
2871 	if (ramdump_info->ramdump_size == 0) {
2872 		cnss_pr_info("Ramdump will not be collected");
2873 		goto out;
2874 	}
2875 
2876 	ret = cnss_init_dump_entry(plat_priv);
2877 	if (ret) {
2878 		cnss_pr_err("Failed to setup dump table, err = %d\n", ret);
2879 		goto free_ramdump;
2880 	}
2881 
2882 	ramdump_info->ramdump_dev = cnss_create_ramdump_device(plat_priv);
2883 	if (!ramdump_info->ramdump_dev) {
2884 		cnss_pr_err("Failed to create ramdump device!");
2885 		ret = -ENOMEM;
2886 		goto free_ramdump;
2887 	}
2888 
2889 	return 0;
2890 free_ramdump:
2891 	dma_free_coherent(dev, ramdump_info->ramdump_size,
2892 			  ramdump_info->ramdump_va, ramdump_info->ramdump_pa);
2893 out:
2894 	return ret;
2895 }
2896 
2897 static void cnss_unregister_ramdump_v1(struct cnss_plat_data *plat_priv)
2898 {
2899 	struct device *dev;
2900 	struct cnss_ramdump_info *ramdump_info;
2901 
2902 	dev = &plat_priv->plat_dev->dev;
2903 	ramdump_info = &plat_priv->ramdump_info;
2904 
2905 	if (ramdump_info->ramdump_dev)
2906 		cnss_destroy_ramdump_device(plat_priv,
2907 					    ramdump_info->ramdump_dev);
2908 
2909 	if (ramdump_info->ramdump_va)
2910 		dma_free_coherent(dev, ramdump_info->ramdump_size,
2911 				  ramdump_info->ramdump_va,
2912 				  ramdump_info->ramdump_pa);
2913 }
2914 
2915 /**
2916  * cnss_ignore_dump_data_reg_fail - Ignore Ramdump table register failure
2917  * @ret: Error returned by msm_dump_data_register_nominidump
2918  *
2919  * For Lahaina GKI boot, we dont have support for mem dump feature. So
2920  * ignore failure.
2921  *
2922  * Return: Same given error code if mem dump feature enabled, 0 otherwise
2923  */
2924 static int cnss_ignore_dump_data_reg_fail(int ret)
2925 {
2926 	return ret;
2927 }
2928 
2929 static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
2930 {
2931 	int ret = 0;
2932 	struct cnss_ramdump_info_v2 *info_v2;
2933 	struct cnss_dump_data *dump_data;
2934 	struct msm_dump_entry dump_entry;
2935 	struct device *dev = &plat_priv->plat_dev->dev;
2936 	u32 ramdump_size = 0;
2937 
2938 	info_v2 = &plat_priv->ramdump_info_v2;
2939 	dump_data = &info_v2->dump_data;
2940 
2941 	if (plat_priv->dt_type != CNSS_DTT_MULTIEXCHG) {
2942 		/* dt type: legacy or converged */
2943 		ret = of_property_read_u32(dev->of_node,
2944 					   "qcom,wlan-ramdump-dynamic",
2945 					   &ramdump_size);
2946 	} else {
2947 		ret = of_property_read_u32(plat_priv->dev_node,
2948 					   "qcom,wlan-ramdump-dynamic",
2949 					   &ramdump_size);
2950 	}
2951 	if (ret == 0)
2952 		info_v2->ramdump_size = ramdump_size;
2953 
2954 	cnss_pr_dbg("Ramdump size 0x%lx\n", info_v2->ramdump_size);
2955 
2956 	info_v2->dump_data_vaddr = kzalloc(CNSS_DUMP_DESC_SIZE, GFP_KERNEL);
2957 	if (!info_v2->dump_data_vaddr)
2958 		return -ENOMEM;
2959 
2960 	dump_data->paddr = virt_to_phys(info_v2->dump_data_vaddr);
2961 	dump_data->version = CNSS_DUMP_FORMAT_VER_V2;
2962 	dump_data->magic = CNSS_DUMP_MAGIC_VER_V2;
2963 	dump_data->seg_version = CNSS_DUMP_SEG_VER;
2964 	strlcpy(dump_data->name, CNSS_DUMP_NAME,
2965 		sizeof(dump_data->name));
2966 	dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
2967 	dump_entry.addr = virt_to_phys(dump_data);
2968 
2969 	ret = msm_dump_data_register_nominidump(MSM_DUMP_TABLE_APPS,
2970 						&dump_entry);
2971 	if (ret) {
2972 		ret = cnss_ignore_dump_data_reg_fail(ret);
2973 		cnss_pr_err("Failed to setup dump table, %s (%d)\n",
2974 			    ret ? "Error" : "Ignoring", ret);
2975 		goto free_ramdump;
2976 	}
2977 
2978 	info_v2->ramdump_dev = cnss_create_ramdump_device(plat_priv);
2979 	if (!info_v2->ramdump_dev) {
2980 		cnss_pr_err("Failed to create ramdump device!\n");
2981 		ret = -ENOMEM;
2982 		goto free_ramdump;
2983 	}
2984 
2985 	return 0;
2986 
2987 free_ramdump:
2988 	kfree(info_v2->dump_data_vaddr);
2989 	info_v2->dump_data_vaddr = NULL;
2990 	return ret;
2991 }
2992 
2993 static void cnss_unregister_ramdump_v2(struct cnss_plat_data *plat_priv)
2994 {
2995 	struct cnss_ramdump_info_v2 *info_v2;
2996 
2997 	info_v2 = &plat_priv->ramdump_info_v2;
2998 
2999 	if (info_v2->ramdump_dev)
3000 		cnss_destroy_ramdump_device(plat_priv, info_v2->ramdump_dev);
3001 
3002 	kfree(info_v2->dump_data_vaddr);
3003 	info_v2->dump_data_vaddr = NULL;
3004 	info_v2->dump_data_valid = false;
3005 }
3006 
3007 int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
3008 {
3009 	int ret = 0;
3010 
3011 	switch (plat_priv->device_id) {
3012 	case QCA6174_DEVICE_ID:
3013 		ret = cnss_register_ramdump_v1(plat_priv);
3014 		break;
3015 	case QCA6290_DEVICE_ID:
3016 	case QCA6390_DEVICE_ID:
3017 	case QCA6490_DEVICE_ID:
3018 	case KIWI_DEVICE_ID:
3019 	case MANGO_DEVICE_ID:
3020 		ret = cnss_register_ramdump_v2(plat_priv);
3021 		break;
3022 	default:
3023 		cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
3024 		ret = -ENODEV;
3025 		break;
3026 	}
3027 	return ret;
3028 }
3029 
3030 void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
3031 {
3032 	switch (plat_priv->device_id) {
3033 	case QCA6174_DEVICE_ID:
3034 		cnss_unregister_ramdump_v1(plat_priv);
3035 		break;
3036 	case QCA6290_DEVICE_ID:
3037 	case QCA6390_DEVICE_ID:
3038 	case QCA6490_DEVICE_ID:
3039 	case KIWI_DEVICE_ID:
3040 	case MANGO_DEVICE_ID:
3041 		cnss_unregister_ramdump_v2(plat_priv);
3042 		break;
3043 	default:
3044 		cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
3045 		break;
3046 	}
3047 }
3048 #else
3049 int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
3050 {
3051 	struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
3052 	struct cnss_dump_data *dump_data = dump_data = &info_v2->dump_data;
3053 	struct device *dev = &plat_priv->plat_dev->dev;
3054 	u32 ramdump_size = 0;
3055 
3056 	if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
3057 				 &ramdump_size) == 0)
3058 		info_v2->ramdump_size = ramdump_size;
3059 
3060 	cnss_pr_dbg("Ramdump size 0x%lx\n", info_v2->ramdump_size);
3061 
3062 	info_v2->dump_data_vaddr = kzalloc(CNSS_DUMP_DESC_SIZE, GFP_KERNEL);
3063 	if (!info_v2->dump_data_vaddr)
3064 		return -ENOMEM;
3065 
3066 	dump_data->paddr = virt_to_phys(info_v2->dump_data_vaddr);
3067 	dump_data->version = CNSS_DUMP_FORMAT_VER_V2;
3068 	dump_data->magic = CNSS_DUMP_MAGIC_VER_V2;
3069 	dump_data->seg_version = CNSS_DUMP_SEG_VER;
3070 	strlcpy(dump_data->name, CNSS_DUMP_NAME,
3071 		sizeof(dump_data->name));
3072 
3073 	info_v2->ramdump_dev = dev;
3074 
3075 	return 0;
3076 }
3077 
3078 void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
3079 {
3080 	struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
3081 
3082 	info_v2->ramdump_dev = NULL;
3083 	kfree(info_v2->dump_data_vaddr);
3084 	info_v2->dump_data_vaddr = NULL;
3085 	info_v2->dump_data_valid = false;
3086 }
3087 #endif /* CONFIG_QCOM_MEMORY_DUMP_V2 */
3088 
3089 #if IS_ENABLED(CONFIG_QCOM_MINIDUMP)
3090 int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
3091 		  phys_addr_t *pa, unsigned long attrs)
3092 {
3093 	struct sg_table sgt;
3094 	int ret;
3095 
3096 	ret = dma_get_sgtable_attrs(dev, &sgt, va, dma, size, attrs);
3097 	if (ret) {
3098 		cnss_pr_err("Failed to get sgtable for va: 0x%pK, dma: %pa, size: 0x%zx, attrs: 0x%x\n",
3099 			    va, &dma, size, attrs);
3100 		return -EINVAL;
3101 	}
3102 
3103 	*pa = page_to_phys(sg_page(sgt.sgl));
3104 	sg_free_table(&sgt);
3105 
3106 	return 0;
3107 }
3108 
3109 int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
3110 			     enum cnss_fw_dump_type type, int seg_no,
3111 			     void *va, phys_addr_t pa, size_t size)
3112 {
3113 	struct md_region md_entry;
3114 	int ret;
3115 
3116 	switch (type) {
3117 	case CNSS_FW_IMAGE:
3118 		snprintf(md_entry.name, sizeof(md_entry.name), "FBC_%X",
3119 			 seg_no);
3120 		break;
3121 	case CNSS_FW_RDDM:
3122 		snprintf(md_entry.name, sizeof(md_entry.name), "RDDM_%X",
3123 			 seg_no);
3124 		break;
3125 	case CNSS_FW_REMOTE_HEAP:
3126 		snprintf(md_entry.name, sizeof(md_entry.name), "RHEAP_%X",
3127 			 seg_no);
3128 		break;
3129 	default:
3130 		cnss_pr_err("Unknown dump type ID: %d\n", type);
3131 		return -EINVAL;
3132 	}
3133 
3134 	md_entry.phys_addr = pa;
3135 	md_entry.virt_addr = (uintptr_t)va;
3136 	md_entry.size = size;
3137 	md_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
3138 
3139 	cnss_pr_dbg("Mini dump region: %s, va: %pK, pa: %pa, size: 0x%zx\n",
3140 		    md_entry.name, va, &pa, size);
3141 
3142 	ret = msm_minidump_add_region(&md_entry);
3143 	if (ret < 0)
3144 		cnss_pr_err("Failed to add mini dump region, err = %d\n", ret);
3145 
3146 	return ret;
3147 }
3148 
3149 int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
3150 				enum cnss_fw_dump_type type, int seg_no,
3151 				void *va, phys_addr_t pa, size_t size)
3152 {
3153 	struct md_region md_entry;
3154 	int ret;
3155 
3156 	switch (type) {
3157 	case CNSS_FW_IMAGE:
3158 		snprintf(md_entry.name, sizeof(md_entry.name), "FBC_%X",
3159 			 seg_no);
3160 		break;
3161 	case CNSS_FW_RDDM:
3162 		snprintf(md_entry.name, sizeof(md_entry.name), "RDDM_%X",
3163 			 seg_no);
3164 		break;
3165 	case CNSS_FW_REMOTE_HEAP:
3166 		snprintf(md_entry.name, sizeof(md_entry.name), "RHEAP_%X",
3167 			 seg_no);
3168 		break;
3169 	default:
3170 		cnss_pr_err("Unknown dump type ID: %d\n", type);
3171 		return -EINVAL;
3172 	}
3173 
3174 	md_entry.phys_addr = pa;
3175 	md_entry.virt_addr = (uintptr_t)va;
3176 	md_entry.size = size;
3177 	md_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
3178 
3179 	cnss_pr_dbg("Remove mini dump region: %s, va: %pK, pa: %pa, size: 0x%zx\n",
3180 		    md_entry.name, va, &pa, size);
3181 
3182 	ret = msm_minidump_remove_region(&md_entry);
3183 	if (ret)
3184 		cnss_pr_err("Failed to remove mini dump region, err = %d\n",
3185 			    ret);
3186 
3187 	return ret;
3188 }
3189 #else
3190 int cnss_va_to_pa(struct device *dev, size_t size, void *va, dma_addr_t dma,
3191 		  phys_addr_t *pa, unsigned long attrs)
3192 {
3193 	return 0;
3194 }
3195 
3196 int cnss_minidump_add_region(struct cnss_plat_data *plat_priv,
3197 			     enum cnss_fw_dump_type type, int seg_no,
3198 			     void *va, phys_addr_t pa, size_t size)
3199 {
3200 	return 0;
3201 }
3202 
3203 int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
3204 				enum cnss_fw_dump_type type, int seg_no,
3205 				void *va, phys_addr_t pa, size_t size)
3206 {
3207 	return 0;
3208 }
3209 #endif /* CONFIG_QCOM_MINIDUMP */
3210 
3211 int cnss_request_firmware_direct(struct cnss_plat_data *plat_priv,
3212 				 const struct firmware **fw_entry,
3213 				 const char *filename)
3214 {
3215 	if (IS_ENABLED(CONFIG_CNSS_REQ_FW_DIRECT))
3216 		return request_firmware_direct(fw_entry, filename,
3217 					       &plat_priv->plat_dev->dev);
3218 	else
3219 		return firmware_request_nowarn(fw_entry, filename,
3220 					       &plat_priv->plat_dev->dev);
3221 }
3222 
3223 #if IS_ENABLED(CONFIG_INTERCONNECT)
3224 /**
3225  * cnss_register_bus_scale() - Setup interconnect voting data
3226  * @plat_priv: Platform data structure
3227  *
3228  * For different interconnect path configured in device tree setup voting data
3229  * for list of bandwidth requirements.
3230  *
3231  * Result: 0 for success. -EINVAL if not configured
3232  */
3233 static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
3234 {
3235 	int ret = -EINVAL;
3236 	u32 idx, i, j, cfg_arr_size, *cfg_arr = NULL;
3237 	struct cnss_bus_bw_info *bus_bw_info, *tmp;
3238 	struct device *dev = &plat_priv->plat_dev->dev;
3239 
3240 	INIT_LIST_HEAD(&plat_priv->icc.list_head);
3241 	ret = of_property_read_u32(dev->of_node,
3242 				   "qcom,icc-path-count",
3243 				   &plat_priv->icc.path_count);
3244 	if (ret) {
3245 		cnss_pr_dbg("Platform Bus Interconnect path not configured\n");
3246 		return 0;
3247 	}
3248 	ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node,
3249 				   "qcom,bus-bw-cfg-count",
3250 				   &plat_priv->icc.bus_bw_cfg_count);
3251 	if (ret) {
3252 		cnss_pr_err("Failed to get Bus BW Config table size\n");
3253 		goto cleanup;
3254 	}
3255 	cfg_arr_size = plat_priv->icc.path_count *
3256 			 plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX;
3257 	cfg_arr = kcalloc(cfg_arr_size, sizeof(*cfg_arr), GFP_KERNEL);
3258 	if (!cfg_arr) {
3259 		cnss_pr_err("Failed to alloc cfg table mem\n");
3260 		ret = -ENOMEM;
3261 		goto cleanup;
3262 	}
3263 
3264 	ret = of_property_read_u32_array(plat_priv->plat_dev->dev.of_node,
3265 					 "qcom,bus-bw-cfg", cfg_arr,
3266 					 cfg_arr_size);
3267 	if (ret) {
3268 		cnss_pr_err("Invalid Bus BW Config Table\n");
3269 		goto cleanup;
3270 	}
3271 
3272 	cnss_pr_dbg("ICC Path_Count: %d BW_CFG_Count: %d\n",
3273 		    plat_priv->icc.path_count, plat_priv->icc.bus_bw_cfg_count);
3274 
3275 	for (idx = 0; idx < plat_priv->icc.path_count; idx++) {
3276 		bus_bw_info = devm_kzalloc(dev, sizeof(*bus_bw_info),
3277 					   GFP_KERNEL);
3278 		if (!bus_bw_info) {
3279 			ret = -ENOMEM;
3280 			goto out;
3281 		}
3282 		ret = of_property_read_string_index(dev->of_node,
3283 						    "interconnect-names", idx,
3284 						    &bus_bw_info->icc_name);
3285 		if (ret)
3286 			goto out;
3287 
3288 		bus_bw_info->icc_path =
3289 			of_icc_get(&plat_priv->plat_dev->dev,
3290 				   bus_bw_info->icc_name);
3291 
3292 		if (IS_ERR(bus_bw_info->icc_path))  {
3293 			ret = PTR_ERR(bus_bw_info->icc_path);
3294 			if (ret != -EPROBE_DEFER) {
3295 				cnss_pr_err("Failed to get Interconnect path for %s. Err: %d\n",
3296 					    bus_bw_info->icc_name, ret);
3297 				goto out;
3298 			}
3299 		}
3300 
3301 		bus_bw_info->cfg_table =
3302 			devm_kcalloc(dev, plat_priv->icc.bus_bw_cfg_count,
3303 				     sizeof(*bus_bw_info->cfg_table),
3304 				     GFP_KERNEL);
3305 		if (!bus_bw_info->cfg_table) {
3306 			ret = -ENOMEM;
3307 			goto out;
3308 		}
3309 		cnss_pr_dbg("ICC Vote CFG for path: %s\n",
3310 			    bus_bw_info->icc_name);
3311 		for (i = 0, j = (idx * plat_priv->icc.bus_bw_cfg_count *
3312 		     CNSS_ICC_VOTE_MAX);
3313 		     i < plat_priv->icc.bus_bw_cfg_count;
3314 		     i++, j += 2) {
3315 			bus_bw_info->cfg_table[i].avg_bw = cfg_arr[j];
3316 			bus_bw_info->cfg_table[i].peak_bw = cfg_arr[j + 1];
3317 			cnss_pr_dbg("ICC Vote BW: %d avg: %d peak: %d\n",
3318 				    i, bus_bw_info->cfg_table[i].avg_bw,
3319 				    bus_bw_info->cfg_table[i].peak_bw);
3320 		}
3321 		list_add_tail(&bus_bw_info->list,
3322 			      &plat_priv->icc.list_head);
3323 	}
3324 	kfree(cfg_arr);
3325 	return 0;
3326 out:
3327 	list_for_each_entry_safe(bus_bw_info, tmp,
3328 				 &plat_priv->icc.list_head, list) {
3329 		list_del(&bus_bw_info->list);
3330 	}
3331 cleanup:
3332 	kfree(cfg_arr);
3333 	memset(&plat_priv->icc, 0, sizeof(plat_priv->icc));
3334 	return ret;
3335 }
3336 
3337 static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
3338 {
3339 	struct cnss_bus_bw_info *bus_bw_info, *tmp;
3340 
3341 	list_for_each_entry_safe(bus_bw_info, tmp,
3342 				 &plat_priv->icc.list_head, list) {
3343 		list_del(&bus_bw_info->list);
3344 		if (bus_bw_info->icc_path)
3345 			icc_put(bus_bw_info->icc_path);
3346 	}
3347 	memset(&plat_priv->icc, 0, sizeof(plat_priv->icc));
3348 }
3349 #else
3350 static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
3351 {
3352 	return 0;
3353 }
3354 
3355 static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv) {}
3356 #endif /* CONFIG_INTERCONNECT */
3357 
3358 void cnss_daemon_connection_update_cb(void *cb_ctx, bool status)
3359 {
3360 	struct cnss_plat_data *plat_priv = cb_ctx;
3361 
3362 	if (!plat_priv) {
3363 		cnss_pr_err("%s: Invalid context\n", __func__);
3364 		return;
3365 	}
3366 	if (status) {
3367 		cnss_pr_info("CNSS Daemon connected\n");
3368 		set_bit(CNSS_DAEMON_CONNECTED, &plat_priv->driver_state);
3369 		complete(&plat_priv->daemon_connected);
3370 	} else {
3371 		cnss_pr_info("CNSS Daemon disconnected\n");
3372 		reinit_completion(&plat_priv->daemon_connected);
3373 		clear_bit(CNSS_DAEMON_CONNECTED, &plat_priv->driver_state);
3374 	}
3375 }
3376 
3377 static ssize_t enable_hds_store(struct device *dev,
3378 				struct device_attribute *attr,
3379 				const char *buf, size_t count)
3380 {
3381 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3382 	unsigned int enable_hds = 0;
3383 
3384 	if (!plat_priv)
3385 		return -ENODEV;
3386 
3387 	if (sscanf(buf, "%du", &enable_hds) != 1) {
3388 		cnss_pr_err("Invalid enable_hds sysfs command\n");
3389 		return -EINVAL;
3390 	}
3391 
3392 	if (enable_hds)
3393 		plat_priv->hds_enabled = true;
3394 	else
3395 		plat_priv->hds_enabled = false;
3396 
3397 	cnss_pr_dbg("%s HDS file download, count is %zu\n",
3398 		    plat_priv->hds_enabled ? "Enable" : "Disable", count);
3399 
3400 	return count;
3401 }
3402 
3403 static ssize_t recovery_show(struct device *dev,
3404 			     struct device_attribute *attr,
3405 			     char *buf)
3406 {
3407 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3408 	u32 buf_size = PAGE_SIZE;
3409 	u32 curr_len = 0;
3410 	u32 buf_written = 0;
3411 
3412 	if (!plat_priv)
3413 		return -ENODEV;
3414 
3415 	buf_written = scnprintf(buf, buf_size,
3416 				"Usage: echo [recovery_bitmap] > /sys/kernel/cnss/recovery\n"
3417 				"BIT0 -- wlan fw recovery\n"
3418 				"BIT1 -- wlan pcss recovery\n"
3419 				"---------------------------------\n");
3420 	curr_len += buf_written;
3421 
3422 	buf_written = scnprintf(buf + curr_len, buf_size - curr_len,
3423 				"WLAN recovery %s[%d]\n",
3424 				plat_priv->recovery_enabled ? "Enabled" : "Disabled",
3425 				plat_priv->recovery_enabled);
3426 	curr_len += buf_written;
3427 
3428 	buf_written = scnprintf(buf + curr_len, buf_size - curr_len,
3429 				"WLAN PCSS recovery %s[%d]\n",
3430 				plat_priv->recovery_pcss_enabled ? "Enabled" : "Disabled",
3431 				plat_priv->recovery_pcss_enabled);
3432 	curr_len += buf_written;
3433 
3434 	/*
3435 	 * Now size of curr_len is not over page size for sure,
3436 	 * later if new item or none-fixed size item added, need
3437 	 * add check to make sure curr_len is not over page size.
3438 	 */
3439 	return curr_len;
3440 }
3441 
3442 static ssize_t time_sync_period_show(struct device *dev,
3443 				     struct device_attribute *attr,
3444 				     char *buf)
3445 {
3446 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3447 
3448 	return scnprintf(buf, PAGE_SIZE, "%u ms\n",
3449 			plat_priv->ctrl_params.time_sync_period);
3450 }
3451 
3452 static ssize_t time_sync_period_store(struct device *dev,
3453 				      struct device_attribute *attr,
3454 				      const char *buf, size_t count)
3455 {
3456 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3457 	unsigned int time_sync_period = 0;
3458 
3459 	if (!plat_priv)
3460 		return -ENODEV;
3461 
3462 	if (sscanf(buf, "%du", &time_sync_period) != 1) {
3463 		cnss_pr_err("Invalid time sync sysfs command\n");
3464 		return -EINVAL;
3465 	}
3466 
3467 	if (time_sync_period >= CNSS_MIN_TIME_SYNC_PERIOD)
3468 		cnss_bus_update_time_sync_period(plat_priv, time_sync_period);
3469 
3470 	return count;
3471 }
3472 
3473 static ssize_t recovery_store(struct device *dev,
3474 			      struct device_attribute *attr,
3475 			      const char *buf, size_t count)
3476 {
3477 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3478 	unsigned int recovery = 0;
3479 	int ret;
3480 
3481 	if (!plat_priv)
3482 		return -ENODEV;
3483 
3484 	if (sscanf(buf, "%du", &recovery) != 1) {
3485 		cnss_pr_err("Invalid recovery sysfs command\n");
3486 		return -EINVAL;
3487 	}
3488 
3489 	plat_priv->recovery_enabled = !!(recovery & CNSS_WLAN_RECOVERY);
3490 	plat_priv->recovery_pcss_enabled = !!(recovery & CNSS_PCSS_RECOVERY);
3491 
3492 	cnss_pr_dbg("%s WLAN recovery, count is %zu\n",
3493 		    plat_priv->recovery_enabled ? "Enable" : "Disable", count);
3494 	cnss_pr_dbg("%s PCSS recovery, count is %zu\n",
3495 		    plat_priv->recovery_pcss_enabled ? "Enable" : "Disable", count);
3496 
3497 	ret = cnss_send_subsys_restart_level_msg(plat_priv);
3498 	if (ret < 0) {
3499 		cnss_pr_err("pcss recovery setting failed with ret %d\n", ret);
3500 		plat_priv->recovery_pcss_enabled = false;
3501 		return -EINVAL;
3502 	}
3503 
3504 	return count;
3505 }
3506 
3507 static ssize_t shutdown_store(struct device *dev,
3508 			      struct device_attribute *attr,
3509 			      const char *buf, size_t count)
3510 {
3511 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3512 
3513 	if (plat_priv) {
3514 		set_bit(CNSS_IN_REBOOT, &plat_priv->driver_state);
3515 		del_timer(&plat_priv->fw_boot_timer);
3516 		complete_all(&plat_priv->power_up_complete);
3517 		complete_all(&plat_priv->cal_complete);
3518 	}
3519 
3520 	cnss_pr_dbg("Received shutdown notification\n");
3521 
3522 	return count;
3523 }
3524 
3525 static ssize_t fs_ready_store(struct device *dev,
3526 			      struct device_attribute *attr,
3527 			      const char *buf, size_t count)
3528 {
3529 	int fs_ready = 0;
3530 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3531 
3532 	if (sscanf(buf, "%du", &fs_ready) != 1)
3533 		return -EINVAL;
3534 
3535 	cnss_pr_dbg("File system is ready, fs_ready is %d, count is %zu\n",
3536 		    fs_ready, count);
3537 
3538 	if (!plat_priv) {
3539 		cnss_pr_err("plat_priv is NULL\n");
3540 		return count;
3541 	}
3542 
3543 	if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks)) {
3544 		cnss_pr_dbg("QMI is bypassed\n");
3545 		return count;
3546 	}
3547 
3548 	set_bit(CNSS_FS_READY, &plat_priv->driver_state);
3549 	if (fs_ready == FILE_SYSTEM_READY && plat_priv->cbc_enabled) {
3550 		cnss_driver_event_post(plat_priv,
3551 				       CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START,
3552 				       0, NULL);
3553 	}
3554 
3555 	return count;
3556 }
3557 
3558 static ssize_t qdss_trace_start_store(struct device *dev,
3559 				      struct device_attribute *attr,
3560 				      const char *buf, size_t count)
3561 {
3562 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3563 
3564 	wlfw_qdss_trace_start(plat_priv);
3565 	cnss_pr_dbg("Received QDSS start command\n");
3566 	return count;
3567 }
3568 
3569 static ssize_t qdss_trace_stop_store(struct device *dev,
3570 				     struct device_attribute *attr,
3571 				     const char *buf, size_t count)
3572 {
3573 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3574 	u32 option = 0;
3575 
3576 	if (sscanf(buf, "%du", &option) != 1)
3577 		return -EINVAL;
3578 
3579 	wlfw_qdss_trace_stop(plat_priv, option);
3580 	cnss_pr_dbg("Received QDSS stop command\n");
3581 	return count;
3582 }
3583 
3584 static ssize_t qdss_conf_download_store(struct device *dev,
3585 					struct device_attribute *attr,
3586 					const char *buf, size_t count)
3587 {
3588 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3589 
3590 	cnss_wlfw_qdss_dnld_send_sync(plat_priv);
3591 	cnss_pr_dbg("Received QDSS download config command\n");
3592 	return count;
3593 }
3594 
3595 static ssize_t hw_trace_override_store(struct device *dev,
3596 				       struct device_attribute *attr,
3597 				       const char *buf, size_t count)
3598 {
3599 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3600 	int tmp = 0;
3601 
3602 	if (sscanf(buf, "%du", &tmp) != 1)
3603 		return -EINVAL;
3604 
3605 	plat_priv->hw_trc_override = tmp;
3606 	cnss_pr_dbg("Received QDSS hw_trc_override indication\n");
3607 	return count;
3608 }
3609 
3610 static ssize_t charger_mode_store(struct device *dev,
3611 				  struct device_attribute *attr,
3612 				  const char *buf, size_t count)
3613 {
3614 	struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
3615 	int tmp = 0;
3616 
3617 	if (sscanf(buf, "%du", &tmp) != 1)
3618 		return -EINVAL;
3619 
3620 	plat_priv->charger_mode = tmp;
3621 	cnss_pr_dbg("Received Charger Mode: %d\n", tmp);
3622 	return count;
3623 }
3624 
3625 static DEVICE_ATTR_WO(fs_ready);
3626 static DEVICE_ATTR_WO(shutdown);
3627 static DEVICE_ATTR_RW(recovery);
3628 static DEVICE_ATTR_WO(enable_hds);
3629 static DEVICE_ATTR_WO(qdss_trace_start);
3630 static DEVICE_ATTR_WO(qdss_trace_stop);
3631 static DEVICE_ATTR_WO(qdss_conf_download);
3632 static DEVICE_ATTR_WO(hw_trace_override);
3633 static DEVICE_ATTR_WO(charger_mode);
3634 static DEVICE_ATTR_RW(time_sync_period);
3635 
3636 static struct attribute *cnss_attrs[] = {
3637 	&dev_attr_fs_ready.attr,
3638 	&dev_attr_shutdown.attr,
3639 	&dev_attr_recovery.attr,
3640 	&dev_attr_enable_hds.attr,
3641 	&dev_attr_qdss_trace_start.attr,
3642 	&dev_attr_qdss_trace_stop.attr,
3643 	&dev_attr_qdss_conf_download.attr,
3644 	&dev_attr_hw_trace_override.attr,
3645 	&dev_attr_charger_mode.attr,
3646 	&dev_attr_time_sync_period.attr,
3647 	NULL,
3648 };
3649 
3650 static struct attribute_group cnss_attr_group = {
3651 	.attrs = cnss_attrs,
3652 };
3653 
3654 static int cnss_create_sysfs_link(struct cnss_plat_data *plat_priv)
3655 {
3656 	struct device *dev = &plat_priv->plat_dev->dev;
3657 	int ret;
3658 
3659 	ret = sysfs_create_link(kernel_kobj, &dev->kobj, "cnss");
3660 	if (ret) {
3661 		cnss_pr_err("Failed to create cnss link, err = %d\n",
3662 			    ret);
3663 		goto out;
3664 	}
3665 
3666 	/* This is only for backward compatibility. */
3667 	ret = sysfs_create_link(kernel_kobj, &dev->kobj, "shutdown_wlan");
3668 	if (ret) {
3669 		cnss_pr_err("Failed to create shutdown_wlan link, err = %d\n",
3670 			    ret);
3671 		goto rm_cnss_link;
3672 	}
3673 
3674 	return 0;
3675 
3676 rm_cnss_link:
3677 	sysfs_remove_link(kernel_kobj, "cnss");
3678 out:
3679 	return ret;
3680 }
3681 
3682 static void cnss_remove_sysfs_link(struct cnss_plat_data *plat_priv)
3683 {
3684 	sysfs_remove_link(kernel_kobj, "shutdown_wlan");
3685 	sysfs_remove_link(kernel_kobj, "cnss");
3686 }
3687 
3688 static int cnss_create_sysfs(struct cnss_plat_data *plat_priv)
3689 {
3690 	int ret = 0;
3691 
3692 	ret = devm_device_add_group(&plat_priv->plat_dev->dev,
3693 				    &cnss_attr_group);
3694 	if (ret) {
3695 		cnss_pr_err("Failed to create cnss device group, err = %d\n",
3696 			    ret);
3697 		goto out;
3698 	}
3699 
3700 	cnss_create_sysfs_link(plat_priv);
3701 
3702 	return 0;
3703 out:
3704 	return ret;
3705 }
3706 
3707 static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv)
3708 {
3709 	cnss_remove_sysfs_link(plat_priv);
3710 	devm_device_remove_group(&plat_priv->plat_dev->dev, &cnss_attr_group);
3711 }
3712 
3713 static int cnss_event_work_init(struct cnss_plat_data *plat_priv)
3714 {
3715 	spin_lock_init(&plat_priv->event_lock);
3716 	plat_priv->event_wq = alloc_workqueue("cnss_driver_event",
3717 					      WQ_UNBOUND, 1);
3718 	if (!plat_priv->event_wq) {
3719 		cnss_pr_err("Failed to create event workqueue!\n");
3720 		return -EFAULT;
3721 	}
3722 
3723 	INIT_WORK(&plat_priv->event_work, cnss_driver_event_work);
3724 	INIT_LIST_HEAD(&plat_priv->event_list);
3725 
3726 	return 0;
3727 }
3728 
3729 static void cnss_event_work_deinit(struct cnss_plat_data *plat_priv)
3730 {
3731 	destroy_workqueue(plat_priv->event_wq);
3732 }
3733 
3734 static int cnss_reboot_notifier(struct notifier_block *nb,
3735 				unsigned long action,
3736 				void *data)
3737 {
3738 	struct cnss_plat_data *plat_priv =
3739 		container_of(nb, struct cnss_plat_data, reboot_nb);
3740 
3741 	set_bit(CNSS_IN_REBOOT, &plat_priv->driver_state);
3742 	del_timer(&plat_priv->fw_boot_timer);
3743 	complete_all(&plat_priv->power_up_complete);
3744 	complete_all(&plat_priv->cal_complete);
3745 	cnss_pr_dbg("Reboot is in progress with action %d\n", action);
3746 
3747 	return NOTIFY_DONE;
3748 }
3749 
3750 #ifdef CONFIG_CNSS_HW_SECURE_DISABLE
3751 int cnss_wlan_hw_disable_check(struct cnss_plat_data *plat_priv)
3752 {
3753 	struct Object client_env;
3754 	struct Object app_object;
3755 	u32 wifi_uid = HW_WIFI_UID;
3756 	union ObjectArg obj_arg[2] = {{{0, 0}}};
3757 	int ret;
3758 	u8 state = 0;
3759 
3760 	/* Once this flag is set, secure peripheral feature
3761 	 * will not be supported till next reboot
3762 	 */
3763 	if (plat_priv->sec_peri_feature_disable)
3764 		return 0;
3765 
3766 	/* get rootObj */
3767 	ret = get_client_env_object(&client_env);
3768 	if (ret) {
3769 		cnss_pr_dbg("Failed to get client_env_object, ret: %d\n", ret);
3770 		goto end;
3771 	}
3772 	ret = IClientEnv_open(client_env, HW_STATE_UID, &app_object);
3773 	if (ret) {
3774 		cnss_pr_dbg("Failed to get app_object, ret: %d\n",  ret);
3775 		if (ret == FEATURE_NOT_SUPPORTED) {
3776 			ret = 0; /* Do not Assert */
3777 			plat_priv->sec_peri_feature_disable = true;
3778 			cnss_pr_dbg("Secure HW feature not supported\n");
3779 		}
3780 		goto exit_release_clientenv;
3781 	}
3782 
3783 	obj_arg[0].b = (struct ObjectBuf) {&wifi_uid, sizeof(u32)};
3784 	obj_arg[1].b = (struct ObjectBuf) {&state, sizeof(u8)};
3785 	ret = Object_invoke(app_object, HW_OP_GET_STATE, obj_arg,
3786 			    ObjectCounts_pack(1, 1, 0, 0));
3787 
3788 	cnss_pr_dbg("SMC invoke ret: %d state: %d\n", ret, state);
3789 	if (ret) {
3790 		if (ret == PERIPHERAL_NOT_FOUND) {
3791 			ret = 0; /* Do not Assert */
3792 			plat_priv->sec_peri_feature_disable = true;
3793 			cnss_pr_dbg("Secure HW mode is not updated. Peripheral not found\n");
3794 		}
3795 		goto exit_release_app_obj;
3796 	}
3797 
3798 	if (state == 1)
3799 		set_bit(CNSS_WLAN_HW_DISABLED,
3800 			&plat_priv->driver_state);
3801 	else
3802 		clear_bit(CNSS_WLAN_HW_DISABLED,
3803 			  &plat_priv->driver_state);
3804 
3805 exit_release_app_obj:
3806 	Object_release(app_object);
3807 exit_release_clientenv:
3808 	Object_release(client_env);
3809 end:
3810 	if (ret) {
3811 		cnss_pr_err("Unable to get HW disable status\n");
3812 		CNSS_ASSERT(0);
3813 	}
3814 	return ret;
3815 }
3816 #else
3817 int cnss_wlan_hw_disable_check(struct cnss_plat_data *plat_priv)
3818 {
3819 	return 0;
3820 }
3821 #endif
3822 
3823 static int cnss_misc_init(struct cnss_plat_data *plat_priv)
3824 {
3825 	int ret;
3826 
3827 	ret = cnss_init_sol_gpio(plat_priv);
3828 	if (ret)
3829 		return ret;
3830 
3831 	timer_setup(&plat_priv->fw_boot_timer,
3832 		    cnss_bus_fw_boot_timeout_hdlr, 0);
3833 
3834 	ret = register_pm_notifier(&cnss_pm_notifier);
3835 	if (ret)
3836 		cnss_pr_err("Failed to register PM notifier, err = %d\n", ret);
3837 
3838 	plat_priv->reboot_nb.notifier_call = cnss_reboot_notifier;
3839 	ret = register_reboot_notifier(&plat_priv->reboot_nb);
3840 	if (ret)
3841 		cnss_pr_err("Failed to register reboot notifier, err = %d\n",
3842 			    ret);
3843 
3844 	ret = device_init_wakeup(&plat_priv->plat_dev->dev, true);
3845 	if (ret)
3846 		cnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
3847 			    ret);
3848 
3849 	INIT_WORK(&plat_priv->recovery_work, cnss_recovery_work_handler);
3850 	init_completion(&plat_priv->power_up_complete);
3851 	init_completion(&plat_priv->cal_complete);
3852 	init_completion(&plat_priv->rddm_complete);
3853 	init_completion(&plat_priv->recovery_complete);
3854 	init_completion(&plat_priv->daemon_connected);
3855 	mutex_init(&plat_priv->dev_lock);
3856 	mutex_init(&plat_priv->driver_ops_lock);
3857 	plat_priv->recovery_ws =
3858 		wakeup_source_register(&plat_priv->plat_dev->dev,
3859 				       "CNSS_FW_RECOVERY");
3860 	if (!plat_priv->recovery_ws)
3861 		cnss_pr_err("Failed to setup FW recovery wake source\n");
3862 
3863 	ret = cnss_plat_ipc_register(CNSS_PLAT_IPC_DAEMON_QMI_CLIENT_V01,
3864 				     cnss_daemon_connection_update_cb,
3865 				     plat_priv);
3866 	if (ret)
3867 		cnss_pr_err("QMI IPC connection call back register failed, err = %d\n",
3868 			    ret);
3869 
3870 	if (plat_priv->device_id == QCA6490_DEVICE_ID &&
3871 	    cnss_get_host_build_type() == QMI_HOST_BUILD_TYPE_PRIMARY_V01)
3872 		plat_priv->sram_dump = kcalloc(SRAM_DUMP_SIZE, 1, GFP_KERNEL);
3873 
3874 	return 0;
3875 }
3876 
3877 static void cnss_misc_deinit(struct cnss_plat_data *plat_priv)
3878 {
3879 	cnss_plat_ipc_unregister(CNSS_PLAT_IPC_DAEMON_QMI_CLIENT_V01,
3880 				 plat_priv);
3881 	complete_all(&plat_priv->recovery_complete);
3882 	complete_all(&plat_priv->rddm_complete);
3883 	complete_all(&plat_priv->cal_complete);
3884 	complete_all(&plat_priv->power_up_complete);
3885 	complete_all(&plat_priv->daemon_connected);
3886 	device_init_wakeup(&plat_priv->plat_dev->dev, false);
3887 	unregister_reboot_notifier(&plat_priv->reboot_nb);
3888 	unregister_pm_notifier(&cnss_pm_notifier);
3889 	del_timer(&plat_priv->fw_boot_timer);
3890 	wakeup_source_unregister(plat_priv->recovery_ws);
3891 	cnss_deinit_sol_gpio(plat_priv);
3892 	kfree(plat_priv->sram_dump);
3893 }
3894 
3895 static void cnss_init_control_params(struct cnss_plat_data *plat_priv)
3896 {
3897 	plat_priv->ctrl_params.quirks = CNSS_QUIRKS_DEFAULT;
3898 
3899 	plat_priv->cbc_enabled = !IS_ENABLED(CONFIG_CNSS_EMULATION) &&
3900 		of_property_read_bool(plat_priv->plat_dev->dev.of_node,
3901 				      "qcom,wlan-cbc-enabled");
3902 
3903 	plat_priv->ctrl_params.mhi_timeout = CNSS_MHI_TIMEOUT_DEFAULT;
3904 	plat_priv->ctrl_params.mhi_m2_timeout = CNSS_MHI_M2_TIMEOUT_DEFAULT;
3905 	plat_priv->ctrl_params.qmi_timeout = CNSS_QMI_TIMEOUT_DEFAULT;
3906 	plat_priv->ctrl_params.bdf_type = CNSS_BDF_TYPE_DEFAULT;
3907 	plat_priv->ctrl_params.time_sync_period = CNSS_TIME_SYNC_PERIOD_DEFAULT;
3908 	/* Set adsp_pc_enabled default value to true as ADSP pc is always
3909 	 * enabled by default
3910 	 */
3911 	plat_priv->adsp_pc_enabled = true;
3912 }
3913 
3914 static void cnss_get_pm_domain_info(struct cnss_plat_data *plat_priv)
3915 {
3916 	struct device *dev = &plat_priv->plat_dev->dev;
3917 
3918 	plat_priv->use_pm_domain =
3919 		of_property_read_bool(dev->of_node, "use-pm-domain");
3920 
3921 	cnss_pr_dbg("use-pm-domain is %d\n", plat_priv->use_pm_domain);
3922 }
3923 
3924 static void cnss_get_wlaon_pwr_ctrl_info(struct cnss_plat_data *plat_priv)
3925 {
3926 	struct device *dev = &plat_priv->plat_dev->dev;
3927 
3928 	plat_priv->set_wlaon_pwr_ctrl =
3929 		of_property_read_bool(dev->of_node, "qcom,set-wlaon-pwr-ctrl");
3930 
3931 	cnss_pr_dbg("set_wlaon_pwr_ctrl is %d\n",
3932 		    plat_priv->set_wlaon_pwr_ctrl);
3933 }
3934 
3935 static bool cnss_use_fw_path_with_prefix(struct cnss_plat_data *plat_priv)
3936 {
3937 	return (of_property_read_bool(plat_priv->plat_dev->dev.of_node,
3938 				      "qcom,converged-dt") ||
3939 		of_property_read_bool(plat_priv->plat_dev->dev.of_node,
3940 				      "qcom,same-dt-multi-dev") ||
3941 		of_property_read_bool(plat_priv->plat_dev->dev.of_node,
3942 				      "qcom,multi-wlan-exchg"));
3943 }
3944 
3945 static const struct platform_device_id cnss_platform_id_table[] = {
3946 	{ .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
3947 	{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
3948 	{ .name = "qca6390", .driver_data = QCA6390_DEVICE_ID, },
3949 	{ .name = "qca6490", .driver_data = QCA6490_DEVICE_ID, },
3950 	{ .name = "kiwi", .driver_data = KIWI_DEVICE_ID, },
3951 	{ .name = "mango", .driver_data = MANGO_DEVICE_ID, },
3952 	{ .name = "qcaconv", .driver_data = 0, },
3953 	{ },
3954 };
3955 
3956 static const struct of_device_id cnss_of_match_table[] = {
3957 	{
3958 		.compatible = "qcom,cnss",
3959 		.data = (void *)&cnss_platform_id_table[0]},
3960 	{
3961 		.compatible = "qcom,cnss-qca6290",
3962 		.data = (void *)&cnss_platform_id_table[1]},
3963 	{
3964 		.compatible = "qcom,cnss-qca6390",
3965 		.data = (void *)&cnss_platform_id_table[2]},
3966 	{
3967 		.compatible = "qcom,cnss-qca6490",
3968 		.data = (void *)&cnss_platform_id_table[3]},
3969 	{
3970 		.compatible = "qcom,cnss-kiwi",
3971 		.data = (void *)&cnss_platform_id_table[4]},
3972 	{
3973 		.compatible = "qcom,cnss-mango",
3974 		.data = (void *)&cnss_platform_id_table[5]},
3975 	{
3976 		.compatible = "qcom,cnss-qca-converged",
3977 		.data = (void *)&cnss_platform_id_table[6]},
3978 	{ },
3979 };
3980 MODULE_DEVICE_TABLE(of, cnss_of_match_table);
3981 
3982 static inline bool
3983 cnss_use_nv_mac(struct cnss_plat_data *plat_priv)
3984 {
3985 	return of_property_read_bool(plat_priv->plat_dev->dev.of_node,
3986 				     "use-nv-mac");
3987 }
3988 
3989 static int cnss_get_dev_cfg_node(struct cnss_plat_data *plat_priv)
3990 {
3991 	struct device_node *child;
3992 	u32 id, i;
3993 	int id_n,  device_identifier_gpio, ret;
3994 	u8 gpio_value;
3995 
3996 
3997 	if (plat_priv->dt_type != CNSS_DTT_CONVERGED)
3998 		return 0;
3999 
4000 	/* Parses the wlan_sw_ctrl gpio which is used to identify device */
4001 	ret = cnss_get_wlan_sw_ctrl(plat_priv);
4002 	if (ret) {
4003 		cnss_pr_dbg("Failed to parse wlan_sw_ctrl gpio, error:%d", ret);
4004 		return ret;
4005 	}
4006 
4007 	device_identifier_gpio = plat_priv->pinctrl_info.wlan_sw_ctrl_gpio;
4008 
4009 	gpio_value = gpio_get_value(device_identifier_gpio);
4010 	cnss_pr_dbg("Value of Device Identifier GPIO: %d\n", gpio_value);
4011 
4012 	for_each_available_child_of_node(plat_priv->plat_dev->dev.of_node,
4013 					 child) {
4014 		if (strcmp(child->name, "chip_cfg"))
4015 			continue;
4016 
4017 		id_n = of_property_count_u32_elems(child, "supported-ids");
4018 		if (id_n <= 0) {
4019 			cnss_pr_err("Device id is NOT set\n");
4020 			return -EINVAL;
4021 		}
4022 
4023 		for (i = 0; i < id_n; i++) {
4024 			ret = of_property_read_u32_index(child,
4025 							 "supported-ids",
4026 							 i, &id);
4027 			if (ret) {
4028 				cnss_pr_err("Failed to read supported ids\n");
4029 				return -EINVAL;
4030 			}
4031 
4032 			if (gpio_value && id == QCA6490_DEVICE_ID) {
4033 				plat_priv->plat_dev->dev.of_node = child;
4034 				plat_priv->device_id = QCA6490_DEVICE_ID;
4035 				cnss_utils_update_device_type(CNSS_HSP_DEVICE_TYPE);
4036 				cnss_pr_dbg("got node[%s@%d] for device[0x%x]\n",
4037 					    child->name, i, id);
4038 				return 0;
4039 			} else if (!gpio_value && id == KIWI_DEVICE_ID) {
4040 				plat_priv->plat_dev->dev.of_node = child;
4041 				plat_priv->device_id = KIWI_DEVICE_ID;
4042 				cnss_utils_update_device_type(CNSS_HMT_DEVICE_TYPE);
4043 				cnss_pr_dbg("got node[%s@%d] for device[0x%x]\n",
4044 					    child->name, i, id);
4045 				return 0;
4046 			}
4047 		}
4048 	}
4049 
4050 	return -EINVAL;
4051 }
4052 
4053 static inline u32
4054 cnss_dt_type(struct cnss_plat_data *plat_priv)
4055 {
4056 	bool is_converged_dt = of_property_read_bool(
4057 		plat_priv->plat_dev->dev.of_node, "qcom,converged-dt");
4058 	bool is_multi_wlan_xchg;
4059 
4060 	if (is_converged_dt)
4061 		return CNSS_DTT_CONVERGED;
4062 
4063 	is_multi_wlan_xchg = of_property_read_bool(
4064 		plat_priv->plat_dev->dev.of_node, "qcom,multi-wlan-exchg");
4065 
4066 	if (is_multi_wlan_xchg)
4067 		return CNSS_DTT_MULTIEXCHG;
4068 	return CNSS_DTT_LEGACY;
4069 }
4070 
4071 static int cnss_wlan_device_init(struct cnss_plat_data *plat_priv)
4072 {
4073 	int ret = 0;
4074 	int retry = 0;
4075 
4076 	if (test_bit(SKIP_DEVICE_BOOT, &plat_priv->ctrl_params.quirks))
4077 		return 0;
4078 
4079 retry:
4080 	ret = cnss_power_on_device(plat_priv);
4081 	if (ret)
4082 		goto end;
4083 
4084 	ret = cnss_bus_init(plat_priv);
4085 	if (ret) {
4086 		if ((ret != -EPROBE_DEFER) &&
4087 		    retry++ < POWER_ON_RETRY_MAX_TIMES) {
4088 			cnss_power_off_device(plat_priv);
4089 			cnss_pr_dbg("Retry cnss_bus_init #%d\n", retry);
4090 			msleep(POWER_ON_RETRY_DELAY_MS * retry);
4091 			goto retry;
4092 		}
4093 		goto power_off;
4094 	}
4095 	return 0;
4096 
4097 power_off:
4098 	cnss_power_off_device(plat_priv);
4099 end:
4100 	return ret;
4101 }
4102 
4103 int cnss_wlan_hw_enable(void)
4104 {
4105 	struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
4106 	int ret = 0;
4107 
4108 	clear_bit(CNSS_WLAN_HW_DISABLED, &plat_priv->driver_state);
4109 
4110 	if (test_bit(CNSS_PCI_PROBE_DONE, &plat_priv->driver_state))
4111 		goto register_driver;
4112 
4113 	ret = cnss_wlan_device_init(plat_priv);
4114 	if (ret) {
4115 		if (!test_bit(CNSS_WLAN_HW_DISABLED, &plat_priv->driver_state))
4116 			CNSS_ASSERT(0);
4117 		return ret;
4118 	}
4119 
4120 	if (test_bit(CNSS_FS_READY, &plat_priv->driver_state))
4121 		cnss_driver_event_post(plat_priv,
4122 				       CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START,
4123 				       0, NULL);
4124 
4125 register_driver:
4126 	if (plat_priv->driver_ops)
4127 		ret = cnss_wlan_register_driver(plat_priv->driver_ops);
4128 
4129 	return ret;
4130 }
4131 EXPORT_SYMBOL(cnss_wlan_hw_enable);
4132 
4133 static int cnss_probe(struct platform_device *plat_dev)
4134 {
4135 	int ret = 0;
4136 	struct cnss_plat_data *plat_priv;
4137 	const struct of_device_id *of_id;
4138 	const struct platform_device_id *device_id;
4139 
4140 	if (cnss_get_plat_priv(plat_dev)) {
4141 		cnss_pr_err("Driver is already initialized!\n");
4142 		ret = -EEXIST;
4143 		goto out;
4144 	}
4145 
4146 	of_id = of_match_device(cnss_of_match_table, &plat_dev->dev);
4147 	if (!of_id || !of_id->data) {
4148 		cnss_pr_err("Failed to find of match device!\n");
4149 		ret = -ENODEV;
4150 		goto out;
4151 	}
4152 
4153 	device_id = of_id->data;
4154 
4155 	plat_priv = devm_kzalloc(&plat_dev->dev, sizeof(*plat_priv),
4156 				 GFP_KERNEL);
4157 	if (!plat_priv) {
4158 		ret = -ENOMEM;
4159 		goto out;
4160 	}
4161 
4162 	plat_priv->plat_dev = plat_dev;
4163 	plat_priv->dev_node = NULL;
4164 	plat_priv->device_id = device_id->driver_data;
4165 	plat_priv->dt_type = cnss_dt_type(plat_priv);
4166 	cnss_pr_dbg("Probing platform driver from dt type: %d\n",
4167 		    plat_priv->dt_type);
4168 
4169 	plat_priv->use_fw_path_with_prefix =
4170 		cnss_use_fw_path_with_prefix(plat_priv);
4171 
4172 	ret = cnss_get_dev_cfg_node(plat_priv);
4173 	if (ret) {
4174 		cnss_pr_err("Failed to get device cfg node, err = %d\n", ret);
4175 		goto reset_plat_dev;
4176 	}
4177 
4178 	plat_priv->bus_type = cnss_get_bus_type(plat_priv);
4179 	plat_priv->use_nv_mac = cnss_use_nv_mac(plat_priv);
4180 	plat_priv->driver_mode = CNSS_DRIVER_MODE_MAX;
4181 	cnss_set_plat_priv(plat_dev, plat_priv);
4182 	platform_set_drvdata(plat_dev, plat_priv);
4183 	INIT_LIST_HEAD(&plat_priv->vreg_list);
4184 	INIT_LIST_HEAD(&plat_priv->clk_list);
4185 
4186 	cnss_get_pm_domain_info(plat_priv);
4187 	cnss_get_wlaon_pwr_ctrl_info(plat_priv);
4188 	cnss_power_misc_params_init(plat_priv);
4189 	cnss_get_tcs_info(plat_priv);
4190 	cnss_get_cpr_info(plat_priv);
4191 	cnss_aop_mbox_init(plat_priv);
4192 	cnss_init_control_params(plat_priv);
4193 
4194 	ret = cnss_get_resources(plat_priv);
4195 	if (ret)
4196 		goto reset_ctx;
4197 
4198 	ret = cnss_register_esoc(plat_priv);
4199 	if (ret)
4200 		goto free_res;
4201 
4202 	ret = cnss_register_bus_scale(plat_priv);
4203 	if (ret)
4204 		goto unreg_esoc;
4205 
4206 	ret = cnss_create_sysfs(plat_priv);
4207 	if (ret)
4208 		goto unreg_bus_scale;
4209 
4210 	ret = cnss_event_work_init(plat_priv);
4211 	if (ret)
4212 		goto remove_sysfs;
4213 
4214 	ret = cnss_qmi_init(plat_priv);
4215 	if (ret)
4216 		goto deinit_event_work;
4217 
4218 	ret = cnss_dms_init(plat_priv);
4219 	if (ret)
4220 		goto deinit_qmi;
4221 
4222 	ret = cnss_debugfs_create(plat_priv);
4223 	if (ret)
4224 		goto deinit_dms;
4225 
4226 	ret = cnss_misc_init(plat_priv);
4227 	if (ret)
4228 		goto destroy_debugfs;
4229 
4230 	ret = cnss_wlan_hw_disable_check(plat_priv);
4231 	if (ret)
4232 		goto deinit_misc;
4233 
4234 	/* Make sure all platform related init are done before
4235 	 * device power on and bus init.
4236 	 */
4237 	if (!test_bit(CNSS_WLAN_HW_DISABLED, &plat_priv->driver_state)) {
4238 		ret = cnss_wlan_device_init(plat_priv);
4239 		if (ret)
4240 			goto deinit_misc;
4241 	} else {
4242 		cnss_pr_info("WLAN HW Disabled. Defer PCI enumeration\n");
4243 	}
4244 	cnss_register_coex_service(plat_priv);
4245 	cnss_register_ims_service(plat_priv);
4246 
4247 	ret = cnss_genl_init();
4248 	if (ret < 0)
4249 		cnss_pr_err("CNSS genl init failed %d\n", ret);
4250 
4251 	cnss_pr_info("Platform driver probed successfully.\n");
4252 
4253 	return 0;
4254 
4255 deinit_misc:
4256 	cnss_misc_deinit(plat_priv);
4257 destroy_debugfs:
4258 	cnss_debugfs_destroy(plat_priv);
4259 deinit_dms:
4260 	cnss_dms_deinit(plat_priv);
4261 deinit_qmi:
4262 	cnss_qmi_deinit(plat_priv);
4263 deinit_event_work:
4264 	cnss_event_work_deinit(plat_priv);
4265 remove_sysfs:
4266 	cnss_remove_sysfs(plat_priv);
4267 unreg_bus_scale:
4268 	cnss_unregister_bus_scale(plat_priv);
4269 unreg_esoc:
4270 	cnss_unregister_esoc(plat_priv);
4271 free_res:
4272 	cnss_put_resources(plat_priv);
4273 reset_ctx:
4274 	platform_set_drvdata(plat_dev, NULL);
4275 reset_plat_dev:
4276 	cnss_set_plat_priv(plat_dev, NULL);
4277 out:
4278 	return ret;
4279 }
4280 
4281 static int cnss_remove(struct platform_device *plat_dev)
4282 {
4283 	struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);
4284 
4285 	cnss_genl_exit();
4286 	cnss_unregister_ims_service(plat_priv);
4287 	cnss_unregister_coex_service(plat_priv);
4288 	cnss_bus_deinit(plat_priv);
4289 	cnss_misc_deinit(plat_priv);
4290 	cnss_debugfs_destroy(plat_priv);
4291 	cnss_dms_deinit(plat_priv);
4292 	cnss_qmi_deinit(plat_priv);
4293 	cnss_event_work_deinit(plat_priv);
4294 	cnss_cancel_dms_work();
4295 	cnss_remove_sysfs(plat_priv);
4296 	cnss_unregister_bus_scale(plat_priv);
4297 	cnss_unregister_esoc(plat_priv);
4298 	cnss_put_resources(plat_priv);
4299 
4300 	if (!IS_ERR_OR_NULL(plat_priv->mbox_chan))
4301 		mbox_free_channel(plat_priv->mbox_chan);
4302 
4303 	platform_set_drvdata(plat_dev, NULL);
4304 	plat_env = NULL;
4305 
4306 	return 0;
4307 }
4308 
4309 static struct platform_driver cnss_platform_driver = {
4310 	.probe  = cnss_probe,
4311 	.remove = cnss_remove,
4312 	.driver = {
4313 		.name = "cnss2",
4314 		.of_match_table = cnss_of_match_table,
4315 #ifdef CONFIG_CNSS_ASYNC
4316 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
4317 #endif
4318 	},
4319 };
4320 
4321 static bool cnss_check_compatible_node(void)
4322 {
4323 	struct device_node *dn = NULL;
4324 
4325 	for_each_matching_node(dn, cnss_of_match_table) {
4326 		if (of_device_is_available(dn)) {
4327 			cnss_allow_driver_loading = true;
4328 			return true;
4329 		}
4330 	}
4331 
4332 	return false;
4333 }
4334 
4335 /**
4336  * cnss_is_valid_dt_node_found - Check if valid device tree node present
4337  *
4338  * Valid device tree node means a node with "compatible" property from the
4339  * device match table and "status" property is not disabled.
4340  *
4341  * Return: true if valid device tree node found, false if not found
4342  */
4343 static bool cnss_is_valid_dt_node_found(void)
4344 {
4345 	struct device_node *dn = NULL;
4346 
4347 	for_each_matching_node(dn, cnss_of_match_table) {
4348 		if (of_device_is_available(dn))
4349 			break;
4350 	}
4351 
4352 	if (dn)
4353 		return true;
4354 
4355 	return false;
4356 }
4357 
4358 static int __init cnss_initialize(void)
4359 {
4360 	int ret = 0;
4361 
4362 	if (!cnss_is_valid_dt_node_found())
4363 		return -ENODEV;
4364 
4365 	if (!cnss_check_compatible_node())
4366 		return ret;
4367 
4368 	cnss_debug_init();
4369 	ret = platform_driver_register(&cnss_platform_driver);
4370 	if (ret)
4371 		cnss_debug_deinit();
4372 
4373 	return ret;
4374 }
4375 
4376 static void __exit cnss_exit(void)
4377 {
4378 	platform_driver_unregister(&cnss_platform_driver);
4379 	cnss_debug_deinit();
4380 }
4381 
4382 module_init(cnss_initialize);
4383 module_exit(cnss_exit);
4384 
4385 MODULE_LICENSE("GPL v2");
4386 MODULE_DESCRIPTION("CNSS2 Platform Driver");
4387