mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
ASoC: SOF: Intel: hda: make DSPless mode work with DSP disabled in BIOS
When the DSP is disabled in the BIOS, the DSP_BAR and PP_BAR cannot be accessed. One possible objection noted in initial reviews is that this patch adds a number of branches. However the number of branches is actually limited in probe/suspend/resume routines mostly, so there isn't really a degradation in terms of readability and maintainability. Adding yet another level of abstraction/ops/callbacks would increase complexity and not really help in terms of code reuse or readability and maintainability. A split between controller and DSP driver would be even more invasive. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20230404092115.27949-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
1f7b5d52be
commit
9fc6786f54
@ -321,6 +321,9 @@ void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev)
|
|||||||
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
|
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
|
||||||
const struct sof_intel_dsp_desc *chip = hda->desc;
|
const struct sof_intel_dsp_desc *chip = hda->desc;
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
return;
|
||||||
|
|
||||||
/* enable IPC DONE and BUSY interrupts */
|
/* enable IPC DONE and BUSY interrupts */
|
||||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
|
||||||
HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
|
HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
|
||||||
@ -336,6 +339,9 @@ void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
|
|||||||
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
|
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
|
||||||
const struct sof_intel_dsp_desc *chip = hda->desc;
|
const struct sof_intel_dsp_desc *chip = hda->desc;
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
return;
|
||||||
|
|
||||||
/* disable IPC interrupt */
|
/* disable IPC interrupt */
|
||||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
|
||||||
HDA_DSP_ADSPIC_IPC, 0);
|
HDA_DSP_ADSPIC_IPC, 0);
|
||||||
@ -681,6 +687,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
|
|||||||
/* power down all hda links */
|
/* power down all hda links */
|
||||||
hda_bus_ml_suspend(bus);
|
hda_bus_ml_suspend(bus);
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
goto skip_dsp;
|
||||||
|
|
||||||
ret = chip->power_down_dsp(sdev);
|
ret = chip->power_down_dsp(sdev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(sdev->dev, "failed to power down DSP during suspend\n");
|
dev_err(sdev->dev, "failed to power down DSP during suspend\n");
|
||||||
@ -694,6 +703,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
|
|||||||
/* disable ppcap interrupt */
|
/* disable ppcap interrupt */
|
||||||
hda_dsp_ctrl_ppcap_enable(sdev, false);
|
hda_dsp_ctrl_ppcap_enable(sdev, false);
|
||||||
hda_dsp_ctrl_ppcap_int_enable(sdev, false);
|
hda_dsp_ctrl_ppcap_int_enable(sdev, false);
|
||||||
|
skip_dsp:
|
||||||
|
|
||||||
/* disable hda bus irq and streams */
|
/* disable hda bus irq and streams */
|
||||||
hda_dsp_ctrl_stop_chip(sdev);
|
hda_dsp_ctrl_stop_chip(sdev);
|
||||||
@ -744,9 +754,11 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
|
|||||||
hda_codec_jack_check(sdev);
|
hda_codec_jack_check(sdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/* enable ppcap interrupt */
|
/* enable ppcap interrupt */
|
||||||
hda_dsp_ctrl_ppcap_enable(sdev, true);
|
hda_dsp_ctrl_ppcap_enable(sdev, true);
|
||||||
hda_dsp_ctrl_ppcap_int_enable(sdev, true);
|
hda_dsp_ctrl_ppcap_int_enable(sdev, true);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
/* display codec can powered off after controller init */
|
/* display codec can powered off after controller init */
|
||||||
@ -843,8 +855,10 @@ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
|
|||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/* cancel any attempt for DSP D0I3 */
|
/* cancel any attempt for DSP D0I3 */
|
||||||
cancel_delayed_work_sync(&hda->d0i3_work);
|
cancel_delayed_work_sync(&hda->d0i3_work);
|
||||||
|
}
|
||||||
|
|
||||||
/* stop hda controller and power dsp off */
|
/* stop hda controller and power dsp off */
|
||||||
ret = hda_suspend(sdev, true);
|
ret = hda_suspend(sdev, true);
|
||||||
@ -866,8 +880,10 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
|
|||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/* cancel any attempt for DSP D0I3 */
|
/* cancel any attempt for DSP D0I3 */
|
||||||
cancel_delayed_work_sync(&hda->d0i3_work);
|
cancel_delayed_work_sync(&hda->d0i3_work);
|
||||||
|
}
|
||||||
|
|
||||||
if (target_state == SOF_DSP_PM_D0) {
|
if (target_state == SOF_DSP_PM_D0) {
|
||||||
/* Set DSP power state */
|
/* Set DSP power state */
|
||||||
|
@ -355,6 +355,9 @@ bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev)
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
u32 irq_status;
|
u32 irq_status;
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* store status */
|
/* store status */
|
||||||
irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIS);
|
irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIS);
|
||||||
trace_sof_intel_hda_irq_ipc_check(sdev, irq_status);
|
trace_sof_intel_hda_irq_ipc_check(sdev, irq_status);
|
||||||
|
@ -874,12 +874,14 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
hext_stream = &hda_stream->hext_stream;
|
hext_stream = &hda_stream->hext_stream;
|
||||||
|
|
||||||
|
if (sdev->bar[HDA_DSP_PP_BAR]) {
|
||||||
hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
||||||
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
|
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
|
||||||
|
|
||||||
hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
||||||
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
|
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
|
||||||
SOF_HDA_PPLC_INTERVAL * i;
|
SOF_HDA_PPLC_INTERVAL * i;
|
||||||
|
}
|
||||||
|
|
||||||
hstream = &hext_stream->hstream;
|
hstream = &hext_stream->hstream;
|
||||||
|
|
||||||
@ -930,13 +932,14 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
hext_stream = &hda_stream->hext_stream;
|
hext_stream = &hda_stream->hext_stream;
|
||||||
|
|
||||||
/* we always have DSP support */
|
if (sdev->bar[HDA_DSP_PP_BAR]) {
|
||||||
hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
||||||
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
|
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
|
||||||
|
|
||||||
hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
|
||||||
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
|
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
|
||||||
SOF_HDA_PPLC_INTERVAL * i;
|
SOF_HDA_PPLC_INTERVAL * i;
|
||||||
|
}
|
||||||
|
|
||||||
hstream = &hext_stream->hstream;
|
hstream = &hext_stream->hstream;
|
||||||
|
|
||||||
|
@ -122,8 +122,12 @@ void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
|
|||||||
|
|
||||||
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
|
void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
|
||||||
{
|
{
|
||||||
|
u32 interface_mask = hda_get_interface_mask(sdev);
|
||||||
const struct sof_intel_dsp_desc *chip;
|
const struct sof_intel_dsp_desc *chip;
|
||||||
|
|
||||||
|
if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
|
||||||
|
return;
|
||||||
|
|
||||||
chip = get_chip_info(sdev->pdata);
|
chip = get_chip_info(sdev->pdata);
|
||||||
if (chip && chip->enable_sdw_irq)
|
if (chip && chip->enable_sdw_irq)
|
||||||
chip->enable_sdw_irq(sdev, enable);
|
chip->enable_sdw_irq(sdev, enable);
|
||||||
@ -131,10 +135,14 @@ void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable)
|
|||||||
|
|
||||||
static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev)
|
static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev)
|
||||||
{
|
{
|
||||||
|
u32 interface_mask = hda_get_interface_mask(sdev);
|
||||||
struct sof_intel_hda_dev *hdev;
|
struct sof_intel_hda_dev *hdev;
|
||||||
acpi_handle handle;
|
acpi_handle handle;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
handle = ACPI_HANDLE(sdev->dev);
|
handle = ACPI_HANDLE(sdev->dev);
|
||||||
|
|
||||||
/* save ACPI info for the probe step */
|
/* save ACPI info for the probe step */
|
||||||
@ -288,8 +296,12 @@ out:
|
|||||||
|
|
||||||
static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
|
static bool hda_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
|
||||||
{
|
{
|
||||||
|
u32 interface_mask = hda_get_interface_mask(sdev);
|
||||||
const struct sof_intel_dsp_desc *chip;
|
const struct sof_intel_dsp_desc *chip;
|
||||||
|
|
||||||
|
if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
|
||||||
|
return false;
|
||||||
|
|
||||||
chip = get_chip_info(sdev->pdata);
|
chip = get_chip_info(sdev->pdata);
|
||||||
if (chip && chip->check_sdw_irq)
|
if (chip && chip->check_sdw_irq)
|
||||||
return chip->check_sdw_irq(sdev);
|
return chip->check_sdw_irq(sdev);
|
||||||
@ -304,8 +316,12 @@ static irqreturn_t hda_dsp_sdw_thread(int irq, void *context)
|
|||||||
|
|
||||||
static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev)
|
static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev)
|
||||||
{
|
{
|
||||||
|
u32 interface_mask = hda_get_interface_mask(sdev);
|
||||||
struct sof_intel_hda_dev *hdev;
|
struct sof_intel_hda_dev *hdev;
|
||||||
|
|
||||||
|
if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
|
||||||
|
return false;
|
||||||
|
|
||||||
hdev = sdev->pdata->hw_pdata;
|
hdev = sdev->pdata->hw_pdata;
|
||||||
if (hdev->sdw &&
|
if (hdev->sdw &&
|
||||||
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
|
snd_sof_dsp_read(sdev, HDA_DSP_BAR,
|
||||||
@ -317,8 +333,12 @@ static bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
void hda_sdw_process_wakeen(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 *hdev;
|
struct sof_intel_hda_dev *hdev;
|
||||||
|
|
||||||
|
if (!(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
|
||||||
|
return;
|
||||||
|
|
||||||
hdev = sdev->pdata->hw_pdata;
|
hdev = sdev->pdata->hw_pdata;
|
||||||
if (!hdev->sdw)
|
if (!hdev->sdw)
|
||||||
return;
|
return;
|
||||||
@ -1010,6 +1030,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
const struct sof_intel_dsp_desc *chip;
|
const struct sof_intel_dsp_desc *chip;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/*
|
/*
|
||||||
* detect DSP by checking class/subclass/prog-id information
|
* detect DSP by checking class/subclass/prog-id information
|
||||||
* class=04 subclass 03 prog-if 00: no DSP, legacy driver is required
|
* class=04 subclass 03 prog-if 00: no DSP, legacy driver is required
|
||||||
@ -1018,13 +1039,16 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
* class=04 subclass 03 prog-if 80: either of DSP or legacy mode works
|
* class=04 subclass 03 prog-if 80: either of DSP or legacy mode works
|
||||||
*/
|
*/
|
||||||
if (pci->class == 0x040300) {
|
if (pci->class == 0x040300) {
|
||||||
dev_err(sdev->dev, "error: the DSP is not enabled on this platform, aborting probe\n");
|
dev_err(sdev->dev, "the DSP is not enabled on this platform, aborting probe\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else if (pci->class != 0x040100 && pci->class != 0x040380) {
|
} else if (pci->class != 0x040100 && pci->class != 0x040380) {
|
||||||
dev_err(sdev->dev, "error: unknown PCI class/subclass/prog-if 0x%06x found, aborting probe\n", pci->class);
|
dev_err(sdev->dev, "unknown PCI class/subclass/prog-if 0x%06x found, aborting probe\n",
|
||||||
|
pci->class);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
dev_info(sdev->dev, "DSP detected with PCI class/subclass/prog-if 0x%06x\n", pci->class);
|
dev_info(sdev->dev, "DSP detected with PCI class/subclass/prog-if 0x%06x\n",
|
||||||
|
pci->class);
|
||||||
|
}
|
||||||
|
|
||||||
chip = get_chip_info(sdev->pdata);
|
chip = get_chip_info(sdev->pdata);
|
||||||
if (!chip) {
|
if (!chip) {
|
||||||
@ -1069,6 +1093,9 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto hdac_bus_unmap;
|
goto hdac_bus_unmap;
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
goto skip_dsp_setup;
|
||||||
|
|
||||||
/* DSP base */
|
/* DSP base */
|
||||||
sdev->bar[HDA_DSP_BAR] = pci_ioremap_bar(pci, HDA_DSP_BAR);
|
sdev->bar[HDA_DSP_BAR] = pci_ioremap_bar(pci, HDA_DSP_BAR);
|
||||||
if (!sdev->bar[HDA_DSP_BAR]) {
|
if (!sdev->bar[HDA_DSP_BAR]) {
|
||||||
@ -1079,6 +1106,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
sdev->mmio_bar = HDA_DSP_BAR;
|
sdev->mmio_bar = HDA_DSP_BAR;
|
||||||
sdev->mailbox_bar = HDA_DSP_BAR;
|
sdev->mailbox_bar = HDA_DSP_BAR;
|
||||||
|
skip_dsp_setup:
|
||||||
|
|
||||||
/* allow 64bit DMA address if supported by H/W */
|
/* allow 64bit DMA address if supported by H/W */
|
||||||
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(64))) {
|
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(64))) {
|
||||||
@ -1144,6 +1172,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto free_ipc_irq;
|
goto free_ipc_irq;
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/* enable ppcap interrupt */
|
/* enable ppcap interrupt */
|
||||||
hda_dsp_ctrl_ppcap_enable(sdev, true);
|
hda_dsp_ctrl_ppcap_enable(sdev, true);
|
||||||
hda_dsp_ctrl_ppcap_int_enable(sdev, true);
|
hda_dsp_ctrl_ppcap_int_enable(sdev, true);
|
||||||
@ -1152,6 +1181,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
|
|||||||
sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET;
|
sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work);
|
INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work);
|
||||||
|
}
|
||||||
|
|
||||||
init_waitqueue_head(&hdev->waitq);
|
init_waitqueue_head(&hdev->waitq);
|
||||||
|
|
||||||
@ -1167,6 +1197,7 @@ free_irq_vector:
|
|||||||
free_streams:
|
free_streams:
|
||||||
hda_dsp_stream_free(sdev);
|
hda_dsp_stream_free(sdev);
|
||||||
/* dsp_unmap: not currently used */
|
/* dsp_unmap: not currently used */
|
||||||
|
if (!sdev->dspless_mode_selected)
|
||||||
iounmap(sdev->bar[HDA_DSP_BAR]);
|
iounmap(sdev->bar[HDA_DSP_BAR]);
|
||||||
hdac_bus_unmap:
|
hdac_bus_unmap:
|
||||||
platform_device_unregister(hdev->dmic_dev);
|
platform_device_unregister(hdev->dmic_dev);
|
||||||
@ -1187,6 +1218,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
|
|||||||
if (nhlt)
|
if (nhlt)
|
||||||
intel_nhlt_free(nhlt);
|
intel_nhlt_free(nhlt);
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected)
|
||||||
/* cancel any attempt for DSP D0I3 */
|
/* cancel any attempt for DSP D0I3 */
|
||||||
cancel_delayed_work_sync(&hda->d0i3_work);
|
cancel_delayed_work_sync(&hda->d0i3_work);
|
||||||
|
|
||||||
@ -1197,14 +1229,19 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
|
|||||||
if (!IS_ERR_OR_NULL(hda->dmic_dev))
|
if (!IS_ERR_OR_NULL(hda->dmic_dev))
|
||||||
platform_device_unregister(hda->dmic_dev);
|
platform_device_unregister(hda->dmic_dev);
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected) {
|
||||||
/* disable DSP IRQ */
|
/* disable DSP IRQ */
|
||||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
|
||||||
SOF_HDA_PPCTL_PIE, 0);
|
SOF_HDA_PPCTL_PIE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* disable CIE and GIE interrupts */
|
/* disable CIE and GIE interrupts */
|
||||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
|
||||||
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 0);
|
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 0);
|
||||||
|
|
||||||
|
if (sdev->dspless_mode_selected)
|
||||||
|
goto skip_disable_dsp;
|
||||||
|
|
||||||
/* no need to check for error as the DSP will be disabled anyway */
|
/* no need to check for error as the DSP will be disabled anyway */
|
||||||
if (chip && chip->power_down_dsp)
|
if (chip && chip->power_down_dsp)
|
||||||
chip->power_down_dsp(sdev);
|
chip->power_down_dsp(sdev);
|
||||||
@ -1213,6 +1250,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
|
|||||||
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
|
||||||
SOF_HDA_PPCTL_GPROCEN, 0);
|
SOF_HDA_PPCTL_GPROCEN, 0);
|
||||||
|
|
||||||
|
skip_disable_dsp:
|
||||||
free_irq(sdev->ipc_irq, sdev);
|
free_irq(sdev->ipc_irq, sdev);
|
||||||
if (sdev->msi_enabled)
|
if (sdev->msi_enabled)
|
||||||
pci_free_irq_vectors(pci);
|
pci_free_irq_vectors(pci);
|
||||||
@ -1221,7 +1259,9 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
|
|||||||
|
|
||||||
hda_bus_ml_free(sof_to_bus(sdev));
|
hda_bus_ml_free(sof_to_bus(sdev));
|
||||||
|
|
||||||
|
if (!sdev->dspless_mode_selected)
|
||||||
iounmap(sdev->bar[HDA_DSP_BAR]);
|
iounmap(sdev->bar[HDA_DSP_BAR]);
|
||||||
|
|
||||||
iounmap(bus->remap_addr);
|
iounmap(bus->remap_addr);
|
||||||
|
|
||||||
sof_hda_bus_exit(sdev);
|
sof_hda_bus_exit(sdev);
|
||||||
|
Loading…
Reference in New Issue
Block a user