1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | |
3 | /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ |
4 | /* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ |
5 | |
6 | #include <linux/delay.h> |
7 | #include <linux/err.h> |
8 | #include <linux/memblock.h> |
9 | #include <linux/mhi.h> |
10 | #include <linux/moduleparam.h> |
11 | #include <linux/pci.h> |
12 | #include <linux/sizes.h> |
13 | |
14 | #include "mhi_controller.h" |
15 | #include "qaic.h" |
16 | |
17 | #define MAX_RESET_TIME_SEC 25 |
18 | |
19 | static unsigned int mhi_timeout_ms = 2000; /* 2 sec default */ |
20 | module_param(mhi_timeout_ms, uint, 0600); |
21 | MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value" ); |
22 | |
23 | static const struct mhi_channel_config aic100_channels[] = { |
24 | { |
25 | .name = "QAIC_LOOPBACK" , |
26 | .num = 0, |
27 | .num_elements = 32, |
28 | .local_elements = 0, |
29 | .event_ring = 0, |
30 | .dir = DMA_TO_DEVICE, |
31 | .ee_mask = MHI_CH_EE_AMSS, |
32 | .pollcfg = 0, |
33 | .doorbell = MHI_DB_BRST_DISABLE, |
34 | .lpm_notify = false, |
35 | .offload_channel = false, |
36 | .doorbell_mode_switch = false, |
37 | .auto_queue = false, |
38 | .wake_capable = false, |
39 | }, |
40 | { |
41 | .name = "QAIC_LOOPBACK" , |
42 | .num = 1, |
43 | .num_elements = 32, |
44 | .local_elements = 0, |
45 | .event_ring = 0, |
46 | .dir = DMA_FROM_DEVICE, |
47 | .ee_mask = MHI_CH_EE_AMSS, |
48 | .pollcfg = 0, |
49 | .doorbell = MHI_DB_BRST_DISABLE, |
50 | .lpm_notify = false, |
51 | .offload_channel = false, |
52 | .doorbell_mode_switch = false, |
53 | .auto_queue = false, |
54 | .wake_capable = false, |
55 | }, |
56 | { |
57 | .name = "QAIC_SAHARA" , |
58 | .num = 2, |
59 | .num_elements = 32, |
60 | .local_elements = 0, |
61 | .event_ring = 0, |
62 | .dir = DMA_TO_DEVICE, |
63 | .ee_mask = MHI_CH_EE_SBL, |
64 | .pollcfg = 0, |
65 | .doorbell = MHI_DB_BRST_DISABLE, |
66 | .lpm_notify = false, |
67 | .offload_channel = false, |
68 | .doorbell_mode_switch = false, |
69 | .auto_queue = false, |
70 | .wake_capable = false, |
71 | }, |
72 | { |
73 | .name = "QAIC_SAHARA" , |
74 | .num = 3, |
75 | .num_elements = 32, |
76 | .local_elements = 0, |
77 | .event_ring = 0, |
78 | .dir = DMA_FROM_DEVICE, |
79 | .ee_mask = MHI_CH_EE_SBL, |
80 | .pollcfg = 0, |
81 | .doorbell = MHI_DB_BRST_DISABLE, |
82 | .lpm_notify = false, |
83 | .offload_channel = false, |
84 | .doorbell_mode_switch = false, |
85 | .auto_queue = false, |
86 | .wake_capable = false, |
87 | }, |
88 | { |
89 | .name = "QAIC_DIAG" , |
90 | .num = 4, |
91 | .num_elements = 32, |
92 | .local_elements = 0, |
93 | .event_ring = 0, |
94 | .dir = DMA_TO_DEVICE, |
95 | .ee_mask = MHI_CH_EE_AMSS, |
96 | .pollcfg = 0, |
97 | .doorbell = MHI_DB_BRST_DISABLE, |
98 | .lpm_notify = false, |
99 | .offload_channel = false, |
100 | .doorbell_mode_switch = false, |
101 | .auto_queue = false, |
102 | .wake_capable = false, |
103 | }, |
104 | { |
105 | .name = "QAIC_DIAG" , |
106 | .num = 5, |
107 | .num_elements = 32, |
108 | .local_elements = 0, |
109 | .event_ring = 0, |
110 | .dir = DMA_FROM_DEVICE, |
111 | .ee_mask = MHI_CH_EE_AMSS, |
112 | .pollcfg = 0, |
113 | .doorbell = MHI_DB_BRST_DISABLE, |
114 | .lpm_notify = false, |
115 | .offload_channel = false, |
116 | .doorbell_mode_switch = false, |
117 | .auto_queue = false, |
118 | .wake_capable = false, |
119 | }, |
120 | { |
121 | .name = "QAIC_SSR" , |
122 | .num = 6, |
123 | .num_elements = 32, |
124 | .local_elements = 0, |
125 | .event_ring = 0, |
126 | .dir = DMA_TO_DEVICE, |
127 | .ee_mask = MHI_CH_EE_AMSS, |
128 | .pollcfg = 0, |
129 | .doorbell = MHI_DB_BRST_DISABLE, |
130 | .lpm_notify = false, |
131 | .offload_channel = false, |
132 | .doorbell_mode_switch = false, |
133 | .auto_queue = false, |
134 | .wake_capable = false, |
135 | }, |
136 | { |
137 | .name = "QAIC_SSR" , |
138 | .num = 7, |
139 | .num_elements = 32, |
140 | .local_elements = 0, |
141 | .event_ring = 0, |
142 | .dir = DMA_FROM_DEVICE, |
143 | .ee_mask = MHI_CH_EE_AMSS, |
144 | .pollcfg = 0, |
145 | .doorbell = MHI_DB_BRST_DISABLE, |
146 | .lpm_notify = false, |
147 | .offload_channel = false, |
148 | .doorbell_mode_switch = false, |
149 | .auto_queue = false, |
150 | .wake_capable = false, |
151 | }, |
152 | { |
153 | .name = "QAIC_QDSS" , |
154 | .num = 8, |
155 | .num_elements = 32, |
156 | .local_elements = 0, |
157 | .event_ring = 0, |
158 | .dir = DMA_TO_DEVICE, |
159 | .ee_mask = MHI_CH_EE_AMSS, |
160 | .pollcfg = 0, |
161 | .doorbell = MHI_DB_BRST_DISABLE, |
162 | .lpm_notify = false, |
163 | .offload_channel = false, |
164 | .doorbell_mode_switch = false, |
165 | .auto_queue = false, |
166 | .wake_capable = false, |
167 | }, |
168 | { |
169 | .name = "QAIC_QDSS" , |
170 | .num = 9, |
171 | .num_elements = 32, |
172 | .local_elements = 0, |
173 | .event_ring = 0, |
174 | .dir = DMA_FROM_DEVICE, |
175 | .ee_mask = MHI_CH_EE_AMSS, |
176 | .pollcfg = 0, |
177 | .doorbell = MHI_DB_BRST_DISABLE, |
178 | .lpm_notify = false, |
179 | .offload_channel = false, |
180 | .doorbell_mode_switch = false, |
181 | .auto_queue = false, |
182 | .wake_capable = false, |
183 | }, |
184 | { |
185 | .name = "QAIC_CONTROL" , |
186 | .num = 10, |
187 | .num_elements = 128, |
188 | .local_elements = 0, |
189 | .event_ring = 0, |
190 | .dir = DMA_TO_DEVICE, |
191 | .ee_mask = MHI_CH_EE_AMSS, |
192 | .pollcfg = 0, |
193 | .doorbell = MHI_DB_BRST_DISABLE, |
194 | .lpm_notify = false, |
195 | .offload_channel = false, |
196 | .doorbell_mode_switch = false, |
197 | .auto_queue = false, |
198 | .wake_capable = false, |
199 | }, |
200 | { |
201 | .name = "QAIC_CONTROL" , |
202 | .num = 11, |
203 | .num_elements = 128, |
204 | .local_elements = 0, |
205 | .event_ring = 0, |
206 | .dir = DMA_FROM_DEVICE, |
207 | .ee_mask = MHI_CH_EE_AMSS, |
208 | .pollcfg = 0, |
209 | .doorbell = MHI_DB_BRST_DISABLE, |
210 | .lpm_notify = false, |
211 | .offload_channel = false, |
212 | .doorbell_mode_switch = false, |
213 | .auto_queue = false, |
214 | .wake_capable = false, |
215 | }, |
216 | { |
217 | .name = "QAIC_LOGGING" , |
218 | .num = 12, |
219 | .num_elements = 32, |
220 | .local_elements = 0, |
221 | .event_ring = 0, |
222 | .dir = DMA_TO_DEVICE, |
223 | .ee_mask = MHI_CH_EE_SBL, |
224 | .pollcfg = 0, |
225 | .doorbell = MHI_DB_BRST_DISABLE, |
226 | .lpm_notify = false, |
227 | .offload_channel = false, |
228 | .doorbell_mode_switch = false, |
229 | .auto_queue = false, |
230 | .wake_capable = false, |
231 | }, |
232 | { |
233 | .name = "QAIC_LOGGING" , |
234 | .num = 13, |
235 | .num_elements = 32, |
236 | .local_elements = 0, |
237 | .event_ring = 0, |
238 | .dir = DMA_FROM_DEVICE, |
239 | .ee_mask = MHI_CH_EE_SBL, |
240 | .pollcfg = 0, |
241 | .doorbell = MHI_DB_BRST_DISABLE, |
242 | .lpm_notify = false, |
243 | .offload_channel = false, |
244 | .doorbell_mode_switch = false, |
245 | .auto_queue = false, |
246 | .wake_capable = false, |
247 | }, |
248 | { |
249 | .name = "QAIC_STATUS" , |
250 | .num = 14, |
251 | .num_elements = 32, |
252 | .local_elements = 0, |
253 | .event_ring = 0, |
254 | .dir = DMA_TO_DEVICE, |
255 | .ee_mask = MHI_CH_EE_AMSS, |
256 | .pollcfg = 0, |
257 | .doorbell = MHI_DB_BRST_DISABLE, |
258 | .lpm_notify = false, |
259 | .offload_channel = false, |
260 | .doorbell_mode_switch = false, |
261 | .auto_queue = false, |
262 | .wake_capable = false, |
263 | }, |
264 | { |
265 | .name = "QAIC_STATUS" , |
266 | .num = 15, |
267 | .num_elements = 32, |
268 | .local_elements = 0, |
269 | .event_ring = 0, |
270 | .dir = DMA_FROM_DEVICE, |
271 | .ee_mask = MHI_CH_EE_AMSS, |
272 | .pollcfg = 0, |
273 | .doorbell = MHI_DB_BRST_DISABLE, |
274 | .lpm_notify = false, |
275 | .offload_channel = false, |
276 | .doorbell_mode_switch = false, |
277 | .auto_queue = false, |
278 | .wake_capable = false, |
279 | }, |
280 | { |
281 | .name = "QAIC_TELEMETRY" , |
282 | .num = 16, |
283 | .num_elements = 32, |
284 | .local_elements = 0, |
285 | .event_ring = 0, |
286 | .dir = DMA_TO_DEVICE, |
287 | .ee_mask = MHI_CH_EE_AMSS, |
288 | .pollcfg = 0, |
289 | .doorbell = MHI_DB_BRST_DISABLE, |
290 | .lpm_notify = false, |
291 | .offload_channel = false, |
292 | .doorbell_mode_switch = false, |
293 | .auto_queue = false, |
294 | .wake_capable = false, |
295 | }, |
296 | { |
297 | .name = "QAIC_TELEMETRY" , |
298 | .num = 17, |
299 | .num_elements = 32, |
300 | .local_elements = 0, |
301 | .event_ring = 0, |
302 | .dir = DMA_FROM_DEVICE, |
303 | .ee_mask = MHI_CH_EE_AMSS, |
304 | .pollcfg = 0, |
305 | .doorbell = MHI_DB_BRST_DISABLE, |
306 | .lpm_notify = false, |
307 | .offload_channel = false, |
308 | .doorbell_mode_switch = false, |
309 | .auto_queue = false, |
310 | .wake_capable = false, |
311 | }, |
312 | { |
313 | .name = "QAIC_DEBUG" , |
314 | .num = 18, |
315 | .num_elements = 32, |
316 | .local_elements = 0, |
317 | .event_ring = 0, |
318 | .dir = DMA_TO_DEVICE, |
319 | .ee_mask = MHI_CH_EE_AMSS, |
320 | .pollcfg = 0, |
321 | .doorbell = MHI_DB_BRST_DISABLE, |
322 | .lpm_notify = false, |
323 | .offload_channel = false, |
324 | .doorbell_mode_switch = false, |
325 | .auto_queue = false, |
326 | .wake_capable = false, |
327 | }, |
328 | { |
329 | .name = "QAIC_DEBUG" , |
330 | .num = 19, |
331 | .num_elements = 32, |
332 | .local_elements = 0, |
333 | .event_ring = 0, |
334 | .dir = DMA_FROM_DEVICE, |
335 | .ee_mask = MHI_CH_EE_AMSS, |
336 | .pollcfg = 0, |
337 | .doorbell = MHI_DB_BRST_DISABLE, |
338 | .lpm_notify = false, |
339 | .offload_channel = false, |
340 | .doorbell_mode_switch = false, |
341 | .auto_queue = false, |
342 | .wake_capable = false, |
343 | }, |
344 | { |
345 | .name = "QAIC_TIMESYNC" , |
346 | .num = 20, |
347 | .num_elements = 32, |
348 | .local_elements = 0, |
349 | .event_ring = 0, |
350 | .dir = DMA_TO_DEVICE, |
351 | .ee_mask = MHI_CH_EE_SBL, |
352 | .pollcfg = 0, |
353 | .doorbell = MHI_DB_BRST_DISABLE, |
354 | .lpm_notify = false, |
355 | .offload_channel = false, |
356 | .doorbell_mode_switch = false, |
357 | .auto_queue = false, |
358 | .wake_capable = false, |
359 | }, |
360 | { |
361 | .name = "QAIC_TIMESYNC" , |
362 | .num = 21, |
363 | .num_elements = 32, |
364 | .local_elements = 0, |
365 | .event_ring = 0, |
366 | .dir = DMA_FROM_DEVICE, |
367 | .ee_mask = MHI_CH_EE_SBL, |
368 | .pollcfg = 0, |
369 | .doorbell = MHI_DB_BRST_DISABLE, |
370 | .lpm_notify = false, |
371 | .offload_channel = false, |
372 | .doorbell_mode_switch = false, |
373 | .auto_queue = false, |
374 | .wake_capable = false, |
375 | }, |
376 | { |
377 | .name = "QAIC_TIMESYNC_PERIODIC" , |
378 | .num = 22, |
379 | .num_elements = 32, |
380 | .local_elements = 0, |
381 | .event_ring = 0, |
382 | .dir = DMA_TO_DEVICE, |
383 | .ee_mask = MHI_CH_EE_AMSS, |
384 | .pollcfg = 0, |
385 | .doorbell = MHI_DB_BRST_DISABLE, |
386 | .lpm_notify = false, |
387 | .offload_channel = false, |
388 | .doorbell_mode_switch = false, |
389 | .auto_queue = false, |
390 | .wake_capable = false, |
391 | }, |
392 | { |
393 | .name = "QAIC_TIMESYNC_PERIODIC" , |
394 | .num = 23, |
395 | .num_elements = 32, |
396 | .local_elements = 0, |
397 | .event_ring = 0, |
398 | .dir = DMA_FROM_DEVICE, |
399 | .ee_mask = MHI_CH_EE_AMSS, |
400 | .pollcfg = 0, |
401 | .doorbell = MHI_DB_BRST_DISABLE, |
402 | .lpm_notify = false, |
403 | .offload_channel = false, |
404 | .doorbell_mode_switch = false, |
405 | .auto_queue = false, |
406 | .wake_capable = false, |
407 | }, |
408 | }; |
409 | |
410 | static struct mhi_event_config aic100_events[] = { |
411 | { |
412 | .num_elements = 32, |
413 | .irq_moderation_ms = 0, |
414 | .irq = 0, |
415 | .channel = U32_MAX, |
416 | .priority = 1, |
417 | .mode = MHI_DB_BRST_DISABLE, |
418 | .data_type = MHI_ER_CTRL, |
419 | .hardware_event = false, |
420 | .client_managed = false, |
421 | .offload_channel = false, |
422 | }, |
423 | }; |
424 | |
425 | static struct mhi_controller_config aic100_config = { |
426 | .max_channels = 128, |
427 | .timeout_ms = 0, /* controlled by mhi_timeout */ |
428 | .buf_len = 0, |
429 | .num_channels = ARRAY_SIZE(aic100_channels), |
430 | .ch_cfg = aic100_channels, |
431 | .num_events = ARRAY_SIZE(aic100_events), |
432 | .event_cfg = aic100_events, |
433 | .use_bounce_buf = false, |
434 | .m2_no_db = false, |
435 | }; |
436 | |
437 | static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out) |
438 | { |
439 | u32 tmp; |
440 | |
441 | /* |
442 | * SOC_HW_VERSION quirk |
443 | * The SOC_HW_VERSION register (offset 0x224) is not reliable and |
444 | * may contain uninitialized values, including 0xFFFFFFFF. This could |
445 | * cause a false positive link down error. Instead, intercept any |
446 | * reads and provide the correct value of the register. |
447 | */ |
448 | if (addr - mhi_cntrl->regs == 0x224) { |
449 | *out = 0x60110200; |
450 | return 0; |
451 | } |
452 | |
453 | tmp = readl_relaxed(addr); |
454 | if (tmp == U32_MAX) |
455 | return -EIO; |
456 | |
457 | *out = tmp; |
458 | |
459 | return 0; |
460 | } |
461 | |
462 | static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val) |
463 | { |
464 | writel_relaxed(val, addr); |
465 | } |
466 | |
467 | static int mhi_runtime_get(struct mhi_controller *mhi_cntrl) |
468 | { |
469 | return 0; |
470 | } |
471 | |
472 | static void mhi_runtime_put(struct mhi_controller *mhi_cntrl) |
473 | { |
474 | } |
475 | |
476 | static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason) |
477 | { |
478 | struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev)); |
479 | |
480 | /* this event occurs in atomic context */ |
481 | if (reason == MHI_CB_FATAL_ERROR) |
482 | pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n" ); |
483 | /* this event occurs in non-atomic context */ |
484 | if (reason == MHI_CB_SYS_ERROR) |
485 | qaic_dev_reset_clean_local_state(qdev); |
486 | } |
487 | |
488 | static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) |
489 | { |
490 | u8 time_sec = 1; |
491 | int current_ee; |
492 | int ret; |
493 | |
494 | /* Reset the device to bring the device in PBL EE */ |
495 | mhi_soc_reset(mhi_cntrl); |
496 | |
497 | /* |
498 | * Keep checking the execution environment(EE) after every 1 second |
499 | * interval. |
500 | */ |
501 | do { |
502 | msleep(msecs: 1000); |
503 | current_ee = mhi_get_exec_env(mhi_cntrl); |
504 | } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC); |
505 | |
506 | /* If the device is in PBL EE retry power up */ |
507 | if (current_ee == MHI_EE_PBL) |
508 | ret = mhi_async_power_up(mhi_cntrl); |
509 | else |
510 | ret = -EIO; |
511 | |
512 | return ret; |
513 | } |
514 | |
515 | struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar, |
516 | int mhi_irq, bool shared_msi) |
517 | { |
518 | struct mhi_controller *mhi_cntrl; |
519 | int ret; |
520 | |
521 | mhi_cntrl = devm_kzalloc(dev: &pci_dev->dev, size: sizeof(*mhi_cntrl), GFP_KERNEL); |
522 | if (!mhi_cntrl) |
523 | return ERR_PTR(error: -ENOMEM); |
524 | |
525 | mhi_cntrl->cntrl_dev = &pci_dev->dev; |
526 | |
527 | /* |
528 | * Covers the entire possible physical ram region. Remote side is |
529 | * going to calculate a size of this range, so subtract 1 to prevent |
530 | * rollover. |
531 | */ |
532 | mhi_cntrl->iova_start = 0; |
533 | mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1; |
534 | mhi_cntrl->status_cb = mhi_status_cb; |
535 | mhi_cntrl->runtime_get = mhi_runtime_get; |
536 | mhi_cntrl->runtime_put = mhi_runtime_put; |
537 | mhi_cntrl->read_reg = mhi_read_reg; |
538 | mhi_cntrl->write_reg = mhi_write_reg; |
539 | mhi_cntrl->regs = mhi_bar; |
540 | mhi_cntrl->reg_len = SZ_4K; |
541 | mhi_cntrl->nr_irqs = 1; |
542 | mhi_cntrl->irq = devm_kmalloc(dev: &pci_dev->dev, size: sizeof(*mhi_cntrl->irq), GFP_KERNEL); |
543 | |
544 | if (!mhi_cntrl->irq) |
545 | return ERR_PTR(error: -ENOMEM); |
546 | |
547 | mhi_cntrl->irq[0] = mhi_irq; |
548 | |
549 | if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */ |
550 | mhi_cntrl->irq_flags = IRQF_SHARED; |
551 | |
552 | mhi_cntrl->fw_image = "qcom/aic100/sbl.bin" ; |
553 | |
554 | /* use latest configured timeout */ |
555 | aic100_config.timeout_ms = mhi_timeout_ms; |
556 | ret = mhi_register_controller(mhi_cntrl, config: &aic100_config); |
557 | if (ret) { |
558 | pci_err(pci_dev, "mhi_register_controller failed %d\n" , ret); |
559 | return ERR_PTR(error: ret); |
560 | } |
561 | |
562 | ret = mhi_prepare_for_power_up(mhi_cntrl); |
563 | if (ret) { |
564 | pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n" , ret); |
565 | goto prepare_power_up_fail; |
566 | } |
567 | |
568 | ret = mhi_async_power_up(mhi_cntrl); |
569 | /* |
570 | * If EIO is returned it is possible that device is in SBL EE, which is |
571 | * undesired. SOC reset the device and try to power up again. |
572 | */ |
573 | if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) { |
574 | pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n" ); |
575 | ret = mhi_reset_and_async_power_up(mhi_cntrl); |
576 | } |
577 | |
578 | if (ret) { |
579 | pci_err(pci_dev, "mhi_async_power_up failed %d\n" , ret); |
580 | goto power_up_fail; |
581 | } |
582 | |
583 | return mhi_cntrl; |
584 | |
585 | power_up_fail: |
586 | mhi_unprepare_after_power_down(mhi_cntrl); |
587 | prepare_power_up_fail: |
588 | mhi_unregister_controller(mhi_cntrl); |
589 | return ERR_PTR(error: ret); |
590 | } |
591 | |
592 | void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up) |
593 | { |
594 | mhi_power_down(mhi_cntrl, graceful: link_up); |
595 | mhi_unprepare_after_power_down(mhi_cntrl); |
596 | mhi_unregister_controller(mhi_cntrl); |
597 | } |
598 | |
599 | void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl) |
600 | { |
601 | mhi_power_down(mhi_cntrl, graceful: true); |
602 | } |
603 | |
604 | void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl) |
605 | { |
606 | struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev); |
607 | int ret; |
608 | |
609 | ret = mhi_async_power_up(mhi_cntrl); |
610 | if (ret) |
611 | pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n" , ret); |
612 | } |
613 | |