1 // SPDX-License-Identifier: (GPL-2.0-only 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 7 // 8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9 // 10 11 #include <linux/firmware.h> 12 #include <linux/module.h> 13 #include <sound/soc.h> 14 #include <sound/sof.h> 15 #include "sof-priv.h" 16 #include "sof-of-dev.h" 17 #include "ops.h" 18 19 #define CREATE_TRACE_POINTS 20 #include <trace/events/sof.h> 21 22 /* Module parameters for firmware, topology and IPC type override */ 23 static char *override_fw_path; 24 module_param_named(fw_path, override_fw_path, charp, 0444); 25 MODULE_PARM_DESC(fw_path, "alternate path for SOF firmware."); 26 27 static char *override_fw_filename; 28 module_param_named(fw_filename, override_fw_filename, charp, 0444); 29 MODULE_PARM_DESC(fw_filename, "alternate filename for SOF firmware."); 30 31 static char *override_lib_path; 32 module_param_named(lib_path, override_lib_path, charp, 0444); 33 MODULE_PARM_DESC(lib_path, "alternate path for SOF firmware libraries."); 34 35 static char *override_tplg_path; 36 module_param_named(tplg_path, override_tplg_path, charp, 0444); 37 MODULE_PARM_DESC(tplg_path, "alternate path for SOF topology."); 38 39 static char *override_tplg_filename; 40 module_param_named(tplg_filename, override_tplg_filename, charp, 0444); 41 MODULE_PARM_DESC(tplg_filename, "alternate filename for SOF topology."); 42 43 static int override_ipc_type = -1; 44 module_param_named(ipc_type, override_ipc_type, int, 0444); 45 MODULE_PARM_DESC(ipc_type, "Force SOF IPC type. 0 - IPC3, 1 - IPC4"); 46 47 /* see SOF_DBG_ flags */ 48 static int sof_core_debug = IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE); 49 module_param_named(sof_debug, sof_core_debug, int, 0444); 50 MODULE_PARM_DESC(sof_debug, "SOF core debug options (0x0 all off)"); 51 52 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG) 53 static unsigned int sof_ipc_timeout_ms; 54 static unsigned int sof_boot_timeout_ms; 55 module_param_named(ipc_timeout, sof_ipc_timeout_ms, uint, 0444); 56 MODULE_PARM_DESC(ipc_timeout, 57 "Set the IPC timeout value in ms (0 to use the platform default)"); 58 module_param_named(boot_timeout, sof_boot_timeout_ms, uint, 0444); 59 MODULE_PARM_DESC(boot_timeout, 60 "Set the DSP boot timeout value in ms (0 to use the platform default)"); 61 #endif 62 63 /* SOF defaults if not provided by the platform in ms */ 64 #define TIMEOUT_DEFAULT_IPC_MS 500 65 #define TIMEOUT_DEFAULT_BOOT_MS 2000 66 67 /** 68 * sof_debug_check_flag - check if a given flag(s) is set in sof_core_debug 69 * @mask: Flag or combination of flags to check 70 * 71 * Returns true if all bits set in mask is also set in sof_core_debug, otherwise 72 * false 73 */ 74 bool sof_debug_check_flag(int mask) 75 { 76 if ((sof_core_debug & mask) == mask) 77 return true; 78 79 return false; 80 } 81 EXPORT_SYMBOL(sof_debug_check_flag); 82 83 /* 84 * FW Panic/fault handling. 85 */ 86 87 struct sof_panic_msg { 88 u32 id; 89 const char *msg; 90 }; 91 92 /* standard FW panic types */ 93 static const struct sof_panic_msg panic_msg[] = { 94 {SOF_IPC_PANIC_MEM, "out of memory"}, 95 {SOF_IPC_PANIC_WORK, "work subsystem init failed"}, 96 {SOF_IPC_PANIC_IPC, "IPC subsystem init failed"}, 97 {SOF_IPC_PANIC_ARCH, "arch init failed"}, 98 {SOF_IPC_PANIC_PLATFORM, "platform init failed"}, 99 {SOF_IPC_PANIC_TASK, "scheduler init failed"}, 100 {SOF_IPC_PANIC_EXCEPTION, "runtime exception"}, 101 {SOF_IPC_PANIC_DEADLOCK, "deadlock"}, 102 {SOF_IPC_PANIC_STACK, "stack overflow"}, 103 {SOF_IPC_PANIC_IDLE, "can't enter idle"}, 104 {SOF_IPC_PANIC_WFI, "invalid wait state"}, 105 {SOF_IPC_PANIC_ASSERT, "assertion failed"}, 106 }; 107 108 /** 109 * sof_print_oops_and_stack - Handle the printing of DSP oops and stack trace 110 * @sdev: Pointer to the device's sdev 111 * @level: prink log level to use for the printing 112 * @panic_code: the panic code 113 * @tracep_code: tracepoint code 114 * @oops: Pointer to DSP specific oops data 115 * @panic_info: Pointer to the received panic information message 116 * @stack: Pointer to the call stack data 117 * @stack_words: Number of words in the stack data 118 * 119 * helper to be called from .dbg_dump callbacks. No error code is 120 * provided, it's left as an exercise for the caller of .dbg_dump 121 * (typically IPC or loader) 122 */ 123 void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, 124 u32 panic_code, u32 tracep_code, void *oops, 125 struct sof_ipc_panic_info *panic_info, 126 void *stack, size_t stack_words) 127 { 128 u32 code; 129 int i; 130 131 /* is firmware dead ? */ 132 if ((panic_code & SOF_IPC_PANIC_MAGIC_MASK) != SOF_IPC_PANIC_MAGIC) { 133 dev_printk(level, sdev->dev, "unexpected fault %#010x trace %#010x\n", 134 panic_code, tracep_code); 135 return; /* no fault ? */ 136 } 137 138 code = panic_code & (SOF_IPC_PANIC_MAGIC_MASK | SOF_IPC_PANIC_CODE_MASK); 139 140 for (i = 0; i < ARRAY_SIZE(panic_msg); i++) { 141 if (panic_msg[i].id == code) { 142 dev_printk(level, sdev->dev, "reason: %s (%#x)\n", 143 panic_msg[i].msg, code & SOF_IPC_PANIC_CODE_MASK); 144 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); 145 goto out; 146 } 147 } 148 149 /* unknown error */ 150 dev_printk(level, sdev->dev, "unknown panic code: %#x\n", 151 code & SOF_IPC_PANIC_CODE_MASK); 152 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); 153 154 out: 155 dev_printk(level, sdev->dev, "panic at %s:%d\n", panic_info->filename, 156 panic_info->linenum); 157 sof_oops(sdev, level, oops); 158 sof_stack(sdev, level, oops, stack, stack_words); 159 } 160 EXPORT_SYMBOL(sof_print_oops_and_stack); 161 162 /* Helper to manage DSP state */ 163 void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state) 164 { 165 if (sdev->fw_state == new_state) 166 return; 167 168 dev_dbg(sdev->dev, "fw_state change: %d -> %d\n", sdev->fw_state, new_state); 169 sdev->fw_state = new_state; 170 171 switch (new_state) { 172 case SOF_FW_BOOT_NOT_STARTED: 173 case SOF_FW_BOOT_COMPLETE: 174 case SOF_FW_CRASHED: 175 sof_client_fw_state_dispatcher(sdev); 176 fallthrough; 177 default: 178 break; 179 } 180 } 181 EXPORT_SYMBOL(sof_set_fw_state); 182 183 static struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev) 184 { 185 struct snd_sof_pdata *sof_pdata = sdev->pdata; 186 const struct sof_dev_desc *desc = sof_pdata->desc; 187 struct snd_sof_of_mach *mach = desc->of_machines; 188 189 if (!mach) 190 return NULL; 191 192 for (; mach->compatible; mach++) { 193 if (of_machine_is_compatible(mach->compatible)) { 194 sof_pdata->tplg_filename = mach->sof_tplg_filename; 195 if (mach->fw_filename) 196 sof_pdata->fw_filename = mach->fw_filename; 197 198 return mach; 199 } 200 } 201 202 return NULL; 203 } 204 205 /* SOF Driver enumeration */ 206 static int sof_machine_check(struct snd_sof_dev *sdev) 207 { 208 struct snd_sof_pdata *sof_pdata = sdev->pdata; 209 const struct sof_dev_desc *desc = sof_pdata->desc; 210 struct snd_soc_acpi_mach *mach; 211 212 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) { 213 const struct snd_sof_of_mach *of_mach; 214 215 if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && 216 sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) 217 goto nocodec; 218 219 /* find machine */ 220 mach = snd_sof_machine_select(sdev); 221 if (mach) { 222 sof_pdata->machine = mach; 223 224 if (sof_pdata->subsystem_id_set) { 225 mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; 226 mach->mach_params.subsystem_device = sof_pdata->subsystem_device; 227 mach->mach_params.subsystem_id_set = true; 228 } 229 230 snd_sof_set_mach_params(mach, sdev); 231 return 0; 232 } 233 234 of_mach = sof_of_machine_select(sdev); 235 if (of_mach) { 236 sof_pdata->of_machine = of_mach; 237 return 0; 238 } 239 240 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) { 241 dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); 242 return -ENODEV; 243 } 244 } else { 245 dev_warn(sdev->dev, "Force to use nocodec mode\n"); 246 } 247 248 nocodec: 249 /* select nocodec mode */ 250 dev_warn(sdev->dev, "Using nocodec machine driver\n"); 251 mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); 252 if (!mach) 253 return -ENOMEM; 254 255 mach->drv_name = "sof-nocodec"; 256 if (!sof_pdata->tplg_filename) 257 sof_pdata->tplg_filename = desc->nocodec_tplg_filename; 258 259 sof_pdata->machine = mach; 260 snd_sof_set_mach_params(mach, sdev); 261 262 return 0; 263 } 264 265 static int sof_select_ipc_and_paths(struct snd_sof_dev *sdev) 266 { 267 struct snd_sof_pdata *plat_data = sdev->pdata; 268 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; 269 struct sof_loadable_file_profile out_profile; 270 struct device *dev = sdev->dev; 271 int ret; 272 273 if (base_profile->ipc_type != plat_data->desc->ipc_default) 274 dev_info(dev, 275 "Module parameter used, overriding default IPC %d to %d\n", 276 plat_data->desc->ipc_default, base_profile->ipc_type); 277 278 if (base_profile->fw_path) 279 dev_dbg(dev, "Module parameter used, changed fw path to %s\n", 280 base_profile->fw_path); 281 else if (base_profile->fw_path_postfix) 282 dev_dbg(dev, "Path postfix appended to default fw path: %s\n", 283 base_profile->fw_path_postfix); 284 285 if (base_profile->fw_lib_path) 286 dev_dbg(dev, "Module parameter used, changed fw_lib path to %s\n", 287 base_profile->fw_lib_path); 288 else if (base_profile->fw_lib_path_postfix) 289 dev_dbg(dev, "Path postfix appended to default fw_lib path: %s\n", 290 base_profile->fw_lib_path_postfix); 291 292 if (base_profile->fw_name) 293 dev_dbg(dev, "Module parameter used, changed fw filename to %s\n", 294 base_profile->fw_name); 295 296 if (base_profile->tplg_path) 297 dev_dbg(dev, "Module parameter used, changed tplg path to %s\n", 298 base_profile->tplg_path); 299 300 if (base_profile->tplg_name) 301 dev_dbg(dev, "Module parameter used, changed tplg name to %s\n", 302 base_profile->tplg_name); 303 304 ret = sof_create_ipc_file_profile(sdev, base_profile, &out_profile); 305 if (ret) 306 return ret; 307 308 plat_data->ipc_type = out_profile.ipc_type; 309 plat_data->fw_filename = out_profile.fw_name; 310 plat_data->fw_filename_prefix = out_profile.fw_path; 311 plat_data->fw_lib_prefix = out_profile.fw_lib_path; 312 plat_data->tplg_filename_prefix = out_profile.tplg_path; 313 314 return 0; 315 } 316 317 static int validate_sof_ops(struct snd_sof_dev *sdev) 318 { 319 int ret; 320 321 /* init ops, if necessary */ 322 ret = sof_ops_init(sdev); 323 if (ret < 0) 324 return ret; 325 326 /* check all mandatory ops */ 327 if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { 328 dev_err(sdev->dev, "missing mandatory ops\n"); 329 sof_ops_free(sdev); 330 return -EINVAL; 331 } 332 333 if (!sdev->dspless_mode_selected && 334 (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || 335 !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || 336 !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { 337 dev_err(sdev->dev, "missing mandatory DSP ops\n"); 338 sof_ops_free(sdev); 339 return -EINVAL; 340 } 341 342 return 0; 343 } 344 345 static int sof_init_sof_ops(struct snd_sof_dev *sdev) 346 { 347 struct snd_sof_pdata *plat_data = sdev->pdata; 348 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; 349 350 /* check IPC support */ 351 if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) { 352 dev_err(sdev->dev, 353 "ipc_type %d is not supported on this platform, mask is %#x\n", 354 base_profile->ipc_type, plat_data->desc->ipc_supported_mask); 355 return -EINVAL; 356 } 357 358 /* 359 * Save the selected IPC type and a topology name override before 360 * selecting ops since platform code might need this information 361 */ 362 plat_data->ipc_type = base_profile->ipc_type; 363 plat_data->tplg_filename = base_profile->tplg_name; 364 365 return validate_sof_ops(sdev); 366 } 367 368 static int sof_init_environment(struct snd_sof_dev *sdev) 369 { 370 struct snd_sof_pdata *plat_data = sdev->pdata; 371 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; 372 int ret; 373 374 /* probe the DSP hardware */ 375 ret = snd_sof_probe(sdev); 376 if (ret < 0) { 377 dev_err(sdev->dev, "failed to probe DSP %d\n", ret); 378 goto err_sof_probe; 379 } 380 381 /* check machine info */ 382 ret = sof_machine_check(sdev); 383 if (ret < 0) { 384 dev_err(sdev->dev, "failed to get machine info %d\n", ret); 385 goto err_machine_check; 386 } 387 388 ret = sof_select_ipc_and_paths(sdev); 389 if (ret) { 390 goto err_machine_check; 391 } else if (plat_data->ipc_type != base_profile->ipc_type) { 392 /* IPC type changed, re-initialize the ops */ 393 sof_ops_free(sdev); 394 395 ret = validate_sof_ops(sdev); 396 if (ret < 0) { 397 snd_sof_remove(sdev); 398 snd_sof_remove_late(sdev); 399 return ret; 400 } 401 } 402 403 return 0; 404 405 err_machine_check: 406 snd_sof_remove(sdev); 407 err_sof_probe: 408 snd_sof_remove_late(sdev); 409 sof_ops_free(sdev); 410 411 return ret; 412 } 413 414 /* 415 * FW Boot State Transition Diagram 416 * 417 * +----------------------------------------------------------------------+ 418 * | | 419 * ------------------ ------------------ | 420 * | | | | | 421 * | BOOT_FAILED |<-------| READY_FAILED | | 422 * | |<--+ | | ------------------ | 423 * ------------------ | ------------------ | | | 424 * ^ | ^ | CRASHED |---+ | 425 * | | | | | | | 426 * (FW Boot Timeout) | (FW_READY FAIL) ------------------ | | 427 * | | | ^ | | 428 * | | | |(DSP Panic) | | 429 * ------------------ | | ------------------ | | 430 * | | | | | | | | 431 * | IN_PROGRESS |---------------+------------->| COMPLETE | | | 432 * | | (FW Boot OK) (FW_READY OK) | | | | 433 * ------------------ | ------------------ | | 434 * ^ | | | | 435 * | | | | | 436 * (FW Loading OK) | (System Suspend/Runtime Suspend) 437 * | | | | | 438 * | (FW Loading Fail) | | | 439 * ------------------ | ------------------ | | | 440 * | | | | |<-----+ | | 441 * | PREPARE |---+ | NOT_STARTED |<---------------------+ | 442 * | | | |<--------------------------+ 443 * ------------------ ------------------ 444 * | ^ | ^ 445 * | | | | 446 * | +-----------------------+ | 447 * | (DSP Probe OK) | 448 * | | 449 * | | 450 * +------------------------------------+ 451 * (System Suspend/Runtime Suspend) 452 */ 453 454 static int sof_probe_continue(struct snd_sof_dev *sdev) 455 { 456 struct snd_sof_pdata *plat_data = sdev->pdata; 457 int ret; 458 459 /* Initialize loadable file paths and check the environment validity */ 460 ret = sof_init_environment(sdev); 461 if (ret) 462 return ret; 463 464 sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE); 465 466 /* set up platform component driver */ 467 snd_sof_new_platform_drv(sdev); 468 469 if (sdev->dspless_mode_selected) { 470 sof_set_fw_state(sdev, SOF_DSPLESS_MODE); 471 goto skip_dsp_init; 472 } 473 474 /* register any debug/trace capabilities */ 475 ret = snd_sof_dbg_init(sdev); 476 if (ret < 0) { 477 /* 478 * debugfs issues are suppressed in snd_sof_dbg_init() since 479 * we cannot rely on debugfs 480 * here we trap errors due to memory allocation only. 481 */ 482 dev_err(sdev->dev, "error: failed to init DSP trace/debug %d\n", 483 ret); 484 goto dbg_err; 485 } 486 487 /* init the IPC */ 488 sdev->ipc = snd_sof_ipc_init(sdev); 489 if (!sdev->ipc) { 490 ret = -ENOMEM; 491 dev_err(sdev->dev, "error: failed to init DSP IPC %d\n", ret); 492 goto ipc_err; 493 } 494 495 /* load the firmware */ 496 ret = snd_sof_load_firmware(sdev); 497 if (ret < 0) { 498 dev_err(sdev->dev, "error: failed to load DSP firmware %d\n", 499 ret); 500 sof_set_fw_state(sdev, SOF_FW_BOOT_FAILED); 501 goto fw_load_err; 502 } 503 504 sof_set_fw_state(sdev, SOF_FW_BOOT_IN_PROGRESS); 505 506 /* 507 * Boot the firmware. The FW boot status will be modified 508 * in snd_sof_run_firmware() depending on the outcome. 509 */ 510 ret = snd_sof_run_firmware(sdev); 511 if (ret < 0) { 512 dev_err(sdev->dev, "error: failed to boot DSP firmware %d\n", 513 ret); 514 sof_set_fw_state(sdev, SOF_FW_BOOT_FAILED); 515 goto fw_run_err; 516 } 517 518 if (sof_debug_check_flag(SOF_DBG_ENABLE_TRACE)) { 519 sdev->fw_trace_is_supported = true; 520 521 /* init firmware tracing */ 522 ret = sof_fw_trace_init(sdev); 523 if (ret < 0) { 524 /* non fatal */ 525 dev_warn(sdev->dev, "failed to initialize firmware tracing %d\n", 526 ret); 527 } 528 } else { 529 dev_dbg(sdev->dev, "SOF firmware trace disabled\n"); 530 } 531 532 skip_dsp_init: 533 /* hereafter all FW boot flows are for PM reasons */ 534 sdev->first_boot = false; 535 536 /* now register audio DSP platform driver and dai */ 537 ret = devm_snd_soc_register_component(sdev->dev, &sdev->plat_drv, 538 sof_ops(sdev)->drv, 539 sof_ops(sdev)->num_drv); 540 if (ret < 0) { 541 dev_err(sdev->dev, 542 "error: failed to register DSP DAI driver %d\n", ret); 543 goto fw_trace_err; 544 } 545 546 ret = snd_sof_machine_register(sdev, plat_data); 547 if (ret < 0) { 548 dev_err(sdev->dev, 549 "error: failed to register machine driver %d\n", ret); 550 goto fw_trace_err; 551 } 552 553 ret = sof_register_clients(sdev); 554 if (ret < 0) { 555 dev_err(sdev->dev, "failed to register clients %d\n", ret); 556 goto sof_machine_err; 557 } 558 559 /* 560 * Some platforms in SOF, ex: BYT, may not have their platform PM 561 * callbacks set. Increment the usage count so as to 562 * prevent the device from entering runtime suspend. 563 */ 564 if (!sof_ops(sdev)->runtime_suspend || !sof_ops(sdev)->runtime_resume) 565 pm_runtime_get_noresume(sdev->dev); 566 567 if (plat_data->sof_probe_complete) 568 plat_data->sof_probe_complete(sdev->dev); 569 570 sdev->probe_completed = true; 571 572 return 0; 573 574 sof_machine_err: 575 snd_sof_machine_unregister(sdev, plat_data); 576 fw_trace_err: 577 sof_fw_trace_free(sdev); 578 fw_run_err: 579 snd_sof_fw_unload(sdev); 580 fw_load_err: 581 snd_sof_ipc_free(sdev); 582 ipc_err: 583 dbg_err: 584 snd_sof_free_debug(sdev); 585 snd_sof_remove(sdev); 586 snd_sof_remove_late(sdev); 587 sof_ops_free(sdev); 588 589 /* all resources freed, update state to match */ 590 sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); 591 sdev->first_boot = true; 592 593 return ret; 594 } 595 596 static void sof_probe_work(struct work_struct *work) 597 { 598 struct snd_sof_dev *sdev = 599 container_of(work, struct snd_sof_dev, probe_work); 600 int ret; 601 602 ret = sof_probe_continue(sdev); 603 if (ret < 0) { 604 /* errors cannot be propagated, log */ 605 dev_err(sdev->dev, "error: %s failed err: %d\n", __func__, ret); 606 } 607 } 608 609 static void 610 sof_apply_profile_override(struct sof_loadable_file_profile *path_override) 611 { 612 if (override_ipc_type >= 0 && override_ipc_type < SOF_IPC_TYPE_COUNT) 613 path_override->ipc_type = override_ipc_type; 614 if (override_fw_path) 615 path_override->fw_path = override_fw_path; 616 if (override_fw_filename) 617 path_override->fw_name = override_fw_filename; 618 if (override_lib_path) 619 path_override->fw_lib_path = override_lib_path; 620 if (override_tplg_path) 621 path_override->tplg_path = override_tplg_path; 622 if (override_tplg_filename) 623 path_override->tplg_name = override_tplg_filename; 624 } 625 626 int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) 627 { 628 struct snd_sof_dev *sdev; 629 int ret; 630 631 sdev = devm_kzalloc(dev, sizeof(*sdev), GFP_KERNEL); 632 if (!sdev) 633 return -ENOMEM; 634 635 /* initialize sof device */ 636 sdev->dev = dev; 637 638 /* initialize default DSP power state */ 639 sdev->dsp_power_state.state = SOF_DSP_PM_D0; 640 641 sdev->pdata = plat_data; 642 sdev->first_boot = true; 643 dev_set_drvdata(dev, sdev); 644 645 if (sof_core_debug) 646 dev_info(dev, "sof_debug value: %#x\n", sof_core_debug); 647 648 if (sof_debug_check_flag(SOF_DBG_DSPLESS_MODE)) { 649 if (plat_data->desc->dspless_mode_supported) { 650 dev_info(dev, "Switching to DSPless mode\n"); 651 sdev->dspless_mode_selected = true; 652 } else { 653 dev_info(dev, "DSPless mode is not supported by the platform\n"); 654 } 655 } 656 657 sof_apply_profile_override(&plat_data->ipc_file_profile_base); 658 659 /* Initialize sof_ops based on the initial selected IPC version */ 660 ret = sof_init_sof_ops(sdev); 661 if (ret) 662 return ret; 663 664 INIT_LIST_HEAD(&sdev->pcm_list); 665 INIT_LIST_HEAD(&sdev->kcontrol_list); 666 INIT_LIST_HEAD(&sdev->widget_list); 667 INIT_LIST_HEAD(&sdev->pipeline_list); 668 INIT_LIST_HEAD(&sdev->dai_list); 669 INIT_LIST_HEAD(&sdev->dai_link_list); 670 INIT_LIST_HEAD(&sdev->route_list); 671 INIT_LIST_HEAD(&sdev->ipc_client_list); 672 INIT_LIST_HEAD(&sdev->ipc_rx_handler_list); 673 INIT_LIST_HEAD(&sdev->fw_state_handler_list); 674 spin_lock_init(&sdev->ipc_lock); 675 spin_lock_init(&sdev->hw_lock); 676 mutex_init(&sdev->power_state_access); 677 mutex_init(&sdev->ipc_client_mutex); 678 mutex_init(&sdev->client_event_handler_mutex); 679 680 /* set default timeouts if none provided */ 681 if (plat_data->desc->ipc_timeout == 0) 682 sdev->ipc_timeout = TIMEOUT_DEFAULT_IPC_MS; 683 else 684 sdev->ipc_timeout = plat_data->desc->ipc_timeout; 685 if (plat_data->desc->boot_timeout == 0) 686 sdev->boot_timeout = TIMEOUT_DEFAULT_BOOT_MS; 687 else 688 sdev->boot_timeout = plat_data->desc->boot_timeout; 689 690 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG) 691 /* Override the timeout values with module parameter, if set */ 692 if (sof_ipc_timeout_ms) 693 sdev->ipc_timeout = sof_ipc_timeout_ms; 694 695 if (sof_boot_timeout_ms) 696 sdev->boot_timeout = sof_boot_timeout_ms; 697 #endif 698 699 sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); 700 701 /* 702 * first pass of probe which isn't allowed to run in a work-queue, 703 * typically to rely on -EPROBE_DEFER dependencies 704 */ 705 ret = snd_sof_probe_early(sdev); 706 if (ret < 0) 707 return ret; 708 709 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) { 710 INIT_WORK(&sdev->probe_work, sof_probe_work); 711 schedule_work(&sdev->probe_work); 712 return 0; 713 } 714 715 return sof_probe_continue(sdev); 716 } 717 EXPORT_SYMBOL(snd_sof_device_probe); 718 719 bool snd_sof_device_probe_completed(struct device *dev) 720 { 721 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 722 723 return sdev->probe_completed; 724 } 725 EXPORT_SYMBOL(snd_sof_device_probe_completed); 726 727 int snd_sof_device_remove(struct device *dev) 728 { 729 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 730 struct snd_sof_pdata *pdata = sdev->pdata; 731 int ret; 732 bool aborted = false; 733 734 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) 735 aborted = cancel_work_sync(&sdev->probe_work); 736 737 /* 738 * Unregister any registered client device first before IPC and debugfs 739 * to allow client drivers to be removed cleanly 740 */ 741 sof_unregister_clients(sdev); 742 743 /* 744 * Unregister machine driver. This will unbind the snd_card which 745 * will remove the component driver and unload the topology 746 * before freeing the snd_card. 747 */ 748 snd_sof_machine_unregister(sdev, pdata); 749 750 /* 751 * Balance the runtime pm usage count in case we are faced with an 752 * exception and we forcably prevented D3 power state to preserve 753 * context 754 */ 755 if (sdev->d3_prevented) { 756 sdev->d3_prevented = false; 757 pm_runtime_put_noidle(sdev->dev); 758 } 759 760 if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { 761 sof_fw_trace_free(sdev); 762 ret = snd_sof_dsp_power_down_notify(sdev); 763 if (ret < 0) 764 dev_warn(dev, "error: %d failed to prepare DSP for device removal", 765 ret); 766 767 snd_sof_ipc_free(sdev); 768 snd_sof_free_debug(sdev); 769 snd_sof_remove(sdev); 770 snd_sof_remove_late(sdev); 771 sof_ops_free(sdev); 772 } else if (aborted) { 773 /* probe_work never ran */ 774 snd_sof_remove_late(sdev); 775 sof_ops_free(sdev); 776 } 777 778 /* release firmware */ 779 snd_sof_fw_unload(sdev); 780 781 return 0; 782 } 783 EXPORT_SYMBOL(snd_sof_device_remove); 784 785 int snd_sof_device_shutdown(struct device *dev) 786 { 787 struct snd_sof_dev *sdev = dev_get_drvdata(dev); 788 789 if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) 790 cancel_work_sync(&sdev->probe_work); 791 792 if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { 793 sof_fw_trace_free(sdev); 794 return snd_sof_shutdown(sdev); 795 } 796 797 return 0; 798 } 799 EXPORT_SYMBOL(snd_sof_device_shutdown); 800 801 /* Machine driver registering and unregistering */ 802 int sof_machine_register(struct snd_sof_dev *sdev, void *pdata) 803 { 804 struct snd_sof_pdata *plat_data = pdata; 805 const char *drv_name; 806 const void *mach; 807 int size; 808 809 drv_name = plat_data->machine->drv_name; 810 mach = plat_data->machine; 811 size = sizeof(*plat_data->machine); 812 813 /* register machine driver, pass machine info as pdata */ 814 plat_data->pdev_mach = 815 platform_device_register_data(sdev->dev, drv_name, 816 PLATFORM_DEVID_NONE, mach, size); 817 if (IS_ERR(plat_data->pdev_mach)) 818 return PTR_ERR(plat_data->pdev_mach); 819 820 dev_dbg(sdev->dev, "created machine %s\n", 821 dev_name(&plat_data->pdev_mach->dev)); 822 823 return 0; 824 } 825 EXPORT_SYMBOL(sof_machine_register); 826 827 void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) 828 { 829 struct snd_sof_pdata *plat_data = pdata; 830 831 platform_device_unregister(plat_data->pdev_mach); 832 } 833 EXPORT_SYMBOL(sof_machine_unregister); 834 835 MODULE_AUTHOR("Liam Girdwood"); 836 MODULE_LICENSE("Dual BSD/GPL"); 837 MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core"); 838 MODULE_ALIAS("platform:sof-audio"); 839 MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT); 840