1 /* 2 * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* this file dispatches functions to bus specific definitions */ 21 #include "hif_debug.h" 22 #include "hif.h" 23 #include "hif_main.h" 24 #include "hif_io32.h" 25 #include "multibus.h" 26 #include "dummy.h" 27 #if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ 28 defined(HIF_IPCI) 29 #include "ce_main.h" 30 #include "ce_api.h" 31 #include "ce_internal.h" 32 #endif 33 #include "htc_services.h" 34 #include "a_types.h" 35 #include "dummy.h" 36 #include "qdf_module.h" 37 38 /** 39 * hif_initialize_default_ops() - initializes default operations values 40 * 41 * bus specific features should assign their dummy implementations here. 42 */ 43 static void hif_initialize_default_ops(struct hif_softc *hif_sc) 44 { 45 struct hif_bus_ops *bus_ops = &hif_sc->bus_ops; 46 47 /* must be filled in by hif_bus_open */ 48 bus_ops->hif_bus_close = NULL; 49 /* dummy implementations */ 50 bus_ops->hif_display_stats = 51 &hif_dummy_display_stats; 52 bus_ops->hif_clear_stats = 53 &hif_dummy_clear_stats; 54 bus_ops->hif_set_bundle_mode = &hif_dummy_set_bundle_mode; 55 bus_ops->hif_bus_reset_resume = &hif_dummy_bus_reset_resume; 56 bus_ops->hif_bus_suspend_noirq = &hif_dummy_bus_suspend_noirq; 57 bus_ops->hif_bus_resume_noirq = &hif_dummy_bus_resume_noirq; 58 bus_ops->hif_bus_early_suspend = &hif_dummy_bus_suspend; 59 bus_ops->hif_bus_late_resume = &hif_dummy_bus_resume; 60 bus_ops->hif_map_ce_to_irq = &hif_dummy_map_ce_to_irq; 61 bus_ops->hif_grp_irq_configure = &hif_dummy_grp_irq_configure; 62 bus_ops->hif_grp_irq_deconfigure = &hif_dummy_grp_irq_deconfigure; 63 bus_ops->hif_config_irq_affinity = 64 &hif_dummy_config_irq_affinity; 65 bus_ops->hif_config_irq_by_ceid = &hif_dummy_config_irq_by_ceid; 66 bus_ops->hif_enable_grp_irqs = &hif_dummy_enable_grp_irqs; 67 bus_ops->hif_disable_grp_irqs = &hif_dummy_enable_grp_irqs; 68 bus_ops->hif_config_irq_clear_cpu_affinity = 69 &hif_dummy_config_irq_clear_cpu_affinity; 70 #ifdef FEATURE_IRQ_AFFINITY 71 bus_ops->hif_set_grp_intr_affinity = &hif_dummy_set_grp_intr_affinity; 72 #endif 73 } 74 75 #define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *)) 76 77 /** 78 * hif_verify_basic_ops() - ensure required bus apis are defined 79 * 80 * all bus operations must be defined to avoid crashes 81 * itterate over the structure and ensure all function pointers 82 * are non null. 83 * 84 * Return: QDF_STATUS_SUCCESS if all the operations are defined 85 */ 86 static QDF_STATUS hif_verify_basic_ops(struct hif_softc *hif_sc) 87 { 88 struct hif_bus_ops *bus_ops = &hif_sc->bus_ops; 89 void **ops_array = (void *)bus_ops; 90 QDF_STATUS status = QDF_STATUS_SUCCESS; 91 int i; 92 93 for (i = 0; i < NUM_OPS; i++) { 94 if (!ops_array[i]) { 95 hif_err("ops_array[%d] is null", i); 96 status = QDF_STATUS_E_NOSUPPORT; 97 } 98 } 99 return status; 100 } 101 102 /** 103 * hif_bus_get_context_size - API to return size of the bus specific structure 104 * 105 * Return: sizeof of hif_pci_softc 106 */ 107 int hif_bus_get_context_size(enum qdf_bus_type bus_type) 108 { 109 switch (bus_type) { 110 case QDF_BUS_TYPE_PCI: 111 return hif_pci_get_context_size(); 112 case QDF_BUS_TYPE_IPCI: 113 return hif_ipci_get_context_size(); 114 case QDF_BUS_TYPE_AHB: 115 return hif_ahb_get_context_size(); 116 case QDF_BUS_TYPE_SNOC: 117 return hif_snoc_get_context_size(); 118 case QDF_BUS_TYPE_SDIO: 119 return hif_sdio_get_context_size(); 120 case QDF_BUS_TYPE_USB: 121 return hif_usb_get_context_size(); 122 default: 123 return 0; 124 } 125 } 126 127 /** 128 * hif_bus_open() - initialize the bus_ops and call the bus specific open 129 * hif_sc: hif_context 130 * bus_type: type of bus being enumerated 131 * 132 * Return: QDF_STATUS_SUCCESS or error 133 */ 134 QDF_STATUS hif_bus_open(struct hif_softc *hif_sc, 135 enum qdf_bus_type bus_type) 136 { 137 QDF_STATUS status = QDF_STATUS_E_INVAL; 138 139 hif_initialize_default_ops(hif_sc); 140 141 switch (bus_type) { 142 case QDF_BUS_TYPE_PCI: 143 status = hif_initialize_pci_ops(hif_sc); 144 break; 145 case QDF_BUS_TYPE_IPCI: 146 status = hif_initialize_ipci_ops(hif_sc); 147 break; 148 case QDF_BUS_TYPE_SNOC: 149 status = hif_initialize_snoc_ops(&hif_sc->bus_ops); 150 break; 151 case QDF_BUS_TYPE_AHB: 152 status = hif_initialize_ahb_ops(&hif_sc->bus_ops); 153 break; 154 case QDF_BUS_TYPE_SDIO: 155 status = hif_initialize_sdio_ops(hif_sc); 156 break; 157 case QDF_BUS_TYPE_USB: 158 status = hif_initialize_usb_ops(&hif_sc->bus_ops); 159 break; 160 default: 161 status = QDF_STATUS_E_NOSUPPORT; 162 break; 163 } 164 165 if (status != QDF_STATUS_SUCCESS) { 166 hif_err("bus_type: %d not supported", bus_type); 167 return status; 168 } 169 170 status = hif_verify_basic_ops(hif_sc); 171 if (status != QDF_STATUS_SUCCESS) 172 return status; 173 174 return hif_sc->bus_ops.hif_bus_open(hif_sc, bus_type); 175 } 176 177 /** 178 * hif_bus_close() - close the bus 179 * @hif_sc: hif_context 180 */ 181 void hif_bus_close(struct hif_softc *hif_sc) 182 { 183 hif_sc->bus_ops.hif_bus_close(hif_sc); 184 } 185 186 /** 187 * hif_bus_prevent_linkdown() - prevent linkdown 188 * @hif_ctx: hif context 189 * @flag: true = keep bus alive false = let bus go to sleep 190 * 191 * Keeps the bus awake durring suspend. 192 */ 193 void hif_bus_prevent_linkdown(struct hif_softc *hif_sc, bool flag) 194 { 195 hif_sc->bus_ops.hif_bus_prevent_linkdown(hif_sc, flag); 196 } 197 198 199 void hif_reset_soc(struct hif_opaque_softc *hif_ctx) 200 { 201 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 202 203 hif_sc->bus_ops.hif_reset_soc(hif_sc); 204 } 205 206 int hif_bus_early_suspend(struct hif_opaque_softc *hif_ctx) 207 { 208 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 209 210 return hif_sc->bus_ops.hif_bus_early_suspend(hif_sc); 211 } 212 213 int hif_bus_late_resume(struct hif_opaque_softc *hif_ctx) 214 { 215 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 216 217 return hif_sc->bus_ops.hif_bus_late_resume(hif_sc); 218 } 219 220 int hif_bus_suspend(struct hif_opaque_softc *hif_ctx) 221 { 222 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 223 224 return hif_sc->bus_ops.hif_bus_suspend(hif_sc); 225 } 226 227 int hif_bus_resume(struct hif_opaque_softc *hif_ctx) 228 { 229 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 230 231 return hif_sc->bus_ops.hif_bus_resume(hif_sc); 232 } 233 234 int hif_bus_suspend_noirq(struct hif_opaque_softc *hif_ctx) 235 { 236 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 237 238 return hif_sc->bus_ops.hif_bus_suspend_noirq(hif_sc); 239 } 240 241 int hif_bus_resume_noirq(struct hif_opaque_softc *hif_ctx) 242 { 243 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 244 245 return hif_sc->bus_ops.hif_bus_resume_noirq(hif_sc); 246 } 247 248 int hif_target_sleep_state_adjust(struct hif_softc *hif_sc, 249 bool sleep_ok, bool wait_for_it) 250 { 251 return hif_sc->bus_ops.hif_target_sleep_state_adjust(hif_sc, 252 sleep_ok, wait_for_it); 253 } 254 qdf_export_symbol(hif_target_sleep_state_adjust); 255 256 void hif_disable_isr(struct hif_opaque_softc *hif_hdl) 257 { 258 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 259 260 hif_sc->bus_ops.hif_disable_isr(hif_sc); 261 } 262 263 void hif_nointrs(struct hif_softc *hif_sc) 264 { 265 hif_sc->bus_ops.hif_nointrs(hif_sc); 266 } 267 268 QDF_STATUS hif_enable_bus(struct hif_softc *hif_sc, struct device *dev, 269 void *bdev, const struct hif_bus_id *bid, 270 enum hif_enable_type type) 271 { 272 return hif_sc->bus_ops.hif_enable_bus(hif_sc, dev, bdev, bid, type); 273 } 274 275 void hif_disable_bus(struct hif_softc *hif_sc) 276 { 277 hif_sc->bus_ops.hif_disable_bus(hif_sc); 278 } 279 280 int hif_bus_configure(struct hif_softc *hif_sc) 281 { 282 return hif_sc->bus_ops.hif_bus_configure(hif_sc); 283 } 284 285 QDF_STATUS hif_get_config_item(struct hif_opaque_softc *hif_ctx, 286 int opcode, void *config, uint32_t config_len) 287 { 288 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 289 290 return hif_sc->bus_ops.hif_get_config_item(hif_sc, opcode, config, 291 config_len); 292 } 293 294 void hif_set_mailbox_swap(struct hif_opaque_softc *hif_ctx) 295 { 296 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 297 298 hif_sc->bus_ops.hif_set_mailbox_swap(hif_sc); 299 } 300 301 void hif_claim_device(struct hif_opaque_softc *hif_ctx) 302 { 303 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 304 305 hif_sc->bus_ops.hif_claim_device(hif_sc); 306 } 307 308 void hif_shutdown_device(struct hif_opaque_softc *hif_ctx) 309 { 310 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 311 312 hif_sc->bus_ops.hif_shutdown_device(hif_sc); 313 } 314 315 void hif_stop(struct hif_opaque_softc *hif_ctx) 316 { 317 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 318 319 hif_sc->bus_ops.hif_stop(hif_sc); 320 } 321 322 void hif_cancel_deferred_target_sleep(struct hif_softc *hif_sc) 323 { 324 return hif_sc->bus_ops.hif_cancel_deferred_target_sleep(hif_sc); 325 } 326 327 void hif_irq_enable(struct hif_softc *hif_sc, int irq_id) 328 { 329 hif_sc->bus_ops.hif_irq_enable(hif_sc, irq_id); 330 } 331 qdf_export_symbol(hif_irq_enable); 332 333 void hif_irq_disable(struct hif_softc *hif_sc, int irq_id) 334 { 335 hif_sc->bus_ops.hif_irq_disable(hif_sc, irq_id); 336 } 337 338 int hif_grp_irq_configure(struct hif_softc *hif_sc, 339 struct hif_exec_context *hif_exec) 340 { 341 return hif_sc->bus_ops.hif_grp_irq_configure(hif_sc, hif_exec); 342 } 343 344 void hif_grp_irq_deconfigure(struct hif_softc *hif_sc) 345 { 346 hif_sc->bus_ops.hif_grp_irq_deconfigure(hif_sc); 347 } 348 349 int hif_dump_registers(struct hif_opaque_softc *hif_hdl) 350 { 351 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 352 353 return hif_sc->bus_ops.hif_dump_registers(hif_sc); 354 } 355 356 void hif_dump_target_memory(struct hif_opaque_softc *hif_hdl, 357 void *ramdump_base, 358 uint32_t address, uint32_t size) 359 { 360 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 361 362 hif_sc->bus_ops.hif_dump_target_memory(hif_sc, ramdump_base, 363 address, size); 364 } 365 366 void hif_ipa_get_ce_resource(struct hif_opaque_softc *hif_hdl, 367 qdf_shared_mem_t **ce_sr, 368 uint32_t *ce_sr_ring_size, 369 qdf_dma_addr_t *ce_reg_paddr) 370 { 371 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 372 373 hif_sc->bus_ops.hif_ipa_get_ce_resource(hif_sc, ce_sr, 374 ce_sr_ring_size, ce_reg_paddr); 375 } 376 377 void hif_mask_interrupt_call(struct hif_opaque_softc *hif_hdl) 378 { 379 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 380 381 hif_sc->bus_ops.hif_mask_interrupt_call(hif_sc); 382 } 383 384 void hif_display_bus_stats(struct hif_opaque_softc *scn) 385 { 386 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 387 388 hif_sc->bus_ops.hif_display_stats(hif_sc); 389 } 390 391 void hif_clear_bus_stats(struct hif_opaque_softc *scn) 392 { 393 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 394 395 hif_sc->bus_ops.hif_clear_stats(hif_sc); 396 } 397 398 /** 399 * hif_enable_power_management() - enable power management after driver load 400 * @hif_hdl: opaque pointer to the hif context 401 * is_packet_log_enabled: true if packet log is enabled 402 * 403 * Driver load and firmware download are done in a high performance mode. 404 * Enable power management after the driver is loaded. 405 * packet log can require fewer power management features to be enabled. 406 */ 407 void hif_enable_power_management(struct hif_opaque_softc *hif_hdl, 408 bool is_packet_log_enabled) 409 { 410 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 411 412 hif_sc->bus_ops.hif_enable_power_management(hif_sc, 413 is_packet_log_enabled); 414 } 415 416 /** 417 * hif_disable_power_management() - reset the bus power management 418 * @hif_hdl: opaque pointer to the hif context 419 * 420 * return the power management of the bus to its default state. 421 * This isn't necessarily a complete reversal of its counterpart. 422 * This should be called when unloading the driver. 423 */ 424 void hif_disable_power_management(struct hif_opaque_softc *hif_hdl) 425 { 426 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 427 428 hif_sc->bus_ops.hif_disable_power_management(hif_sc); 429 } 430 431 /** 432 * hif_set_bundle_mode() - enable bundling and set default rx bundle cnt 433 * @scn: pointer to hif_opaque_softc structure 434 * @enabled: flag to enable/disable bundling 435 * @rx_bundle_cnt: bundle count to be used for RX 436 * 437 * Return: none 438 */ 439 void hif_set_bundle_mode(struct hif_opaque_softc *scn, bool enabled, 440 int rx_bundle_cnt) 441 { 442 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 443 444 hif_sc->bus_ops.hif_set_bundle_mode(hif_sc, enabled, rx_bundle_cnt); 445 } 446 447 /** 448 * hif_bus_reset_resume() - resume the bus after reset 449 * @scn: struct hif_opaque_softc 450 * 451 * This function is called to tell the driver that USB device has been resumed 452 * and it has also been reset. The driver should redo any necessary 453 * initialization. This function resets WLAN SOC. 454 * 455 * Return: int 0 for success, non zero for failure 456 */ 457 int hif_bus_reset_resume(struct hif_opaque_softc *scn) 458 { 459 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 460 461 return hif_sc->bus_ops.hif_bus_reset_resume(hif_sc); 462 } 463 464 int hif_apps_irqs_disable(struct hif_opaque_softc *hif_ctx) 465 { 466 struct hif_softc *scn; 467 int i; 468 469 QDF_BUG(hif_ctx); 470 scn = HIF_GET_SOFTC(hif_ctx); 471 if (!scn) 472 return -EINVAL; 473 474 /* if the wake_irq is shared, don't disable it twice */ 475 for (i = 0; i < scn->ce_count; ++i) { 476 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 477 478 if (irq != scn->wake_irq) 479 disable_irq(irq); 480 } 481 482 return 0; 483 } 484 485 int hif_apps_irqs_enable(struct hif_opaque_softc *hif_ctx) 486 { 487 struct hif_softc *scn; 488 int i; 489 490 QDF_BUG(hif_ctx); 491 scn = HIF_GET_SOFTC(hif_ctx); 492 if (!scn) 493 return -EINVAL; 494 495 /* if the wake_irq is shared, don't enable it twice */ 496 for (i = 0; i < scn->ce_count; ++i) { 497 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 498 499 if (irq != scn->wake_irq) 500 enable_irq(irq); 501 } 502 503 return 0; 504 } 505 506 int hif_apps_wake_irq_disable(struct hif_opaque_softc *hif_ctx) 507 { 508 struct hif_softc *scn; 509 510 QDF_BUG(hif_ctx); 511 scn = HIF_GET_SOFTC(hif_ctx); 512 if (!scn) 513 return -EINVAL; 514 515 disable_irq(scn->wake_irq); 516 517 return 0; 518 } 519 520 int hif_apps_wake_irq_enable(struct hif_opaque_softc *hif_ctx) 521 { 522 struct hif_softc *scn; 523 524 QDF_BUG(hif_ctx); 525 scn = HIF_GET_SOFTC(hif_ctx); 526 if (!scn) 527 return -EINVAL; 528 529 enable_irq(scn->wake_irq); 530 531 return 0; 532 } 533 534 int hif_apps_disable_irq_wake(struct hif_opaque_softc *hif_ctx) 535 { 536 struct hif_softc *scn; 537 538 QDF_BUG(hif_ctx); 539 scn = HIF_GET_SOFTC(hif_ctx); 540 if (!scn) 541 return -EINVAL; 542 543 return disable_irq_wake(scn->wake_irq); 544 } 545 546 int hif_apps_enable_irq_wake(struct hif_opaque_softc *hif_ctx) 547 { 548 struct hif_softc *scn; 549 550 QDF_BUG(hif_ctx); 551 scn = HIF_GET_SOFTC(hif_ctx); 552 if (!scn) 553 return -EINVAL; 554 555 return enable_irq_wake(scn->wake_irq); 556 } 557 558 int hif_apps_disable_irqs_except_wake_irq(struct hif_opaque_softc *hif_ctx) 559 { 560 struct hif_softc *scn; 561 int i; 562 563 QDF_BUG(hif_ctx); 564 scn = HIF_GET_SOFTC(hif_ctx); 565 if (!scn) 566 return -EINVAL; 567 568 for (i = 0; i < scn->ce_count; ++i) { 569 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 570 571 if (irq != scn->wake_irq) 572 disable_irq(irq); 573 } 574 575 return 0; 576 } 577 578 int hif_apps_enable_irqs_except_wake_irq(struct hif_opaque_softc *hif_ctx) 579 { 580 struct hif_softc *scn; 581 int i; 582 583 QDF_BUG(hif_ctx); 584 scn = HIF_GET_SOFTC(hif_ctx); 585 if (!scn) 586 return -EINVAL; 587 588 for (i = 0; i < scn->ce_count; ++i) { 589 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 590 591 if (irq != scn->wake_irq) 592 enable_irq(irq); 593 } 594 595 return 0; 596 } 597 598 #ifdef WLAN_FEATURE_BMI 599 bool hif_needs_bmi(struct hif_opaque_softc *scn) 600 { 601 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 602 603 return hif_sc->bus_ops.hif_needs_bmi(hif_sc); 604 } 605 qdf_export_symbol(hif_needs_bmi); 606 #endif /* WLAN_FEATURE_BMI */ 607 608 void hif_config_irq_affinity(struct hif_softc *hif_sc) 609 { 610 hif_sc->bus_ops.hif_config_irq_affinity(hif_sc); 611 } 612 613 int hif_config_irq_by_ceid(struct hif_softc *hif_sc, int ce_id) 614 { 615 return hif_sc->bus_ops.hif_config_irq_by_ceid(hif_sc, ce_id); 616 } 617 618 #ifdef HIF_CPU_CLEAR_AFFINITY 619 void hif_config_irq_clear_cpu_affinity(struct hif_opaque_softc *scn, 620 int intr_ctxt_id, int cpu) 621 { 622 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 623 624 hif_sc->bus_ops.hif_config_irq_clear_cpu_affinity(hif_sc, 625 intr_ctxt_id, cpu); 626 } 627 628 qdf_export_symbol(hif_config_irq_clear_affinity); 629 #endif 630 631 #ifdef HIF_BUS_LOG_INFO 632 bool hif_log_bus_info(struct hif_softc *hif_sc, uint8_t *data, 633 unsigned int *offset) 634 { 635 if (hif_sc->bus_ops.hif_log_bus_info) 636 return hif_sc->bus_ops.hif_log_bus_info(hif_sc, data, offset); 637 638 return false; 639 } 640 #endif 641 642 int hif_apps_grp_irqs_enable(struct hif_opaque_softc *hif_ctx) 643 { 644 struct hif_exec_context *hif_exec; 645 struct hif_softc *scn; 646 int i, j; 647 648 QDF_BUG(hif_ctx); 649 scn = HIF_GET_SOFTC(hif_ctx); 650 if (!scn) 651 return -EINVAL; 652 653 for (i = 0 ; i < HIF_MAX_GROUP; i++) { 654 hif_exec = hif_exec_get_ctx(hif_ctx, i); 655 if (!hif_exec) 656 continue; 657 658 for (j = 0; j < hif_exec->numirq; j++) 659 pfrm_enable_irq(scn->qdf_dev->dev, 660 hif_exec->os_irq[j]); 661 } 662 663 return 0; 664 } 665 666 int hif_apps_grp_irqs_disable(struct hif_opaque_softc *hif_ctx) 667 { 668 struct hif_exec_context *hif_exec; 669 struct hif_softc *scn; 670 int i, j; 671 672 QDF_BUG(hif_ctx); 673 scn = HIF_GET_SOFTC(hif_ctx); 674 if (!scn) 675 return -EINVAL; 676 677 for (i = 0 ; i < HIF_MAX_GROUP; i++) { 678 hif_exec = hif_exec_get_ctx(hif_ctx, i); 679 if (!hif_exec) 680 continue; 681 682 for (j = 0; j < hif_exec->numirq; j++) 683 pfrm_disable_irq(scn->qdf_dev->dev, 684 hif_exec->os_irq[j]); 685 } 686 687 return 0; 688 } 689 690 int hif_disable_grp_irqs(struct hif_opaque_softc *scn) 691 { 692 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 693 694 return hif_sc->bus_ops.hif_disable_grp_irqs(hif_sc); 695 } 696 697 int hif_enable_grp_irqs(struct hif_opaque_softc *scn) 698 { 699 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 700 701 return hif_sc->bus_ops.hif_enable_grp_irqs(hif_sc); 702 } 703 704 #ifdef FEATURE_IRQ_AFFINITY 705 void hif_set_grp_intr_affinity(struct hif_opaque_softc *scn, 706 uint32_t grp_intr_bitmask, bool perf) 707 { 708 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 709 710 if (!hif_sc) 711 return; 712 713 hif_sc->bus_ops.hif_set_grp_intr_affinity(hif_sc, grp_intr_bitmask, 714 perf); 715 } 716 #endif 717