* @is_pdm_dev: flag set to true when ACP PDM controller exists
* @is_pdm_config: flat set to true when PDM configuration is selected from BIOS
* @is_sdw_config: flag set to true when SDW configuration is selected from BIOS
+ * @sdw_en_stat: flag set to true when any one of the SoundWire manager instance is enabled
* @addr: pci ioremap address
* @reg_range: ACP reigister range
* @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance
* @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance
- * @acp_reset: flag set to true when bus reset is applied across all
- * the active SoundWire manager instances
*/
struct acp63_dev_data {
bool is_pdm_dev;
bool is_pdm_config;
bool is_sdw_config;
+ bool sdw_en_stat;
u32 addr;
u32 reg_range;
u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS];
u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS];
- bool acp_reset;
};
int snd_amd_acp_find_config(struct pci_dev *pci);
}
adata->addr = addr;
adata->reg_range = ACP63_REG_END - ACP63_REG_START;
- /*
- * By default acp_reset flag is set to true. i.e acp_deinit() and acp_init()
- * will be invoked for all ACP configurations during suspend/resume callbacks.
- * This flag should be set to false only when SoundWire manager power mode
- * set to ClockStopMode.
- */
- adata->acp_reset = true;
pci_set_master(pci);
pci_set_drvdata(pci, adata);
mutex_init(&adata->acp_lock);
return ret;
}
+static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata)
+{
+ u32 sdw0_en, sdw1_en;
+
+ sdw0_en = readl(adata->acp63_base + ACP_SW0_EN);
+ sdw1_en = readl(adata->acp63_base + ACP_SW1_EN);
+ return (sdw0_en || sdw1_en);
+}
+
static int __maybe_unused snd_acp63_suspend(struct device *dev)
{
struct acp63_dev_data *adata;
- int ret = 0;
+ int ret;
adata = dev_get_drvdata(dev);
- if (adata->acp_reset) {
- ret = acp63_deinit(adata->acp63_base, dev);
- if (ret)
- dev_err(dev, "ACP de-init failed\n");
+ if (adata->is_sdw_dev) {
+ adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
+ if (adata->sdw_en_stat)
+ return 0;
}
+ ret = acp63_deinit(adata->acp63_base, dev);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+
return ret;
}
static int __maybe_unused snd_acp63_resume(struct device *dev)
{
struct acp63_dev_data *adata;
- int ret = 0;
+ int ret;
adata = dev_get_drvdata(dev);
- if (adata->acp_reset) {
- ret = acp63_init(adata->acp63_base, dev);
- if (ret)
- dev_err(dev, "ACP init failed\n");
- }
+ if (adata->sdw_en_stat)
+ return 0;
+
+ ret = acp63_init(adata->acp63_base, dev);
+ if (ret)
+ dev_err(dev, "ACP init failed\n");
+
return ret;
}