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