1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #include <linux/msi.h> 8 #include <linux/pci.h> 9 #include <linux/firmware.h> 10 11 #include "core.h" 12 #include "debug.h" 13 #include "mhi.h" 14 #include "pci.h" 15 16 #define MHI_TIMEOUT_DEFAULT_MS 90000 17 #define OTP_INVALID_BOARD_ID 0xFFFF 18 #define OTP_VALID_DUALMAC_BOARD_ID_MASK 0x1000 19 20 static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = { 21 { 22 .num = 0, 23 .name = "LOOPBACK", 24 .num_elements = 32, 25 .event_ring = 1, 26 .dir = DMA_TO_DEVICE, 27 .ee_mask = 0x4, 28 .pollcfg = 0, 29 .doorbell = MHI_DB_BRST_DISABLE, 30 .lpm_notify = false, 31 .offload_channel = false, 32 .doorbell_mode_switch = false, 33 .auto_queue = false, 34 }, 35 { 36 .num = 1, 37 .name = "LOOPBACK", 38 .num_elements = 32, 39 .event_ring = 1, 40 .dir = DMA_FROM_DEVICE, 41 .ee_mask = 0x4, 42 .pollcfg = 0, 43 .doorbell = MHI_DB_BRST_DISABLE, 44 .lpm_notify = false, 45 .offload_channel = false, 46 .doorbell_mode_switch = false, 47 .auto_queue = false, 48 }, 49 { 50 .num = 20, 51 .name = "IPCR", 52 .num_elements = 32, 53 .event_ring = 1, 54 .dir = DMA_TO_DEVICE, 55 .ee_mask = 0x4, 56 .pollcfg = 0, 57 .doorbell = MHI_DB_BRST_DISABLE, 58 .lpm_notify = false, 59 .offload_channel = false, 60 .doorbell_mode_switch = false, 61 .auto_queue = false, 62 }, 63 { 64 .num = 21, 65 .name = "IPCR", 66 .num_elements = 32, 67 .event_ring = 1, 68 .dir = DMA_FROM_DEVICE, 69 .ee_mask = 0x4, 70 .pollcfg = 0, 71 .doorbell = MHI_DB_BRST_DISABLE, 72 .lpm_notify = false, 73 .offload_channel = false, 74 .doorbell_mode_switch = false, 75 .auto_queue = true, 76 }, 77 }; 78 79 static struct mhi_event_config ath12k_mhi_events_qcn9274[] = { 80 { 81 .num_elements = 32, 82 .irq_moderation_ms = 0, 83 .irq = 1, 84 .data_type = MHI_ER_CTRL, 85 .mode = MHI_DB_BRST_DISABLE, 86 .hardware_event = false, 87 .client_managed = false, 88 .offload_channel = false, 89 }, 90 { 91 .num_elements = 256, 92 .irq_moderation_ms = 1, 93 .irq = 2, 94 .mode = MHI_DB_BRST_DISABLE, 95 .priority = 1, 96 .hardware_event = false, 97 .client_managed = false, 98 .offload_channel = false, 99 }, 100 }; 101 102 const struct mhi_controller_config ath12k_mhi_config_qcn9274 = { 103 .max_channels = 30, 104 .timeout_ms = 10000, 105 .use_bounce_buf = false, 106 .buf_len = 0, 107 .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274), 108 .ch_cfg = ath12k_mhi_channels_qcn9274, 109 .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274), 110 .event_cfg = ath12k_mhi_events_qcn9274, 111 }; 112 113 static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = { 114 { 115 .num = 0, 116 .name = "LOOPBACK", 117 .num_elements = 32, 118 .event_ring = 0, 119 .dir = DMA_TO_DEVICE, 120 .ee_mask = 0x4, 121 .pollcfg = 0, 122 .doorbell = MHI_DB_BRST_DISABLE, 123 .lpm_notify = false, 124 .offload_channel = false, 125 .doorbell_mode_switch = false, 126 .auto_queue = false, 127 }, 128 { 129 .num = 1, 130 .name = "LOOPBACK", 131 .num_elements = 32, 132 .event_ring = 0, 133 .dir = DMA_FROM_DEVICE, 134 .ee_mask = 0x4, 135 .pollcfg = 0, 136 .doorbell = MHI_DB_BRST_DISABLE, 137 .lpm_notify = false, 138 .offload_channel = false, 139 .doorbell_mode_switch = false, 140 .auto_queue = false, 141 }, 142 { 143 .num = 20, 144 .name = "IPCR", 145 .num_elements = 64, 146 .event_ring = 1, 147 .dir = DMA_TO_DEVICE, 148 .ee_mask = 0x4, 149 .pollcfg = 0, 150 .doorbell = MHI_DB_BRST_DISABLE, 151 .lpm_notify = false, 152 .offload_channel = false, 153 .doorbell_mode_switch = false, 154 .auto_queue = false, 155 }, 156 { 157 .num = 21, 158 .name = "IPCR", 159 .num_elements = 64, 160 .event_ring = 1, 161 .dir = DMA_FROM_DEVICE, 162 .ee_mask = 0x4, 163 .pollcfg = 0, 164 .doorbell = MHI_DB_BRST_DISABLE, 165 .lpm_notify = false, 166 .offload_channel = false, 167 .doorbell_mode_switch = false, 168 .auto_queue = true, 169 }, 170 }; 171 172 static struct mhi_event_config ath12k_mhi_events_wcn7850[] = { 173 { 174 .num_elements = 32, 175 .irq_moderation_ms = 0, 176 .irq = 1, 177 .mode = MHI_DB_BRST_DISABLE, 178 .data_type = MHI_ER_CTRL, 179 .hardware_event = false, 180 .client_managed = false, 181 .offload_channel = false, 182 }, 183 { 184 .num_elements = 256, 185 .irq_moderation_ms = 1, 186 .irq = 2, 187 .mode = MHI_DB_BRST_DISABLE, 188 .priority = 1, 189 .hardware_event = false, 190 .client_managed = false, 191 .offload_channel = false, 192 }, 193 }; 194 195 const struct mhi_controller_config ath12k_mhi_config_wcn7850 = { 196 .max_channels = 128, 197 .timeout_ms = 2000, 198 .use_bounce_buf = false, 199 .buf_len = 0, 200 .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850), 201 .ch_cfg = ath12k_mhi_channels_wcn7850, 202 .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850), 203 .event_cfg = ath12k_mhi_events_wcn7850, 204 }; 205 206 void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab) 207 { 208 u32 val; 209 210 val = ath12k_pci_read32(ab, MHISTATUS); 211 212 ath12k_dbg(ab, ATH12K_DBG_PCI, "MHISTATUS 0x%x\n", val); 213 214 /* Observed on some targets that after SOC_GLOBAL_RESET, MHISTATUS 215 * has SYSERR bit set and thus need to set MHICTRL_RESET 216 * to clear SYSERR. 217 */ 218 ath12k_pci_write32(ab, MHICTRL, MHICTRL_RESET_MASK); 219 220 mdelay(10); 221 } 222 223 static void ath12k_mhi_reset_txvecdb(struct ath12k_base *ab) 224 { 225 ath12k_pci_write32(ab, PCIE_TXVECDB, 0); 226 } 227 228 static void ath12k_mhi_reset_txvecstatus(struct ath12k_base *ab) 229 { 230 ath12k_pci_write32(ab, PCIE_TXVECSTATUS, 0); 231 } 232 233 static void ath12k_mhi_reset_rxvecdb(struct ath12k_base *ab) 234 { 235 ath12k_pci_write32(ab, PCIE_RXVECDB, 0); 236 } 237 238 static void ath12k_mhi_reset_rxvecstatus(struct ath12k_base *ab) 239 { 240 ath12k_pci_write32(ab, PCIE_RXVECSTATUS, 0); 241 } 242 243 void ath12k_mhi_clear_vector(struct ath12k_base *ab) 244 { 245 ath12k_mhi_reset_txvecdb(ab); 246 ath12k_mhi_reset_txvecstatus(ab); 247 ath12k_mhi_reset_rxvecdb(ab); 248 ath12k_mhi_reset_rxvecstatus(ab); 249 } 250 251 static int ath12k_mhi_get_msi(struct ath12k_pci *ab_pci) 252 { 253 struct ath12k_base *ab = ab_pci->ab; 254 u32 user_base_data, base_vector; 255 int ret, num_vectors, i; 256 int *irq; 257 unsigned int msi_data; 258 259 ret = ath12k_pci_get_user_msi_assignment(ab, 260 "MHI", &num_vectors, 261 &user_base_data, &base_vector); 262 if (ret) 263 return ret; 264 265 ath12k_dbg(ab, ATH12K_DBG_PCI, "Number of assigned MSI for MHI is %d, base vector is %d\n", 266 num_vectors, base_vector); 267 268 irq = kcalloc(num_vectors, sizeof(*irq), GFP_KERNEL); 269 if (!irq) 270 return -ENOMEM; 271 272 msi_data = base_vector; 273 for (i = 0; i < num_vectors; i++) { 274 if (test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) 275 irq[i] = ath12k_pci_get_msi_irq(ab->dev, 276 msi_data++); 277 else 278 irq[i] = ath12k_pci_get_msi_irq(ab->dev, 279 msi_data); 280 } 281 282 ab_pci->mhi_ctrl->irq = irq; 283 ab_pci->mhi_ctrl->nr_irqs = num_vectors; 284 285 return 0; 286 } 287 288 static int ath12k_mhi_op_runtime_get(struct mhi_controller *mhi_cntrl) 289 { 290 return 0; 291 } 292 293 static void ath12k_mhi_op_runtime_put(struct mhi_controller *mhi_cntrl) 294 { 295 } 296 297 static char *ath12k_mhi_op_callback_to_str(enum mhi_callback reason) 298 { 299 switch (reason) { 300 case MHI_CB_IDLE: 301 return "MHI_CB_IDLE"; 302 case MHI_CB_PENDING_DATA: 303 return "MHI_CB_PENDING_DATA"; 304 case MHI_CB_LPM_ENTER: 305 return "MHI_CB_LPM_ENTER"; 306 case MHI_CB_LPM_EXIT: 307 return "MHI_CB_LPM_EXIT"; 308 case MHI_CB_EE_RDDM: 309 return "MHI_CB_EE_RDDM"; 310 case MHI_CB_EE_MISSION_MODE: 311 return "MHI_CB_EE_MISSION_MODE"; 312 case MHI_CB_SYS_ERROR: 313 return "MHI_CB_SYS_ERROR"; 314 case MHI_CB_FATAL_ERROR: 315 return "MHI_CB_FATAL_ERROR"; 316 case MHI_CB_BW_REQ: 317 return "MHI_CB_BW_REQ"; 318 default: 319 return "UNKNOWN"; 320 } 321 } 322 323 static void ath12k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl, 324 enum mhi_callback cb) 325 { 326 struct ath12k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev); 327 328 ath12k_dbg(ab, ATH12K_DBG_BOOT, "mhi notify status reason %s\n", 329 ath12k_mhi_op_callback_to_str(cb)); 330 331 switch (cb) { 332 case MHI_CB_SYS_ERROR: 333 ath12k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n"); 334 break; 335 case MHI_CB_EE_RDDM: 336 if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))) 337 queue_work(ab->workqueue_aux, &ab->reset_work); 338 break; 339 default: 340 break; 341 } 342 } 343 344 static int ath12k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, 345 void __iomem *addr, 346 u32 *out) 347 { 348 *out = readl(addr); 349 350 return 0; 351 } 352 353 static void ath12k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, 354 void __iomem *addr, 355 u32 val) 356 { 357 writel(val, addr); 358 } 359 360 int ath12k_mhi_register(struct ath12k_pci *ab_pci) 361 { 362 struct ath12k_base *ab = ab_pci->ab; 363 struct mhi_controller *mhi_ctrl; 364 unsigned int board_id; 365 int ret; 366 bool dualmac = false; 367 368 mhi_ctrl = mhi_alloc_controller(); 369 if (!mhi_ctrl) 370 return -ENOMEM; 371 372 ab_pci->mhi_ctrl = mhi_ctrl; 373 mhi_ctrl->cntrl_dev = ab->dev; 374 mhi_ctrl->regs = ab->mem; 375 mhi_ctrl->reg_len = ab->mem_len; 376 mhi_ctrl->rddm_size = ab->hw_params->rddm_size; 377 378 if (ab->hw_params->otp_board_id_register) { 379 board_id = 380 ath12k_pci_read32(ab, ab->hw_params->otp_board_id_register); 381 board_id = u32_get_bits(board_id, OTP_BOARD_ID_MASK); 382 383 if (!board_id || (board_id == OTP_INVALID_BOARD_ID)) { 384 ath12k_dbg(ab, ATH12K_DBG_BOOT, 385 "failed to read board id\n"); 386 } else if (board_id & OTP_VALID_DUALMAC_BOARD_ID_MASK) { 387 dualmac = true; 388 ab->slo_capable = false; 389 ath12k_dbg(ab, ATH12K_DBG_BOOT, 390 "dualmac fw selected for board id: %x\n", board_id); 391 } 392 } 393 394 if (dualmac) { 395 if (ab->fw.amss_dualmac_data && ab->fw.amss_dualmac_len > 0) { 396 /* use MHI firmware file from firmware-N.bin */ 397 mhi_ctrl->fw_data = ab->fw.amss_dualmac_data; 398 mhi_ctrl->fw_sz = ab->fw.amss_dualmac_len; 399 } else { 400 ath12k_warn(ab, "dualmac firmware IE not present in firmware-N.bin\n"); 401 ret = -ENOENT; 402 goto free_controller; 403 } 404 } else { 405 if (ab->fw.amss_data && ab->fw.amss_len > 0) { 406 /* use MHI firmware file from firmware-N.bin */ 407 mhi_ctrl->fw_data = ab->fw.amss_data; 408 mhi_ctrl->fw_sz = ab->fw.amss_len; 409 } else { 410 /* use the old separate mhi.bin MHI firmware file */ 411 ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE, 412 ab_pci->amss_path, 413 sizeof(ab_pci->amss_path)); 414 mhi_ctrl->fw_image = ab_pci->amss_path; 415 } 416 } 417 418 ret = ath12k_mhi_get_msi(ab_pci); 419 if (ret) { 420 ath12k_err(ab, "failed to get msi for mhi\n"); 421 goto free_controller; 422 } 423 424 if (!test_bit(ATH12K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) 425 mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; 426 427 mhi_ctrl->iova_start = 0; 428 mhi_ctrl->iova_stop = 0xffffffff; 429 mhi_ctrl->sbl_size = SZ_512K; 430 mhi_ctrl->seg_len = SZ_512K; 431 mhi_ctrl->fbc_download = true; 432 mhi_ctrl->runtime_get = ath12k_mhi_op_runtime_get; 433 mhi_ctrl->runtime_put = ath12k_mhi_op_runtime_put; 434 mhi_ctrl->status_cb = ath12k_mhi_op_status_cb; 435 mhi_ctrl->read_reg = ath12k_mhi_op_read_reg; 436 mhi_ctrl->write_reg = ath12k_mhi_op_write_reg; 437 438 ret = mhi_register_controller(mhi_ctrl, ab->hw_params->mhi_config); 439 if (ret) { 440 ath12k_err(ab, "failed to register to mhi bus, err = %d\n", ret); 441 goto free_controller; 442 } 443 444 return 0; 445 446 free_controller: 447 mhi_free_controller(mhi_ctrl); 448 ab_pci->mhi_ctrl = NULL; 449 return ret; 450 } 451 452 void ath12k_mhi_unregister(struct ath12k_pci *ab_pci) 453 { 454 struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl; 455 456 mhi_unregister_controller(mhi_ctrl); 457 kfree(mhi_ctrl->irq); 458 mhi_free_controller(mhi_ctrl); 459 ab_pci->mhi_ctrl = NULL; 460 } 461 462 static char *ath12k_mhi_state_to_str(enum ath12k_mhi_state mhi_state) 463 { 464 switch (mhi_state) { 465 case ATH12K_MHI_INIT: 466 return "INIT"; 467 case ATH12K_MHI_DEINIT: 468 return "DEINIT"; 469 case ATH12K_MHI_POWER_ON: 470 return "POWER_ON"; 471 case ATH12K_MHI_POWER_OFF: 472 return "POWER_OFF"; 473 case ATH12K_MHI_FORCE_POWER_OFF: 474 return "FORCE_POWER_OFF"; 475 case ATH12K_MHI_SUSPEND: 476 return "SUSPEND"; 477 case ATH12K_MHI_RESUME: 478 return "RESUME"; 479 case ATH12K_MHI_TRIGGER_RDDM: 480 return "TRIGGER_RDDM"; 481 case ATH12K_MHI_RDDM_DONE: 482 return "RDDM_DONE"; 483 default: 484 return "UNKNOWN"; 485 } 486 }; 487 488 static void ath12k_mhi_set_state_bit(struct ath12k_pci *ab_pci, 489 enum ath12k_mhi_state mhi_state) 490 { 491 struct ath12k_base *ab = ab_pci->ab; 492 493 switch (mhi_state) { 494 case ATH12K_MHI_INIT: 495 set_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state); 496 break; 497 case ATH12K_MHI_DEINIT: 498 clear_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state); 499 break; 500 case ATH12K_MHI_POWER_ON: 501 set_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state); 502 break; 503 case ATH12K_MHI_POWER_OFF: 504 case ATH12K_MHI_FORCE_POWER_OFF: 505 clear_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state); 506 clear_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state); 507 clear_bit(ATH12K_MHI_RDDM_DONE, &ab_pci->mhi_state); 508 break; 509 case ATH12K_MHI_SUSPEND: 510 set_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state); 511 break; 512 case ATH12K_MHI_RESUME: 513 clear_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state); 514 break; 515 case ATH12K_MHI_TRIGGER_RDDM: 516 set_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state); 517 break; 518 case ATH12K_MHI_RDDM_DONE: 519 set_bit(ATH12K_MHI_RDDM_DONE, &ab_pci->mhi_state); 520 break; 521 default: 522 ath12k_err(ab, "unhandled mhi state (%d)\n", mhi_state); 523 } 524 } 525 526 static int ath12k_mhi_check_state_bit(struct ath12k_pci *ab_pci, 527 enum ath12k_mhi_state mhi_state) 528 { 529 struct ath12k_base *ab = ab_pci->ab; 530 531 switch (mhi_state) { 532 case ATH12K_MHI_INIT: 533 if (!test_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state)) 534 return 0; 535 break; 536 case ATH12K_MHI_DEINIT: 537 case ATH12K_MHI_POWER_ON: 538 if (test_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state) && 539 !test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state)) 540 return 0; 541 break; 542 case ATH12K_MHI_FORCE_POWER_OFF: 543 if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state)) 544 return 0; 545 break; 546 case ATH12K_MHI_POWER_OFF: 547 case ATH12K_MHI_SUSPEND: 548 if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state) && 549 !test_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state)) 550 return 0; 551 break; 552 case ATH12K_MHI_RESUME: 553 if (test_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state)) 554 return 0; 555 break; 556 case ATH12K_MHI_TRIGGER_RDDM: 557 if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state) && 558 !test_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state)) 559 return 0; 560 break; 561 case ATH12K_MHI_RDDM_DONE: 562 return 0; 563 default: 564 ath12k_err(ab, "unhandled mhi state: %s(%d)\n", 565 ath12k_mhi_state_to_str(mhi_state), mhi_state); 566 } 567 568 ath12k_err(ab, "failed to set mhi state %s(%d) in current mhi state (0x%lx)\n", 569 ath12k_mhi_state_to_str(mhi_state), mhi_state, 570 ab_pci->mhi_state); 571 572 return -EINVAL; 573 } 574 575 static int ath12k_mhi_set_state(struct ath12k_pci *ab_pci, 576 enum ath12k_mhi_state mhi_state) 577 { 578 struct ath12k_base *ab = ab_pci->ab; 579 int ret; 580 581 ret = ath12k_mhi_check_state_bit(ab_pci, mhi_state); 582 if (ret) 583 goto out; 584 585 ath12k_dbg(ab, ATH12K_DBG_PCI, "setting mhi state: %s(%d)\n", 586 ath12k_mhi_state_to_str(mhi_state), mhi_state); 587 588 switch (mhi_state) { 589 case ATH12K_MHI_INIT: 590 ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl); 591 break; 592 case ATH12K_MHI_DEINIT: 593 mhi_unprepare_after_power_down(ab_pci->mhi_ctrl); 594 ret = 0; 595 break; 596 case ATH12K_MHI_POWER_ON: 597 ret = mhi_async_power_up(ab_pci->mhi_ctrl); 598 break; 599 case ATH12K_MHI_POWER_OFF: 600 mhi_power_down(ab_pci->mhi_ctrl, true); 601 ret = 0; 602 break; 603 case ATH12K_MHI_FORCE_POWER_OFF: 604 mhi_power_down(ab_pci->mhi_ctrl, false); 605 ret = 0; 606 break; 607 case ATH12K_MHI_SUSPEND: 608 ret = mhi_pm_suspend(ab_pci->mhi_ctrl); 609 break; 610 case ATH12K_MHI_RESUME: 611 ret = mhi_pm_resume(ab_pci->mhi_ctrl); 612 break; 613 case ATH12K_MHI_TRIGGER_RDDM: 614 ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); 615 break; 616 case ATH12K_MHI_RDDM_DONE: 617 break; 618 default: 619 ath12k_err(ab, "unhandled MHI state (%d)\n", mhi_state); 620 ret = -EINVAL; 621 } 622 623 if (ret) 624 goto out; 625 626 ath12k_mhi_set_state_bit(ab_pci, mhi_state); 627 628 return 0; 629 630 out: 631 ath12k_err(ab, "failed to set mhi state: %s(%d)\n", 632 ath12k_mhi_state_to_str(mhi_state), mhi_state); 633 return ret; 634 } 635 636 int ath12k_mhi_start(struct ath12k_pci *ab_pci) 637 { 638 int ret; 639 640 ab_pci->mhi_ctrl->timeout_ms = MHI_TIMEOUT_DEFAULT_MS; 641 642 ret = ath12k_mhi_set_state(ab_pci, ATH12K_MHI_INIT); 643 if (ret) 644 goto out; 645 646 ret = ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_ON); 647 if (ret) 648 goto out; 649 650 return 0; 651 652 out: 653 return ret; 654 } 655 656 void ath12k_mhi_stop(struct ath12k_pci *ab_pci) 657 { 658 ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF); 659 ath12k_mhi_set_state(ab_pci, ATH12K_MHI_DEINIT); 660 } 661 662 void ath12k_mhi_suspend(struct ath12k_pci *ab_pci) 663 { 664 ath12k_mhi_set_state(ab_pci, ATH12K_MHI_SUSPEND); 665 } 666 667 void ath12k_mhi_resume(struct ath12k_pci *ab_pci) 668 { 669 ath12k_mhi_set_state(ab_pci, ATH12K_MHI_RESUME); 670 } 671