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