From 4b90ba9b10b10fe5b1071997b72e9e090c6e053c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 19 Oct 2023 10:52:48 -0500 Subject: [PATCH 01/19] Revert "ALSA: hda: hdac-i915: fix i915 timeout variable to msec" This reverts commit 479dd2bb40ae28e354a34f6318e28e56a119efcd. Signed-off-by: Pierre-Louis Bossart --- sound/hda/hdac_i915.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 5927d5200785ab..221c23a5b429c7 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -11,9 +11,9 @@ #include #include -static int hdac_i915_timeout_ms = 60000; +static int hdac_i915_timeout_ms = 60; module_param(hdac_i915_timeout_ms, int, 0444); -MODULE_PARM_DESC(hdac_i915_timeout_ms, "i915 initialization timeout in msec"); +MODULE_PARM_DESC(hdac_i915_timeout_ms, "i915 initialization timeout"); /** * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW @@ -170,7 +170,7 @@ int snd_hdac_i915_init(struct hdac_bus *bus) if (!IS_ENABLED(CONFIG_MODULES) || !request_module("i915")) { wait_for_completion_killable_timeout(&acomp->master_bind_complete, - msecs_to_jiffies(hdac_i915_timeout_ms)); + msecs_to_jiffies(hdac_i915_timeout_ms * 1000)); } } if (!acomp->ops) { From 6d6ad90ff2831f11aae876fef8ba2007a37e9c9b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 19 Oct 2023 10:53:06 -0500 Subject: [PATCH 02/19] Revert "ALSA: hda: hdac-i915: make i915 timeout configurable" This reverts commit c75dbfeb003b2b49529e28a063e298619cf2a6b5. Signed-off-by: Pierre-Louis Bossart --- sound/hda/hdac_i915.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 221c23a5b429c7..b428537f284c72 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -11,10 +11,6 @@ #include #include -static int hdac_i915_timeout_ms = 60; -module_param(hdac_i915_timeout_ms, int, 0444); -MODULE_PARM_DESC(hdac_i915_timeout_ms, "i915 initialization timeout"); - /** * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW * @bus: HDA core bus @@ -169,8 +165,9 @@ int snd_hdac_i915_init(struct hdac_bus *bus) if (!acomp->ops) { if (!IS_ENABLED(CONFIG_MODULES) || !request_module("i915")) { + /* 60s timeout */ wait_for_completion_killable_timeout(&acomp->master_bind_complete, - msecs_to_jiffies(hdac_i915_timeout_ms * 1000)); + msecs_to_jiffies(60 * 1000)); } } if (!acomp->ops) { From 93067d478ab1e38dec6309f5015b7b70dcd9b6f0 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 19 Oct 2023 11:01:07 -0500 Subject: [PATCH 03/19] Revert "ASoC: SOF: Intel: Use consistent name for struct sof_intel_hda_dev variable" This reverts commit 180286d83326ed5d306a49ae3d36147beb57644d. Signed-off-by: Pierre-Louis Bossart --- sound/soc/sof/intel/cnl.c | 18 ++-- sound/soc/sof/intel/hda-dsp.c | 7 +- sound/soc/sof/intel/hda-ipc.c | 18 ++-- sound/soc/sof/intel/hda-loader.c | 4 +- sound/soc/sof/intel/hda-stream.c | 8 +- sound/soc/sof/intel/hda.c | 152 +++++++++++++++---------------- sound/soc/sof/intel/hda.h | 2 +- sound/soc/sof/intel/icl.c | 4 +- sound/soc/sof/intel/mtl.c | 22 ++--- 9 files changed, 118 insertions(+), 117 deletions(-) diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 4b422d4258888f..598cf50abadb3a 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -102,10 +102,10 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context) dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n"); if (ack_received) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; - if (hda->delayed_ipc_tx_msg) - cnl_ipc4_send_msg(sdev, hda->delayed_ipc_tx_msg); + if (hdev->delayed_ipc_tx_msg) + cnl_ipc4_send_msg(sdev, hdev->delayed_ipc_tx_msg); } return IRQ_HANDLED; @@ -261,15 +261,15 @@ static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg, int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct sof_ipc4_msg *msg_data = msg->msg_data; if (hda_ipc4_tx_is_busy(sdev)) { - hda->delayed_ipc_tx_msg = msg; + hdev->delayed_ipc_tx_msg = msg; return 0; } - hda->delayed_ipc_tx_msg = NULL; + hdev->delayed_ipc_tx_msg = NULL; /* send the message via mailbox */ if (msg_data->data_size) @@ -280,14 +280,14 @@ int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, msg_data->primary | CNL_DSP_REG_HIPCIDR_BUSY); - hda_dsp_ipc4_schedule_d0i3_work(hda, msg); + hda_dsp_ipc4_schedule_d0i3_work(hdev, msg); return 0; } int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct sof_ipc_cmd_hdr *hdr; u32 dr = 0; u32 dd = 0; @@ -326,7 +326,7 @@ int cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) * CTX_SAVE IPC, which is sent before the DSP enters D3. */ if (hdr->cmd != (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CTX_SAVE)) - mod_delayed_work(system_wq, &hda->d0i3_work, + mod_delayed_work(system_wq, &hdev->d0i3_work, msecs_to_jiffies(SOF_HDA_D0I3_WORK_DELAY_MS)); return 0; diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 806f5d6f3bb667..2445ae7f6b2e92 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -1040,9 +1040,10 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev) void hda_dsp_d0i3_work(struct work_struct *work) { - struct sof_intel_hda_dev *hda = container_of(work, struct sof_intel_hda_dev, - d0i3_work.work); - struct hdac_bus *bus = &hda->hbus.core; + struct sof_intel_hda_dev *hdev = container_of(work, + struct sof_intel_hda_dev, + d0i3_work.work); + struct hdac_bus *bus = &hdev->hbus.core; struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev); struct sof_dsp_power_state target_state = { .state = SOF_DSP_PM_D0, diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index b13cfb68a8436e..a838dddb1d327f 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -80,7 +80,7 @@ static inline bool hda_dsp_ipc4_pm_msg(u32 primary) return false; } -void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hda, +void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hdev, struct snd_sof_ipc_msg *msg) { struct sof_ipc4_msg *msg_data = msg->msg_data; @@ -89,21 +89,21 @@ void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hda, if (hda_dsp_ipc4_pm_msg(msg_data->primary)) return; - mod_delayed_work(system_wq, &hda->d0i3_work, + mod_delayed_work(system_wq, &hdev->d0i3_work, msecs_to_jiffies(SOF_HDA_D0I3_WORK_DELAY_MS)); } int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct sof_ipc4_msg *msg_data = msg->msg_data; if (hda_ipc4_tx_is_busy(sdev)) { - hda->delayed_ipc_tx_msg = msg; + hdev->delayed_ipc_tx_msg = msg; return 0; } - hda->delayed_ipc_tx_msg = NULL; + hdev->delayed_ipc_tx_msg = NULL; /* send the message via mailbox */ if (msg_data->data_size) @@ -114,7 +114,7 @@ int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) snd_sof_dsp_write(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCI, msg_data->primary | HDA_DSP_REG_HIPCI_BUSY); - hda_dsp_ipc4_schedule_d0i3_work(hda, msg); + hda_dsp_ipc4_schedule_d0i3_work(hdev, msg); return 0; } @@ -227,10 +227,10 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n"); if (ack_received) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; - if (hda->delayed_ipc_tx_msg) - hda_dsp_ipc4_send_msg(sdev, hda->delayed_ipc_tx_msg); + if (hdev->delayed_ipc_tx_msg) + hda_dsp_ipc4_send_msg(sdev, hdev->delayed_ipc_tx_msg); } return IRQ_HANDLED; diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 9d50652cc3f45e..1805cf754beb33 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -630,7 +630,7 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) int ret; if (sdev->first_boot) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; ret = hda_sdw_startup(sdev); if (ret < 0) { @@ -643,7 +643,7 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT) && (sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT || sdev->pdata->ipc_type == SOF_IPC_TYPE_4)) - hda->imrboot_supported = true; + hdev->imrboot_supported = true; } hda_sdw_int_enable(sdev, true); diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index d6753830acb52f..f2ebadbbcc10e3 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -750,7 +750,7 @@ hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction) static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) { - struct sof_intel_hda_dev *hda = bus_to_sof_hda(bus); + struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); struct hdac_stream *s; bool active = false; u32 sd_status; @@ -770,7 +770,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) continue; /* Inform ALSA only in case not do that with IPC */ - if (s->substream && hda->no_ipc_position) { + if (s->substream && sof_hda->no_ipc_position) { snd_sof_pcm_period_elapsed(s->substream); } else if (s->cstream) { hda_dsp_compr_bytes_transferred(s, s->cstream->direction); @@ -818,7 +818,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) struct hdac_ext_stream *hext_stream; struct hdac_stream *hstream; struct pci_dev *pci = to_pci_dev(sdev->dev); - struct sof_intel_hda_dev *hda = bus_to_sof_hda(bus); + struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus); int sd_offset; int i, num_playback, num_capture, num_total, ret; u32 gcap; @@ -935,7 +935,7 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) } /* store total stream count (playback + capture) from GCAP */ - hda->stream_max = num_total; + sof_hda->stream_max = num_total; return 0; } diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 2d443643b458d3..c4687a50dd380a 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -182,11 +182,11 @@ static struct sdw_intel_ops sdw_ace2x_callback = { void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; - if (!hda->sdw) + if (!hdev->sdw) return; snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC2, @@ -210,7 +210,7 @@ void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) { u32 interface_mask = hda_get_interface_mask(sdev); - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; acpi_handle handle; int ret; @@ -220,9 +220,9 @@ static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) handle = ACPI_HANDLE(sdev->dev); /* save ACPI info for the probe step */ - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; - ret = sdw_intel_acpi_scan(handle, &hda->info); + ret = sdw_intel_acpi_scan(handle, &hdev->info); if (ret < 0) return -EINVAL; @@ -232,11 +232,11 @@ static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) static int hda_sdw_probe(struct snd_sof_dev *sdev) { const struct sof_intel_dsp_desc *chip; - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; struct sdw_intel_res res; void *sdw; - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; memset(&res, 0, sizeof(res)); @@ -244,8 +244,8 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) if (chip->hw_ip_version < SOF_INTEL_ACE_2_0) { res.mmio_base = sdev->bar[HDA_DSP_BAR]; res.hw_ops = &sdw_intel_cnl_hw_ops; - res.shim_base = hda->desc->sdw_shim_base; - res.alh_base = hda->desc->sdw_alh_base; + res.shim_base = hdev->desc->sdw_shim_base; + res.alh_base = hdev->desc->sdw_alh_base; res.ext = false; res.ops = &sdw_callback; } else { @@ -269,7 +269,7 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) } res.irq = sdev->ipc_irq; - res.handle = hda->info.handle; + res.handle = hdev->info.handle; res.parent = sdev->dev; res.dev = sdev->dev; @@ -283,8 +283,8 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) */ /* we could filter links here if needed, e.g for quirks */ - res.count = hda->info.count; - res.link_mask = hda->info.link_mask; + res.count = hdev->info.count; + res.link_mask = hdev->info.link_mask; sdw = sdw_intel_probe(&res); if (!sdw) { @@ -293,19 +293,19 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) } /* save context */ - hda->sdw = sdw; + hdev->sdw = sdw; return 0; } int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; struct sdw_intel_ctx *ctx; u32 caps; - hda = sdev->pdata->hw_pdata; - ctx = hda->sdw; + hdev = sdev->pdata->hw_pdata; + ctx = hdev->sdw; caps = snd_sof_dsp_read(sdev, HDA_DSP_BAR, ctx->shim_base + SDW_SHIM_LCAP); caps &= SDW_SHIM_LCAP_LCOUNT_MASK; @@ -323,15 +323,15 @@ int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev) int hda_sdw_check_lcount_ext(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; struct sdw_intel_ctx *ctx; struct hdac_bus *bus; u32 slcount; bus = sof_to_bus(sdev); - hda = sdev->pdata->hw_pdata; - ctx = hda->sdw; + hdev = sdev->pdata->hw_pdata; + ctx = hdev->sdw; slcount = hdac_bus_eml_get_count(bus, true, AZX_REG_ML_LEPTR_ID_SDW); @@ -359,13 +359,13 @@ static int hda_sdw_check_lcount(struct snd_sof_dev *sdev) int hda_sdw_startup(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; struct snd_sof_pdata *pdata = sdev->pdata; int ret; - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; - if (!hda->sdw) + if (!hdev->sdw) return 0; if (pdata->machine && !pdata->machine->mach_params.link_mask) @@ -375,33 +375,33 @@ int hda_sdw_startup(struct snd_sof_dev *sdev) if (ret < 0) return ret; - return sdw_intel_startup(hda->sdw); + return sdw_intel_startup(hdev->sdw); } static int hda_sdw_exit(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; hda_sdw_int_enable(sdev, false); - if (hda->sdw) - sdw_intel_exit(hda->sdw); - hda->sdw = NULL; + if (hdev->sdw) + sdw_intel_exit(hdev->sdw); + hdev->sdw = NULL; return 0; } bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; bool ret = false; u32 irq_status; - hda = sdev->pdata->hw_pdata; + hdev = sdev->pdata->hw_pdata; - if (!hda->sdw) + if (!hdev->sdw) return ret; /* store status */ @@ -441,12 +441,12 @@ static irqreturn_t hda_dsp_sdw_thread(int irq, void *context) bool hda_sdw_check_wakeen_irq_common(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; - hda = sdev->pdata->hw_pdata; - if (hda->sdw && + hdev = sdev->pdata->hw_pdata; + if (hdev->sdw && snd_sof_dsp_read(sdev, HDA_DSP_BAR, - hda->desc->sdw_shim_base + SDW_SHIM_WAKESTS)) + hdev->desc->sdw_shim_base + SDW_SHIM_WAKESTS)) return true; return false; @@ -470,16 +470,16 @@ static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) void hda_sdw_process_wakeen(struct snd_sof_dev *sdev) { u32 interface_mask = hda_get_interface_mask(sdev); - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH))) return; - hda = sdev->pdata->hw_pdata; - if (!hda->sdw) + hdev = sdev->pdata->hw_pdata; + if (!hdev->sdw) return; - sdw_intel_process_wakeen_event(hda->sdw); + sdw_intel_process_wakeen_event(hdev->sdw); } #else /* IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) */ @@ -914,11 +914,11 @@ static int hda_init(struct snd_sof_dev *sdev) static int check_dmic_num(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct nhlt_acpi_table *nhlt; int dmic_num = 0; - nhlt = hda->nhlt; + nhlt = hdev->nhlt; if (nhlt) dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt); @@ -940,11 +940,11 @@ static int check_dmic_num(struct snd_sof_dev *sdev) static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct nhlt_acpi_table *nhlt; int ssp_mask = 0; - nhlt = hda->nhlt; + nhlt = hdev->nhlt; if (!nhlt) return ssp_mask; @@ -959,10 +959,10 @@ static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev) static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct nhlt_acpi_table *nhlt; - nhlt = hda->nhlt; + nhlt = hdev->nhlt; if (!nhlt) return 0; @@ -1050,7 +1050,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev) u32 interface_mask = hda_get_interface_mask(sdev); struct hdac_bus *bus = sof_to_bus(sdev); struct snd_sof_pdata *pdata = sdev->pdata; - struct sof_intel_hda_dev *hda = pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = pdata->hw_pdata; u32 link_mask; int ret = 0; @@ -1079,7 +1079,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev) goto skip_soundwire; } - link_mask = hda->info.link_mask; + link_mask = hdev->info.link_mask; if (!link_mask) { dev_dbg(sdev->dev, "skipping SoundWire, no links enabled\n"); goto skip_soundwire; @@ -1137,7 +1137,7 @@ static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context) static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) { struct snd_sof_dev *sdev = context; - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; /* deal with streams and controller first */ if (hda_dsp_check_stream_irq(sdev)) { @@ -1152,7 +1152,7 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) if (hda_dsp_check_sdw_irq(sdev)) { trace_sof_intel_hda_irq(sdev, "sdw"); - hda_dsp_sdw_thread(irq, hda->sdw); + hda_dsp_sdw_thread(irq, hdev->sdw); } if (hda_sdw_check_wakeen_irq(sdev)) { @@ -1174,7 +1174,7 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) int hda_dsp_probe(struct snd_sof_dev *sdev) { struct pci_dev *pci = to_pci_dev(sdev->dev); - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; struct hdac_bus *bus; const struct sof_intel_dsp_desc *chip; int ret = 0; @@ -1209,18 +1209,18 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) sdev->num_cores = chip->cores_num; - hda = devm_kzalloc(sdev->dev, sizeof(*hda), GFP_KERNEL); - if (!hda) + hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) return -ENOMEM; - sdev->pdata->hw_pdata = hda; - hda->desc = chip; + sdev->pdata->hw_pdata = hdev; + hdev->desc = chip; - hda->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", - PLATFORM_DEVID_NONE, - NULL, 0); - if (IS_ERR(hda->dmic_dev)) { + hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", + PLATFORM_DEVID_NONE, + NULL, 0); + if (IS_ERR(hdev->dmic_dev)) { dev_err(sdev->dev, "error: failed to create DMIC device\n"); - return PTR_ERR(hda->dmic_dev); + return PTR_ERR(hdev->dmic_dev); } /* @@ -1228,13 +1228,13 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) * or we don't have other choice */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION) - hda->no_ipc_position = 0; + hdev->no_ipc_position = 0; #else - hda->no_ipc_position = sof_ops(sdev)->pcm_pointer ? 1 : 0; + hdev->no_ipc_position = sof_ops(sdev)->pcm_pointer ? 1 : 0; #endif if (sdev->dspless_mode_selected) - hda->no_ipc_position = 1; + hdev->no_ipc_position = 1; /* set up HDA base */ bus = sof_to_bus(sdev); @@ -1329,12 +1329,12 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) /* set default mailbox offset for FW ready message */ sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET; - INIT_DELAYED_WORK(&hda->d0i3_work, hda_dsp_d0i3_work); + INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work); } - init_waitqueue_head(&hda->waitq); + init_waitqueue_head(&hdev->waitq); - hda->nhlt = intel_nhlt_init(sdev->dev); + hdev->nhlt = intel_nhlt_init(sdev->dev); return 0; @@ -1349,7 +1349,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) if (!sdev->dspless_mode_selected) iounmap(sdev->bar[HDA_DSP_BAR]); hdac_bus_unmap: - platform_device_unregister(hda->dmic_dev); + platform_device_unregister(hdev->dmic_dev); iounmap(bus->remap_addr); hda_codec_i915_exit(sdev); err: @@ -1500,9 +1500,9 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, * was detected. This will not create a SoundWire card but * will help detect if any SoundWire codec reports as ATTACHED. */ - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; - hda_mach->mach_params.link_mask = hda->info.link_mask; + hda_mach->mach_params.link_mask = hdev->info.link_mask; } *mach = hda_mach; @@ -1530,12 +1530,12 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; struct snd_soc_acpi_mach *mach; - struct sof_intel_hda_dev *hda; + struct sof_intel_hda_dev *hdev; u32 link_mask; int i; - hda = pdata->hw_pdata; - link_mask = hda->info.link_mask; + hdev = pdata->hw_pdata; + link_mask = hdev->info.link_mask; /* * Select SoundWire machine driver if needed using the @@ -1562,19 +1562,19 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev break; link = mach->links; - for (i = 0; i < hda->info.count && link->num_adr; + for (i = 0; i < hdev->info.count && link->num_adr; i++, link++) { /* * Try next machine if any expected Slaves * are not found on this link. */ if (!snd_soc_acpi_sdw_link_slaves_found(sdev->dev, link, - hda->sdw->ids, - hda->sdw->num_slaves)) + hdev->sdw->ids, + hdev->sdw->num_slaves)) break; } /* Found if all Slaves are checked */ - if (i == hda->info.count || !link->num_adr) + if (i == hdev->info.count || !link->num_adr) break; } if (mach && mach->link_mask) { diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 88b3c6002426e2..4ecfb606abdf1f 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -935,7 +935,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context); int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context); bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev); -void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hda, +void hda_dsp_ipc4_schedule_d0i3_work(struct sof_intel_hda_dev *hdev, struct snd_sof_ipc_msg *msg); int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); void hda_ipc4_dump(struct snd_sof_dev *sdev); diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index 670bb48b8cfc9c..8e29d6bb6fe82f 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -57,7 +57,7 @@ static int icl_dsp_post_fw_run(struct snd_sof_dev *sdev) int ret; if (sdev->first_boot) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; ret = hda_sdw_startup(sdev); if (ret < 0) { @@ -68,7 +68,7 @@ static int icl_dsp_post_fw_run(struct snd_sof_dev *sdev) /* Check if IMR boot is usable */ if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT) && sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) - hda->imrboot_supported = true; + hdev->imrboot_supported = true; } hda_sdw_int_enable(sdev, true); diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 1b2cf9f696ae61..3ef9e5c3702837 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -94,15 +94,15 @@ static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct sof_ipc4_msg *msg_data = msg->msg_data; if (hda_ipc4_tx_is_busy(sdev)) { - hda->delayed_ipc_tx_msg = msg; + hdev->delayed_ipc_tx_msg = msg; return 0; } - hda->delayed_ipc_tx_msg = NULL; + hdev->delayed_ipc_tx_msg = NULL; /* send the message via mailbox */ if (msg_data->data_size) @@ -114,7 +114,7 @@ int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR, msg_data->primary | MTL_DSP_REG_HFIPCXIDR_BUSY); - hda_dsp_ipc4_schedule_d0i3_work(hda, msg); + hda_dsp_ipc4_schedule_d0i3_work(hdev, msg); return 0; } @@ -233,7 +233,7 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) /* pre fw run operations */ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; u32 dsphfpwrsts; u32 dsphfdsscs; u32 cpa; @@ -273,7 +273,7 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) dev_err(sdev->dev, "failed to power up gated DSP domain\n"); /* if SoundWire is used, make sure it is not power-gated */ - if (hda->info.handle && hda->info.link_mask > 0) + if (hdev->info.handle && hdev->info.link_mask > 0) snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL, MTL_HfPWRCTL_WPIOXPG(1), MTL_HfPWRCTL_WPIOXPG(1)); @@ -285,7 +285,7 @@ int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) int ret; if (sdev->first_boot) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; ret = hda_sdw_startup(sdev); if (ret < 0) { @@ -295,7 +295,7 @@ int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) /* Check if IMR boot is usable */ if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) - hda->imrboot_supported = true; + hdev->imrboot_supported = true; } hda_sdw_int_enable(sdev, true); @@ -583,10 +583,10 @@ irqreturn_t mtl_ipc_irq_thread(int irq, void *context) } if (ack_received) { - struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; - if (hda->delayed_ipc_tx_msg) - mtl_ipc_send_msg(sdev, hda->delayed_ipc_tx_msg); + if (hdev->delayed_ipc_tx_msg) + mtl_ipc_send_msg(sdev, hdev->delayed_ipc_tx_msg); } return IRQ_HANDLED; From e4c7ae03f2752e0105e03c92a9d9d609e05eefa2 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 9 Oct 2023 13:54:25 +0200 Subject: [PATCH 04/19] ASoC: SOF: core: Ensure sof_ops_free() is still called when probe never ran. In an effort to not call sof_ops_free twice, we stopped running it when probe was aborted. Check the result of cancel_work_sync to see if this was the case. Fixes: 31bb7bd9ffee ("ASoC: SOF: core: Only call sof_ops_free() on remove if the probe was successful") Cc: Peter Ujfalusi Acked-by: Mark Brown --- sound/soc/sof/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 2d1616b81485c5..0938b259f70340 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -459,9 +459,10 @@ int snd_sof_device_remove(struct device *dev) struct snd_sof_dev *sdev = dev_get_drvdata(dev); struct snd_sof_pdata *pdata = sdev->pdata; int ret; + bool aborted = false; if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) - cancel_work_sync(&sdev->probe_work); + aborted = cancel_work_sync(&sdev->probe_work); /* * Unregister any registered client device first before IPC and debugfs @@ -487,6 +488,9 @@ int snd_sof_device_remove(struct device *dev) snd_sof_free_debug(sdev); snd_sof_remove(sdev); sof_ops_free(sdev); + } else if (aborted) { + /* probe_work never ran */ + sof_ops_free(sdev); } /* release firmware */ From fc4ae5a5bb18fde5ee31780d52b9d13b3e445f73 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 9 Oct 2023 13:54:26 +0200 Subject: [PATCH 05/19] ASoC: SOF: core: Add probe_early and remove_late callbacks The existing DSP probe may be handled in a workqueue to allow for extra time, typically for the i915 request_module and HDAudio codec handling. With the upcoming changes for i915/Xe driver relying on the -EPROBE_DEFER mechanism, we need to have a first pass of the probe which cannot be pushed to a workqueue. Introduce 2 new optional callbacks. probe_early is called before the workqueue runs. remove_late may be called from the workqueue if load is unsuccesful, but will otherwise be called on module unload. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Maarten Lankhorst Acked-by: Mark Brown --- sound/soc/sof/core.c | 11 +++++++++++ sound/soc/sof/ops.h | 16 ++++++++++++++++ sound/soc/sof/sof-priv.h | 2 ++ 3 files changed, 29 insertions(+) diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 0938b259f70340..d7b090224f1b9a 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -327,6 +327,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) dsp_err: snd_sof_remove(sdev); probe_err: + snd_sof_remove_late(sdev); sof_ops_free(sdev); /* all resources freed, update state to match */ @@ -436,6 +437,14 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); + /* + * first pass of probe which isn't allowed to run in a work-queue, + * typically to rely on -EPROBE_DEFER dependencies + */ + ret = snd_sof_probe_early(sdev); + if (ret < 0) + return ret; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) { INIT_WORK(&sdev->probe_work, sof_probe_work); schedule_work(&sdev->probe_work); @@ -487,9 +496,11 @@ int snd_sof_device_remove(struct device *dev) snd_sof_ipc_free(sdev); snd_sof_free_debug(sdev); snd_sof_remove(sdev); + snd_sof_remove_late(sdev); sof_ops_free(sdev); } else if (aborted) { /* probe_work never ran */ + snd_sof_remove_late(sdev); sof_ops_free(sdev); } diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index c617d20ce21768..b947c36bba8585 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -38,6 +38,14 @@ static inline void sof_ops_free(struct snd_sof_dev *sdev) /* Mandatory operations are verified during probing */ /* init */ +static inline int snd_sof_probe_early(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->probe_early) + return sof_ops(sdev)->probe_early(sdev); + + return 0; +} + static inline int snd_sof_probe(struct snd_sof_dev *sdev) { return sof_ops(sdev)->probe(sdev); @@ -49,6 +57,14 @@ static inline void snd_sof_remove(struct snd_sof_dev *sdev) sof_ops(sdev)->remove(sdev); } +static inline int snd_sof_remove_late(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->remove_late) + return sof_ops(sdev)->remove_late(sdev); + + return 0; +} + static inline int snd_sof_shutdown(struct snd_sof_dev *sdev) { if (sof_ops(sdev)->shutdown) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 7fcb1c8577f262..1adffa479faf64 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -172,8 +172,10 @@ enum sof_dai_access { struct snd_sof_dsp_ops { /* probe/remove/shutdown */ + int (*probe_early)(struct snd_sof_dev *sof_dev); /* optional */ int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */ void (*remove)(struct snd_sof_dev *sof_dev); /* optional */ + int (*remove_late)(struct snd_sof_dev *sof_dev); /* optional */ int (*shutdown)(struct snd_sof_dev *sof_dev); /* optional */ /* DSP core boot / reset */ From d50c38038cc668ba7465309c16191027839c3881 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 9 Oct 2023 13:54:27 +0200 Subject: [PATCH 06/19] ASoC: SOF: Intel: hda: start splitting the probe This patch moves the initial parts of the probe to the probe_early() callback, which provides a much faster decision on whether the SOF driver shall deal with a specific platform or yield to other Intel drivers. This is a limited functionality change, the bigger change is to move the i915/Xe initialization to the probe_early(). Signed-off-by: Pierre-Louis Bossart Signed-off-by: Maarten Lankhorst Acked-by: Mark Brown --- sound/soc/sof/intel/hda-common-ops.c | 1 + sound/soc/sof/intel/hda.c | 16 +++++++++++++--- sound/soc/sof/intel/hda.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-common-ops.c b/sound/soc/sof/intel/hda-common-ops.c index 4b6cf3528a717e..3f9d3db68a3ccc 100644 --- a/sound/soc/sof/intel/hda-common-ops.c +++ b/sound/soc/sof/intel/hda-common-ops.c @@ -16,6 +16,7 @@ struct snd_sof_dsp_ops sof_hda_common_ops = { /* probe/remove/shutdown */ + .probe_early = hda_dsp_probe_early, .probe = hda_dsp_probe, .remove = hda_dsp_remove, diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index c4687a50dd380a..c42026b0cb7e44 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1171,11 +1171,10 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) return IRQ_HANDLED; } -int hda_dsp_probe(struct snd_sof_dev *sdev) +int hda_dsp_probe_early(struct snd_sof_dev *sdev) { struct pci_dev *pci = to_pci_dev(sdev->dev); struct sof_intel_hda_dev *hdev; - struct hdac_bus *bus; const struct sof_intel_dsp_desc *chip; int ret = 0; @@ -1215,6 +1214,17 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) sdev->pdata->hw_pdata = hdev; hdev->desc = chip; +err: + return ret; +} + +int hda_dsp_probe(struct snd_sof_dev *sdev) +{ + struct pci_dev *pci = to_pci_dev(sdev->dev); + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; + struct hdac_bus *bus; + int ret = 0; + hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0); @@ -1352,7 +1362,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) platform_device_unregister(hdev->dmic_dev); iounmap(bus->remap_addr); hda_codec_i915_exit(sdev); -err: + return ret; } diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 4ecfb606abdf1f..2d20aafbe07b08 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -581,6 +581,7 @@ bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type); /* * DSP Core services. */ +int hda_dsp_probe_early(struct snd_sof_dev *sdev); int hda_dsp_probe(struct snd_sof_dev *sdev); void hda_dsp_remove(struct snd_sof_dev *sdev); int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask); From accbe06fc5d5a0e8b8847d82c551ce61e850fcc4 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 9 Oct 2023 13:54:28 +0200 Subject: [PATCH 07/19] ASoC: SOF: Intel: Fix error handling in hda_init() The hda_codec_i915_init() errors are ignored in hda_init() so it can never return -EPROBE_DEFER. Fix this before we move the call to hda_init() from the deferred probe to early probe. While at it, also fix error handling when hda_dsp_ctrl_get_caps fails. Suggested-by: Kai Vehmanen Signed-off-by: Maarten Lankhorst Reviewed-by: Kai Vehmanen --- sound/soc/sof/intel/hda.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index c42026b0cb7e44..53c7c6cf908247 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -901,13 +901,21 @@ static int hda_init(struct snd_sof_dev *sdev) /* init i915 and HDMI codecs */ ret = hda_codec_i915_init(sdev); - if (ret < 0) - dev_warn(sdev->dev, "init of i915 and HDMI codec failed\n"); + if (ret < 0 && ret != -ENODEV) { + dev_err_probe(sdev->dev, ret, "init of i915 and HDMI codec failed\n"); + goto out; + } /* get controller capabilities */ ret = hda_dsp_ctrl_get_caps(sdev); - if (ret < 0) + if (ret < 0) { dev_err(sdev->dev, "error: get caps error\n"); + hda_codec_i915_exit(sdev); + } + +out: + if (ret < 0) + iounmap(sof_to_bus(sdev)->remap_addr); return ret; } From 5fe0f711054c7bc2dfac76717463a6f408dd57a7 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 9 Oct 2023 13:54:29 +0200 Subject: [PATCH 08/19] ALSA: hda: Intel: Fix error handling in azx_probe() Add missing pci_set_drv to NULL call on error. Signed-off-by: Maarten Lankhorst Reviewed-by: Pierre-Louis Bossart Reviewed-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e19274fd990d98..e1354ae905564f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2176,6 +2176,7 @@ static int azx_probe(struct pci_dev *pci, return 0; out_free: + pci_set_drvdata(pci, NULL); snd_card_free(card); return err; } From 663c94d1cb6077bfe3ff4fb45ec7acc070f9c4a4 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 9 Oct 2023 13:54:30 +0200 Subject: [PATCH 09/19] ALSA: hda: i915: Allow override of gpu binding. Selecting CONFIG_DRM selects CONFIG_VIDEO_NOMODESET, which exports video_firmware_drivers_only(). This can be used as a first approximation on whether i915 will be available. It's safe to use as this is only built when CONFIG_SND_HDA_I915 is selected by CONFIG_I915. It's not completely fool proof, as you can boot with "nomodeset i915.modeset=1" to make i915 load regardless, or use "i915.force_probe=!*" to never load i915, but the common case of booting with nomodeset to disable all GPU drivers this will work as intended. Because of this, we add an extra module parameter, snd_hda_core.gpu_bind that can be used to signal users intent. -1 follows nomodeset, 0 disables binding, 1 forces wait/-EPROBE_DEFER on binding. Signed-off-by: Maarten Lankhorst Reviewed-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen Reviewed-by: Pierre-Louis Bossart --- sound/hda/hdac_i915.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index b428537f284c72..a4a712c795c3dd 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -10,6 +10,12 @@ #include #include #include +#include