1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 8 // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9 // Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 10 // Rander Wang <rander.wang@intel.com> 11 // Keyon Jie <yang.jie@linux.intel.com> 12 // 13 14 /* 15 * Hardware interface for generic Intel audio DSP HDA IP 16 */ 17 18 #include <sound/hdaudio_ext.h> 19 #include <sound/hda_register.h> 20 21 #include <linux/module.h> 22 #include <sound/sof.h> 23 #include <sound/sof/xtensa.h> 24 #include "../ops.h" 25 #include "hda.h" 26 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 27 #include "../../codecs/hdac_hda.h" 28 #endif 29 30 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 31 #include <sound/soc-acpi-intel-match.h> 32 #endif 33 34 /* platform specific devices */ 35 #include "shim.h" 36 37 #define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348) 38 #define IS_CNL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9dc8) 39 40 /* 41 * Debug 42 */ 43 44 struct hda_dsp_msg_code { 45 u32 code; 46 const char *msg; 47 }; 48 49 static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { 50 {HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"}, 51 {HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"}, 52 {HDA_DSP_ROM_FW_ENTERED, "status: fw entered"}, 53 {HDA_DSP_ROM_CSE_ERROR, "error: cse error"}, 54 {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"}, 55 {HDA_DSP_ROM_IMR_TO_SMALL, "error: IMR too small"}, 56 {HDA_DSP_ROM_BASE_FW_NOT_FOUND, "error: base fw not found"}, 57 {HDA_DSP_ROM_CSE_VALIDATION_FAILED, "error: signature verification failed"}, 58 {HDA_DSP_ROM_IPC_FATAL_ERROR, "error: ipc fatal error"}, 59 {HDA_DSP_ROM_L2_CACHE_ERROR, "error: L2 cache error"}, 60 {HDA_DSP_ROM_LOAD_OFFSET_TO_SMALL, "error: load offset too small"}, 61 {HDA_DSP_ROM_API_PTR_INVALID, "error: API ptr invalid"}, 62 {HDA_DSP_ROM_BASEFW_INCOMPAT, "error: base fw incompatible"}, 63 {HDA_DSP_ROM_UNHANDLED_INTERRUPT, "error: unhandled interrupt"}, 64 {HDA_DSP_ROM_MEMORY_HOLE_ECC, "error: ECC memory hole"}, 65 {HDA_DSP_ROM_KERNEL_EXCEPTION, "error: kernel exception"}, 66 {HDA_DSP_ROM_USER_EXCEPTION, "error: user exception"}, 67 {HDA_DSP_ROM_UNEXPECTED_RESET, "error: unexpected reset"}, 68 {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"}, 69 }; 70 71 static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev) 72 { 73 u32 status; 74 int i; 75 76 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 77 HDA_ADSP_FW_STATUS_SKL); 78 79 for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { 80 if (status == hda_dsp_rom_msg[i].code) { 81 dev_err(sdev->dev, "%s - code %8.8x\n", 82 hda_dsp_rom_msg[i].msg, status); 83 return; 84 } 85 } 86 87 /* not for us, must be generic sof message */ 88 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); 89 } 90 91 static void hda_dsp_get_status(struct snd_sof_dev *sdev) 92 { 93 u32 status; 94 int i; 95 96 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 97 HDA_DSP_SRAM_REG_ROM_STATUS); 98 99 for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { 100 if (status == hda_dsp_rom_msg[i].code) { 101 dev_err(sdev->dev, "%s - code %8.8x\n", 102 hda_dsp_rom_msg[i].msg, status); 103 return; 104 } 105 } 106 107 /* not for us, must be generic sof message */ 108 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); 109 } 110 111 static void hda_dsp_get_registers(struct snd_sof_dev *sdev, 112 struct sof_ipc_dsp_oops_xtensa *xoops, 113 struct sof_ipc_panic_info *panic_info, 114 u32 *stack, size_t stack_words) 115 { 116 u32 offset = sdev->dsp_oops_offset; 117 118 /* first read registers */ 119 sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 120 121 /* note: variable AR register array is not read */ 122 123 /* then get panic info */ 124 offset += xoops->arch_hdr.totalsize; 125 sof_block_read(sdev, sdev->mmio_bar, offset, 126 panic_info, sizeof(*panic_info)); 127 128 /* then get the stack */ 129 offset += sizeof(*panic_info); 130 sof_block_read(sdev, sdev->mmio_bar, offset, stack, 131 stack_words * sizeof(u32)); 132 } 133 134 void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) 135 { 136 struct sof_ipc_dsp_oops_xtensa xoops; 137 struct sof_ipc_panic_info panic_info; 138 u32 stack[HDA_DSP_STACK_DUMP_SIZE]; 139 u32 status, panic; 140 141 /* try APL specific status message types first */ 142 hda_dsp_get_status_skl(sdev); 143 144 /* now try generic SOF status messages */ 145 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 146 HDA_ADSP_ERROR_CODE_SKL); 147 148 /*TODO: Check: there is no define in spec, but it is used in the code*/ 149 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 150 HDA_ADSP_ERROR_CODE_SKL + 0x4); 151 152 if (sdev->boot_complete) { 153 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, 154 HDA_DSP_STACK_DUMP_SIZE); 155 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, 156 stack, HDA_DSP_STACK_DUMP_SIZE); 157 } else { 158 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", 159 status, panic); 160 hda_dsp_get_status_skl(sdev); 161 } 162 } 163 164 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) 165 { 166 struct sof_ipc_dsp_oops_xtensa xoops; 167 struct sof_ipc_panic_info panic_info; 168 u32 stack[HDA_DSP_STACK_DUMP_SIZE]; 169 u32 status, panic; 170 171 /* try APL specific status message types first */ 172 hda_dsp_get_status(sdev); 173 174 /* now try generic SOF status messages */ 175 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 176 HDA_DSP_SRAM_REG_FW_STATUS); 177 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP); 178 179 if (sdev->boot_complete) { 180 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, 181 HDA_DSP_STACK_DUMP_SIZE); 182 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, 183 stack, HDA_DSP_STACK_DUMP_SIZE); 184 } else { 185 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", 186 status, panic); 187 hda_dsp_get_status(sdev); 188 } 189 } 190 191 void hda_ipc_irq_dump(struct snd_sof_dev *sdev) 192 { 193 struct hdac_bus *bus = sof_to_bus(sdev); 194 u32 adspis; 195 u32 intsts; 196 u32 intctl; 197 u32 ppsts; 198 u8 rirbsts; 199 200 /* read key IRQ stats and config registers */ 201 adspis = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIS); 202 intsts = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS); 203 intctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL); 204 ppsts = snd_sof_dsp_read(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPSTS); 205 rirbsts = snd_hdac_chip_readb(bus, RIRBSTS); 206 207 dev_err(sdev->dev, 208 "error: hda irq intsts 0x%8.8x intlctl 0x%8.8x rirb %2.2x\n", 209 intsts, intctl, rirbsts); 210 dev_err(sdev->dev, 211 "error: dsp irq ppsts 0x%8.8x adspis 0x%8.8x\n", 212 ppsts, adspis); 213 } 214 215 void hda_ipc_dump(struct snd_sof_dev *sdev) 216 { 217 u32 hipcie; 218 u32 hipct; 219 u32 hipcctl; 220 221 hda_ipc_irq_dump(sdev); 222 223 /* read IPC status */ 224 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE); 225 hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT); 226 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL); 227 228 /* dump the IPC regs */ 229 /* TODO: parse the raw msg */ 230 dev_err(sdev->dev, 231 "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", 232 hipcie, hipct, hipcctl); 233 } 234 235 static int hda_init(struct snd_sof_dev *sdev) 236 { 237 struct hda_bus *hbus; 238 struct hdac_bus *bus; 239 struct hdac_ext_bus_ops *ext_ops = NULL; 240 struct pci_dev *pci = to_pci_dev(sdev->dev); 241 int ret; 242 243 hbus = sof_to_hbus(sdev); 244 bus = sof_to_bus(sdev); 245 246 /* HDA bus init */ 247 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 248 ext_ops = snd_soc_hdac_hda_get_ops(); 249 #endif 250 sof_hda_bus_init(bus, &pci->dev, ext_ops); 251 252 /* Workaround for a communication error on CFL (bko#199007) and CNL */ 253 if (IS_CFL(pci) || IS_CNL(pci)) 254 bus->polling_mode = 1; 255 256 bus->use_posbuf = 1; 257 bus->bdl_pos_adj = 0; 258 259 mutex_init(&hbus->prepare_mutex); 260 hbus->pci = pci; 261 hbus->mixer_assigned = -1; 262 hbus->modelname = "sofbus"; 263 264 /* initialise hdac bus */ 265 bus->addr = pci_resource_start(pci, 0); 266 #if IS_ENABLED(CONFIG_PCI) 267 bus->remap_addr = pci_ioremap_bar(pci, 0); 268 #endif 269 if (!bus->remap_addr) { 270 dev_err(bus->dev, "error: ioremap error\n"); 271 return -ENXIO; 272 } 273 274 /* HDA base */ 275 sdev->bar[HDA_DSP_HDA_BAR] = bus->remap_addr; 276 277 /* get controller capabilities */ 278 ret = hda_dsp_ctrl_get_caps(sdev); 279 if (ret < 0) 280 dev_err(sdev->dev, "error: get caps error\n"); 281 282 return ret; 283 } 284 285 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 286 287 static const char *fixup_tplg_name(struct snd_sof_dev *sdev, 288 const char *sof_tplg_filename) 289 { 290 const char *tplg_filename = NULL; 291 char *filename; 292 char *split_ext; 293 294 filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); 295 if (!filename) 296 return NULL; 297 298 /* this assumes a .tplg extension */ 299 split_ext = strsep(&filename, "."); 300 if (split_ext) { 301 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 302 "%s-idisp.tplg", split_ext); 303 if (!tplg_filename) 304 return NULL; 305 } 306 return tplg_filename; 307 } 308 309 #endif 310 311 static int hda_init_caps(struct snd_sof_dev *sdev) 312 { 313 struct hdac_bus *bus = sof_to_bus(sdev); 314 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 315 struct hdac_ext_link *hlink; 316 struct snd_soc_acpi_mach_params *mach_params; 317 struct snd_soc_acpi_mach *hda_mach; 318 struct snd_sof_pdata *pdata = sdev->pdata; 319 struct snd_soc_acpi_mach *mach; 320 const char *tplg_filename; 321 int codec_num = 0; 322 int i; 323 #endif 324 int ret = 0; 325 326 device_disable_async_suspend(bus->dev); 327 328 /* check if dsp is there */ 329 if (bus->ppcap) 330 dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n"); 331 332 ret = hda_dsp_ctrl_init_chip(sdev, true); 333 if (ret < 0) { 334 dev_err(bus->dev, "error: init chip failed with ret: %d\n", 335 ret); 336 return ret; 337 } 338 339 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 340 if (bus->mlcap) 341 snd_hdac_ext_bus_get_ml_capabilities(bus); 342 343 /* init i915 and HDMI codecs */ 344 ret = hda_codec_i915_init(sdev); 345 if (ret < 0) { 346 dev_err(sdev->dev, "error: no HDMI audio devices found\n"); 347 return ret; 348 } 349 350 /* codec detection */ 351 if (!bus->codec_mask) { 352 dev_info(bus->dev, "no hda codecs found!\n"); 353 } else { 354 dev_info(bus->dev, "hda codecs found, mask %lx\n", 355 bus->codec_mask); 356 357 for (i = 0; i < HDA_MAX_CODECS; i++) { 358 if (bus->codec_mask & (1 << i)) 359 codec_num++; 360 } 361 362 /* 363 * If no machine driver is found, then: 364 * 365 * hda machine driver is used if : 366 * 1. there is one HDMI codec and one external HDAudio codec 367 * 2. only HDMI codec 368 */ 369 if (!pdata->machine && codec_num <= 2 && 370 HDA_IDISP_CODEC(bus->codec_mask)) { 371 hda_mach = snd_soc_acpi_intel_hda_machines; 372 pdata->machine = hda_mach; 373 374 /* topology: use the info from hda_machines */ 375 pdata->tplg_filename = 376 hda_mach->sof_tplg_filename; 377 378 /* firmware: pick the first in machine list */ 379 mach = pdata->desc->machines; 380 pdata->fw_filename = mach->sof_fw_filename; 381 382 dev_info(bus->dev, "using HDA machine driver %s now\n", 383 hda_mach->drv_name); 384 385 /* fixup topology file for HDMI only platforms */ 386 if (codec_num == 1) { 387 /* use local variable for readability */ 388 tplg_filename = pdata->tplg_filename; 389 tplg_filename = fixup_tplg_name(sdev, tplg_filename); 390 if (!tplg_filename) { 391 hda_codec_i915_exit(sdev); 392 return ret; 393 } 394 pdata->tplg_filename = tplg_filename; 395 } 396 } 397 } 398 399 /* used by hda machine driver to create dai links */ 400 if (pdata->machine) { 401 mach_params = (struct snd_soc_acpi_mach_params *) 402 &pdata->machine->mach_params; 403 mach_params->codec_mask = bus->codec_mask; 404 mach_params->platform = dev_name(sdev->dev); 405 } 406 407 /* create codec instances */ 408 hda_codec_probe_bus(sdev); 409 410 hda_codec_i915_put(sdev); 411 412 /* 413 * we are done probing so decrement link counts 414 */ 415 list_for_each_entry(hlink, &bus->hlink_list, list) 416 snd_hdac_ext_bus_link_put(bus, hlink); 417 #endif 418 return 0; 419 } 420 421 static const struct sof_intel_dsp_desc 422 *get_chip_info(struct snd_sof_pdata *pdata) 423 { 424 const struct sof_dev_desc *desc = pdata->desc; 425 const struct sof_intel_dsp_desc *chip_info; 426 427 chip_info = desc->chip_info; 428 429 return chip_info; 430 } 431 432 int hda_dsp_probe(struct snd_sof_dev *sdev) 433 { 434 struct pci_dev *pci = to_pci_dev(sdev->dev); 435 struct sof_intel_hda_dev *hdev; 436 struct hdac_bus *bus; 437 const struct sof_intel_dsp_desc *chip; 438 int ret = 0; 439 440 /* 441 * detect DSP by checking class/subclass/prog-id information 442 * class=04 subclass 03 prog-if 00: no DSP, legacy driver is required 443 * class=04 subclass 01 prog-if 00: DSP is present 444 * (and may be required e.g. for DMIC or SSP support) 445 * class=04 subclass 03 prog-if 80: either of DSP or legacy mode works 446 */ 447 if (pci->class == 0x040300) { 448 dev_err(sdev->dev, "error: the DSP is not enabled on this platform, aborting probe\n"); 449 return -ENODEV; 450 } else if (pci->class != 0x040100 && pci->class != 0x040380) { 451 dev_err(sdev->dev, "error: unknown PCI class/subclass/prog-if 0x%06x found, aborting probe\n", pci->class); 452 return -ENODEV; 453 } 454 dev_info(sdev->dev, "DSP detected with PCI class/subclass/prog-if 0x%06x\n", pci->class); 455 456 chip = get_chip_info(sdev->pdata); 457 if (!chip) { 458 dev_err(sdev->dev, "error: no such device supported, chip id:%x\n", 459 pci->device); 460 ret = -EIO; 461 goto err; 462 } 463 464 hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL); 465 if (!hdev) 466 return -ENOMEM; 467 sdev->pdata->hw_pdata = hdev; 468 hdev->desc = chip; 469 470 hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", 471 PLATFORM_DEVID_NONE, 472 NULL, 0); 473 if (IS_ERR(hdev->dmic_dev)) { 474 dev_err(sdev->dev, "error: failed to create DMIC device\n"); 475 return PTR_ERR(hdev->dmic_dev); 476 } 477 478 /* 479 * use position update IPC if either it is forced 480 * or we don't have other choice 481 */ 482 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION) 483 hdev->no_ipc_position = 0; 484 #else 485 hdev->no_ipc_position = sof_ops(sdev)->pcm_pointer ? 1 : 0; 486 #endif 487 488 /* set up HDA base */ 489 bus = sof_to_bus(sdev); 490 ret = hda_init(sdev); 491 if (ret < 0) 492 goto hdac_bus_unmap; 493 494 /* DSP base */ 495 #if IS_ENABLED(CONFIG_PCI) 496 sdev->bar[HDA_DSP_BAR] = pci_ioremap_bar(pci, HDA_DSP_BAR); 497 #endif 498 if (!sdev->bar[HDA_DSP_BAR]) { 499 dev_err(sdev->dev, "error: ioremap error\n"); 500 ret = -ENXIO; 501 goto hdac_bus_unmap; 502 } 503 504 sdev->mmio_bar = HDA_DSP_BAR; 505 sdev->mailbox_bar = HDA_DSP_BAR; 506 507 /* allow 64bit DMA address if supported by H/W */ 508 if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(64))) { 509 dev_dbg(sdev->dev, "DMA mask is 64 bit\n"); 510 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(64)); 511 } else { 512 dev_dbg(sdev->dev, "DMA mask is 32 bit\n"); 513 dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); 514 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); 515 } 516 517 /* init streams */ 518 ret = hda_dsp_stream_init(sdev); 519 if (ret < 0) { 520 dev_err(sdev->dev, "error: failed to init streams\n"); 521 /* 522 * not all errors are due to memory issues, but trying 523 * to free everything does not harm 524 */ 525 goto free_streams; 526 } 527 528 /* 529 * register our IRQ 530 * let's try to enable msi firstly 531 * if it fails, use legacy interrupt mode 532 * TODO: support interrupt mode selection with kernel parameter 533 * support msi multiple vectors 534 */ 535 ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI); 536 if (ret < 0) { 537 dev_info(sdev->dev, "use legacy interrupt mode\n"); 538 /* 539 * in IO-APIC mode, hda->irq and ipc_irq are using the same 540 * irq number of pci->irq 541 */ 542 hdev->irq = pci->irq; 543 sdev->ipc_irq = pci->irq; 544 sdev->msi_enabled = 0; 545 } else { 546 dev_info(sdev->dev, "use msi interrupt mode\n"); 547 hdev->irq = pci_irq_vector(pci, 0); 548 /* ipc irq number is the same of hda irq */ 549 sdev->ipc_irq = hdev->irq; 550 sdev->msi_enabled = 1; 551 } 552 553 dev_dbg(sdev->dev, "using HDA IRQ %d\n", hdev->irq); 554 ret = request_threaded_irq(hdev->irq, hda_dsp_stream_interrupt, 555 hda_dsp_stream_threaded_handler, 556 IRQF_SHARED, "AudioHDA", bus); 557 if (ret < 0) { 558 dev_err(sdev->dev, "error: failed to register HDA IRQ %d\n", 559 hdev->irq); 560 goto free_irq_vector; 561 } 562 563 dev_dbg(sdev->dev, "using IPC IRQ %d\n", sdev->ipc_irq); 564 ret = request_threaded_irq(sdev->ipc_irq, hda_dsp_ipc_irq_handler, 565 sof_ops(sdev)->irq_thread, IRQF_SHARED, 566 "AudioDSP", sdev); 567 if (ret < 0) { 568 dev_err(sdev->dev, "error: failed to register IPC IRQ %d\n", 569 sdev->ipc_irq); 570 goto free_hda_irq; 571 } 572 573 pci_set_master(pci); 574 synchronize_irq(pci->irq); 575 576 /* 577 * clear TCSEL to clear playback on some HD Audio 578 * codecs. PCI TCSEL is defined in the Intel manuals. 579 */ 580 snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0); 581 582 /* init HDA capabilities */ 583 ret = hda_init_caps(sdev); 584 if (ret < 0) 585 goto free_ipc_irq; 586 587 /* enable ppcap interrupt */ 588 hda_dsp_ctrl_ppcap_enable(sdev, true); 589 hda_dsp_ctrl_ppcap_int_enable(sdev, true); 590 591 /* initialize waitq for code loading */ 592 init_waitqueue_head(&sdev->waitq); 593 594 /* set default mailbox offset for FW ready message */ 595 sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET; 596 597 return 0; 598 599 free_ipc_irq: 600 free_irq(sdev->ipc_irq, sdev); 601 free_hda_irq: 602 free_irq(hdev->irq, bus); 603 free_irq_vector: 604 if (sdev->msi_enabled) 605 pci_free_irq_vectors(pci); 606 free_streams: 607 hda_dsp_stream_free(sdev); 608 /* dsp_unmap: not currently used */ 609 iounmap(sdev->bar[HDA_DSP_BAR]); 610 hdac_bus_unmap: 611 iounmap(bus->remap_addr); 612 err: 613 return ret; 614 } 615 616 int hda_dsp_remove(struct snd_sof_dev *sdev) 617 { 618 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 619 struct hdac_bus *bus = sof_to_bus(sdev); 620 struct pci_dev *pci = to_pci_dev(sdev->dev); 621 const struct sof_intel_dsp_desc *chip = hda->desc; 622 623 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 624 /* codec removal, invoke bus_device_remove */ 625 snd_hdac_ext_bus_device_remove(bus); 626 #endif 627 628 if (!IS_ERR_OR_NULL(hda->dmic_dev)) 629 platform_device_unregister(hda->dmic_dev); 630 631 /* disable DSP IRQ */ 632 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, 633 SOF_HDA_PPCTL_PIE, 0); 634 635 /* disable CIE and GIE interrupts */ 636 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, 637 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 0); 638 639 /* disable cores */ 640 if (chip) 641 hda_dsp_core_reset_power_down(sdev, chip->cores_mask); 642 643 /* disable DSP */ 644 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, 645 SOF_HDA_PPCTL_GPROCEN, 0); 646 647 free_irq(sdev->ipc_irq, sdev); 648 free_irq(hda->irq, bus); 649 if (sdev->msi_enabled) 650 pci_free_irq_vectors(pci); 651 652 hda_dsp_stream_free(sdev); 653 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 654 snd_hdac_link_free_all(bus); 655 #endif 656 657 iounmap(sdev->bar[HDA_DSP_BAR]); 658 iounmap(bus->remap_addr); 659 660 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 661 snd_hdac_ext_bus_exit(bus); 662 #endif 663 hda_codec_i915_exit(sdev); 664 665 return 0; 666 } 667 668 MODULE_LICENSE("Dual BSD/GPL"); 669