1212#include <linux/firmware.h>
1313#include <sound/sof/ipc4/header.h>
1414#include <trace/events/sof_intel.h>
15+ #include <sound/intel-nhlt.h>
1516#include "../ipc4-priv.h"
1617#include "../ops.h"
1718#include "hda.h"
@@ -720,6 +721,70 @@ static void mtl_ipc_dump(struct snd_sof_dev *sdev)
720721 hipcida , hipctdr , hipcctl );
721722}
722723
724+ /*
725+ * copied from hda_dsp_remove. Only difference is
726+ * hda_dsp_core_reset_power_down() is replaced with mtl_dsp_core_power_down()
727+ */
728+ int mtl_dsp_remove (struct snd_sof_dev * sdev )
729+ {
730+ struct sof_intel_hda_dev * hda = sdev -> pdata -> hw_pdata ;
731+ const struct sof_intel_dsp_desc * chip = hda -> desc ;
732+ struct hdac_bus * bus = sof_to_bus (sdev );
733+ struct pci_dev * pci = to_pci_dev (sdev -> dev );
734+ struct nhlt_acpi_table * nhlt = hda -> nhlt ;
735+
736+ if (nhlt )
737+ intel_nhlt_free (nhlt );
738+
739+ /* cancel any attempt for DSP D0I3 */
740+ cancel_delayed_work_sync (& hda -> d0i3_work );
741+
742+ #if IS_ENABLED (CONFIG_SND_SOC_SOF_HDA )
743+ /* codec removal, invoke bus_device_remove */
744+ snd_hdac_ext_bus_device_remove (bus );
745+ #endif
746+
747+ hda_sdw_exit (sdev );
748+
749+ if (!IS_ERR_OR_NULL (hda -> dmic_dev ))
750+ platform_device_unregister (hda -> dmic_dev );
751+
752+ /* disable DSP IRQ */
753+ snd_sof_dsp_update_bits (sdev , HDA_DSP_PP_BAR , SOF_HDA_REG_PP_PPCTL ,
754+ SOF_HDA_PPCTL_PIE , 0 );
755+
756+ /* disable CIE and GIE interrupts */
757+ snd_sof_dsp_update_bits (sdev , HDA_DSP_HDA_BAR , SOF_HDA_INTCTL ,
758+ SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN , 0 );
759+
760+ /* disable cores */
761+ if (chip )
762+ mtl_dsp_core_power_down (sdev , chip -> host_managed_cores_mask );
763+
764+ /* disable DSP */
765+ snd_sof_dsp_update_bits (sdev , HDA_DSP_PP_BAR , SOF_HDA_REG_PP_PPCTL ,
766+ SOF_HDA_PPCTL_GPROCEN , 0 );
767+
768+ free_irq (sdev -> ipc_irq , sdev );
769+ if (sdev -> msi_enabled )
770+ pci_free_irq_vectors (pci );
771+
772+ hda_dsp_stream_free (sdev );
773+ #if IS_ENABLED (CONFIG_SND_SOC_SOF_HDA )
774+ snd_hdac_link_free_all (bus );
775+ #endif
776+
777+ iounmap (sdev -> bar [HDA_DSP_BAR ]);
778+ iounmap (bus -> remap_addr );
779+
780+ #if IS_ENABLED (CONFIG_SND_SOC_SOF_HDA )
781+ snd_hdac_ext_bus_exit (bus );
782+ #endif
783+ hda_codec_i915_exit (sdev );
784+
785+ return 0 ;
786+ }
787+
723788/* Meteorlake ops */
724789struct snd_sof_dsp_ops sof_mtl_ops ;
725790EXPORT_SYMBOL_NS (sof_mtl_ops , SND_SOC_SOF_INTEL_HDA_COMMON );
@@ -731,6 +796,9 @@ int sof_mtl_ops_init(struct snd_sof_dev *sdev)
731796 /* common defaults */
732797 memcpy (& sof_mtl_ops , & sof_hda_common_ops , sizeof (struct snd_sof_dsp_ops ));
733798
799+ /* override from sof_hda_common_ops */
800+ sof_mtl_ops .remove = mtl_dsp_remove ;
801+
734802 /* shutdown */
735803 sof_mtl_ops .shutdown = hda_dsp_shutdown ;
736804
0 commit comments