mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08: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
	 Pierre-Louis Bossart
						Pierre-Louis Bossart