xref: /openbmc/linux/drivers/net/wireless/ath/ath11k/ahb.c (revision c4a7b9b5)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/of_device.h>
10 #include <linux/of.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/of_address.h>
13 #include <linux/iommu.h>
14 #include "ahb.h"
15 #include "debug.h"
16 #include "hif.h"
17 #include <linux/remoteproc.h>
18 #include "pcic.h"
19 #include <linux/soc/qcom/smem.h>
20 #include <linux/soc/qcom/smem_state.h>
21 
22 static const struct of_device_id ath11k_ahb_of_match[] = {
23 	/* TODO: Should we change the compatible string to something similar
24 	 * to one that ath10k uses?
25 	 */
26 	{ .compatible = "qcom,ipq8074-wifi",
27 	  .data = (void *)ATH11K_HW_IPQ8074,
28 	},
29 	{ .compatible = "qcom,ipq6018-wifi",
30 	  .data = (void *)ATH11K_HW_IPQ6018_HW10,
31 	},
32 	{ .compatible = "qcom,wcn6750-wifi",
33 	  .data = (void *)ATH11K_HW_WCN6750_HW10,
34 	},
35 	{ }
36 };
37 
38 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match);
39 
40 #define ATH11K_IRQ_CE0_OFFSET 4
41 
42 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
43 	"misc-pulse1",
44 	"misc-latch",
45 	"sw-exception",
46 	"watchdog",
47 	"ce0",
48 	"ce1",
49 	"ce2",
50 	"ce3",
51 	"ce4",
52 	"ce5",
53 	"ce6",
54 	"ce7",
55 	"ce8",
56 	"ce9",
57 	"ce10",
58 	"ce11",
59 	"host2wbm-desc-feed",
60 	"host2reo-re-injection",
61 	"host2reo-command",
62 	"host2rxdma-monitor-ring3",
63 	"host2rxdma-monitor-ring2",
64 	"host2rxdma-monitor-ring1",
65 	"reo2ost-exception",
66 	"wbm2host-rx-release",
67 	"reo2host-status",
68 	"reo2host-destination-ring4",
69 	"reo2host-destination-ring3",
70 	"reo2host-destination-ring2",
71 	"reo2host-destination-ring1",
72 	"rxdma2host-monitor-destination-mac3",
73 	"rxdma2host-monitor-destination-mac2",
74 	"rxdma2host-monitor-destination-mac1",
75 	"ppdu-end-interrupts-mac3",
76 	"ppdu-end-interrupts-mac2",
77 	"ppdu-end-interrupts-mac1",
78 	"rxdma2host-monitor-status-ring-mac3",
79 	"rxdma2host-monitor-status-ring-mac2",
80 	"rxdma2host-monitor-status-ring-mac1",
81 	"host2rxdma-host-buf-ring-mac3",
82 	"host2rxdma-host-buf-ring-mac2",
83 	"host2rxdma-host-buf-ring-mac1",
84 	"rxdma2host-destination-ring-mac3",
85 	"rxdma2host-destination-ring-mac2",
86 	"rxdma2host-destination-ring-mac1",
87 	"host2tcl-input-ring4",
88 	"host2tcl-input-ring3",
89 	"host2tcl-input-ring2",
90 	"host2tcl-input-ring1",
91 	"wbm2host-tx-completions-ring3",
92 	"wbm2host-tx-completions-ring2",
93 	"wbm2host-tx-completions-ring1",
94 	"tcl2host-status-ring",
95 };
96 
97 /* enum ext_irq_num - irq numbers that can be used by external modules
98  * like datapath
99  */
100 enum ext_irq_num {
101 	host2wbm_desc_feed = 16,
102 	host2reo_re_injection,
103 	host2reo_command,
104 	host2rxdma_monitor_ring3,
105 	host2rxdma_monitor_ring2,
106 	host2rxdma_monitor_ring1,
107 	reo2host_exception,
108 	wbm2host_rx_release,
109 	reo2host_status,
110 	reo2host_destination_ring4,
111 	reo2host_destination_ring3,
112 	reo2host_destination_ring2,
113 	reo2host_destination_ring1,
114 	rxdma2host_monitor_destination_mac3,
115 	rxdma2host_monitor_destination_mac2,
116 	rxdma2host_monitor_destination_mac1,
117 	ppdu_end_interrupts_mac3,
118 	ppdu_end_interrupts_mac2,
119 	ppdu_end_interrupts_mac1,
120 	rxdma2host_monitor_status_ring_mac3,
121 	rxdma2host_monitor_status_ring_mac2,
122 	rxdma2host_monitor_status_ring_mac1,
123 	host2rxdma_host_buf_ring_mac3,
124 	host2rxdma_host_buf_ring_mac2,
125 	host2rxdma_host_buf_ring_mac1,
126 	rxdma2host_destination_ring_mac3,
127 	rxdma2host_destination_ring_mac2,
128 	rxdma2host_destination_ring_mac1,
129 	host2tcl_input_ring4,
130 	host2tcl_input_ring3,
131 	host2tcl_input_ring2,
132 	host2tcl_input_ring1,
133 	wbm2host_tx_completions_ring3,
134 	wbm2host_tx_completions_ring2,
135 	wbm2host_tx_completions_ring1,
136 	tcl2host_status_ring,
137 };
138 
139 static int
140 ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector)
141 {
142 	return ab->pci.msi.irqs[vector];
143 }
144 
145 static inline u32
146 ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset)
147 {
148 	u32 window_start = 0;
149 
150 	/* If offset lies within DP register range, use 1st window */
151 	if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK)
152 		window_start = ATH11K_PCI_WINDOW_START;
153 	/* If offset lies within CE register range, use 2nd window */
154 	else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) <
155 		 ATH11K_PCI_WINDOW_RANGE_MASK)
156 		window_start = 2 * ATH11K_PCI_WINDOW_START;
157 
158 	return window_start;
159 }
160 
161 static void
162 ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value)
163 {
164 	u32 window_start;
165 
166 	/* WCN6750 uses static window based register access*/
167 	window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
168 
169 	iowrite32(value, ab->mem + window_start +
170 		  (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
171 }
172 
173 static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset)
174 {
175 	u32 window_start;
176 	u32 val;
177 
178 	/* WCN6750 uses static window based register access */
179 	window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
180 
181 	val = ioread32(ab->mem + window_start +
182 		       (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
183 	return val;
184 }
185 
186 static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = {
187 	.wakeup = NULL,
188 	.release = NULL,
189 	.get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750,
190 	.window_write32 = ath11k_ahb_window_write32_wcn6750,
191 	.window_read32 = ath11k_ahb_window_read32_wcn6750,
192 };
193 
194 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
195 {
196 	return ioread32(ab->mem + offset);
197 }
198 
199 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
200 {
201 	iowrite32(value, ab->mem + offset);
202 }
203 
204 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab)
205 {
206 	int i;
207 
208 	for (i = 0; i < ab->hw_params.ce_count; i++) {
209 		struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
210 
211 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
212 			continue;
213 
214 		tasklet_kill(&ce_pipe->intr_tq);
215 	}
216 }
217 
218 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
219 {
220 	int i;
221 
222 	for (i = 0; i < irq_grp->num_irq; i++)
223 		disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
224 }
225 
226 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
227 {
228 	int i;
229 
230 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
231 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
232 
233 		ath11k_ahb_ext_grp_disable(irq_grp);
234 
235 		if (irq_grp->napi_enabled) {
236 			napi_synchronize(&irq_grp->napi);
237 			napi_disable(&irq_grp->napi);
238 			irq_grp->napi_enabled = false;
239 		}
240 	}
241 }
242 
243 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
244 {
245 	int i;
246 
247 	for (i = 0; i < irq_grp->num_irq; i++)
248 		enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
249 }
250 
251 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset)
252 {
253 	u32 val;
254 
255 	val = ath11k_ahb_read32(ab, offset);
256 	ath11k_ahb_write32(ab, offset, val | BIT(bit));
257 }
258 
259 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset)
260 {
261 	u32 val;
262 
263 	val = ath11k_ahb_read32(ab, offset);
264 	ath11k_ahb_write32(ab, offset, val & ~BIT(bit));
265 }
266 
267 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
268 {
269 	const struct ce_attr *ce_attr;
270 
271 	ce_attr = &ab->hw_params.host_ce_config[ce_id];
272 	if (ce_attr->src_nentries)
273 		ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
274 
275 	if (ce_attr->dest_nentries) {
276 		ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
277 		ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
278 				    CE_HOST_IE_3_ADDRESS);
279 	}
280 }
281 
282 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
283 {
284 	const struct ce_attr *ce_attr;
285 
286 	ce_attr = &ab->hw_params.host_ce_config[ce_id];
287 	if (ce_attr->src_nentries)
288 		ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
289 
290 	if (ce_attr->dest_nentries) {
291 		ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
292 		ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
293 				      CE_HOST_IE_3_ADDRESS);
294 	}
295 }
296 
297 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab)
298 {
299 	int i;
300 	int irq_idx;
301 
302 	for (i = 0; i < ab->hw_params.ce_count; i++) {
303 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
304 			continue;
305 
306 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
307 		synchronize_irq(ab->irq_num[irq_idx]);
308 	}
309 }
310 
311 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab)
312 {
313 	int i, j;
314 	int irq_idx;
315 
316 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
317 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
318 
319 		for (j = 0; j < irq_grp->num_irq; j++) {
320 			irq_idx = irq_grp->irqs[j];
321 			synchronize_irq(ab->irq_num[irq_idx]);
322 		}
323 	}
324 }
325 
326 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab)
327 {
328 	int i;
329 
330 	for (i = 0; i < ab->hw_params.ce_count; i++) {
331 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
332 			continue;
333 		ath11k_ahb_ce_irq_enable(ab, i);
334 	}
335 }
336 
337 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab)
338 {
339 	int i;
340 
341 	for (i = 0; i < ab->hw_params.ce_count; i++) {
342 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
343 			continue;
344 		ath11k_ahb_ce_irq_disable(ab, i);
345 	}
346 }
347 
348 static int ath11k_ahb_start(struct ath11k_base *ab)
349 {
350 	ath11k_ahb_ce_irqs_enable(ab);
351 	ath11k_ce_rx_post_buf(ab);
352 
353 	return 0;
354 }
355 
356 static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
357 {
358 	int i;
359 
360 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
361 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
362 
363 		if (!irq_grp->napi_enabled) {
364 			dev_set_threaded(&irq_grp->napi_ndev, true);
365 			napi_enable(&irq_grp->napi);
366 			irq_grp->napi_enabled = true;
367 		}
368 		ath11k_ahb_ext_grp_enable(irq_grp);
369 	}
370 }
371 
372 static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
373 {
374 	__ath11k_ahb_ext_irq_disable(ab);
375 	ath11k_ahb_sync_ext_irqs(ab);
376 }
377 
378 static void ath11k_ahb_stop(struct ath11k_base *ab)
379 {
380 	if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
381 		ath11k_ahb_ce_irqs_disable(ab);
382 	ath11k_ahb_sync_ce_irqs(ab);
383 	ath11k_ahb_kill_tasklets(ab);
384 	del_timer_sync(&ab->rx_replenish_retry);
385 	ath11k_ce_cleanup_pipes(ab);
386 }
387 
388 static int ath11k_ahb_power_up(struct ath11k_base *ab)
389 {
390 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
391 	int ret;
392 
393 	ret = rproc_boot(ab_ahb->tgt_rproc);
394 	if (ret)
395 		ath11k_err(ab, "failed to boot the remote processor Q6\n");
396 
397 	return ret;
398 }
399 
400 static void ath11k_ahb_power_down(struct ath11k_base *ab)
401 {
402 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
403 
404 	rproc_shutdown(ab_ahb->tgt_rproc);
405 }
406 
407 static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab)
408 {
409 	int timeout;
410 
411 	if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done ||
412 	    ab->hw_params.cold_boot_calib == 0 ||
413 	    ab->hw_params.cbcal_restart_fw == 0)
414 		return 0;
415 
416 	ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n");
417 	timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
418 				     (ab->qmi.cal_done  == 1),
419 				     ATH11K_COLD_BOOT_FW_RESET_DELAY);
420 	if (timeout <= 0) {
421 		ath11k_cold_boot_cal = 0;
422 		ath11k_warn(ab, "Coldboot Calibration failed timed out\n");
423 	}
424 
425 	/* reset the firmware */
426 	ath11k_ahb_power_down(ab);
427 	ath11k_ahb_power_up(ab);
428 
429 	ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n");
430 	return 0;
431 }
432 
433 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
434 {
435 	struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
436 
437 	cfg->tgt_ce_len = ab->hw_params.target_ce_count;
438 	cfg->tgt_ce = ab->hw_params.target_ce_config;
439 	cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
440 	cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
441 	ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
442 }
443 
444 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
445 {
446 	int i, j;
447 
448 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
449 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
450 
451 		for (j = 0; j < irq_grp->num_irq; j++)
452 			free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
453 
454 		netif_napi_del(&irq_grp->napi);
455 	}
456 }
457 
458 static void ath11k_ahb_free_irq(struct ath11k_base *ab)
459 {
460 	int irq_idx;
461 	int i;
462 
463 	if (ab->hw_params.hybrid_bus_type)
464 		return ath11k_pcic_free_irq(ab);
465 
466 	for (i = 0; i < ab->hw_params.ce_count; i++) {
467 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
468 			continue;
469 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
470 		free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
471 	}
472 
473 	ath11k_ahb_free_ext_irq(ab);
474 }
475 
476 static void ath11k_ahb_ce_tasklet(struct tasklet_struct *t)
477 {
478 	struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
479 
480 	ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
481 
482 	ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
483 }
484 
485 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
486 {
487 	struct ath11k_ce_pipe *ce_pipe = arg;
488 
489 	/* last interrupt received for this CE */
490 	ce_pipe->timestamp = jiffies;
491 
492 	ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
493 
494 	tasklet_schedule(&ce_pipe->intr_tq);
495 
496 	return IRQ_HANDLED;
497 }
498 
499 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget)
500 {
501 	struct ath11k_ext_irq_grp *irq_grp = container_of(napi,
502 						struct ath11k_ext_irq_grp,
503 						napi);
504 	struct ath11k_base *ab = irq_grp->ab;
505 	int work_done;
506 
507 	work_done = ath11k_dp_service_srng(ab, irq_grp, budget);
508 	if (work_done < budget) {
509 		napi_complete_done(napi, work_done);
510 		ath11k_ahb_ext_grp_enable(irq_grp);
511 	}
512 
513 	if (work_done > budget)
514 		work_done = budget;
515 
516 	return work_done;
517 }
518 
519 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
520 {
521 	struct ath11k_ext_irq_grp *irq_grp = arg;
522 
523 	/* last interrupt received for this group */
524 	irq_grp->timestamp = jiffies;
525 
526 	ath11k_ahb_ext_grp_disable(irq_grp);
527 
528 	napi_schedule(&irq_grp->napi);
529 
530 	return IRQ_HANDLED;
531 }
532 
533 static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
534 {
535 	struct ath11k_hw_params *hw = &ab->hw_params;
536 	int i, j;
537 	int irq;
538 	int ret;
539 
540 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
541 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
542 		u32 num_irq = 0;
543 
544 		irq_grp->ab = ab;
545 		irq_grp->grp_id = i;
546 		init_dummy_netdev(&irq_grp->napi_ndev);
547 		netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
548 			       ath11k_ahb_ext_grp_napi_poll);
549 
550 		for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
551 			if (ab->hw_params.ring_mask->tx[i] & BIT(j)) {
552 				irq_grp->irqs[num_irq++] =
553 					wbm2host_tx_completions_ring1 - j;
554 			}
555 
556 			if (ab->hw_params.ring_mask->rx[i] & BIT(j)) {
557 				irq_grp->irqs[num_irq++] =
558 					reo2host_destination_ring1 - j;
559 			}
560 
561 			if (ab->hw_params.ring_mask->rx_err[i] & BIT(j))
562 				irq_grp->irqs[num_irq++] = reo2host_exception;
563 
564 			if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j))
565 				irq_grp->irqs[num_irq++] = wbm2host_rx_release;
566 
567 			if (ab->hw_params.ring_mask->reo_status[i] & BIT(j))
568 				irq_grp->irqs[num_irq++] = reo2host_status;
569 
570 			if (j < ab->hw_params.max_radios) {
571 				if (ab->hw_params.ring_mask->rxdma2host[i] & BIT(j)) {
572 					irq_grp->irqs[num_irq++] =
573 						rxdma2host_destination_ring_mac1 -
574 						ath11k_hw_get_mac_from_pdev_id(hw, j);
575 				}
576 
577 				if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) {
578 					irq_grp->irqs[num_irq++] =
579 						host2rxdma_host_buf_ring_mac1 -
580 						ath11k_hw_get_mac_from_pdev_id(hw, j);
581 				}
582 
583 				if (ab->hw_params.ring_mask->rx_mon_status[i] & BIT(j)) {
584 					irq_grp->irqs[num_irq++] =
585 						ppdu_end_interrupts_mac1 -
586 						ath11k_hw_get_mac_from_pdev_id(hw, j);
587 					irq_grp->irqs[num_irq++] =
588 						rxdma2host_monitor_status_ring_mac1 -
589 						ath11k_hw_get_mac_from_pdev_id(hw, j);
590 				}
591 			}
592 		}
593 		irq_grp->num_irq = num_irq;
594 
595 		for (j = 0; j < irq_grp->num_irq; j++) {
596 			int irq_idx = irq_grp->irqs[j];
597 
598 			irq = platform_get_irq_byname(ab->pdev,
599 						      irq_name[irq_idx]);
600 			ab->irq_num[irq_idx] = irq;
601 			irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
602 			ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
603 					  IRQF_TRIGGER_RISING,
604 					  irq_name[irq_idx], irq_grp);
605 			if (ret) {
606 				ath11k_err(ab, "failed request_irq for %d\n",
607 					   irq);
608 			}
609 		}
610 	}
611 
612 	return 0;
613 }
614 
615 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
616 {
617 	int irq, irq_idx, i;
618 	int ret;
619 
620 	if (ab->hw_params.hybrid_bus_type)
621 		return ath11k_pcic_config_irq(ab);
622 
623 	/* Configure CE irqs */
624 	for (i = 0; i < ab->hw_params.ce_count; i++) {
625 		struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
626 
627 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
628 			continue;
629 
630 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
631 
632 		tasklet_setup(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet);
633 		irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]);
634 		ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
635 				  IRQF_TRIGGER_RISING, irq_name[irq_idx],
636 				  ce_pipe);
637 		if (ret)
638 			return ret;
639 
640 		ab->irq_num[irq_idx] = irq;
641 	}
642 
643 	/* Configure external interrupts */
644 	ret = ath11k_ahb_config_ext_irq(ab);
645 
646 	return ret;
647 }
648 
649 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
650 					  u8 *ul_pipe, u8 *dl_pipe)
651 {
652 	const struct service_to_pipe *entry;
653 	bool ul_set = false, dl_set = false;
654 	int i;
655 
656 	for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) {
657 		entry = &ab->hw_params.svc_to_ce_map[i];
658 
659 		if (__le32_to_cpu(entry->service_id) != service_id)
660 			continue;
661 
662 		switch (__le32_to_cpu(entry->pipedir)) {
663 		case PIPEDIR_NONE:
664 			break;
665 		case PIPEDIR_IN:
666 			WARN_ON(dl_set);
667 			*dl_pipe = __le32_to_cpu(entry->pipenum);
668 			dl_set = true;
669 			break;
670 		case PIPEDIR_OUT:
671 			WARN_ON(ul_set);
672 			*ul_pipe = __le32_to_cpu(entry->pipenum);
673 			ul_set = true;
674 			break;
675 		case PIPEDIR_INOUT:
676 			WARN_ON(dl_set);
677 			WARN_ON(ul_set);
678 			*dl_pipe = __le32_to_cpu(entry->pipenum);
679 			*ul_pipe = __le32_to_cpu(entry->pipenum);
680 			dl_set = true;
681 			ul_set = true;
682 			break;
683 		}
684 	}
685 
686 	if (WARN_ON(!ul_set || !dl_set))
687 		return -ENOENT;
688 
689 	return 0;
690 }
691 
692 static int ath11k_ahb_hif_suspend(struct ath11k_base *ab)
693 {
694 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
695 	u32 wake_irq;
696 	u32 value = 0;
697 	int ret;
698 
699 	if (!device_may_wakeup(ab->dev))
700 		return -EPERM;
701 
702 	wake_irq = ab->irq_num[ATH11K_PCI_IRQ_CE0_OFFSET + ATH11K_PCI_CE_WAKE_IRQ];
703 
704 	ret = enable_irq_wake(wake_irq);
705 	if (ret) {
706 		ath11k_err(ab, "failed to enable wakeup irq :%d\n", ret);
707 		return ret;
708 	}
709 
710 	value = u32_encode_bits(ab_ahb->smp2p_info.seq_no++,
711 				ATH11K_AHB_SMP2P_SMEM_SEQ_NO);
712 	value |= u32_encode_bits(ATH11K_AHB_POWER_SAVE_ENTER,
713 				 ATH11K_AHB_SMP2P_SMEM_MSG);
714 
715 	ret = qcom_smem_state_update_bits(ab_ahb->smp2p_info.smem_state,
716 					  ATH11K_AHB_SMP2P_SMEM_VALUE_MASK, value);
717 	if (ret) {
718 		ath11k_err(ab, "failed to send smp2p power save enter cmd :%d\n", ret);
719 		return ret;
720 	}
721 
722 	ath11k_dbg(ab, ATH11K_DBG_AHB, "ahb device suspended\n");
723 
724 	return ret;
725 }
726 
727 static int ath11k_ahb_hif_resume(struct ath11k_base *ab)
728 {
729 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
730 	u32 wake_irq;
731 	u32 value = 0;
732 	int ret;
733 
734 	if (!device_may_wakeup(ab->dev))
735 		return -EPERM;
736 
737 	wake_irq = ab->irq_num[ATH11K_PCI_IRQ_CE0_OFFSET + ATH11K_PCI_CE_WAKE_IRQ];
738 
739 	ret = disable_irq_wake(wake_irq);
740 	if (ret) {
741 		ath11k_err(ab, "failed to disable wakeup irq: %d\n", ret);
742 		return ret;
743 	}
744 
745 	reinit_completion(&ab->wow.wakeup_completed);
746 
747 	value = u32_encode_bits(ab_ahb->smp2p_info.seq_no++,
748 				ATH11K_AHB_SMP2P_SMEM_SEQ_NO);
749 	value |= u32_encode_bits(ATH11K_AHB_POWER_SAVE_EXIT,
750 				 ATH11K_AHB_SMP2P_SMEM_MSG);
751 
752 	ret = qcom_smem_state_update_bits(ab_ahb->smp2p_info.smem_state,
753 					  ATH11K_AHB_SMP2P_SMEM_VALUE_MASK, value);
754 	if (ret) {
755 		ath11k_err(ab, "failed to send smp2p power save enter cmd :%d\n", ret);
756 		return ret;
757 	}
758 
759 	ret = wait_for_completion_timeout(&ab->wow.wakeup_completed, 3 * HZ);
760 	if (ret == 0) {
761 		ath11k_warn(ab, "timed out while waiting for wow wakeup completion\n");
762 		return -ETIMEDOUT;
763 	}
764 
765 	ath11k_dbg(ab, ATH11K_DBG_AHB, "ahb device resumed\n");
766 
767 	return 0;
768 }
769 
770 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
771 	.start = ath11k_ahb_start,
772 	.stop = ath11k_ahb_stop,
773 	.read32 = ath11k_ahb_read32,
774 	.write32 = ath11k_ahb_write32,
775 	.read = NULL,
776 	.irq_enable = ath11k_ahb_ext_irq_enable,
777 	.irq_disable = ath11k_ahb_ext_irq_disable,
778 	.map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
779 	.power_down = ath11k_ahb_power_down,
780 	.power_up = ath11k_ahb_power_up,
781 };
782 
783 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
784 	.start = ath11k_pcic_start,
785 	.stop = ath11k_pcic_stop,
786 	.read32 = ath11k_pcic_read32,
787 	.write32 = ath11k_pcic_write32,
788 	.read = NULL,
789 	.irq_enable = ath11k_pcic_ext_irq_enable,
790 	.irq_disable = ath11k_pcic_ext_irq_disable,
791 	.get_msi_address =  ath11k_pcic_get_msi_address,
792 	.get_user_msi_vector = ath11k_pcic_get_user_msi_assignment,
793 	.map_service_to_pipe = ath11k_pcic_map_service_to_pipe,
794 	.power_down = ath11k_ahb_power_down,
795 	.power_up = ath11k_ahb_power_up,
796 	.suspend = ath11k_ahb_hif_suspend,
797 	.resume = ath11k_ahb_hif_resume,
798 	.ce_irq_enable = ath11k_pci_enable_ce_irqs_except_wake_irq,
799 	.ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
800 };
801 
802 static int ath11k_core_get_rproc(struct ath11k_base *ab)
803 {
804 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
805 	struct device *dev = ab->dev;
806 	struct rproc *prproc;
807 	phandle rproc_phandle;
808 
809 	if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
810 		ath11k_err(ab, "failed to get q6_rproc handle\n");
811 		return -ENOENT;
812 	}
813 
814 	prproc = rproc_get_by_phandle(rproc_phandle);
815 	if (!prproc) {
816 		ath11k_err(ab, "failed to get rproc\n");
817 		return -EINVAL;
818 	}
819 	ab_ahb->tgt_rproc = prproc;
820 
821 	return 0;
822 }
823 
824 static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab)
825 {
826 	struct platform_device *pdev = ab->pdev;
827 	phys_addr_t msi_addr_pa;
828 	dma_addr_t msi_addr_iova;
829 	struct resource *res;
830 	int int_prop;
831 	int ret;
832 	int i;
833 
834 	ret = ath11k_pcic_init_msi_config(ab);
835 	if (ret) {
836 		ath11k_err(ab, "failed to init msi config: %d\n", ret);
837 		return ret;
838 	}
839 
840 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
841 	if (!res) {
842 		ath11k_err(ab, "failed to fetch msi_addr\n");
843 		return -ENOENT;
844 	}
845 
846 	msi_addr_pa = res->start;
847 	msi_addr_iova = dma_map_resource(ab->dev, msi_addr_pa, PAGE_SIZE,
848 					 DMA_FROM_DEVICE, 0);
849 	if (dma_mapping_error(ab->dev, msi_addr_iova))
850 		return -ENOMEM;
851 
852 	ab->pci.msi.addr_lo = lower_32_bits(msi_addr_iova);
853 	ab->pci.msi.addr_hi = upper_32_bits(msi_addr_iova);
854 
855 	ret = of_property_read_u32_index(ab->dev->of_node, "interrupts", 1, &int_prop);
856 	if (ret)
857 		return ret;
858 
859 	ab->pci.msi.ep_base_data = int_prop + 32;
860 
861 	for (i = 0; i < ab->pci.msi.config->total_vectors; i++) {
862 		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
863 		if (!res)
864 			return -ENODEV;
865 
866 		ab->pci.msi.irqs[i] = res->start;
867 	}
868 
869 	set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
870 
871 	return 0;
872 }
873 
874 static int ath11k_ahb_setup_smp2p_handle(struct ath11k_base *ab)
875 {
876 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
877 
878 	if (!ab->hw_params.smp2p_wow_exit)
879 		return 0;
880 
881 	ab_ahb->smp2p_info.smem_state = qcom_smem_state_get(ab->dev, "wlan-smp2p-out",
882 							    &ab_ahb->smp2p_info.smem_bit);
883 	if (IS_ERR(ab_ahb->smp2p_info.smem_state)) {
884 		ath11k_err(ab, "failed to fetch smem state: %ld\n",
885 			   PTR_ERR(ab_ahb->smp2p_info.smem_state));
886 		return PTR_ERR(ab_ahb->smp2p_info.smem_state);
887 	}
888 
889 	return 0;
890 }
891 
892 static void ath11k_ahb_release_smp2p_handle(struct ath11k_base *ab)
893 {
894 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
895 
896 	if (!ab->hw_params.smp2p_wow_exit)
897 		return;
898 
899 	qcom_smem_state_put(ab_ahb->smp2p_info.smem_state);
900 }
901 
902 static int ath11k_ahb_setup_resources(struct ath11k_base *ab)
903 {
904 	struct platform_device *pdev = ab->pdev;
905 	struct resource *mem_res;
906 	void __iomem *mem;
907 
908 	if (ab->hw_params.hybrid_bus_type)
909 		return ath11k_ahb_setup_msi_resources(ab);
910 
911 	mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res);
912 	if (IS_ERR(mem)) {
913 		dev_err(&pdev->dev, "ioremap error\n");
914 		return PTR_ERR(mem);
915 	}
916 
917 	ab->mem = mem;
918 	ab->mem_len = resource_size(mem_res);
919 
920 	return 0;
921 }
922 
923 static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab)
924 {
925 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
926 	struct device *dev = ab->dev;
927 	struct device_node *node;
928 	struct resource r;
929 	int ret;
930 
931 	node = of_parse_phandle(dev->of_node, "memory-region", 0);
932 	if (!node)
933 		return -ENOENT;
934 
935 	ret = of_address_to_resource(node, 0, &r);
936 	of_node_put(node);
937 	if (ret) {
938 		dev_err(dev, "failed to resolve msa fixed region\n");
939 		return ret;
940 	}
941 
942 	ab_ahb->fw.msa_paddr = r.start;
943 	ab_ahb->fw.msa_size = resource_size(&r);
944 
945 	node = of_parse_phandle(dev->of_node, "memory-region", 1);
946 	if (!node)
947 		return -ENOENT;
948 
949 	ret = of_address_to_resource(node, 0, &r);
950 	of_node_put(node);
951 	if (ret) {
952 		dev_err(dev, "failed to resolve ce fixed region\n");
953 		return ret;
954 	}
955 
956 	ab_ahb->fw.ce_paddr = r.start;
957 	ab_ahb->fw.ce_size = resource_size(&r);
958 
959 	return 0;
960 }
961 
962 static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab)
963 {
964 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
965 	struct device *host_dev = ab->dev;
966 	struct platform_device_info info = {0};
967 	struct iommu_domain *iommu_dom;
968 	struct platform_device *pdev;
969 	struct device_node *node;
970 	int ret;
971 
972 	/* Chipsets not requiring MSA need not initialize
973 	 * MSA resources, return success in such cases.
974 	 */
975 	if (!ab->hw_params.fixed_fw_mem)
976 		return 0;
977 
978 	ret = ath11k_ahb_setup_msa_resources(ab);
979 	if (ret) {
980 		ath11k_err(ab, "failed to setup msa resources\n");
981 		return ret;
982 	}
983 
984 	node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
985 	if (!node) {
986 		ab_ahb->fw.use_tz = true;
987 		return 0;
988 	}
989 
990 	info.fwnode = &node->fwnode;
991 	info.parent = host_dev;
992 	info.name = node->name;
993 	info.dma_mask = DMA_BIT_MASK(32);
994 
995 	pdev = platform_device_register_full(&info);
996 	if (IS_ERR(pdev)) {
997 		of_node_put(node);
998 		return PTR_ERR(pdev);
999 	}
1000 
1001 	ret = of_dma_configure(&pdev->dev, node, true);
1002 	if (ret) {
1003 		ath11k_err(ab, "dma configure fail: %d\n", ret);
1004 		goto err_unregister;
1005 	}
1006 
1007 	ab_ahb->fw.dev = &pdev->dev;
1008 
1009 	iommu_dom = iommu_domain_alloc(&platform_bus_type);
1010 	if (!iommu_dom) {
1011 		ath11k_err(ab, "failed to allocate iommu domain\n");
1012 		ret = -ENOMEM;
1013 		goto err_unregister;
1014 	}
1015 
1016 	ret = iommu_attach_device(iommu_dom, ab_ahb->fw.dev);
1017 	if (ret) {
1018 		ath11k_err(ab, "could not attach device: %d\n", ret);
1019 		goto err_iommu_free;
1020 	}
1021 
1022 	ret = iommu_map(iommu_dom, ab_ahb->fw.msa_paddr,
1023 			ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size,
1024 			IOMMU_READ | IOMMU_WRITE);
1025 	if (ret) {
1026 		ath11k_err(ab, "failed to map firmware region: %d\n", ret);
1027 		goto err_iommu_detach;
1028 	}
1029 
1030 	ret = iommu_map(iommu_dom, ab_ahb->fw.ce_paddr,
1031 			ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size,
1032 			IOMMU_READ | IOMMU_WRITE);
1033 	if (ret) {
1034 		ath11k_err(ab, "failed to map firmware CE region: %d\n", ret);
1035 		goto err_iommu_unmap;
1036 	}
1037 
1038 	ab_ahb->fw.use_tz = false;
1039 	ab_ahb->fw.iommu_domain = iommu_dom;
1040 	of_node_put(node);
1041 
1042 	return 0;
1043 
1044 err_iommu_unmap:
1045 	iommu_unmap(iommu_dom, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
1046 
1047 err_iommu_detach:
1048 	iommu_detach_device(iommu_dom, ab_ahb->fw.dev);
1049 
1050 err_iommu_free:
1051 	iommu_domain_free(iommu_dom);
1052 
1053 err_unregister:
1054 	platform_device_unregister(pdev);
1055 	of_node_put(node);
1056 
1057 	return ret;
1058 }
1059 
1060 static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
1061 {
1062 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
1063 	struct iommu_domain *iommu;
1064 	size_t unmapped_size;
1065 
1066 	if (ab_ahb->fw.use_tz)
1067 		return 0;
1068 
1069 	iommu = ab_ahb->fw.iommu_domain;
1070 
1071 	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
1072 	if (unmapped_size != ab_ahb->fw.msa_size)
1073 		ath11k_err(ab, "failed to unmap firmware: %zu\n",
1074 			   unmapped_size);
1075 
1076 	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size);
1077 	if (unmapped_size != ab_ahb->fw.ce_size)
1078 		ath11k_err(ab, "failed to unmap firmware CE memory: %zu\n",
1079 			   unmapped_size);
1080 
1081 	iommu_detach_device(iommu, ab_ahb->fw.dev);
1082 	iommu_domain_free(iommu);
1083 
1084 	platform_device_unregister(to_platform_device(ab_ahb->fw.dev));
1085 
1086 	return 0;
1087 }
1088 
1089 static int ath11k_ahb_probe(struct platform_device *pdev)
1090 {
1091 	struct ath11k_base *ab;
1092 	const struct of_device_id *of_id;
1093 	const struct ath11k_hif_ops *hif_ops;
1094 	const struct ath11k_pci_ops *pci_ops;
1095 	enum ath11k_hw_rev hw_rev;
1096 	int ret;
1097 
1098 	of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev);
1099 	if (!of_id) {
1100 		dev_err(&pdev->dev, "failed to find matching device tree id\n");
1101 		return -EINVAL;
1102 	}
1103 
1104 	hw_rev = (enum ath11k_hw_rev)of_id->data;
1105 
1106 	switch (hw_rev) {
1107 	case ATH11K_HW_IPQ8074:
1108 	case ATH11K_HW_IPQ6018_HW10:
1109 		hif_ops = &ath11k_ahb_hif_ops_ipq8074;
1110 		pci_ops = NULL;
1111 		break;
1112 	case ATH11K_HW_WCN6750_HW10:
1113 		hif_ops = &ath11k_ahb_hif_ops_wcn6750;
1114 		pci_ops = &ath11k_ahb_pci_ops_wcn6750;
1115 		break;
1116 	default:
1117 		dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev);
1118 		return -EOPNOTSUPP;
1119 	}
1120 
1121 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1122 	if (ret) {
1123 		dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
1124 		return ret;
1125 	}
1126 
1127 	ab = ath11k_core_alloc(&pdev->dev, sizeof(struct ath11k_ahb),
1128 			       ATH11K_BUS_AHB);
1129 	if (!ab) {
1130 		dev_err(&pdev->dev, "failed to allocate ath11k base\n");
1131 		return -ENOMEM;
1132 	}
1133 
1134 	ab->hif.ops = hif_ops;
1135 	ab->pdev = pdev;
1136 	ab->hw_rev = hw_rev;
1137 	platform_set_drvdata(pdev, ab);
1138 
1139 	ret = ath11k_pcic_register_pci_ops(ab, pci_ops);
1140 	if (ret) {
1141 		ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
1142 		goto err_core_free;
1143 	}
1144 
1145 	ret = ath11k_core_pre_init(ab);
1146 	if (ret)
1147 		goto err_core_free;
1148 
1149 	ret = ath11k_ahb_setup_resources(ab);
1150 	if (ret)
1151 		goto err_core_free;
1152 
1153 	ret = ath11k_ahb_fw_resources_init(ab);
1154 	if (ret)
1155 		goto err_core_free;
1156 
1157 	ret = ath11k_ahb_setup_smp2p_handle(ab);
1158 	if (ret)
1159 		goto err_fw_deinit;
1160 
1161 	ret = ath11k_hal_srng_init(ab);
1162 	if (ret)
1163 		goto err_release_smp2p_handle;
1164 
1165 	ret = ath11k_ce_alloc_pipes(ab);
1166 	if (ret) {
1167 		ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
1168 		goto err_hal_srng_deinit;
1169 	}
1170 
1171 	ath11k_ahb_init_qmi_ce_config(ab);
1172 
1173 	ret = ath11k_core_get_rproc(ab);
1174 	if (ret) {
1175 		ath11k_err(ab, "failed to get rproc: %d\n", ret);
1176 		goto err_ce_free;
1177 	}
1178 
1179 	ret = ath11k_core_init(ab);
1180 	if (ret) {
1181 		ath11k_err(ab, "failed to init core: %d\n", ret);
1182 		goto err_ce_free;
1183 	}
1184 
1185 	ret = ath11k_ahb_config_irq(ab);
1186 	if (ret) {
1187 		ath11k_err(ab, "failed to configure irq: %d\n", ret);
1188 		goto err_ce_free;
1189 	}
1190 
1191 	ath11k_ahb_fwreset_from_cold_boot(ab);
1192 
1193 	return 0;
1194 
1195 err_ce_free:
1196 	ath11k_ce_free_pipes(ab);
1197 
1198 err_hal_srng_deinit:
1199 	ath11k_hal_srng_deinit(ab);
1200 
1201 err_release_smp2p_handle:
1202 	ath11k_ahb_release_smp2p_handle(ab);
1203 
1204 err_fw_deinit:
1205 	ath11k_ahb_fw_resource_deinit(ab);
1206 
1207 err_core_free:
1208 	ath11k_core_free(ab);
1209 	platform_set_drvdata(pdev, NULL);
1210 
1211 	return ret;
1212 }
1213 
1214 static void ath11k_ahb_remove_prepare(struct ath11k_base *ab)
1215 {
1216 	unsigned long left;
1217 
1218 	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
1219 		left = wait_for_completion_timeout(&ab->driver_recovery,
1220 						   ATH11K_AHB_RECOVERY_TIMEOUT);
1221 		if (!left)
1222 			ath11k_warn(ab, "failed to receive recovery response completion\n");
1223 	}
1224 
1225 	set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
1226 	cancel_work_sync(&ab->restart_work);
1227 	cancel_work_sync(&ab->qmi.event_work);
1228 }
1229 
1230 static void ath11k_ahb_free_resources(struct ath11k_base *ab)
1231 {
1232 	struct platform_device *pdev = ab->pdev;
1233 
1234 	ath11k_ahb_free_irq(ab);
1235 	ath11k_hal_srng_deinit(ab);
1236 	ath11k_ahb_release_smp2p_handle(ab);
1237 	ath11k_ahb_fw_resource_deinit(ab);
1238 	ath11k_ce_free_pipes(ab);
1239 	ath11k_core_free(ab);
1240 	platform_set_drvdata(pdev, NULL);
1241 }
1242 
1243 static int ath11k_ahb_remove(struct platform_device *pdev)
1244 {
1245 	struct ath11k_base *ab = platform_get_drvdata(pdev);
1246 
1247 	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
1248 		ath11k_ahb_power_down(ab);
1249 		ath11k_debugfs_soc_destroy(ab);
1250 		ath11k_qmi_deinit_service(ab);
1251 		goto qmi_fail;
1252 	}
1253 
1254 	ath11k_ahb_remove_prepare(ab);
1255 	ath11k_core_deinit(ab);
1256 
1257 qmi_fail:
1258 	ath11k_ahb_free_resources(ab);
1259 
1260 	return 0;
1261 }
1262 
1263 static void ath11k_ahb_shutdown(struct platform_device *pdev)
1264 {
1265 	struct ath11k_base *ab = platform_get_drvdata(pdev);
1266 
1267 	/* platform shutdown() & remove() are mutually exclusive.
1268 	 * remove() is invoked during rmmod & shutdown() during
1269 	 * system reboot/shutdown.
1270 	 */
1271 	ath11k_ahb_remove_prepare(ab);
1272 
1273 	if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)))
1274 		goto free_resources;
1275 
1276 	ath11k_core_deinit(ab);
1277 
1278 free_resources:
1279 	ath11k_ahb_free_resources(ab);
1280 }
1281 
1282 static struct platform_driver ath11k_ahb_driver = {
1283 	.driver         = {
1284 		.name   = "ath11k",
1285 		.of_match_table = ath11k_ahb_of_match,
1286 	},
1287 	.probe  = ath11k_ahb_probe,
1288 	.remove = ath11k_ahb_remove,
1289 	.shutdown = ath11k_ahb_shutdown,
1290 };
1291 
1292 static int ath11k_ahb_init(void)
1293 {
1294 	return platform_driver_register(&ath11k_ahb_driver);
1295 }
1296 module_init(ath11k_ahb_init);
1297 
1298 static void ath11k_ahb_exit(void)
1299 {
1300 	platform_driver_unregister(&ath11k_ahb_driver);
1301 }
1302 module_exit(ath11k_ahb_exit);
1303 
1304 MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN AHB devices");
1305 MODULE_LICENSE("Dual BSD/GPL");
1306