brintos

brintos / linux-shallow public Read only

0
0
Text · 19.4 KiB · c72d666 Raw
757 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * AMD Pink Sardine ACP PCI Driver4 *5 * Copyright 2022 Advanced Micro Devices, Inc.6 */7 8#include <linux/pci.h>9#include <linux/bitops.h>10#include <linux/module.h>11#include <linux/io.h>12#include <linux/delay.h>13#include <linux/platform_device.h>14#include <linux/acpi.h>15#include <linux/interrupt.h>16#include <sound/pcm_params.h>17#include <linux/pm_runtime.h>18#include <linux/iopoll.h>19#include <linux/soundwire/sdw_amd.h>20#include "../mach-config.h"21 22#include "acp63.h"23 24static int acp63_power_on(void __iomem *acp_base)25{26	u32 val;27 28	val = readl(acp_base + ACP_PGFSM_STATUS);29 30	if (!val)31		return val;32 33	if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)34		writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);35 36	return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT);37}38 39static int acp63_reset(void __iomem *acp_base)40{41	u32 val;42	int ret;43 44	writel(1, acp_base + ACP_SOFT_RESET);45 46	ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val,47				 val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK,48				 DELAY_US, ACP_TIMEOUT);49	if (ret)50		return ret;51 52	writel(0, acp_base + ACP_SOFT_RESET);53 54	return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);55}56 57static void acp63_enable_interrupts(void __iomem *acp_base)58{59	writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);60	writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);61}62 63static void acp63_disable_interrupts(void __iomem *acp_base)64{65	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT);66	writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL);67	writel(0, acp_base + ACP_EXTERNAL_INTR_ENB);68}69 70static int acp63_init(void __iomem *acp_base, struct device *dev)71{72	int ret;73 74	ret = acp63_power_on(acp_base);75	if (ret) {76		dev_err(dev, "ACP power on failed\n");77		return ret;78	}79	writel(0x01, acp_base + ACP_CONTROL);80	ret = acp63_reset(acp_base);81	if (ret) {82		dev_err(dev, "ACP reset failed\n");83		return ret;84	}85	acp63_enable_interrupts(acp_base);86	return 0;87}88 89static int acp63_deinit(void __iomem *acp_base, struct device *dev)90{91	int ret;92 93	acp63_disable_interrupts(acp_base);94	ret = acp63_reset(acp_base);95	if (ret) {96		dev_err(dev, "ACP reset failed\n");97		return ret;98	}99	writel(0, acp_base + ACP_CONTROL);100	return 0;101}102 103static irqreturn_t acp63_irq_thread(int irq, void *context)104{105	struct sdw_dma_dev_data *sdw_dma_data;106	struct acp63_dev_data *adata = context;107	u32 stream_index;108 109	sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);110 111	for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) {112		if (adata->sdw0_dma_intr_stat[stream_index]) {113			if (sdw_dma_data->sdw0_dma_stream[stream_index])114				snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]);115			adata->sdw0_dma_intr_stat[stream_index] = 0;116		}117	}118	for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) {119		if (adata->sdw1_dma_intr_stat[stream_index]) {120			if (sdw_dma_data->sdw1_dma_stream[stream_index])121				snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]);122			adata->sdw1_dma_intr_stat[stream_index] = 0;123		}124	}125	return IRQ_HANDLED;126}127 128static irqreturn_t acp63_irq_handler(int irq, void *dev_id)129{130	struct acp63_dev_data *adata;131	struct pdm_dev_data *ps_pdm_data;132	struct amd_sdw_manager *amd_manager;133	u32 ext_intr_stat, ext_intr_stat1;134	u32 stream_id = 0;135	u16 irq_flag = 0;136	u16 sdw_dma_irq_flag = 0;137	u16 index;138 139	adata = dev_id;140	if (!adata)141		return IRQ_NONE;142	/* ACP interrupts will be cleared by reading particular bit and writing143	 * same value to the status register. writing zero's doesn't have any144	 * effect.145	 * Bit by bit checking of IRQ field is implemented.146	 */147	ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);148	if (ext_intr_stat & ACP_SDW0_STAT) {149		writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);150		amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);151		if (amd_manager)152			schedule_work(&amd_manager->amd_sdw_irq_thread);153		irq_flag = 1;154	}155 156	ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);157	if (ext_intr_stat1 & ACP_SDW1_STAT) {158		writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);159		amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);160		if (amd_manager)161			schedule_work(&amd_manager->amd_sdw_irq_thread);162		irq_flag = 1;163	}164 165	if (ext_intr_stat & ACP_ERROR_IRQ) {166		writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);167		/* TODO: Report SoundWire Manager instance errors */168		writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON);169		writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON);170		writel(0, adata->acp63_base + ACP_ERROR_STATUS);171		irq_flag = 1;172	}173 174	if (ext_intr_stat & BIT(PDM_DMA_STAT)) {175		ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev);176		writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);177		if (ps_pdm_data->capture_stream)178			snd_pcm_period_elapsed(ps_pdm_data->capture_stream);179		irq_flag = 1;180	}181	if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) {182		for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) {183			if (ext_intr_stat & BIT(index)) {184				writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);185				switch (index) {186				case ACP_AUDIO0_TX_THRESHOLD:187					stream_id = ACP_SDW0_AUDIO0_TX;188					break;189				case ACP_AUDIO1_TX_THRESHOLD:190					stream_id = ACP_SDW0_AUDIO1_TX;191					break;192				case ACP_AUDIO2_TX_THRESHOLD:193					stream_id = ACP_SDW0_AUDIO2_TX;194					break;195				case ACP_AUDIO0_RX_THRESHOLD:196					stream_id = ACP_SDW0_AUDIO0_RX;197					break;198				case ACP_AUDIO1_RX_THRESHOLD:199					stream_id = ACP_SDW0_AUDIO1_RX;200					break;201				case ACP_AUDIO2_RX_THRESHOLD:202					stream_id = ACP_SDW0_AUDIO2_RX;203					break;204				}205 206				adata->sdw0_dma_intr_stat[stream_id] = 1;207				sdw_dma_irq_flag = 1;208			}209		}210	}211 212	if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) {213		writel(ACP_P1_AUDIO1_RX_THRESHOLD,214		       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);215		adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1;216		sdw_dma_irq_flag = 1;217	}218 219	if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) {220		writel(ACP_P1_AUDIO1_TX_THRESHOLD,221		       adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);222		adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1;223		sdw_dma_irq_flag = 1;224	}225 226	if (sdw_dma_irq_flag)227		return IRQ_WAKE_THREAD;228 229	if (irq_flag)230		return IRQ_HANDLED;231	else232		return IRQ_NONE;233}234 235#if IS_ENABLED(CONFIG_SND_SOC_AMD_SOUNDWIRE)236static int acp_scan_sdw_devices(struct device *dev, u64 addr)237{238	struct acpi_device *sdw_dev;239	struct acp63_dev_data *acp_data;240 241	acp_data = dev_get_drvdata(dev);242	if (!addr)243		return -ENODEV;244 245	sdw_dev = acpi_find_child_device(ACPI_COMPANION(dev), addr, 0);246	if (!sdw_dev)247		return -ENODEV;248 249	acp_data->info.handle = sdw_dev->handle;250	acp_data->info.count = AMD_SDW_MAX_MANAGERS;251	return amd_sdw_scan_controller(&acp_data->info);252}253 254static int amd_sdw_probe(struct device *dev)255{256	struct acp63_dev_data *acp_data;257	struct sdw_amd_res sdw_res;258	int ret;259 260	acp_data = dev_get_drvdata(dev);261	memset(&sdw_res, 0, sizeof(sdw_res));262	sdw_res.addr = acp_data->addr;263	sdw_res.reg_range = acp_data->reg_range;264	sdw_res.handle = acp_data->info.handle;265	sdw_res.parent = dev;266	sdw_res.dev = dev;267	sdw_res.acp_lock = &acp_data->acp_lock;268	sdw_res.count = acp_data->info.count;269	sdw_res.mmio_base = acp_data->acp63_base;270	sdw_res.link_mask = acp_data->info.link_mask;271	ret = sdw_amd_probe(&sdw_res, &acp_data->sdw);272	if (ret)273		dev_err(dev, "error: SoundWire probe failed\n");274	return ret;275}276 277static int amd_sdw_exit(struct acp63_dev_data *acp_data)278{279	if (acp_data->sdw)280		sdw_amd_exit(acp_data->sdw);281	acp_data->sdw = NULL;282 283	return 0;284}285 286static struct snd_soc_acpi_mach *acp63_sdw_machine_select(struct device *dev)287{288	struct snd_soc_acpi_mach *mach;289	const struct snd_soc_acpi_link_adr *link;290	struct acp63_dev_data *acp_data = dev_get_drvdata(dev);291	int ret, i;292 293	if (acp_data->info.count) {294		ret = sdw_amd_get_slave_info(acp_data->sdw);295		if (ret) {296			dev_dbg(dev, "failed to read slave information\n");297			return NULL;298		}299		for (mach = acp_data->machines; mach; mach++) {300			if (!mach->links)301				break;302			link = mach->links;303			for (i = 0; i < acp_data->info.count && link->num_adr; link++, i++) {304				if (!snd_soc_acpi_sdw_link_slaves_found(dev, link,305									acp_data->sdw->ids,306									acp_data->sdw->num_slaves))307					break;308			}309			if (i == acp_data->info.count || !link->num_adr)310				break;311		}312		if (mach && mach->link_mask) {313			mach->mach_params.links = mach->links;314			mach->mach_params.link_mask = mach->link_mask;315			return mach;316		}317	}318	dev_dbg(dev, "No SoundWire machine driver found\n");319	return NULL;320}321#else322static int acp_scan_sdw_devices(struct device *dev, u64 addr)323{324	return 0;325}326 327static int amd_sdw_probe(struct device *dev)328{329	return 0;330}331 332static int amd_sdw_exit(struct acp63_dev_data *acp_data)333{334	return 0;335}336 337static struct snd_soc_acpi_mach *acp63_sdw_machine_select(struct device *dev)338{339	return NULL;340}341#endif342 343static int acp63_machine_register(struct device *dev)344{345	struct snd_soc_acpi_mach *mach;346	struct acp63_dev_data *adata = dev_get_drvdata(dev);347	int size;348 349	if (adata->is_sdw_dev && adata->is_sdw_config) {350		size = sizeof(*adata->machines);351		mach = acp63_sdw_machine_select(dev);352		if (mach) {353			adata->mach_dev = platform_device_register_data(dev, mach->drv_name,354									PLATFORM_DEVID_NONE, mach,355									size);356			if (IS_ERR(adata->mach_dev)) {357				dev_err(dev,358					"cannot register Machine device for SoundWire Interface\n");359				return PTR_ERR(adata->mach_dev);360			}361		}362 363	} else if (adata->is_pdm_dev && !adata->is_sdw_dev && adata->is_pdm_config) {364		adata->mach_dev = platform_device_register_data(dev, "acp_ps_mach",365								PLATFORM_DEVID_NONE, NULL, 0);366		if (IS_ERR(adata->mach_dev)) {367			dev_err(dev, "cannot register amd_ps_mach device\n");368			return PTR_ERR(adata->mach_dev);369		}370	}371	return 0;372}373 374static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *acp_data)375{376	struct acpi_device *pdm_dev;377	const union acpi_object *obj;378	u32 config;379	bool is_dmic_dev = false;380	bool is_sdw_dev = false;381	int ret;382 383	config = readl(acp_data->acp63_base + ACP_PIN_CONFIG);384	switch (config) {385	case ACP_CONFIG_4:386	case ACP_CONFIG_5:387	case ACP_CONFIG_10:388	case ACP_CONFIG_11:389		acp_data->is_pdm_config = true;390		break;391	case ACP_CONFIG_2:392	case ACP_CONFIG_3:393		acp_data->is_sdw_config = true;394		break;395	case ACP_CONFIG_6:396	case ACP_CONFIG_7:397	case ACP_CONFIG_12:398	case ACP_CONFIG_8:399	case ACP_CONFIG_13:400	case ACP_CONFIG_14:401		acp_data->is_pdm_config = true;402		acp_data->is_sdw_config = true;403		break;404	default:405		break;406	}407 408	if (acp_data->is_pdm_config) {409		pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);410		if (pdm_dev) {411			/* is_dmic_dev flag will be set when ACP PDM controller device exists */412			if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type",413						   ACPI_TYPE_INTEGER, &obj) &&414						   obj->integer.value == ACP_DMIC_DEV)415				is_dmic_dev = true;416		}417	}418 419	if (acp_data->is_sdw_config) {420		ret = acp_scan_sdw_devices(&pci->dev, ACP63_SDW_ADDR);421		if (!ret && acp_data->info.link_mask)422			is_sdw_dev = true;423	}424 425	acp_data->is_pdm_dev = is_dmic_dev;426	acp_data->is_sdw_dev = is_sdw_dev;427	if (!is_dmic_dev && !is_sdw_dev) {428		dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n");429		return -ENODEV;430	}431	return 0;432}433 434static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,435					 struct device *parent,436					 struct fwnode_handle *fw_node,437					 char *name, unsigned int id,438					 const struct resource *res,439					 unsigned int num_res,440					 const void *data,441					 size_t size_data)442{443	pdevinfo->name = name;444	pdevinfo->id = id;445	pdevinfo->parent = parent;446	pdevinfo->num_res = num_res;447	pdevinfo->res = res;448	pdevinfo->data = data;449	pdevinfo->size_data = size_data;450	pdevinfo->fwnode = fw_node;451}452 453static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)454{455	struct platform_device_info pdevinfo;456	struct device *parent;457	int ret;458 459	parent = &pci->dev;460 461	if (adata->is_sdw_dev || adata->is_pdm_dev) {462		adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);463		if (!adata->res) {464			ret = -ENOMEM;465			goto de_init;466		}467		adata->res->flags = IORESOURCE_MEM;468		adata->res->start = addr;469		adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);470		memset(&pdevinfo, 0, sizeof(pdevinfo));471	}472 473	if (adata->is_pdm_dev && adata->is_pdm_config) {474		acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "acp_ps_pdm_dma",475					     0, adata->res, 1, NULL, 0);476 477		adata->pdm_dev = platform_device_register_full(&pdevinfo);478		if (IS_ERR(adata->pdm_dev)) {479			dev_err(&pci->dev,480				"cannot register %s device\n", pdevinfo.name);481			ret = PTR_ERR(adata->pdm_dev);482			goto de_init;483		}484		memset(&pdevinfo, 0, sizeof(pdevinfo));485		acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "dmic-codec",486					     0, NULL, 0, NULL, 0);487		adata->dmic_codec_dev = platform_device_register_full(&pdevinfo);488		if (IS_ERR(adata->dmic_codec_dev)) {489			dev_err(&pci->dev,490				"cannot register %s device\n", pdevinfo.name);491			ret = PTR_ERR(adata->dmic_codec_dev);492			goto unregister_pdm_dev;493		}494	}495	if (adata->is_sdw_dev && adata->is_sdw_config) {496		ret = amd_sdw_probe(&pci->dev);497		if (ret) {498			if (adata->is_pdm_dev)499				goto unregister_dmic_codec_dev;500			else501				goto de_init;502		}503		memset(&pdevinfo, 0, sizeof(pdevinfo));504		acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "amd_ps_sdw_dma",505					     0, adata->res, 1, NULL, 0);506 507		adata->sdw_dma_dev = platform_device_register_full(&pdevinfo);508		if (IS_ERR(adata->sdw_dma_dev)) {509			dev_err(&pci->dev,510				"cannot register %s device\n", pdevinfo.name);511			ret = PTR_ERR(adata->sdw_dma_dev);512			if (adata->is_pdm_dev)513				goto unregister_dmic_codec_dev;514			else515				goto de_init;516		}517	}518 519	return 0;520unregister_dmic_codec_dev:521		platform_device_unregister(adata->dmic_codec_dev);522unregister_pdm_dev:523		platform_device_unregister(adata->pdm_dev);524de_init:525	if (acp63_deinit(adata->acp63_base, &pci->dev))526		dev_err(&pci->dev, "ACP de-init failed\n");527	return ret;528}529 530static int snd_acp63_probe(struct pci_dev *pci,531			   const struct pci_device_id *pci_id)532{533	struct acp63_dev_data *adata;534	u32 addr;535	u32 irqflags, flag;536	int ret;537 538	irqflags = IRQF_SHARED;539 540	/* Return if acp config flag is defined */541	flag = snd_amd_acp_find_config(pci);542	if (flag)543		return -ENODEV;544 545	/* Pink Sardine device check */546	switch (pci->revision) {547	case 0x63:548		break;549	default:550		dev_dbg(&pci->dev, "acp63 pci device not found\n");551		return -ENODEV;552	}553	if (pci_enable_device(pci)) {554		dev_err(&pci->dev, "pci_enable_device failed\n");555		return -ENODEV;556	}557 558	ret = pci_request_regions(pci, "AMD ACP6.2 audio");559	if (ret < 0) {560		dev_err(&pci->dev, "pci_request_regions failed\n");561		goto disable_pci;562	}563	adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data),564			     GFP_KERNEL);565	if (!adata) {566		ret = -ENOMEM;567		goto release_regions;568	}569 570	addr = pci_resource_start(pci, 0);571	adata->acp63_base = devm_ioremap(&pci->dev, addr,572					 pci_resource_len(pci, 0));573	if (!adata->acp63_base) {574		ret = -ENOMEM;575		goto release_regions;576	}577	adata->addr = addr;578	adata->reg_range = ACP63_REG_END - ACP63_REG_START;579	pci_set_master(pci);580	pci_set_drvdata(pci, adata);581	mutex_init(&adata->acp_lock);582	ret = acp63_init(adata->acp63_base, &pci->dev);583	if (ret)584		goto release_regions;585	ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler,586					acp63_irq_thread, irqflags, "ACP_PCI_IRQ", adata);587	if (ret) {588		dev_err(&pci->dev, "ACP PCI IRQ request failed\n");589		goto de_init;590	}591	ret = get_acp63_device_config(pci, adata);592	/* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */593	if (ret) {594		dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret);595		goto skip_pdev_creation;596	}597	ret = create_acp63_platform_devs(pci, adata, addr);598	if (ret < 0) {599		dev_err(&pci->dev, "ACP platform devices creation failed\n");600		goto de_init;601	}602	ret = acp63_machine_register(&pci->dev);603	if (ret) {604		dev_err(&pci->dev, "ACP machine register failed\n");605		goto de_init;606	}607skip_pdev_creation:608	device_set_wakeup_enable(&pci->dev, true);609	pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);610	pm_runtime_use_autosuspend(&pci->dev);611	pm_runtime_put_noidle(&pci->dev);612	pm_runtime_allow(&pci->dev);613	return 0;614de_init:615	if (acp63_deinit(adata->acp63_base, &pci->dev))616		dev_err(&pci->dev, "ACP de-init failed\n");617release_regions:618	pci_release_regions(pci);619disable_pci:620	pci_disable_device(pci);621 622	return ret;623}624 625static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata)626{627	u32 sdw0_en, sdw1_en;628 629	sdw0_en = readl(adata->acp63_base + ACP_SW0_EN);630	sdw1_en = readl(adata->acp63_base + ACP_SW1_EN);631	return (sdw0_en || sdw1_en);632}633 634static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata)635{636	u32 val;637 638	val = readl(adata->acp63_base + ACP_SW0_WAKE_EN);639	if (val && adata->sdw->pdev[0])640		pm_request_resume(&adata->sdw->pdev[0]->dev);641 642	val = readl(adata->acp63_base + ACP_SW1_WAKE_EN);643	if (val && adata->sdw->pdev[1])644		pm_request_resume(&adata->sdw->pdev[1]->dev);645}646 647static int __maybe_unused snd_acp63_suspend(struct device *dev)648{649	struct acp63_dev_data *adata;650	int ret;651 652	adata = dev_get_drvdata(dev);653	if (adata->is_sdw_dev) {654		adata->sdw_en_stat = check_acp_sdw_enable_status(adata);655		if (adata->sdw_en_stat)656			return 0;657	}658	ret = acp63_deinit(adata->acp63_base, dev);659	if (ret)660		dev_err(dev, "ACP de-init failed\n");661 662	return ret;663}664 665static int __maybe_unused snd_acp63_runtime_resume(struct device *dev)666{667	struct acp63_dev_data *adata;668	int ret;669 670	adata = dev_get_drvdata(dev);671	if (adata->sdw_en_stat)672		return 0;673 674	ret = acp63_init(adata->acp63_base, dev);675	if (ret) {676		dev_err(dev, "ACP init failed\n");677		return ret;678	}679 680	if (!adata->sdw_en_stat)681		handle_acp63_sdw_pme_event(adata);682	return 0;683}684 685static int __maybe_unused snd_acp63_resume(struct device *dev)686{687	struct acp63_dev_data *adata;688	int ret;689 690	adata = dev_get_drvdata(dev);691	if (adata->sdw_en_stat)692		return 0;693 694	ret = acp63_init(adata->acp63_base, dev);695	if (ret)696		dev_err(dev, "ACP init failed\n");697 698	return ret;699}700 701static const struct dev_pm_ops acp63_pm_ops = {702	SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_runtime_resume, NULL)703	SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume)704};705 706static void snd_acp63_remove(struct pci_dev *pci)707{708	struct acp63_dev_data *adata;709	int ret;710 711	adata = pci_get_drvdata(pci);712	if (adata->sdw) {713		amd_sdw_exit(adata);714		platform_device_unregister(adata->sdw_dma_dev);715	}716	if (adata->is_pdm_dev) {717		platform_device_unregister(adata->pdm_dev);718		platform_device_unregister(adata->dmic_codec_dev);719	}720	if (adata->mach_dev)721		platform_device_unregister(adata->mach_dev);722	ret = acp63_deinit(adata->acp63_base, &pci->dev);723	if (ret)724		dev_err(&pci->dev, "ACP de-init failed\n");725	pm_runtime_forbid(&pci->dev);726	pm_runtime_get_noresume(&pci->dev);727	pci_release_regions(pci);728	pci_disable_device(pci);729}730 731static const struct pci_device_id snd_acp63_ids[] = {732	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),733	.class = PCI_CLASS_MULTIMEDIA_OTHER << 8,734	.class_mask = 0xffffff },735	{ 0, },736};737MODULE_DEVICE_TABLE(pci, snd_acp63_ids);738 739static struct pci_driver ps_acp63_driver  = {740	.name = KBUILD_MODNAME,741	.id_table = snd_acp63_ids,742	.probe = snd_acp63_probe,743	.remove = snd_acp63_remove,744	.driver = {745		.pm = &acp63_pm_ops,746	}747};748 749module_pci_driver(ps_acp63_driver);750 751MODULE_AUTHOR("Vijendar.Mukunda@amd.com");752MODULE_AUTHOR("Syed.SabaKareem@amd.com");753MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver");754MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT);755MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI);756MODULE_LICENSE("GPL v2");757