1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2025 Cirrus Logic, Inc. and 3 // Cirrus Logic International Semiconductor Ltd. 4 5 /* 6 * The MIPI SDCA specification is available for public downloads at 7 * https://www.mipi.org/mipi-sdca-v1-0-download 8 */ 9 10 #include <linux/bitmap.h> 11 #include <linux/bits.h> 12 #include <linux/cleanup.h> 13 #include <linux/device.h> 14 #include <linux/dev_printk.h> 15 #include <linux/interrupt.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/soundwire/sdw.h> 19 #include <linux/soundwire/sdw_registers.h> 20 #include <sound/sdca.h> 21 #include <sound/sdca_fdl.h> 22 #include <sound/sdca_function.h> 23 #include <sound/sdca_hid.h> 24 #include <sound/sdca_interrupts.h> 25 #include <sound/sdca_jack.h> 26 #include <sound/sdca_ump.h> 27 #include <sound/soc-component.h> 28 #include <sound/soc.h> 29 30 #define IRQ_SDCA(number) REGMAP_IRQ_REG(number, ((number) / BITS_PER_BYTE), \ 31 SDW_SCP_SDCA_INTMASK_SDCA_##number) 32 33 static const struct regmap_irq regmap_irqs[SDCA_MAX_INTERRUPTS] = { 34 IRQ_SDCA(0), 35 IRQ_SDCA(1), 36 IRQ_SDCA(2), 37 IRQ_SDCA(3), 38 IRQ_SDCA(4), 39 IRQ_SDCA(5), 40 IRQ_SDCA(6), 41 IRQ_SDCA(7), 42 IRQ_SDCA(8), 43 IRQ_SDCA(9), 44 IRQ_SDCA(10), 45 IRQ_SDCA(11), 46 IRQ_SDCA(12), 47 IRQ_SDCA(13), 48 IRQ_SDCA(14), 49 IRQ_SDCA(15), 50 IRQ_SDCA(16), 51 IRQ_SDCA(17), 52 IRQ_SDCA(18), 53 IRQ_SDCA(19), 54 IRQ_SDCA(20), 55 IRQ_SDCA(21), 56 IRQ_SDCA(22), 57 IRQ_SDCA(23), 58 IRQ_SDCA(24), 59 IRQ_SDCA(25), 60 IRQ_SDCA(26), 61 IRQ_SDCA(27), 62 IRQ_SDCA(28), 63 IRQ_SDCA(29), 64 IRQ_SDCA(30), 65 }; 66 67 static const struct regmap_irq_chip sdca_irq_chip = { 68 .name = "sdca_irq", 69 70 .status_base = SDW_SCP_SDCA_INT1, 71 .unmask_base = SDW_SCP_SDCA_INTMASK1, 72 .ack_base = SDW_SCP_SDCA_INT1, 73 .num_regs = 4, 74 75 .irqs = regmap_irqs, 76 .num_irqs = SDCA_MAX_INTERRUPTS, 77 78 .runtime_pm = true, 79 }; 80 81 static irqreturn_t base_handler(int irq, void *data) 82 { 83 struct sdca_interrupt *interrupt = data; 84 struct device *dev = interrupt->dev; 85 86 dev_info(dev, "%s irq without full handling\n", interrupt->name); 87 88 return IRQ_HANDLED; 89 } 90 91 static irqreturn_t function_status_handler(int irq, void *data) 92 { 93 struct sdca_interrupt *interrupt = data; 94 struct device *dev = interrupt->dev; 95 irqreturn_t irqret = IRQ_NONE; 96 unsigned int reg, val; 97 unsigned long status; 98 unsigned int mask; 99 int ret; 100 101 ret = pm_runtime_get_sync(dev); 102 if (ret < 0) { 103 dev_err(dev, "failed to resume for function status: %d\n", ret); 104 goto error; 105 } 106 107 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, interrupt->entity->id, 108 interrupt->control->sel, 0); 109 110 ret = regmap_read(interrupt->function_regmap, reg, &val); 111 if (ret < 0) { 112 dev_err(dev, "failed to read function status: %d\n", ret); 113 goto error; 114 } 115 116 dev_dbg(dev, "function status: %#x\n", val); 117 118 status = val; 119 for_each_set_bit(mask, &status, BITS_PER_BYTE) { 120 switch (BIT(mask)) { 121 case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION: 122 /* 123 * FIXME: Should this do init writes? 124 * 125 * Currently init writes/cache sync are done from the suspend/resume 126 * infrastructure. It is unclear in what situations one would receive this 127 * IRQ outside of that flow. Presumably it would be something like the chip 128 * crashing. In that case however doing the init writes and a cache sync might 129 * not be sufficient, for example if the failure was during audio playback 130 * there could be ordering constraints on the register writes to restore the 131 * state that are not handled by a simple cache sync. 132 */ 133 break; 134 case SDCA_CTL_ENTITY_0_FUNCTION_FAULT: 135 dev_err(dev, "function fault\n"); 136 break; 137 case SDCA_CTL_ENTITY_0_UMP_SEQUENCE_FAULT: 138 dev_err(dev, "ump sequence fault\n"); 139 break; 140 case SDCA_CTL_ENTITY_0_FUNCTION_BUSY: 141 dev_info(dev, "unexpected function busy\n"); 142 break; 143 case SDCA_CTL_ENTITY_0_DEVICE_NEWLY_ATTACHED: 144 case SDCA_CTL_ENTITY_0_INTS_DISABLED_ABNORMALLY: 145 case SDCA_CTL_ENTITY_0_STREAMING_STOPPED_ABNORMALLY: 146 case SDCA_CTL_ENTITY_0_FUNCTION_HAS_BEEN_RESET: 147 break; 148 } 149 } 150 151 ret = regmap_write(interrupt->function_regmap, reg, val & 0x7F); 152 if (ret < 0) { 153 dev_err(dev, "failed to clear function status: %d\n", ret); 154 goto error; 155 } 156 157 irqret = IRQ_HANDLED; 158 error: 159 pm_runtime_put(dev); 160 return irqret; 161 } 162 163 static irqreturn_t detected_mode_handler(int irq, void *data) 164 { 165 struct sdca_interrupt *interrupt = data; 166 struct device *dev = interrupt->dev; 167 irqreturn_t irqret = IRQ_NONE; 168 int ret; 169 170 ret = pm_runtime_get_sync(dev); 171 if (ret < 0) { 172 dev_err(dev, "failed to resume for detected mode: %d\n", ret); 173 goto error; 174 } 175 176 ret = sdca_jack_process(interrupt); 177 if (ret) 178 goto error; 179 180 irqret = IRQ_HANDLED; 181 error: 182 pm_runtime_put(dev); 183 return irqret; 184 } 185 186 static irqreturn_t hid_handler(int irq, void *data) 187 { 188 struct sdca_interrupt *interrupt = data; 189 struct device *dev = interrupt->dev; 190 irqreturn_t irqret = IRQ_NONE; 191 int ret; 192 193 ret = pm_runtime_get_sync(dev); 194 if (ret < 0) { 195 dev_err(dev, "failed to resume for hid: %d\n", ret); 196 goto error; 197 } 198 199 ret = sdca_hid_process_report(interrupt); 200 if (ret) 201 goto error; 202 203 irqret = IRQ_HANDLED; 204 error: 205 pm_runtime_put(dev); 206 return irqret; 207 } 208 209 #ifdef CONFIG_PM_SLEEP 210 static bool no_pm_in_progress(struct device *dev) 211 { 212 return completion_done(&dev->power.completion); 213 } 214 #else 215 static bool no_pm_in_progress(struct device *dev) 216 { 217 return true; 218 } 219 #endif 220 221 static irqreturn_t fdl_owner_handler(int irq, void *data) 222 { 223 struct sdca_interrupt *interrupt = data; 224 struct device *dev = interrupt->dev; 225 irqreturn_t irqret = IRQ_NONE; 226 int ret; 227 228 /* 229 * FDL has to run from the system resume handler, at which point 230 * we can't wait for the pm runtime. 231 */ 232 if (no_pm_in_progress(dev)) { 233 ret = pm_runtime_get_sync(dev); 234 if (ret < 0) { 235 dev_err(dev, "failed to resume for fdl: %d\n", ret); 236 goto error; 237 } 238 } 239 240 ret = sdca_fdl_process(interrupt); 241 if (ret) 242 goto error; 243 244 irqret = IRQ_HANDLED; 245 error: 246 if (no_pm_in_progress(dev)) 247 pm_runtime_put(dev); 248 return irqret; 249 } 250 251 static int sdca_irq_request_locked(struct device *dev, 252 struct sdca_interrupt_info *info, 253 int sdca_irq, const char *name, 254 irq_handler_t handler, void *data) 255 { 256 int irq; 257 int ret; 258 259 irq = regmap_irq_get_virq(info->irq_data, sdca_irq); 260 if (irq < 0) 261 return irq; 262 263 ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, name, data); 264 if (ret) 265 return ret; 266 267 info->irqs[sdca_irq].irq = irq; 268 269 dev_dbg(dev, "requested irq %d for %s\n", irq, name); 270 271 return 0; 272 } 273 274 static void sdca_irq_free_locked(struct device *dev, struct sdca_interrupt_info *info, 275 int sdca_irq, const char *name, void *data) 276 { 277 int irq; 278 279 irq = regmap_irq_get_virq(info->irq_data, sdca_irq); 280 if (irq < 0) 281 return; 282 283 free_irq(irq, data); 284 285 info->irqs[sdca_irq].irq = 0; 286 287 dev_dbg(dev, "freed irq %d for %s\n", irq, name); 288 } 289 290 /** 291 * sdca_irq_request - request an individual SDCA interrupt 292 * @dev: Pointer to the struct device against which things should be allocated. 293 * @info: Pointer to the interrupt information structure. 294 * @sdca_irq: SDCA interrupt position. 295 * @name: Name to be given to the IRQ. 296 * @handler: A callback thread function to be called for the IRQ. 297 * @data: Private data pointer that will be passed to the handler. 298 * 299 * Typically this is handled internally by sdca_irq_populate, however if 300 * a device requires custom IRQ handling this can be called manually before 301 * calling sdca_irq_populate, which will then skip that IRQ whilst processing. 302 * 303 * Return: Zero on success, and a negative error code on failure. 304 */ 305 int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info, 306 int sdca_irq, const char *name, irq_handler_t handler, 307 void *data) 308 { 309 int ret; 310 311 if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS) { 312 dev_err(dev, "bad irq request: %d\n", sdca_irq); 313 return -EINVAL; 314 } 315 316 guard(mutex)(&info->irq_lock); 317 318 ret = sdca_irq_request_locked(dev, info, sdca_irq, name, handler, data); 319 if (ret) { 320 dev_err(dev, "failed to request irq %s: %d\n", name, ret); 321 return ret; 322 } 323 324 return 0; 325 } 326 EXPORT_SYMBOL_NS_GPL(sdca_irq_request, "SND_SOC_SDCA"); 327 328 /** 329 * sdca_irq_free - free an individual SDCA interrupt 330 * @dev: Pointer to the struct device. 331 * @info: Pointer to the interrupt information structure. 332 * @sdca_irq: SDCA interrupt position. 333 * @name: Name to be given to the IRQ. 334 * @data: Private data pointer that will be passed to the handler. 335 * 336 * Typically this is handled internally by sdca_irq_cleanup, however if 337 * a device requires custom IRQ handling this can be called manually before 338 * calling sdca_irq_cleanup, which will then skip that IRQ whilst processing. 339 */ 340 void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *info, 341 int sdca_irq, const char *name, void *data) 342 { 343 if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS) 344 return; 345 346 guard(mutex)(&info->irq_lock); 347 348 sdca_irq_free_locked(dev, info, sdca_irq, name, data); 349 } 350 EXPORT_SYMBOL_NS_GPL(sdca_irq_free, "SND_SOC_SDCA"); 351 352 /** 353 * sdca_irq_data_populate - Populate common interrupt data 354 * @dev: Pointer to the Function device. 355 * @regmap: Pointer to the Function regmap. 356 * @component: Pointer to the ASoC component for the Function. 357 * @function: Pointer to the SDCA Function. 358 * @entity: Pointer to the SDCA Entity. 359 * @control: Pointer to the SDCA Control. 360 * @interrupt: Pointer to the SDCA interrupt for this IRQ. 361 * 362 * Return: Zero on success, and a negative error code on failure. 363 */ 364 int sdca_irq_data_populate(struct device *dev, struct regmap *regmap, 365 struct snd_soc_component *component, 366 struct sdca_function_data *function, 367 struct sdca_entity *entity, 368 struct sdca_control *control, 369 struct sdca_interrupt *interrupt) 370 { 371 const char *name; 372 373 if (!dev && component) 374 dev = component->dev; 375 if (!dev) 376 return -ENODEV; 377 378 name = kasprintf(GFP_KERNEL, "%s %s %s", function->desc->name, 379 entity->label, control->label); 380 if (!name) 381 return -ENOMEM; 382 383 interrupt->name = name; 384 interrupt->dev = dev; 385 if (!regmap && component) 386 interrupt->function_regmap = component->regmap; 387 else 388 interrupt->function_regmap = regmap; 389 interrupt->component = component; 390 interrupt->function = function; 391 interrupt->entity = entity; 392 interrupt->control = control; 393 394 return 0; 395 } 396 EXPORT_SYMBOL_NS_GPL(sdca_irq_data_populate, "SND_SOC_SDCA"); 397 398 static struct sdca_interrupt *get_interrupt_data(struct device *dev, int irq, 399 struct sdca_interrupt_info *info) 400 { 401 if (irq == SDCA_NO_INTERRUPT) { 402 return NULL; 403 } else if (irq < 0 || irq >= SDCA_MAX_INTERRUPTS) { 404 dev_err(dev, "bad irq position: %d\n", irq); 405 return ERR_PTR(-EINVAL); 406 } 407 408 if (info->irqs[irq].irq) { 409 dev_dbg(dev, "skipping irq %d, already requested\n", irq); 410 return NULL; 411 } 412 413 return &info->irqs[irq]; 414 } 415 416 /** 417 * sdca_irq_populate_early - process pre-audio card IRQ registrations 418 * @dev: Device pointer for SDCA Function. 419 * @regmap: Regmap pointer for the SDCA Function. 420 * @function: Pointer to the SDCA Function. 421 * @info: Pointer to the SDCA interrupt info for this device. 422 * 423 * This is intended to be used as part of the Function boot process. It 424 * can be called before the soundcard is registered (ie. doesn't depend 425 * on component) and will register the FDL interrupts. 426 * 427 * Return: Zero on success, and a negative error code on failure. 428 */ 429 int sdca_irq_populate_early(struct device *dev, struct regmap *regmap, 430 struct sdca_function_data *function, 431 struct sdca_interrupt_info *info) 432 { 433 int i, j; 434 435 guard(mutex)(&info->irq_lock); 436 437 for (i = 0; i < function->num_entities; i++) { 438 struct sdca_entity *entity = &function->entities[i]; 439 440 for (j = 0; j < entity->num_controls; j++) { 441 struct sdca_control *control = &entity->controls[j]; 442 int irq = control->interrupt_position; 443 struct sdca_interrupt *interrupt; 444 int ret; 445 446 interrupt = get_interrupt_data(dev, irq, info); 447 if (IS_ERR(interrupt)) 448 return PTR_ERR(interrupt); 449 else if (!interrupt) 450 continue; 451 452 switch (SDCA_CTL_TYPE(entity->type, control->sel)) { 453 case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): 454 ret = sdca_irq_data_populate(dev, regmap, NULL, 455 function, entity, 456 control, interrupt); 457 if (ret) 458 return ret; 459 460 ret = sdca_fdl_alloc_state(interrupt); 461 if (ret) 462 return ret; 463 464 ret = sdca_irq_request_locked(dev, info, irq, 465 interrupt->name, 466 fdl_owner_handler, 467 interrupt); 468 if (ret) { 469 dev_err(dev, "failed to request irq %s: %d\n", 470 interrupt->name, ret); 471 return ret; 472 } 473 break; 474 default: 475 break; 476 } 477 } 478 } 479 480 return 0; 481 } 482 EXPORT_SYMBOL_NS_GPL(sdca_irq_populate_early, "SND_SOC_SDCA"); 483 484 /** 485 * sdca_irq_populate - Request all the individual IRQs for an SDCA Function 486 * @function: Pointer to the SDCA Function. 487 * @component: Pointer to the ASoC component for the Function. 488 * @info: Pointer to the SDCA interrupt info for this device. 489 * 490 * Typically this would be called from the driver for a single SDCA Function. 491 * 492 * Return: Zero on success, and a negative error code on failure. 493 */ 494 int sdca_irq_populate(struct sdca_function_data *function, 495 struct snd_soc_component *component, 496 struct sdca_interrupt_info *info) 497 { 498 struct device *dev = component->dev; 499 int i, j; 500 501 guard(mutex)(&info->irq_lock); 502 503 for (i = 0; i < function->num_entities; i++) { 504 struct sdca_entity *entity = &function->entities[i]; 505 506 for (j = 0; j < entity->num_controls; j++) { 507 struct sdca_control *control = &entity->controls[j]; 508 int irq = control->interrupt_position; 509 struct sdca_interrupt *interrupt; 510 irq_handler_t handler; 511 int ret; 512 513 interrupt = get_interrupt_data(dev, irq, info); 514 if (IS_ERR(interrupt)) 515 return PTR_ERR(interrupt); 516 else if (!interrupt) 517 continue; 518 519 ret = sdca_irq_data_populate(dev, NULL, component, 520 function, entity, control, 521 interrupt); 522 if (ret) 523 return ret; 524 525 handler = base_handler; 526 527 switch (SDCA_CTL_TYPE(entity->type, control->sel)) { 528 case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS): 529 handler = function_status_handler; 530 break; 531 case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): 532 ret = sdca_jack_alloc_state(interrupt); 533 if (ret) 534 return ret; 535 536 handler = detected_mode_handler; 537 break; 538 case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): 539 ret = sdca_fdl_alloc_state(interrupt); 540 if (ret) 541 return ret; 542 543 handler = fdl_owner_handler; 544 break; 545 case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER): 546 handler = hid_handler; 547 break; 548 default: 549 break; 550 } 551 552 ret = sdca_irq_request_locked(dev, info, irq, interrupt->name, 553 handler, interrupt); 554 if (ret) { 555 dev_err(dev, "failed to request irq %s: %d\n", 556 interrupt->name, ret); 557 return ret; 558 } 559 } 560 } 561 562 return 0; 563 } 564 EXPORT_SYMBOL_NS_GPL(sdca_irq_populate, "SND_SOC_SDCA"); 565 566 /** 567 * sdca_irq_cleanup - Free all the individual IRQs for an SDCA Function 568 * @dev: Device pointer against which the sdca_interrupt_info was allocated. 569 * @function: Pointer to the SDCA Function. 570 * @info: Pointer to the SDCA interrupt info for this device. 571 * 572 * Typically this would be called from the driver for a single SDCA Function. 573 */ 574 void sdca_irq_cleanup(struct device *dev, 575 struct sdca_function_data *function, 576 struct sdca_interrupt_info *info) 577 { 578 int i; 579 580 guard(mutex)(&info->irq_lock); 581 582 for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) { 583 struct sdca_interrupt *interrupt = &info->irqs[i]; 584 585 if (interrupt->function != function || !interrupt->irq) 586 continue; 587 588 sdca_irq_free_locked(dev, info, i, interrupt->name, interrupt); 589 590 kfree(interrupt->name); 591 } 592 } 593 EXPORT_SYMBOL_NS_GPL(sdca_irq_cleanup, "SND_SOC_SDCA"); 594 595 /** 596 * sdca_irq_allocate - allocate an SDCA interrupt structure for a device 597 * @sdev: Device pointer against which things should be allocated. 598 * @regmap: regmap to be used for accessing the SDCA IRQ registers. 599 * @irq: The interrupt number. 600 * 601 * Typically this would be called from the top level driver for the whole 602 * SDCA device, as only a single instance is required across all Functions 603 * on the device. 604 * 605 * Return: A pointer to the allocated sdca_interrupt_info struct, or an 606 * error code. 607 */ 608 struct sdca_interrupt_info *sdca_irq_allocate(struct device *sdev, 609 struct regmap *regmap, int irq) 610 { 611 struct sdca_interrupt_info *info; 612 int ret, i; 613 614 info = devm_kzalloc(sdev, sizeof(*info), GFP_KERNEL); 615 if (!info) 616 return ERR_PTR(-ENOMEM); 617 618 info->irq_chip = sdca_irq_chip; 619 620 for (i = 0; i < ARRAY_SIZE(info->irqs); i++) 621 info->irqs[i].device_regmap = regmap; 622 623 ret = devm_mutex_init(sdev, &info->irq_lock); 624 if (ret) 625 return ERR_PTR(ret); 626 627 ret = devm_regmap_add_irq_chip(sdev, regmap, irq, IRQF_ONESHOT, 0, 628 &info->irq_chip, &info->irq_data); 629 if (ret) { 630 dev_err(sdev, "failed to register irq chip: %d\n", ret); 631 return ERR_PTR(ret); 632 } 633 634 dev_dbg(sdev, "registered on irq %d\n", irq); 635 636 return info; 637 } 638 EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA"); 639 640 static void irq_enable_flags(struct sdca_function_data *function, 641 struct sdca_interrupt_info *info, bool early) 642 { 643 int i; 644 645 for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) { 646 struct sdca_interrupt *interrupt = &info->irqs[i]; 647 648 if (!interrupt->irq || interrupt->function != function) 649 continue; 650 651 switch (SDCA_CTL_TYPE(interrupt->entity->type, 652 interrupt->control->sel)) { 653 case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): 654 if (early) 655 enable_irq(interrupt->irq); 656 break; 657 default: 658 if (!early) 659 enable_irq(interrupt->irq); 660 break; 661 } 662 } 663 } 664 665 /** 666 * sdca_irq_enable_early - Re-enable early SDCA IRQs for a given function 667 * @function: Pointer to the SDCA Function. 668 * @info: Pointer to the SDCA interrupt info for this device. 669 * 670 * The early version of the IRQ enable allows enabling IRQs which may be 671 * necessary to bootstrap functionality for other IRQs, such as the FDL 672 * process. 673 */ 674 void sdca_irq_enable_early(struct sdca_function_data *function, 675 struct sdca_interrupt_info *info) 676 { 677 irq_enable_flags(function, info, true); 678 } 679 EXPORT_SYMBOL_NS_GPL(sdca_irq_enable_early, "SND_SOC_SDCA"); 680 681 /** 682 * sdca_irq_enable - Re-enable SDCA IRQs for a given function 683 * @function: Pointer to the SDCA Function. 684 * @info: Pointer to the SDCA interrupt info for this device. 685 */ 686 void sdca_irq_enable(struct sdca_function_data *function, 687 struct sdca_interrupt_info *info) 688 { 689 irq_enable_flags(function, info, false); 690 } 691 EXPORT_SYMBOL_NS_GPL(sdca_irq_enable, "SND_SOC_SDCA"); 692 693 /** 694 * sdca_irq_disable - Disable SDCA IRQs for a given function 695 * @function: Pointer to the SDCA Function. 696 * @info: Pointer to the SDCA interrupt info for this device. 697 */ 698 void sdca_irq_disable(struct sdca_function_data *function, 699 struct sdca_interrupt_info *info) 700 { 701 int i; 702 703 for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) { 704 struct sdca_interrupt *interrupt = &info->irqs[i]; 705 706 if (!interrupt->irq || interrupt->function != function) 707 continue; 708 709 disable_irq(interrupt->irq); 710 } 711 } 712 EXPORT_SYMBOL_NS_GPL(sdca_irq_disable, "SND_SOC_SDCA"); 713