Lines Matching +full:machine +full:- +full:level

1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
15 #include "sof-priv.h"
16 #include "sof-of-dev.h"
32 * sof_debug_check_flag - check if a given flag(s) is set in sof_core_debug
73 * sof_print_oops_and_stack - Handle the printing of DSP oops and stack trace
75 * @level: prink log level to use for the printing
87 void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, in sof_print_oops_and_stack() argument
97 dev_printk(level, sdev->dev, "unexpected fault %#010x trace %#010x\n", in sof_print_oops_and_stack()
106 dev_printk(level, sdev->dev, "reason: %s (%#x)\n", in sof_print_oops_and_stack()
108 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); in sof_print_oops_and_stack()
114 dev_printk(level, sdev->dev, "unknown panic code: %#x\n", in sof_print_oops_and_stack()
116 dev_printk(level, sdev->dev, "trace point: %#010x\n", tracep_code); in sof_print_oops_and_stack()
119 dev_printk(level, sdev->dev, "panic at %s:%d\n", panic_info->filename, in sof_print_oops_and_stack()
120 panic_info->linenum); in sof_print_oops_and_stack()
121 sof_oops(sdev, level, oops); in sof_print_oops_and_stack()
122 sof_stack(sdev, level, oops, stack, stack_words); in sof_print_oops_and_stack()
129 if (sdev->fw_state == new_state) in sof_set_fw_state()
132 dev_dbg(sdev->dev, "fw_state change: %d -> %d\n", sdev->fw_state, new_state); in sof_set_fw_state()
133 sdev->fw_state = new_state; in sof_set_fw_state()
149 struct snd_sof_pdata *sof_pdata = sdev->pdata; in sof_of_machine_select()
150 const struct sof_dev_desc *desc = sof_pdata->desc; in sof_of_machine_select()
151 struct snd_sof_of_mach *mach = desc->of_machines; in sof_of_machine_select()
156 for (; mach->compatible; mach++) { in sof_of_machine_select()
157 if (of_machine_is_compatible(mach->compatible)) { in sof_of_machine_select()
158 sof_pdata->tplg_filename = mach->sof_tplg_filename; in sof_of_machine_select()
159 if (mach->fw_filename) in sof_of_machine_select()
160 sof_pdata->fw_filename = mach->fw_filename; in sof_of_machine_select()
172 struct snd_sof_pdata *sof_pdata = sdev->pdata; in sof_machine_check()
173 const struct sof_dev_desc *desc = sof_pdata->desc; in sof_machine_check()
183 /* find machine */ in sof_machine_check()
186 sof_pdata->machine = mach; in sof_machine_check()
188 if (sof_pdata->subsystem_id_set) { in sof_machine_check()
189 mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; in sof_machine_check()
190 mach->mach_params.subsystem_device = sof_pdata->subsystem_device; in sof_machine_check()
191 mach->mach_params.subsystem_id_set = true; in sof_machine_check()
200 sof_pdata->of_machine = of_mach; in sof_machine_check()
205 dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n"); in sof_machine_check()
206 return -ENODEV; in sof_machine_check()
209 dev_warn(sdev->dev, "Force to use nocodec mode\n"); in sof_machine_check()
214 dev_warn(sdev->dev, "Using nocodec machine driver\n"); in sof_machine_check()
215 mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); in sof_machine_check()
217 return -ENOMEM; in sof_machine_check()
219 mach->drv_name = "sof-nocodec"; in sof_machine_check()
220 if (!sof_pdata->tplg_filename) in sof_machine_check()
221 sof_pdata->tplg_filename = desc->nocodec_tplg_filename; in sof_machine_check()
223 sof_pdata->machine = mach; in sof_machine_check()
231 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_select_ipc_and_paths()
232 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_select_ipc_and_paths()
234 struct device *dev = sdev->dev; in sof_select_ipc_and_paths()
237 if (base_profile->ipc_type != plat_data->desc->ipc_default) in sof_select_ipc_and_paths()
240 plat_data->desc->ipc_default, base_profile->ipc_type); in sof_select_ipc_and_paths()
242 if (base_profile->fw_path) in sof_select_ipc_and_paths()
244 base_profile->fw_path); in sof_select_ipc_and_paths()
245 else if (base_profile->fw_path_postfix) in sof_select_ipc_and_paths()
247 base_profile->fw_path_postfix); in sof_select_ipc_and_paths()
249 if (base_profile->fw_lib_path) in sof_select_ipc_and_paths()
251 base_profile->fw_lib_path); in sof_select_ipc_and_paths()
252 else if (base_profile->fw_lib_path_postfix) in sof_select_ipc_and_paths()
254 base_profile->fw_lib_path_postfix); in sof_select_ipc_and_paths()
256 if (base_profile->fw_name) in sof_select_ipc_and_paths()
258 base_profile->fw_name); in sof_select_ipc_and_paths()
260 if (base_profile->tplg_path) in sof_select_ipc_and_paths()
262 base_profile->tplg_path); in sof_select_ipc_and_paths()
264 if (base_profile->tplg_name) in sof_select_ipc_and_paths()
266 base_profile->tplg_name); in sof_select_ipc_and_paths()
272 plat_data->ipc_type = out_profile.ipc_type; in sof_select_ipc_and_paths()
273 plat_data->fw_filename = out_profile.fw_name; in sof_select_ipc_and_paths()
274 plat_data->fw_filename_prefix = out_profile.fw_path; in sof_select_ipc_and_paths()
275 plat_data->fw_lib_prefix = out_profile.fw_lib_path; in sof_select_ipc_and_paths()
276 plat_data->tplg_filename_prefix = out_profile.tplg_path; in sof_select_ipc_and_paths()
291 if (!sof_ops(sdev) || !sof_ops(sdev)->probe) { in validate_sof_ops()
292 dev_err(sdev->dev, "missing mandatory ops\n"); in validate_sof_ops()
294 return -EINVAL; in validate_sof_ops()
297 if (!sdev->dspless_mode_selected && in validate_sof_ops()
298 (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read || in validate_sof_ops()
299 !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || in validate_sof_ops()
300 !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) { in validate_sof_ops()
301 dev_err(sdev->dev, "missing mandatory DSP ops\n"); in validate_sof_ops()
303 return -EINVAL; in validate_sof_ops()
311 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_init_sof_ops()
312 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_init_sof_ops()
315 if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) { in sof_init_sof_ops()
316 dev_err(sdev->dev, in sof_init_sof_ops()
318 base_profile->ipc_type, plat_data->desc->ipc_supported_mask); in sof_init_sof_ops()
319 return -EINVAL; in sof_init_sof_ops()
326 plat_data->ipc_type = base_profile->ipc_type; in sof_init_sof_ops()
327 plat_data->tplg_filename = base_profile->tplg_name; in sof_init_sof_ops()
334 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_init_environment()
335 struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base; in sof_init_environment()
341 dev_err(sdev->dev, "failed to probe DSP %d\n", ret); in sof_init_environment()
345 /* check machine info */ in sof_init_environment()
348 dev_err(sdev->dev, "failed to get machine info %d\n", ret); in sof_init_environment()
355 } else if (plat_data->ipc_type != base_profile->ipc_type) { in sof_init_environment()
356 /* IPC type changed, re-initialize the ops */ in sof_init_environment()
381 * +----------------------------------------------------------------------+
383 * ------------------ ------------------ |
385 * | BOOT_FAILED |<-------| READY_FAILED | |
386 * | |<--+ | | ------------------ |
387 * ------------------ | ------------------ | | |
388 * ^ | ^ | CRASHED |---+ |
390 * (FW Boot Timeout) | (FW_READY FAIL) ------------------ | |
393 * ------------------ | | ------------------ | |
395 * | IN_PROGRESS |---------------+------------->| COMPLETE | | |
397 * ------------------ | ------------------ | |
403 * ------------------ | ------------------ | | |
404 * | | | | |<-----+ | |
405 * | PREPARE |---+ | NOT_STARTED |<---------------------+ |
406 * | | | |<--------------------------+
407 * ------------------ ------------------
410 * | +-----------------------+ |
414 * +------------------------------------+
420 struct snd_sof_pdata *plat_data = sdev->pdata; in sof_probe_continue()
433 if (sdev->dspless_mode_selected) { in sof_probe_continue()
446 dev_err(sdev->dev, "error: failed to init DSP trace/debug %d\n", in sof_probe_continue()
452 sdev->ipc = snd_sof_ipc_init(sdev); in sof_probe_continue()
453 if (!sdev->ipc) { in sof_probe_continue()
454 ret = -ENOMEM; in sof_probe_continue()
455 dev_err(sdev->dev, "error: failed to init DSP IPC %d\n", ret); in sof_probe_continue()
462 dev_err(sdev->dev, "error: failed to load DSP firmware %d\n", in sof_probe_continue()
476 dev_err(sdev->dev, "error: failed to boot DSP firmware %d\n", in sof_probe_continue()
483 sdev->fw_trace_is_supported = true; in sof_probe_continue()
489 dev_warn(sdev->dev, "failed to initialize firmware tracing %d\n", in sof_probe_continue()
493 dev_dbg(sdev->dev, "SOF firmware trace disabled\n"); in sof_probe_continue()
498 sdev->first_boot = false; in sof_probe_continue()
501 ret = devm_snd_soc_register_component(sdev->dev, &sdev->plat_drv, in sof_probe_continue()
502 sof_ops(sdev)->drv, in sof_probe_continue()
503 sof_ops(sdev)->num_drv); in sof_probe_continue()
505 dev_err(sdev->dev, in sof_probe_continue()
512 dev_err(sdev->dev, in sof_probe_continue()
513 "error: failed to register machine driver %d\n", ret); in sof_probe_continue()
519 dev_err(sdev->dev, "failed to register clients %d\n", ret); in sof_probe_continue()
528 if (!sof_ops(sdev)->runtime_suspend || !sof_ops(sdev)->runtime_resume) in sof_probe_continue()
529 pm_runtime_get_noresume(sdev->dev); in sof_probe_continue()
531 if (plat_data->sof_probe_complete) in sof_probe_continue()
532 plat_data->sof_probe_complete(sdev->dev); in sof_probe_continue()
534 sdev->probe_completed = true; in sof_probe_continue()
555 sdev->first_boot = true; in sof_probe_continue()
569 dev_err(sdev->dev, "error: %s failed err: %d\n", __func__, ret); in sof_probe_work()
580 return -ENOMEM; in snd_sof_device_probe()
583 sdev->dev = dev; in snd_sof_device_probe()
586 sdev->dsp_power_state.state = SOF_DSP_PM_D0; in snd_sof_device_probe()
588 sdev->pdata = plat_data; in snd_sof_device_probe()
589 sdev->first_boot = true; in snd_sof_device_probe()
596 if (plat_data->desc->dspless_mode_supported) { in snd_sof_device_probe()
598 sdev->dspless_mode_selected = true; in snd_sof_device_probe()
609 INIT_LIST_HEAD(&sdev->pcm_list); in snd_sof_device_probe()
610 INIT_LIST_HEAD(&sdev->kcontrol_list); in snd_sof_device_probe()
611 INIT_LIST_HEAD(&sdev->widget_list); in snd_sof_device_probe()
612 INIT_LIST_HEAD(&sdev->pipeline_list); in snd_sof_device_probe()
613 INIT_LIST_HEAD(&sdev->dai_list); in snd_sof_device_probe()
614 INIT_LIST_HEAD(&sdev->dai_link_list); in snd_sof_device_probe()
615 INIT_LIST_HEAD(&sdev->route_list); in snd_sof_device_probe()
616 INIT_LIST_HEAD(&sdev->ipc_client_list); in snd_sof_device_probe()
617 INIT_LIST_HEAD(&sdev->ipc_rx_handler_list); in snd_sof_device_probe()
618 INIT_LIST_HEAD(&sdev->fw_state_handler_list); in snd_sof_device_probe()
619 spin_lock_init(&sdev->ipc_lock); in snd_sof_device_probe()
620 spin_lock_init(&sdev->hw_lock); in snd_sof_device_probe()
621 mutex_init(&sdev->power_state_access); in snd_sof_device_probe()
622 mutex_init(&sdev->ipc_client_mutex); in snd_sof_device_probe()
623 mutex_init(&sdev->client_event_handler_mutex); in snd_sof_device_probe()
626 if (plat_data->desc->ipc_timeout == 0) in snd_sof_device_probe()
627 sdev->ipc_timeout = TIMEOUT_DEFAULT_IPC_MS; in snd_sof_device_probe()
629 sdev->ipc_timeout = plat_data->desc->ipc_timeout; in snd_sof_device_probe()
630 if (plat_data->desc->boot_timeout == 0) in snd_sof_device_probe()
631 sdev->boot_timeout = TIMEOUT_DEFAULT_BOOT_MS; in snd_sof_device_probe()
633 sdev->boot_timeout = plat_data->desc->boot_timeout; in snd_sof_device_probe()
638 * first pass of probe which isn't allowed to run in a work-queue, in snd_sof_device_probe()
639 * typically to rely on -EPROBE_DEFER dependencies in snd_sof_device_probe()
646 INIT_WORK(&sdev->probe_work, sof_probe_work); in snd_sof_device_probe()
647 schedule_work(&sdev->probe_work); in snd_sof_device_probe()
659 return sdev->probe_completed; in snd_sof_device_probe_completed()
666 struct snd_sof_pdata *pdata = sdev->pdata; in snd_sof_device_remove()
671 aborted = cancel_work_sync(&sdev->probe_work); in snd_sof_device_remove()
680 * Unregister machine driver. This will unbind the snd_card which in snd_sof_device_remove()
691 if (sdev->d3_prevented) { in snd_sof_device_remove()
692 sdev->d3_prevented = false; in snd_sof_device_remove()
693 pm_runtime_put_noidle(sdev->dev); in snd_sof_device_remove()
696 if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { in snd_sof_device_remove()
726 cancel_work_sync(&sdev->probe_work); in snd_sof_device_shutdown()
728 if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { in snd_sof_device_shutdown()
737 /* Machine driver registering and unregistering */
745 drv_name = plat_data->machine->drv_name; in sof_machine_register()
746 mach = plat_data->machine; in sof_machine_register()
747 size = sizeof(*plat_data->machine); in sof_machine_register()
749 /* register machine driver, pass machine info as pdata */ in sof_machine_register()
750 plat_data->pdev_mach = in sof_machine_register()
751 platform_device_register_data(sdev->dev, drv_name, in sof_machine_register()
753 if (IS_ERR(plat_data->pdev_mach)) in sof_machine_register()
754 return PTR_ERR(plat_data->pdev_mach); in sof_machine_register()
756 dev_dbg(sdev->dev, "created machine %s\n", in sof_machine_register()
757 dev_name(&plat_data->pdev_mach->dev)); in sof_machine_register()
767 platform_device_unregister(plat_data->pdev_mach); in sof_machine_unregister()
774 MODULE_ALIAS("platform:sof-audio");