1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/clk.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/of_device.h>
22 #include <linux/platform_device.h>
23 #include <linux/regulator/consumer.h>
24 
25 #include "ce.h"
26 #include "debug.h"
27 #include "hif.h"
28 #include "htc.h"
29 #include "snoc.h"
30 
31 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
32 #define CE_POLL_PIPE 4
33 
34 static char *const ce_name[] = {
35 	"WLAN_CE_0",
36 	"WLAN_CE_1",
37 	"WLAN_CE_2",
38 	"WLAN_CE_3",
39 	"WLAN_CE_4",
40 	"WLAN_CE_5",
41 	"WLAN_CE_6",
42 	"WLAN_CE_7",
43 	"WLAN_CE_8",
44 	"WLAN_CE_9",
45 	"WLAN_CE_10",
46 	"WLAN_CE_11",
47 };
48 
49 static struct ath10k_wcn3990_vreg_info vreg_cfg[] = {
50 	{NULL, "vdd-0.8-cx-mx", 800000, 800000, 0, 0, false},
51 	{NULL, "vdd-1.8-xo", 1800000, 1800000, 0, 0, false},
52 	{NULL, "vdd-1.3-rfa", 1304000, 1304000, 0, 0, false},
53 	{NULL, "vdd-3.3-ch0", 3312000, 3312000, 0, 0, false},
54 };
55 
56 static struct ath10k_wcn3990_clk_info clk_cfg[] = {
57 	{NULL, "cxo_ref_clk_pin", 0, false},
58 };
59 
60 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
61 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
62 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
63 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
64 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
65 
66 static const struct ath10k_snoc_drv_priv drv_priv = {
67 	.hw_rev = ATH10K_HW_WCN3990,
68 	.dma_mask = DMA_BIT_MASK(37),
69 };
70 
71 static struct ce_attr host_ce_config_wlan[] = {
72 	/* CE0: host->target HTC control streams */
73 	{
74 		.flags = CE_ATTR_FLAGS,
75 		.src_nentries = 16,
76 		.src_sz_max = 2048,
77 		.dest_nentries = 0,
78 		.send_cb = ath10k_snoc_htc_tx_cb,
79 	},
80 
81 	/* CE1: target->host HTT + HTC control */
82 	{
83 		.flags = CE_ATTR_FLAGS,
84 		.src_nentries = 0,
85 		.src_sz_max = 2048,
86 		.dest_nentries = 512,
87 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
88 	},
89 
90 	/* CE2: target->host WMI */
91 	{
92 		.flags = CE_ATTR_FLAGS,
93 		.src_nentries = 0,
94 		.src_sz_max = 2048,
95 		.dest_nentries = 64,
96 		.recv_cb = ath10k_snoc_htc_rx_cb,
97 	},
98 
99 	/* CE3: host->target WMI */
100 	{
101 		.flags = CE_ATTR_FLAGS,
102 		.src_nentries = 32,
103 		.src_sz_max = 2048,
104 		.dest_nentries = 0,
105 		.send_cb = ath10k_snoc_htc_tx_cb,
106 	},
107 
108 	/* CE4: host->target HTT */
109 	{
110 		.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
111 		.src_nentries = 256,
112 		.src_sz_max = 256,
113 		.dest_nentries = 0,
114 		.send_cb = ath10k_snoc_htt_tx_cb,
115 	},
116 
117 	/* CE5: target->host HTT (ipa_uc->target ) */
118 	{
119 		.flags = CE_ATTR_FLAGS,
120 		.src_nentries = 0,
121 		.src_sz_max = 512,
122 		.dest_nentries = 512,
123 		.recv_cb = ath10k_snoc_htt_rx_cb,
124 	},
125 
126 	/* CE6: target autonomous hif_memcpy */
127 	{
128 		.flags = CE_ATTR_FLAGS,
129 		.src_nentries = 0,
130 		.src_sz_max = 0,
131 		.dest_nentries = 0,
132 	},
133 
134 	/* CE7: ce_diag, the Diagnostic Window */
135 	{
136 		.flags = CE_ATTR_FLAGS,
137 		.src_nentries = 2,
138 		.src_sz_max = 2048,
139 		.dest_nentries = 2,
140 	},
141 
142 	/* CE8: Target to uMC */
143 	{
144 		.flags = CE_ATTR_FLAGS,
145 		.src_nentries = 0,
146 		.src_sz_max = 2048,
147 		.dest_nentries = 128,
148 	},
149 
150 	/* CE9 target->host HTT */
151 	{
152 		.flags = CE_ATTR_FLAGS,
153 		.src_nentries = 0,
154 		.src_sz_max = 2048,
155 		.dest_nentries = 512,
156 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
157 	},
158 
159 	/* CE10: target->host HTT */
160 	{
161 		.flags = CE_ATTR_FLAGS,
162 		.src_nentries = 0,
163 		.src_sz_max = 2048,
164 		.dest_nentries = 512,
165 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
166 	},
167 
168 	/* CE11: target -> host PKTLOG */
169 	{
170 		.flags = CE_ATTR_FLAGS,
171 		.src_nentries = 0,
172 		.src_sz_max = 2048,
173 		.dest_nentries = 512,
174 		.recv_cb = ath10k_snoc_htt_htc_rx_cb,
175 	},
176 };
177 
178 static struct service_to_pipe target_service_to_ce_map_wlan[] = {
179 	{
180 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
181 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
182 		__cpu_to_le32(3),
183 	},
184 	{
185 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
186 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
187 		__cpu_to_le32(2),
188 	},
189 	{
190 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
191 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
192 		__cpu_to_le32(3),
193 	},
194 	{
195 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
196 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
197 		__cpu_to_le32(2),
198 	},
199 	{
200 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
201 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
202 		__cpu_to_le32(3),
203 	},
204 	{
205 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
206 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
207 		__cpu_to_le32(2),
208 	},
209 	{
210 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
211 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
212 		__cpu_to_le32(3),
213 	},
214 	{
215 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
216 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
217 		__cpu_to_le32(2),
218 	},
219 	{
220 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
221 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
222 		__cpu_to_le32(3),
223 	},
224 	{
225 		__cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
226 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
227 		__cpu_to_le32(2),
228 	},
229 	{
230 		__cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
231 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
232 		__cpu_to_le32(0),
233 	},
234 	{
235 		__cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
236 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
237 		__cpu_to_le32(2),
238 	},
239 	{ /* not used */
240 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
241 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
242 		__cpu_to_le32(0),
243 	},
244 	{ /* not used */
245 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
246 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
247 		__cpu_to_le32(2),
248 	},
249 	{
250 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
251 		__cpu_to_le32(PIPEDIR_OUT),	/* out = UL = host -> target */
252 		__cpu_to_le32(4),
253 	},
254 	{
255 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
256 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
257 		__cpu_to_le32(1),
258 	},
259 	{ /* not used */
260 		__cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
261 		__cpu_to_le32(PIPEDIR_OUT),
262 		__cpu_to_le32(5),
263 	},
264 	{ /* in = DL = target -> host */
265 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA2_MSG),
266 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
267 		__cpu_to_le32(9),
268 	},
269 	{ /* in = DL = target -> host */
270 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA3_MSG),
271 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
272 		__cpu_to_le32(10),
273 	},
274 	{ /* in = DL = target -> host pktlog */
275 		__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_LOG_MSG),
276 		__cpu_to_le32(PIPEDIR_IN),	/* in = DL = target -> host */
277 		__cpu_to_le32(11),
278 	},
279 	/* (Additions here) */
280 
281 	{ /* must be last */
282 		__cpu_to_le32(0),
283 		__cpu_to_le32(0),
284 		__cpu_to_le32(0),
285 	},
286 };
287 
288 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
289 {
290 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
291 
292 	iowrite32(value, ar_snoc->mem + offset);
293 }
294 
295 u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
296 {
297 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
298 	u32 val;
299 
300 	val = ioread32(ar_snoc->mem + offset);
301 
302 	return val;
303 }
304 
305 static int __ath10k_snoc_rx_post_buf(struct ath10k_snoc_pipe *pipe)
306 {
307 	struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
308 	struct ath10k *ar = pipe->hif_ce_state;
309 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
310 	struct sk_buff *skb;
311 	dma_addr_t paddr;
312 	int ret;
313 
314 	skb = dev_alloc_skb(pipe->buf_sz);
315 	if (!skb)
316 		return -ENOMEM;
317 
318 	WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
319 
320 	paddr = dma_map_single(ar->dev, skb->data,
321 			       skb->len + skb_tailroom(skb),
322 			       DMA_FROM_DEVICE);
323 	if (unlikely(dma_mapping_error(ar->dev, paddr))) {
324 		ath10k_warn(ar, "failed to dma map snoc rx buf\n");
325 		dev_kfree_skb_any(skb);
326 		return -EIO;
327 	}
328 
329 	ATH10K_SKB_RXCB(skb)->paddr = paddr;
330 
331 	spin_lock_bh(&ce->ce_lock);
332 	ret = ce_pipe->ops->ce_rx_post_buf(ce_pipe, skb, paddr);
333 	spin_unlock_bh(&ce->ce_lock);
334 	if (ret) {
335 		dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
336 				 DMA_FROM_DEVICE);
337 		dev_kfree_skb_any(skb);
338 		return ret;
339 	}
340 
341 	return 0;
342 }
343 
344 static void ath10k_snoc_rx_post_pipe(struct ath10k_snoc_pipe *pipe)
345 {
346 	struct ath10k *ar = pipe->hif_ce_state;
347 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
348 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
349 	struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
350 	int ret, num;
351 
352 	if (pipe->buf_sz == 0)
353 		return;
354 
355 	if (!ce_pipe->dest_ring)
356 		return;
357 
358 	spin_lock_bh(&ce->ce_lock);
359 	num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
360 	spin_unlock_bh(&ce->ce_lock);
361 	while (num--) {
362 		ret = __ath10k_snoc_rx_post_buf(pipe);
363 		if (ret) {
364 			if (ret == -ENOSPC)
365 				break;
366 			ath10k_warn(ar, "failed to post rx buf: %d\n", ret);
367 			mod_timer(&ar_snoc->rx_post_retry, jiffies +
368 				  ATH10K_SNOC_RX_POST_RETRY_MS);
369 			break;
370 		}
371 	}
372 }
373 
374 static void ath10k_snoc_rx_post(struct ath10k *ar)
375 {
376 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
377 	int i;
378 
379 	for (i = 0; i < CE_COUNT; i++)
380 		ath10k_snoc_rx_post_pipe(&ar_snoc->pipe_info[i]);
381 }
382 
383 static void ath10k_snoc_process_rx_cb(struct ath10k_ce_pipe *ce_state,
384 				      void (*callback)(struct ath10k *ar,
385 						       struct sk_buff *skb))
386 {
387 	struct ath10k *ar = ce_state->ar;
388 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
389 	struct ath10k_snoc_pipe *pipe_info =  &ar_snoc->pipe_info[ce_state->id];
390 	struct sk_buff *skb;
391 	struct sk_buff_head list;
392 	void *transfer_context;
393 	unsigned int nbytes, max_nbytes;
394 
395 	__skb_queue_head_init(&list);
396 	while (ath10k_ce_completed_recv_next(ce_state, &transfer_context,
397 					     &nbytes) == 0) {
398 		skb = transfer_context;
399 		max_nbytes = skb->len + skb_tailroom(skb);
400 		dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
401 				 max_nbytes, DMA_FROM_DEVICE);
402 
403 		if (unlikely(max_nbytes < nbytes)) {
404 			ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)",
405 				    nbytes, max_nbytes);
406 			dev_kfree_skb_any(skb);
407 			continue;
408 		}
409 
410 		skb_put(skb, nbytes);
411 		__skb_queue_tail(&list, skb);
412 	}
413 
414 	while ((skb = __skb_dequeue(&list))) {
415 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc rx ce pipe %d len %d\n",
416 			   ce_state->id, skb->len);
417 
418 		callback(ar, skb);
419 	}
420 
421 	ath10k_snoc_rx_post_pipe(pipe_info);
422 }
423 
424 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
425 {
426 	ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
427 }
428 
429 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
430 {
431 	/* CE4 polling needs to be done whenever CE pipe which transports
432 	 * HTT Rx (target->host) is processed.
433 	 */
434 	ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
435 
436 	ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
437 }
438 
439 static void ath10k_snoc_htt_rx_deliver(struct ath10k *ar, struct sk_buff *skb)
440 {
441 	skb_pull(skb, sizeof(struct ath10k_htc_hdr));
442 	ath10k_htt_t2h_msg_handler(ar, skb);
443 }
444 
445 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
446 {
447 	ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
448 	ath10k_snoc_process_rx_cb(ce_state, ath10k_snoc_htt_rx_deliver);
449 }
450 
451 static void ath10k_snoc_rx_replenish_retry(struct timer_list *t)
452 {
453 	struct ath10k_snoc *ar_snoc = from_timer(ar_snoc, t, rx_post_retry);
454 	struct ath10k *ar = ar_snoc->ar;
455 
456 	ath10k_snoc_rx_post(ar);
457 }
458 
459 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
460 {
461 	struct ath10k *ar = ce_state->ar;
462 	struct sk_buff_head list;
463 	struct sk_buff *skb;
464 
465 	__skb_queue_head_init(&list);
466 	while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
467 		if (!skb)
468 			continue;
469 
470 		__skb_queue_tail(&list, skb);
471 	}
472 
473 	while ((skb = __skb_dequeue(&list)))
474 		ath10k_htc_tx_completion_handler(ar, skb);
475 }
476 
477 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
478 {
479 	struct ath10k *ar = ce_state->ar;
480 	struct sk_buff *skb;
481 
482 	while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
483 		if (!skb)
484 			continue;
485 
486 		dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
487 				 skb->len, DMA_TO_DEVICE);
488 		ath10k_htt_hif_tx_complete(ar, skb);
489 	}
490 }
491 
492 static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
493 				 struct ath10k_hif_sg_item *items, int n_items)
494 {
495 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
496 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
497 	struct ath10k_snoc_pipe *snoc_pipe;
498 	struct ath10k_ce_pipe *ce_pipe;
499 	int err, i = 0;
500 
501 	snoc_pipe = &ar_snoc->pipe_info[pipe_id];
502 	ce_pipe = snoc_pipe->ce_hdl;
503 	spin_lock_bh(&ce->ce_lock);
504 
505 	for (i = 0; i < n_items - 1; i++) {
506 		ath10k_dbg(ar, ATH10K_DBG_SNOC,
507 			   "snoc tx item %d paddr %pad len %d n_items %d\n",
508 			   i, &items[i].paddr, items[i].len, n_items);
509 
510 		err = ath10k_ce_send_nolock(ce_pipe,
511 					    items[i].transfer_context,
512 					    items[i].paddr,
513 					    items[i].len,
514 					    items[i].transfer_id,
515 					    CE_SEND_FLAG_GATHER);
516 		if (err)
517 			goto err;
518 	}
519 
520 	ath10k_dbg(ar, ATH10K_DBG_SNOC,
521 		   "snoc tx item %d paddr %pad len %d n_items %d\n",
522 		   i, &items[i].paddr, items[i].len, n_items);
523 
524 	err = ath10k_ce_send_nolock(ce_pipe,
525 				    items[i].transfer_context,
526 				    items[i].paddr,
527 				    items[i].len,
528 				    items[i].transfer_id,
529 				    0);
530 	if (err)
531 		goto err;
532 
533 	spin_unlock_bh(&ce->ce_lock);
534 
535 	return 0;
536 
537 err:
538 	for (; i > 0; i--)
539 		__ath10k_ce_send_revert(ce_pipe);
540 
541 	spin_unlock_bh(&ce->ce_lock);
542 	return err;
543 }
544 
545 static int ath10k_snoc_hif_get_target_info(struct ath10k *ar,
546 					   struct bmi_target_info *target_info)
547 {
548 	target_info->version = ATH10K_HW_WCN3990;
549 	target_info->type = ATH10K_HW_WCN3990;
550 
551 	return 0;
552 }
553 
554 static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
555 {
556 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
557 
558 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
559 
560 	return ath10k_ce_num_free_src_entries(ar_snoc->pipe_info[pipe].ce_hdl);
561 }
562 
563 static void ath10k_snoc_hif_send_complete_check(struct ath10k *ar, u8 pipe,
564 						int force)
565 {
566 	int resources;
567 
568 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif send complete check\n");
569 
570 	if (!force) {
571 		resources = ath10k_snoc_hif_get_free_queue_number(ar, pipe);
572 
573 		if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1))
574 			return;
575 	}
576 	ath10k_ce_per_engine_service(ar, pipe);
577 }
578 
579 static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar,
580 					       u16 service_id,
581 					       u8 *ul_pipe, u8 *dl_pipe)
582 {
583 	const struct service_to_pipe *entry;
584 	bool ul_set = false, dl_set = false;
585 	int i;
586 
587 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif map service\n");
588 
589 	for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
590 		entry = &target_service_to_ce_map_wlan[i];
591 
592 		if (__le32_to_cpu(entry->service_id) != service_id)
593 			continue;
594 
595 		switch (__le32_to_cpu(entry->pipedir)) {
596 		case PIPEDIR_NONE:
597 			break;
598 		case PIPEDIR_IN:
599 			WARN_ON(dl_set);
600 			*dl_pipe = __le32_to_cpu(entry->pipenum);
601 			dl_set = true;
602 			break;
603 		case PIPEDIR_OUT:
604 			WARN_ON(ul_set);
605 			*ul_pipe = __le32_to_cpu(entry->pipenum);
606 			ul_set = true;
607 			break;
608 		case PIPEDIR_INOUT:
609 			WARN_ON(dl_set);
610 			WARN_ON(ul_set);
611 			*dl_pipe = __le32_to_cpu(entry->pipenum);
612 			*ul_pipe = __le32_to_cpu(entry->pipenum);
613 			dl_set = true;
614 			ul_set = true;
615 			break;
616 		}
617 	}
618 
619 	if (WARN_ON(!ul_set || !dl_set))
620 		return -ENOENT;
621 
622 	return 0;
623 }
624 
625 static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar,
626 					     u8 *ul_pipe, u8 *dl_pipe)
627 {
628 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif get default pipe\n");
629 
630 	(void)ath10k_snoc_hif_map_service_to_pipe(ar,
631 						 ATH10K_HTC_SVC_ID_RSVD_CTRL,
632 						 ul_pipe, dl_pipe);
633 }
634 
635 static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
636 {
637 	ath10k_ce_disable_interrupts(ar);
638 }
639 
640 static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
641 {
642 	ath10k_ce_enable_interrupts(ar);
643 }
644 
645 static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
646 {
647 	struct ath10k_ce_pipe *ce_pipe;
648 	struct ath10k_ce_ring *ce_ring;
649 	struct sk_buff *skb;
650 	struct ath10k *ar;
651 	int i;
652 
653 	ar = snoc_pipe->hif_ce_state;
654 	ce_pipe = snoc_pipe->ce_hdl;
655 	ce_ring = ce_pipe->dest_ring;
656 
657 	if (!ce_ring)
658 		return;
659 
660 	if (!snoc_pipe->buf_sz)
661 		return;
662 
663 	for (i = 0; i < ce_ring->nentries; i++) {
664 		skb = ce_ring->per_transfer_context[i];
665 		if (!skb)
666 			continue;
667 
668 		ce_ring->per_transfer_context[i] = NULL;
669 
670 		dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
671 				 skb->len + skb_tailroom(skb),
672 				 DMA_FROM_DEVICE);
673 		dev_kfree_skb_any(skb);
674 	}
675 }
676 
677 static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
678 {
679 	struct ath10k_ce_pipe *ce_pipe;
680 	struct ath10k_ce_ring *ce_ring;
681 	struct ath10k_snoc *ar_snoc;
682 	struct sk_buff *skb;
683 	struct ath10k *ar;
684 	int i;
685 
686 	ar = snoc_pipe->hif_ce_state;
687 	ar_snoc = ath10k_snoc_priv(ar);
688 	ce_pipe = snoc_pipe->ce_hdl;
689 	ce_ring = ce_pipe->src_ring;
690 
691 	if (!ce_ring)
692 		return;
693 
694 	if (!snoc_pipe->buf_sz)
695 		return;
696 
697 	for (i = 0; i < ce_ring->nentries; i++) {
698 		skb = ce_ring->per_transfer_context[i];
699 		if (!skb)
700 			continue;
701 
702 		ce_ring->per_transfer_context[i] = NULL;
703 
704 		ath10k_htc_tx_completion_handler(ar, skb);
705 	}
706 }
707 
708 static void ath10k_snoc_buffer_cleanup(struct ath10k *ar)
709 {
710 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
711 	struct ath10k_snoc_pipe *pipe_info;
712 	int pipe_num;
713 
714 	del_timer_sync(&ar_snoc->rx_post_retry);
715 	for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
716 		pipe_info = &ar_snoc->pipe_info[pipe_num];
717 		ath10k_snoc_rx_pipe_cleanup(pipe_info);
718 		ath10k_snoc_tx_pipe_cleanup(pipe_info);
719 	}
720 }
721 
722 static void ath10k_snoc_hif_stop(struct ath10k *ar)
723 {
724 	ath10k_snoc_irq_disable(ar);
725 	ath10k_snoc_buffer_cleanup(ar);
726 	napi_synchronize(&ar->napi);
727 	napi_disable(&ar->napi);
728 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
729 }
730 
731 static int ath10k_snoc_hif_start(struct ath10k *ar)
732 {
733 	ath10k_snoc_irq_enable(ar);
734 	ath10k_snoc_rx_post(ar);
735 
736 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n");
737 
738 	return 0;
739 }
740 
741 static int ath10k_snoc_init_pipes(struct ath10k *ar)
742 {
743 	int i, ret;
744 
745 	for (i = 0; i < CE_COUNT; i++) {
746 		ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]);
747 		if (ret) {
748 			ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n",
749 				   i, ret);
750 			return ret;
751 		}
752 	}
753 
754 	return 0;
755 }
756 
757 static int ath10k_snoc_wlan_enable(struct ath10k *ar)
758 {
759 	return 0;
760 }
761 
762 static void ath10k_snoc_wlan_disable(struct ath10k *ar)
763 {
764 }
765 
766 static void ath10k_snoc_hif_power_down(struct ath10k *ar)
767 {
768 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
769 
770 	ath10k_snoc_wlan_disable(ar);
771 	ath10k_ce_free_rri(ar);
772 }
773 
774 static int ath10k_snoc_hif_power_up(struct ath10k *ar)
775 {
776 	int ret;
777 
778 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
779 		   __func__, ar->state);
780 
781 	ret = ath10k_snoc_wlan_enable(ar);
782 	if (ret) {
783 		ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
784 		return ret;
785 	}
786 
787 	ath10k_ce_alloc_rri(ar);
788 
789 	ret = ath10k_snoc_init_pipes(ar);
790 	if (ret) {
791 		ath10k_err(ar, "failed to initialize CE: %d\n", ret);
792 		goto err_wlan_enable;
793 	}
794 
795 	napi_enable(&ar->napi);
796 	return 0;
797 
798 err_wlan_enable:
799 	ath10k_snoc_wlan_disable(ar);
800 
801 	return ret;
802 }
803 
804 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
805 	.read32		= ath10k_snoc_read32,
806 	.write32	= ath10k_snoc_write32,
807 	.start		= ath10k_snoc_hif_start,
808 	.stop		= ath10k_snoc_hif_stop,
809 	.map_service_to_pipe	= ath10k_snoc_hif_map_service_to_pipe,
810 	.get_default_pipe	= ath10k_snoc_hif_get_default_pipe,
811 	.power_up		= ath10k_snoc_hif_power_up,
812 	.power_down		= ath10k_snoc_hif_power_down,
813 	.tx_sg			= ath10k_snoc_hif_tx_sg,
814 	.send_complete_check	= ath10k_snoc_hif_send_complete_check,
815 	.get_free_queue_number	= ath10k_snoc_hif_get_free_queue_number,
816 	.get_target_info	= ath10k_snoc_hif_get_target_info,
817 };
818 
819 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
820 	.read32		= ath10k_snoc_read32,
821 	.write32	= ath10k_snoc_write32,
822 };
823 
824 static int ath10k_snoc_get_ce_id_from_irq(struct ath10k *ar, int irq)
825 {
826 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
827 	int i;
828 
829 	for (i = 0; i < CE_COUNT_MAX; i++) {
830 		if (ar_snoc->ce_irqs[i].irq_line == irq)
831 			return i;
832 	}
833 	ath10k_err(ar, "No matching CE id for irq %d\n", irq);
834 
835 	return -EINVAL;
836 }
837 
838 static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
839 {
840 	struct ath10k *ar = arg;
841 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
842 	int ce_id = ath10k_snoc_get_ce_id_from_irq(ar, irq);
843 
844 	if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_snoc->pipe_info)) {
845 		ath10k_warn(ar, "unexpected/invalid irq %d ce_id %d\n", irq,
846 			    ce_id);
847 		return IRQ_HANDLED;
848 	}
849 
850 	ath10k_snoc_irq_disable(ar);
851 	napi_schedule(&ar->napi);
852 
853 	return IRQ_HANDLED;
854 }
855 
856 static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
857 {
858 	struct ath10k *ar = container_of(ctx, struct ath10k, napi);
859 	int done = 0;
860 
861 	ath10k_ce_per_engine_service_any(ar);
862 	done = ath10k_htt_txrx_compl_task(ar, budget);
863 
864 	if (done < budget) {
865 		napi_complete(ctx);
866 		ath10k_snoc_irq_enable(ar);
867 	}
868 
869 	return done;
870 }
871 
872 static void ath10k_snoc_init_napi(struct ath10k *ar)
873 {
874 	netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll,
875 		       ATH10K_NAPI_BUDGET);
876 }
877 
878 static int ath10k_snoc_request_irq(struct ath10k *ar)
879 {
880 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
881 	int irqflags = IRQF_TRIGGER_RISING;
882 	int ret, id;
883 
884 	for (id = 0; id < CE_COUNT_MAX; id++) {
885 		ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
886 				  ath10k_snoc_per_engine_handler,
887 				  irqflags, ce_name[id], ar);
888 		if (ret) {
889 			ath10k_err(ar,
890 				   "failed to register IRQ handler for CE %d: %d",
891 				   id, ret);
892 			goto err_irq;
893 		}
894 	}
895 
896 	return 0;
897 
898 err_irq:
899 	for (id -= 1; id >= 0; id--)
900 		free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
901 
902 	return ret;
903 }
904 
905 static void ath10k_snoc_free_irq(struct ath10k *ar)
906 {
907 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
908 	int id;
909 
910 	for (id = 0; id < CE_COUNT_MAX; id++)
911 		free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
912 }
913 
914 static int ath10k_snoc_resource_init(struct ath10k *ar)
915 {
916 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
917 	struct platform_device *pdev;
918 	struct resource *res;
919 	int i, ret = 0;
920 
921 	pdev = ar_snoc->dev;
922 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase");
923 	if (!res) {
924 		ath10k_err(ar, "Memory base not found in DT\n");
925 		return -EINVAL;
926 	}
927 
928 	ar_snoc->mem_pa = res->start;
929 	ar_snoc->mem = devm_ioremap(&pdev->dev, ar_snoc->mem_pa,
930 				    resource_size(res));
931 	if (!ar_snoc->mem) {
932 		ath10k_err(ar, "Memory base ioremap failed with physical address %pa\n",
933 			   &ar_snoc->mem_pa);
934 		return -EINVAL;
935 	}
936 
937 	for (i = 0; i < CE_COUNT; i++) {
938 		res = platform_get_resource(ar_snoc->dev, IORESOURCE_IRQ, i);
939 		if (!res) {
940 			ath10k_err(ar, "failed to get IRQ%d\n", i);
941 			ret = -ENODEV;
942 			goto out;
943 		}
944 		ar_snoc->ce_irqs[i].irq_line = res->start;
945 	}
946 
947 out:
948 	return ret;
949 }
950 
951 static int ath10k_snoc_setup_resource(struct ath10k *ar)
952 {
953 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
954 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
955 	struct ath10k_snoc_pipe *pipe;
956 	int i, ret;
957 
958 	timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0);
959 	spin_lock_init(&ce->ce_lock);
960 	for (i = 0; i < CE_COUNT; i++) {
961 		pipe = &ar_snoc->pipe_info[i];
962 		pipe->ce_hdl = &ce->ce_states[i];
963 		pipe->pipe_num = i;
964 		pipe->hif_ce_state = ar;
965 
966 		ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
967 		if (ret) {
968 			ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n",
969 				   i, ret);
970 			return ret;
971 		}
972 
973 		pipe->buf_sz = host_ce_config_wlan[i].src_sz_max;
974 	}
975 	ath10k_snoc_init_napi(ar);
976 
977 	return 0;
978 }
979 
980 static void ath10k_snoc_release_resource(struct ath10k *ar)
981 {
982 	int i;
983 
984 	netif_napi_del(&ar->napi);
985 	for (i = 0; i < CE_COUNT; i++)
986 		ath10k_ce_free_pipe(ar, i);
987 }
988 
989 static int ath10k_get_vreg_info(struct ath10k *ar, struct device *dev,
990 				struct ath10k_wcn3990_vreg_info *vreg_info)
991 {
992 	struct regulator *reg;
993 	int ret = 0;
994 
995 	reg = devm_regulator_get_optional(dev, vreg_info->name);
996 
997 	if (IS_ERR(reg)) {
998 		ret = PTR_ERR(reg);
999 
1000 		if (ret  == -EPROBE_DEFER) {
1001 			ath10k_err(ar, "EPROBE_DEFER for regulator: %s\n",
1002 				   vreg_info->name);
1003 			return ret;
1004 		}
1005 		if (vreg_info->required) {
1006 			ath10k_err(ar, "Regulator %s doesn't exist: %d\n",
1007 				   vreg_info->name, ret);
1008 			return ret;
1009 		}
1010 		ath10k_dbg(ar, ATH10K_DBG_SNOC,
1011 			   "Optional regulator %s doesn't exist: %d\n",
1012 			   vreg_info->name, ret);
1013 		goto done;
1014 	}
1015 
1016 	vreg_info->reg = reg;
1017 
1018 done:
1019 	ath10k_dbg(ar, ATH10K_DBG_SNOC,
1020 		   "snog vreg %s min_v %u max_v %u load_ua %u settle_delay %lu\n",
1021 		   vreg_info->name, vreg_info->min_v, vreg_info->max_v,
1022 		   vreg_info->load_ua, vreg_info->settle_delay);
1023 
1024 	return 0;
1025 }
1026 
1027 static int ath10k_get_clk_info(struct ath10k *ar, struct device *dev,
1028 			       struct ath10k_wcn3990_clk_info *clk_info)
1029 {
1030 	struct clk *handle;
1031 	int ret = 0;
1032 
1033 	handle = devm_clk_get(dev, clk_info->name);
1034 	if (IS_ERR(handle)) {
1035 		ret = PTR_ERR(handle);
1036 		if (clk_info->required) {
1037 			ath10k_err(ar, "snoc clock %s isn't available: %d\n",
1038 				   clk_info->name, ret);
1039 			return ret;
1040 		}
1041 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc ignoring clock %s: %d\n",
1042 			   clk_info->name,
1043 			   ret);
1044 		return 0;
1045 	}
1046 
1047 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s freq %u\n",
1048 		   clk_info->name, clk_info->freq);
1049 
1050 	clk_info->handle = handle;
1051 
1052 	return ret;
1053 }
1054 
1055 static int ath10k_wcn3990_vreg_on(struct ath10k *ar)
1056 {
1057 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1058 	struct ath10k_wcn3990_vreg_info *vreg_info;
1059 	int ret = 0;
1060 	int i;
1061 
1062 	for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1063 		vreg_info = &ar_snoc->vreg[i];
1064 
1065 		if (!vreg_info->reg)
1066 			continue;
1067 
1068 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being enabled\n",
1069 			   vreg_info->name);
1070 
1071 		ret = regulator_set_voltage(vreg_info->reg, vreg_info->min_v,
1072 					    vreg_info->max_v);
1073 		if (ret) {
1074 			ath10k_err(ar,
1075 				   "failed to set regulator %s voltage-min: %d voltage-max: %d\n",
1076 				   vreg_info->name, vreg_info->min_v, vreg_info->max_v);
1077 			goto err_reg_config;
1078 		}
1079 
1080 		if (vreg_info->load_ua) {
1081 			ret = regulator_set_load(vreg_info->reg,
1082 						 vreg_info->load_ua);
1083 			if (ret < 0) {
1084 				ath10k_err(ar,
1085 					   "failed to set regulator %s load: %d\n",
1086 					   vreg_info->name,
1087 					   vreg_info->load_ua);
1088 				goto err_reg_config;
1089 			}
1090 		}
1091 
1092 		ret = regulator_enable(vreg_info->reg);
1093 		if (ret) {
1094 			ath10k_err(ar, "failed to enable regulator %s\n",
1095 				   vreg_info->name);
1096 			goto err_reg_config;
1097 		}
1098 
1099 		if (vreg_info->settle_delay)
1100 			udelay(vreg_info->settle_delay);
1101 	}
1102 
1103 	return 0;
1104 
1105 err_reg_config:
1106 	for (; i >= 0; i--) {
1107 		vreg_info = &ar_snoc->vreg[i];
1108 
1109 		if (!vreg_info->reg)
1110 			continue;
1111 
1112 		regulator_disable(vreg_info->reg);
1113 		regulator_set_load(vreg_info->reg, 0);
1114 		regulator_set_voltage(vreg_info->reg, 0, vreg_info->max_v);
1115 	}
1116 
1117 	return ret;
1118 }
1119 
1120 static int ath10k_wcn3990_vreg_off(struct ath10k *ar)
1121 {
1122 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1123 	struct ath10k_wcn3990_vreg_info *vreg_info;
1124 	int ret = 0;
1125 	int i;
1126 
1127 	for (i = ARRAY_SIZE(vreg_cfg) - 1; i >= 0; i--) {
1128 		vreg_info = &ar_snoc->vreg[i];
1129 
1130 		if (!vreg_info->reg)
1131 			continue;
1132 
1133 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc regulator %s being disabled\n",
1134 			   vreg_info->name);
1135 
1136 		ret = regulator_disable(vreg_info->reg);
1137 		if (ret)
1138 			ath10k_err(ar, "failed to disable regulator %s\n",
1139 				   vreg_info->name);
1140 
1141 		ret = regulator_set_load(vreg_info->reg, 0);
1142 		if (ret < 0)
1143 			ath10k_err(ar, "failed to set load %s\n",
1144 				   vreg_info->name);
1145 
1146 		ret = regulator_set_voltage(vreg_info->reg, 0,
1147 					    vreg_info->max_v);
1148 		if (ret)
1149 			ath10k_err(ar, "failed to set voltage %s\n",
1150 				   vreg_info->name);
1151 	}
1152 
1153 	return ret;
1154 }
1155 
1156 static int ath10k_wcn3990_clk_init(struct ath10k *ar)
1157 {
1158 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1159 	struct ath10k_wcn3990_clk_info *clk_info;
1160 	int ret = 0;
1161 	int i;
1162 
1163 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1164 		clk_info = &ar_snoc->clk[i];
1165 
1166 		if (!clk_info->handle)
1167 			continue;
1168 
1169 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being enabled\n",
1170 			   clk_info->name);
1171 
1172 		if (clk_info->freq) {
1173 			ret = clk_set_rate(clk_info->handle, clk_info->freq);
1174 
1175 			if (ret) {
1176 				ath10k_err(ar, "failed to set clock %s freq %u\n",
1177 					   clk_info->name, clk_info->freq);
1178 				goto err_clock_config;
1179 			}
1180 		}
1181 
1182 		ret = clk_prepare_enable(clk_info->handle);
1183 		if (ret) {
1184 			ath10k_err(ar, "failed to enable clock %s\n",
1185 				   clk_info->name);
1186 			goto err_clock_config;
1187 		}
1188 	}
1189 
1190 	return 0;
1191 
1192 err_clock_config:
1193 	for (; i >= 0; i--) {
1194 		clk_info = &ar_snoc->clk[i];
1195 
1196 		if (!clk_info->handle)
1197 			continue;
1198 
1199 		clk_disable_unprepare(clk_info->handle);
1200 	}
1201 
1202 	return ret;
1203 }
1204 
1205 static int ath10k_wcn3990_clk_deinit(struct ath10k *ar)
1206 {
1207 	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1208 	struct ath10k_wcn3990_clk_info *clk_info;
1209 	int i;
1210 
1211 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1212 		clk_info = &ar_snoc->clk[i];
1213 
1214 		if (!clk_info->handle)
1215 			continue;
1216 
1217 		ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc clock %s being disabled\n",
1218 			   clk_info->name);
1219 
1220 		clk_disable_unprepare(clk_info->handle);
1221 	}
1222 
1223 	return 0;
1224 }
1225 
1226 static int ath10k_hw_power_on(struct ath10k *ar)
1227 {
1228 	int ret;
1229 
1230 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n");
1231 
1232 	ret = ath10k_wcn3990_vreg_on(ar);
1233 	if (ret)
1234 		return ret;
1235 
1236 	ret = ath10k_wcn3990_clk_init(ar);
1237 	if (ret)
1238 		goto vreg_off;
1239 
1240 	return ret;
1241 
1242 vreg_off:
1243 	ath10k_wcn3990_vreg_off(ar);
1244 	return ret;
1245 }
1246 
1247 static int ath10k_hw_power_off(struct ath10k *ar)
1248 {
1249 	int ret;
1250 
1251 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n");
1252 
1253 	ath10k_wcn3990_clk_deinit(ar);
1254 
1255 	ret = ath10k_wcn3990_vreg_off(ar);
1256 
1257 	return ret;
1258 }
1259 
1260 static const struct of_device_id ath10k_snoc_dt_match[] = {
1261 	{ .compatible = "qcom,wcn3990-wifi",
1262 	 .data = &drv_priv,
1263 	},
1264 	{ }
1265 };
1266 MODULE_DEVICE_TABLE(of, ath10k_snoc_dt_match);
1267 
1268 static int ath10k_snoc_probe(struct platform_device *pdev)
1269 {
1270 	const struct ath10k_snoc_drv_priv *drv_data;
1271 	const struct of_device_id *of_id;
1272 	struct ath10k_snoc *ar_snoc;
1273 	struct device *dev;
1274 	struct ath10k *ar;
1275 	int ret;
1276 	u32 i;
1277 
1278 	of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev);
1279 	if (!of_id) {
1280 		dev_err(&pdev->dev, "failed to find matching device tree id\n");
1281 		return -EINVAL;
1282 	}
1283 
1284 	drv_data = of_id->data;
1285 	dev = &pdev->dev;
1286 
1287 	ret = dma_set_mask_and_coherent(dev, drv_data->dma_mask);
1288 	if (ret) {
1289 		dev_err(dev, "failed to set dma mask: %d", ret);
1290 		return ret;
1291 	}
1292 
1293 	ar = ath10k_core_create(sizeof(*ar_snoc), dev, ATH10K_BUS_SNOC,
1294 				drv_data->hw_rev, &ath10k_snoc_hif_ops);
1295 	if (!ar) {
1296 		dev_err(dev, "failed to allocate core\n");
1297 		return -ENOMEM;
1298 	}
1299 
1300 	ar_snoc = ath10k_snoc_priv(ar);
1301 	ar_snoc->dev = pdev;
1302 	platform_set_drvdata(pdev, ar);
1303 	ar_snoc->ar = ar;
1304 	ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops;
1305 	ar->ce_priv = &ar_snoc->ce;
1306 
1307 	ret = ath10k_snoc_resource_init(ar);
1308 	if (ret) {
1309 		ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
1310 		goto err_core_destroy;
1311 	}
1312 
1313 	ret = ath10k_snoc_setup_resource(ar);
1314 	if (ret) {
1315 		ath10k_warn(ar, "failed to setup resource: %d\n", ret);
1316 		goto err_core_destroy;
1317 	}
1318 	ret = ath10k_snoc_request_irq(ar);
1319 	if (ret) {
1320 		ath10k_warn(ar, "failed to request irqs: %d\n", ret);
1321 		goto err_release_resource;
1322 	}
1323 
1324 	ar_snoc->vreg = vreg_cfg;
1325 	for (i = 0; i < ARRAY_SIZE(vreg_cfg); i++) {
1326 		ret = ath10k_get_vreg_info(ar, dev, &ar_snoc->vreg[i]);
1327 		if (ret)
1328 			goto err_free_irq;
1329 	}
1330 
1331 	ar_snoc->clk = clk_cfg;
1332 	for (i = 0; i < ARRAY_SIZE(clk_cfg); i++) {
1333 		ret = ath10k_get_clk_info(ar, dev, &ar_snoc->clk[i]);
1334 		if (ret)
1335 			goto err_free_irq;
1336 	}
1337 
1338 	ret = ath10k_hw_power_on(ar);
1339 	if (ret) {
1340 		ath10k_err(ar, "failed to power on device: %d\n", ret);
1341 		goto err_free_irq;
1342 	}
1343 
1344 	ret = ath10k_core_register(ar, drv_data->hw_rev);
1345 	if (ret) {
1346 		ath10k_err(ar, "failed to register driver core: %d\n", ret);
1347 		goto err_hw_power_off;
1348 	}
1349 
1350 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
1351 	ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
1352 
1353 	return 0;
1354 
1355 err_hw_power_off:
1356 	ath10k_hw_power_off(ar);
1357 
1358 err_free_irq:
1359 	ath10k_snoc_free_irq(ar);
1360 
1361 err_release_resource:
1362 	ath10k_snoc_release_resource(ar);
1363 
1364 err_core_destroy:
1365 	ath10k_core_destroy(ar);
1366 
1367 	return ret;
1368 }
1369 
1370 static int ath10k_snoc_remove(struct platform_device *pdev)
1371 {
1372 	struct ath10k *ar = platform_get_drvdata(pdev);
1373 
1374 	ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
1375 	ath10k_core_unregister(ar);
1376 	ath10k_hw_power_off(ar);
1377 	ath10k_snoc_free_irq(ar);
1378 	ath10k_snoc_release_resource(ar);
1379 	ath10k_core_destroy(ar);
1380 
1381 	return 0;
1382 }
1383 
1384 static struct platform_driver ath10k_snoc_driver = {
1385 		.probe  = ath10k_snoc_probe,
1386 		.remove = ath10k_snoc_remove,
1387 		.driver = {
1388 			.name   = "ath10k_snoc",
1389 			.of_match_table = ath10k_snoc_dt_match,
1390 		},
1391 };
1392 module_platform_driver(ath10k_snoc_driver);
1393 
1394 MODULE_AUTHOR("Qualcomm");
1395 MODULE_LICENSE("Dual BSD/GPL");
1396 MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices");
1397