GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / wwan / t7xx / t7xx_hif_dpmaif.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2021, MediaTek Inc.
4  * Copyright (c) 2021-2022, Intel Corporation.
5  *
6  * Authors:
7  *  Amir Hanania <amir.hanania@intel.com>
8  *  Haijun Liu <haijun.liu@mediatek.com>
9  *  Moises Veleta <moises.veleta@intel.com>
10  *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
11  *
12  * Contributors:
13  *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
14  *  Eliot Lee <eliot.lee@intel.com>
15  *  Sreehari Kancharla <sreehari.kancharla@intel.com>
16  */
17
18 #include <linux/device.h>
19 #include <linux/gfp.h>
20 #include <linux/irqreturn.h>
21 #include <linux/kernel.h>
22 #include <linux/list.h>
23 #include <linux/string.h>
24 #include <linux/wait.h>
25 #include <linux/workqueue.h>
26
27 #include "t7xx_dpmaif.h"
28 #include "t7xx_hif_dpmaif.h"
29 #include "t7xx_hif_dpmaif_rx.h"
30 #include "t7xx_hif_dpmaif_tx.h"
31 #include "t7xx_pci.h"
32 #include "t7xx_pcie_mac.h"
33 #include "t7xx_state_monitor.h"
34
35 unsigned int t7xx_ring_buf_get_next_wr_idx(unsigned int buf_len, unsigned int buf_idx)
36 {
37         buf_idx++;
38
39         return buf_idx < buf_len ? buf_idx : 0;
40 }
41
42 unsigned int t7xx_ring_buf_rd_wr_count(unsigned int total_cnt, unsigned int rd_idx,
43                                        unsigned int wr_idx, enum dpmaif_rdwr rd_wr)
44 {
45         int pkt_cnt;
46
47         if (rd_wr == DPMAIF_READ)
48                 pkt_cnt = wr_idx - rd_idx;
49         else
50                 pkt_cnt = rd_idx - wr_idx - 1;
51
52         if (pkt_cnt < 0)
53                 pkt_cnt += total_cnt;
54
55         return (unsigned int)pkt_cnt;
56 }
57
58 static void t7xx_dpmaif_enable_irq(struct dpmaif_ctrl *dpmaif_ctrl)
59 {
60         struct dpmaif_isr_para *isr_para;
61         int i;
62
63         for (i = 0; i < ARRAY_SIZE(dpmaif_ctrl->isr_para); i++) {
64                 isr_para = &dpmaif_ctrl->isr_para[i];
65                 t7xx_pcie_mac_set_int(dpmaif_ctrl->t7xx_dev, isr_para->pcie_int);
66         }
67 }
68
69 static void t7xx_dpmaif_disable_irq(struct dpmaif_ctrl *dpmaif_ctrl)
70 {
71         struct dpmaif_isr_para *isr_para;
72         int i;
73
74         for (i = 0; i < ARRAY_SIZE(dpmaif_ctrl->isr_para); i++) {
75                 isr_para = &dpmaif_ctrl->isr_para[i];
76                 t7xx_pcie_mac_clear_int(dpmaif_ctrl->t7xx_dev, isr_para->pcie_int);
77         }
78 }
79
80 static void t7xx_dpmaif_irq_cb(struct dpmaif_isr_para *isr_para)
81 {
82         struct dpmaif_ctrl *dpmaif_ctrl = isr_para->dpmaif_ctrl;
83         struct dpmaif_hw_intr_st_para intr_status;
84         struct device *dev = dpmaif_ctrl->dev;
85         struct dpmaif_hw_info *hw_info;
86         int i;
87
88         memset(&intr_status, 0, sizeof(intr_status));
89         hw_info = &dpmaif_ctrl->hw_info;
90
91         if (t7xx_dpmaif_hw_get_intr_cnt(hw_info, &intr_status, isr_para->dlq_id) < 0) {
92                 dev_err(dev, "Failed to get HW interrupt count\n");
93                 return;
94         }
95
96         t7xx_pcie_mac_clear_int_status(dpmaif_ctrl->t7xx_dev, isr_para->pcie_int);
97
98         for (i = 0; i < intr_status.intr_cnt; i++) {
99                 switch (intr_status.intr_types[i]) {
100                 case DPF_INTR_UL_DONE:
101                         t7xx_dpmaif_irq_tx_done(dpmaif_ctrl, intr_status.intr_queues[i]);
102                         break;
103
104                 case DPF_INTR_UL_DRB_EMPTY:
105                 case DPF_INTR_UL_MD_NOTREADY:
106                 case DPF_INTR_UL_MD_PWR_NOTREADY:
107                         /* No need to log an error for these */
108                         break;
109
110                 case DPF_INTR_DL_BATCNT_LEN_ERR:
111                         dev_err_ratelimited(dev, "DL interrupt: packet BAT count length error\n");
112                         t7xx_dpmaif_dl_unmask_batcnt_len_err_intr(hw_info);
113                         break;
114
115                 case DPF_INTR_DL_PITCNT_LEN_ERR:
116                         dev_err_ratelimited(dev, "DL interrupt: PIT count length error\n");
117                         t7xx_dpmaif_dl_unmask_pitcnt_len_err_intr(hw_info);
118                         break;
119
120                 case DPF_INTR_DL_Q0_PITCNT_LEN_ERR:
121                         dev_err_ratelimited(dev, "DL interrupt: DLQ0 PIT count length error\n");
122                         t7xx_dpmaif_dlq_unmask_pitcnt_len_err_intr(hw_info, DPF_RX_QNO_DFT);
123                         break;
124
125                 case DPF_INTR_DL_Q1_PITCNT_LEN_ERR:
126                         dev_err_ratelimited(dev, "DL interrupt: DLQ1 PIT count length error\n");
127                         t7xx_dpmaif_dlq_unmask_pitcnt_len_err_intr(hw_info, DPF_RX_QNO1);
128                         break;
129
130                 case DPF_INTR_DL_DONE:
131                 case DPF_INTR_DL_Q0_DONE:
132                 case DPF_INTR_DL_Q1_DONE:
133                         t7xx_dpmaif_irq_rx_done(dpmaif_ctrl, intr_status.intr_queues[i]);
134                         break;
135
136                 default:
137                         dev_err_ratelimited(dev, "DL interrupt error: unknown type : %d\n",
138                                             intr_status.intr_types[i]);
139                 }
140         }
141 }
142
143 static irqreturn_t t7xx_dpmaif_isr_handler(int irq, void *data)
144 {
145         struct dpmaif_isr_para *isr_para = data;
146         struct dpmaif_ctrl *dpmaif_ctrl;
147
148         dpmaif_ctrl = isr_para->dpmaif_ctrl;
149         if (dpmaif_ctrl->state != DPMAIF_STATE_PWRON) {
150                 dev_err(dpmaif_ctrl->dev, "Interrupt received before initializing DPMAIF\n");
151                 return IRQ_HANDLED;
152         }
153
154         t7xx_pcie_mac_clear_int(dpmaif_ctrl->t7xx_dev, isr_para->pcie_int);
155
156         return IRQ_WAKE_THREAD;
157 }
158
159 static irqreturn_t t7xx_dpmaif_isr_thread(int irq, void *data)
160 {
161         struct dpmaif_isr_para *isr_para = data;
162         struct dpmaif_ctrl *dpmaif_ctrl = isr_para->dpmaif_ctrl;
163
164         t7xx_dpmaif_irq_cb(isr_para);
165         t7xx_pcie_mac_set_int(dpmaif_ctrl->t7xx_dev, isr_para->pcie_int);
166         return IRQ_HANDLED;
167 }
168
169 static void t7xx_dpmaif_isr_parameter_init(struct dpmaif_ctrl *dpmaif_ctrl)
170 {
171         struct dpmaif_isr_para *isr_para;
172         unsigned char i;
173
174         dpmaif_ctrl->rxq_int_mapping[DPF_RX_QNO0] = DPMAIF_INT;
175         dpmaif_ctrl->rxq_int_mapping[DPF_RX_QNO1] = DPMAIF2_INT;
176
177         for (i = 0; i < DPMAIF_RXQ_NUM; i++) {
178                 isr_para = &dpmaif_ctrl->isr_para[i];
179                 isr_para->dpmaif_ctrl = dpmaif_ctrl;
180                 isr_para->dlq_id = i;
181                 isr_para->pcie_int = dpmaif_ctrl->rxq_int_mapping[i];
182         }
183 }
184
185 static void t7xx_dpmaif_register_pcie_irq(struct dpmaif_ctrl *dpmaif_ctrl)
186 {
187         struct t7xx_pci_dev *t7xx_dev = dpmaif_ctrl->t7xx_dev;
188         struct dpmaif_isr_para *isr_para;
189         enum t7xx_int int_type;
190         int i;
191
192         t7xx_dpmaif_isr_parameter_init(dpmaif_ctrl);
193
194         for (i = 0; i < DPMAIF_RXQ_NUM; i++) {
195                 isr_para = &dpmaif_ctrl->isr_para[i];
196                 int_type = isr_para->pcie_int;
197                 t7xx_pcie_mac_clear_int(t7xx_dev, int_type);
198
199                 t7xx_dev->intr_handler[int_type] = t7xx_dpmaif_isr_handler;
200                 t7xx_dev->intr_thread[int_type] = t7xx_dpmaif_isr_thread;
201                 t7xx_dev->callback_param[int_type] = isr_para;
202
203                 t7xx_pcie_mac_clear_int_status(t7xx_dev, int_type);
204                 t7xx_pcie_mac_set_int(t7xx_dev, int_type);
205         }
206 }
207
208 static int t7xx_dpmaif_rxtx_sw_allocs(struct dpmaif_ctrl *dpmaif_ctrl)
209 {
210         struct dpmaif_rx_queue *rx_q;
211         struct dpmaif_tx_queue *tx_q;
212         int ret, rx_idx, tx_idx, i;
213
214         ret = t7xx_dpmaif_bat_alloc(dpmaif_ctrl, &dpmaif_ctrl->bat_req, BAT_TYPE_NORMAL);
215         if (ret) {
216                 dev_err(dpmaif_ctrl->dev, "Failed to allocate normal BAT table: %d\n", ret);
217                 return ret;
218         }
219
220         ret = t7xx_dpmaif_bat_alloc(dpmaif_ctrl, &dpmaif_ctrl->bat_frag, BAT_TYPE_FRAG);
221         if (ret) {
222                 dev_err(dpmaif_ctrl->dev, "Failed to allocate frag BAT table: %d\n", ret);
223                 goto err_free_normal_bat;
224         }
225
226         for (rx_idx = 0; rx_idx < DPMAIF_RXQ_NUM; rx_idx++) {
227                 rx_q = &dpmaif_ctrl->rxq[rx_idx];
228                 rx_q->index = rx_idx;
229                 rx_q->dpmaif_ctrl = dpmaif_ctrl;
230                 ret = t7xx_dpmaif_rxq_init(rx_q);
231                 if (ret)
232                         goto err_free_rxq;
233         }
234
235         for (tx_idx = 0; tx_idx < DPMAIF_TXQ_NUM; tx_idx++) {
236                 tx_q = &dpmaif_ctrl->txq[tx_idx];
237                 tx_q->index = tx_idx;
238                 tx_q->dpmaif_ctrl = dpmaif_ctrl;
239                 ret = t7xx_dpmaif_txq_init(tx_q);
240                 if (ret)
241                         goto err_free_txq;
242         }
243
244         ret = t7xx_dpmaif_tx_thread_init(dpmaif_ctrl);
245         if (ret) {
246                 dev_err(dpmaif_ctrl->dev, "Failed to start TX thread\n");
247                 goto err_free_txq;
248         }
249
250         ret = t7xx_dpmaif_bat_rel_wq_alloc(dpmaif_ctrl);
251         if (ret)
252                 goto err_thread_rel;
253
254         return 0;
255
256 err_thread_rel:
257         t7xx_dpmaif_tx_thread_rel(dpmaif_ctrl);
258
259 err_free_txq:
260         for (i = 0; i < tx_idx; i++) {
261                 tx_q = &dpmaif_ctrl->txq[i];
262                 t7xx_dpmaif_txq_free(tx_q);
263         }
264
265 err_free_rxq:
266         for (i = 0; i < rx_idx; i++) {
267                 rx_q = &dpmaif_ctrl->rxq[i];
268                 t7xx_dpmaif_rxq_free(rx_q);
269         }
270
271         t7xx_dpmaif_bat_free(dpmaif_ctrl, &dpmaif_ctrl->bat_frag);
272
273 err_free_normal_bat:
274         t7xx_dpmaif_bat_free(dpmaif_ctrl, &dpmaif_ctrl->bat_req);
275
276         return ret;
277 }
278
279 static void t7xx_dpmaif_sw_release(struct dpmaif_ctrl *dpmaif_ctrl)
280 {
281         struct dpmaif_rx_queue *rx_q;
282         struct dpmaif_tx_queue *tx_q;
283         int i;
284
285         t7xx_dpmaif_tx_thread_rel(dpmaif_ctrl);
286         t7xx_dpmaif_bat_wq_rel(dpmaif_ctrl);
287
288         for (i = 0; i < DPMAIF_TXQ_NUM; i++) {
289                 tx_q = &dpmaif_ctrl->txq[i];
290                 t7xx_dpmaif_txq_free(tx_q);
291         }
292
293         for (i = 0; i < DPMAIF_RXQ_NUM; i++) {
294                 rx_q = &dpmaif_ctrl->rxq[i];
295                 t7xx_dpmaif_rxq_free(rx_q);
296         }
297 }
298
299 static int t7xx_dpmaif_start(struct dpmaif_ctrl *dpmaif_ctrl)
300 {
301         struct dpmaif_hw_info *hw_info = &dpmaif_ctrl->hw_info;
302         struct dpmaif_hw_params hw_init_para;
303         struct dpmaif_rx_queue *rxq;
304         struct dpmaif_tx_queue *txq;
305         unsigned int buf_cnt;
306         int i, ret = 0;
307
308         if (dpmaif_ctrl->state == DPMAIF_STATE_PWRON)
309                 return -EFAULT;
310
311         memset(&hw_init_para, 0, sizeof(hw_init_para));
312
313         for (i = 0; i < DPMAIF_RXQ_NUM; i++) {
314                 rxq = &dpmaif_ctrl->rxq[i];
315                 rxq->que_started = true;
316                 rxq->index = i;
317                 rxq->budget = rxq->bat_req->bat_size_cnt - 1;
318
319                 hw_init_para.pkt_bat_base_addr[i] = rxq->bat_req->bat_bus_addr;
320                 hw_init_para.pkt_bat_size_cnt[i] = rxq->bat_req->bat_size_cnt;
321                 hw_init_para.pit_base_addr[i] = rxq->pit_bus_addr;
322                 hw_init_para.pit_size_cnt[i] = rxq->pit_size_cnt;
323                 hw_init_para.frg_bat_base_addr[i] = rxq->bat_frag->bat_bus_addr;
324                 hw_init_para.frg_bat_size_cnt[i] = rxq->bat_frag->bat_size_cnt;
325         }
326
327         bitmap_zero(dpmaif_ctrl->bat_req.bat_bitmap, dpmaif_ctrl->bat_req.bat_size_cnt);
328         buf_cnt = dpmaif_ctrl->bat_req.bat_size_cnt - 1;
329         ret = t7xx_dpmaif_rx_buf_alloc(dpmaif_ctrl, &dpmaif_ctrl->bat_req, 0, buf_cnt, true);
330         if (ret) {
331                 dev_err(dpmaif_ctrl->dev, "Failed to allocate RX buffer: %d\n", ret);
332                 return ret;
333         }
334
335         buf_cnt = dpmaif_ctrl->bat_frag.bat_size_cnt - 1;
336         ret = t7xx_dpmaif_rx_frag_alloc(dpmaif_ctrl, &dpmaif_ctrl->bat_frag, buf_cnt, true);
337         if (ret) {
338                 dev_err(dpmaif_ctrl->dev, "Failed to allocate frag RX buffer: %d\n", ret);
339                 goto err_free_normal_bat;
340         }
341
342         for (i = 0; i < DPMAIF_TXQ_NUM; i++) {
343                 txq = &dpmaif_ctrl->txq[i];
344                 txq->que_started = true;
345
346                 hw_init_para.drb_base_addr[i] = txq->drb_bus_addr;
347                 hw_init_para.drb_size_cnt[i] = txq->drb_size_cnt;
348         }
349
350         ret = t7xx_dpmaif_hw_init(hw_info, &hw_init_para);
351         if (ret) {
352                 dev_err(dpmaif_ctrl->dev, "Failed to initialize DPMAIF HW: %d\n", ret);
353                 goto err_free_frag_bat;
354         }
355
356         ret = t7xx_dpmaif_dl_snd_hw_bat_cnt(hw_info, rxq->bat_req->bat_size_cnt - 1);
357         if (ret)
358                 goto err_free_frag_bat;
359
360         ret = t7xx_dpmaif_dl_snd_hw_frg_cnt(hw_info, rxq->bat_frag->bat_size_cnt - 1);
361         if (ret)
362                 goto err_free_frag_bat;
363
364         t7xx_dpmaif_ul_clr_all_intr(hw_info);
365         t7xx_dpmaif_dl_clr_all_intr(hw_info);
366         dpmaif_ctrl->state = DPMAIF_STATE_PWRON;
367         t7xx_dpmaif_enable_irq(dpmaif_ctrl);
368         wake_up(&dpmaif_ctrl->tx_wq);
369         return 0;
370
371 err_free_frag_bat:
372         t7xx_dpmaif_bat_free(rxq->dpmaif_ctrl, rxq->bat_frag);
373
374 err_free_normal_bat:
375         t7xx_dpmaif_bat_free(rxq->dpmaif_ctrl, rxq->bat_req);
376
377         return ret;
378 }
379
380 static void t7xx_dpmaif_stop_sw(struct dpmaif_ctrl *dpmaif_ctrl)
381 {
382         t7xx_dpmaif_tx_stop(dpmaif_ctrl);
383         t7xx_dpmaif_rx_stop(dpmaif_ctrl);
384 }
385
386 static void t7xx_dpmaif_stop_hw(struct dpmaif_ctrl *dpmaif_ctrl)
387 {
388         t7xx_dpmaif_hw_stop_all_txq(&dpmaif_ctrl->hw_info);
389         t7xx_dpmaif_hw_stop_all_rxq(&dpmaif_ctrl->hw_info);
390 }
391
392 static int t7xx_dpmaif_stop(struct dpmaif_ctrl *dpmaif_ctrl)
393 {
394         if (!dpmaif_ctrl->dpmaif_sw_init_done) {
395                 dev_err(dpmaif_ctrl->dev, "dpmaif SW init fail\n");
396                 return -EFAULT;
397         }
398
399         if (dpmaif_ctrl->state == DPMAIF_STATE_PWROFF)
400                 return -EFAULT;
401
402         t7xx_dpmaif_disable_irq(dpmaif_ctrl);
403         dpmaif_ctrl->state = DPMAIF_STATE_PWROFF;
404         t7xx_dpmaif_stop_sw(dpmaif_ctrl);
405         t7xx_dpmaif_tx_clear(dpmaif_ctrl);
406         t7xx_dpmaif_rx_clear(dpmaif_ctrl);
407         return 0;
408 }
409
410 static int t7xx_dpmaif_suspend(struct t7xx_pci_dev *t7xx_dev, void *param)
411 {
412         struct dpmaif_ctrl *dpmaif_ctrl = param;
413
414         t7xx_dpmaif_tx_stop(dpmaif_ctrl);
415         t7xx_dpmaif_hw_stop_all_txq(&dpmaif_ctrl->hw_info);
416         t7xx_dpmaif_hw_stop_all_rxq(&dpmaif_ctrl->hw_info);
417         t7xx_dpmaif_disable_irq(dpmaif_ctrl);
418         t7xx_dpmaif_rx_stop(dpmaif_ctrl);
419         return 0;
420 }
421
422 static void t7xx_dpmaif_unmask_dlq_intr(struct dpmaif_ctrl *dpmaif_ctrl)
423 {
424         int qno;
425
426         for (qno = 0; qno < DPMAIF_RXQ_NUM; qno++)
427                 t7xx_dpmaif_dlq_unmask_rx_done(&dpmaif_ctrl->hw_info, qno);
428 }
429
430 static void t7xx_dpmaif_start_txrx_qs(struct dpmaif_ctrl *dpmaif_ctrl)
431 {
432         struct dpmaif_rx_queue *rxq;
433         struct dpmaif_tx_queue *txq;
434         unsigned int que_cnt;
435
436         for (que_cnt = 0; que_cnt < DPMAIF_TXQ_NUM; que_cnt++) {
437                 txq = &dpmaif_ctrl->txq[que_cnt];
438                 txq->que_started = true;
439         }
440
441         for (que_cnt = 0; que_cnt < DPMAIF_RXQ_NUM; que_cnt++) {
442                 rxq = &dpmaif_ctrl->rxq[que_cnt];
443                 rxq->que_started = true;
444         }
445 }
446
447 static int t7xx_dpmaif_resume(struct t7xx_pci_dev *t7xx_dev, void *param)
448 {
449         struct dpmaif_ctrl *dpmaif_ctrl = param;
450
451         if (!dpmaif_ctrl)
452                 return 0;
453
454         t7xx_dpmaif_start_txrx_qs(dpmaif_ctrl);
455         t7xx_dpmaif_enable_irq(dpmaif_ctrl);
456         t7xx_dpmaif_unmask_dlq_intr(dpmaif_ctrl);
457         t7xx_dpmaif_start_hw(&dpmaif_ctrl->hw_info);
458         wake_up(&dpmaif_ctrl->tx_wq);
459         return 0;
460 }
461
462 static int t7xx_dpmaif_pm_entity_init(struct dpmaif_ctrl *dpmaif_ctrl)
463 {
464         struct md_pm_entity *dpmaif_pm_entity = &dpmaif_ctrl->dpmaif_pm_entity;
465         int ret;
466
467         INIT_LIST_HEAD(&dpmaif_pm_entity->entity);
468         dpmaif_pm_entity->suspend = &t7xx_dpmaif_suspend;
469         dpmaif_pm_entity->suspend_late = NULL;
470         dpmaif_pm_entity->resume_early = NULL;
471         dpmaif_pm_entity->resume = &t7xx_dpmaif_resume;
472         dpmaif_pm_entity->id = PM_ENTITY_ID_DATA;
473         dpmaif_pm_entity->entity_param = dpmaif_ctrl;
474
475         ret = t7xx_pci_pm_entity_register(dpmaif_ctrl->t7xx_dev, dpmaif_pm_entity);
476         if (ret)
477                 dev_err(dpmaif_ctrl->dev, "dpmaif register pm_entity fail\n");
478
479         return ret;
480 }
481
482 static int t7xx_dpmaif_pm_entity_release(struct dpmaif_ctrl *dpmaif_ctrl)
483 {
484         struct md_pm_entity *dpmaif_pm_entity = &dpmaif_ctrl->dpmaif_pm_entity;
485         int ret;
486
487         ret = t7xx_pci_pm_entity_unregister(dpmaif_ctrl->t7xx_dev, dpmaif_pm_entity);
488         if (ret < 0)
489                 dev_err(dpmaif_ctrl->dev, "dpmaif register pm_entity fail\n");
490
491         return ret;
492 }
493
494 int t7xx_dpmaif_md_state_callback(struct dpmaif_ctrl *dpmaif_ctrl, enum md_state state)
495 {
496         int ret = 0;
497
498         switch (state) {
499         case MD_STATE_WAITING_FOR_HS1:
500                 ret = t7xx_dpmaif_start(dpmaif_ctrl);
501                 break;
502
503         case MD_STATE_EXCEPTION:
504                 ret = t7xx_dpmaif_stop(dpmaif_ctrl);
505                 break;
506
507         case MD_STATE_STOPPED:
508                 ret = t7xx_dpmaif_stop(dpmaif_ctrl);
509                 break;
510
511         case MD_STATE_WAITING_TO_STOP:
512                 t7xx_dpmaif_stop_hw(dpmaif_ctrl);
513                 break;
514
515         default:
516                 break;
517         }
518
519         return ret;
520 }
521
522 /**
523  * t7xx_dpmaif_hif_init() - Initialize data path.
524  * @t7xx_dev: MTK context structure.
525  * @callbacks: Callbacks implemented by the network layer to handle RX skb and
526  *             event notifications.
527  *
528  * Allocate and initialize datapath control block.
529  * Register datapath ISR, TX and RX resources.
530  *
531  * Return:
532  * * dpmaif_ctrl pointer - Pointer to DPMAIF context structure.
533  * * NULL                - In case of error.
534  */
535 struct dpmaif_ctrl *t7xx_dpmaif_hif_init(struct t7xx_pci_dev *t7xx_dev,
536                                          struct dpmaif_callbacks *callbacks)
537 {
538         struct device *dev = &t7xx_dev->pdev->dev;
539         struct dpmaif_ctrl *dpmaif_ctrl;
540         int ret;
541
542         if (!callbacks)
543                 return NULL;
544
545         dpmaif_ctrl = devm_kzalloc(dev, sizeof(*dpmaif_ctrl), GFP_KERNEL);
546         if (!dpmaif_ctrl)
547                 return NULL;
548
549         dpmaif_ctrl->t7xx_dev = t7xx_dev;
550         dpmaif_ctrl->callbacks = callbacks;
551         dpmaif_ctrl->dev = dev;
552         dpmaif_ctrl->dpmaif_sw_init_done = false;
553         dpmaif_ctrl->hw_info.dev = dev;
554         dpmaif_ctrl->hw_info.pcie_base = t7xx_dev->base_addr.pcie_ext_reg_base -
555                                          t7xx_dev->base_addr.pcie_dev_reg_trsl_addr;
556
557         ret = t7xx_dpmaif_pm_entity_init(dpmaif_ctrl);
558         if (ret)
559                 return NULL;
560
561         t7xx_dpmaif_register_pcie_irq(dpmaif_ctrl);
562         t7xx_dpmaif_disable_irq(dpmaif_ctrl);
563
564         ret = t7xx_dpmaif_rxtx_sw_allocs(dpmaif_ctrl);
565         if (ret) {
566                 t7xx_dpmaif_pm_entity_release(dpmaif_ctrl);
567                 dev_err(dev, "Failed to allocate RX/TX SW resources: %d\n", ret);
568                 return NULL;
569         }
570
571         dpmaif_ctrl->dpmaif_sw_init_done = true;
572         return dpmaif_ctrl;
573 }
574
575 void t7xx_dpmaif_hif_exit(struct dpmaif_ctrl *dpmaif_ctrl)
576 {
577         if (dpmaif_ctrl->dpmaif_sw_init_done) {
578                 t7xx_dpmaif_stop(dpmaif_ctrl);
579                 t7xx_dpmaif_pm_entity_release(dpmaif_ctrl);
580                 t7xx_dpmaif_sw_release(dpmaif_ctrl);
581                 dpmaif_ctrl->dpmaif_sw_init_done = false;
582         }
583 }