xref: /OK3568_Linux_fs/kernel/sound/soc/amd/raven/pci-acp3x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // AMD ACP PCI Driver
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun //Copyright 2016 Advanced Micro Devices, Inc.
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/pci.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/io.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun #include <linux/pm_runtime.h>
13*4882a593Smuzhiyun #include <linux/delay.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include "acp3x.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun struct acp3x_dev_data {
18*4882a593Smuzhiyun 	void __iomem *acp3x_base;
19*4882a593Smuzhiyun 	bool acp3x_audio_mode;
20*4882a593Smuzhiyun 	struct resource *res;
21*4882a593Smuzhiyun 	struct platform_device *pdev[ACP3x_DEVS];
22*4882a593Smuzhiyun 	u32 pme_en;
23*4882a593Smuzhiyun };
24*4882a593Smuzhiyun 
acp3x_power_on(struct acp3x_dev_data * adata)25*4882a593Smuzhiyun static int acp3x_power_on(struct acp3x_dev_data *adata)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	void __iomem *acp3x_base = adata->acp3x_base;
28*4882a593Smuzhiyun 	u32 val;
29*4882a593Smuzhiyun 	int timeout;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	if (val == 0)
34*4882a593Smuzhiyun 		return val;
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	if (!((val & ACP_PGFSM_STATUS_MASK) ==
37*4882a593Smuzhiyun 				ACP_POWER_ON_IN_PROGRESS))
38*4882a593Smuzhiyun 		rv_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
39*4882a593Smuzhiyun 			acp3x_base + mmACP_PGFSM_CONTROL);
40*4882a593Smuzhiyun 	timeout = 0;
41*4882a593Smuzhiyun 	while (++timeout < 500) {
42*4882a593Smuzhiyun 		val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
43*4882a593Smuzhiyun 		if (!val) {
44*4882a593Smuzhiyun 			/* ACP power On clears PME_EN.
45*4882a593Smuzhiyun 			 * Restore the value to its prior state
46*4882a593Smuzhiyun 			 */
47*4882a593Smuzhiyun 			rv_writel(adata->pme_en, acp3x_base + mmACP_PME_EN);
48*4882a593Smuzhiyun 			return 0;
49*4882a593Smuzhiyun 		}
50*4882a593Smuzhiyun 		udelay(1);
51*4882a593Smuzhiyun 	}
52*4882a593Smuzhiyun 	return -ETIMEDOUT;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
acp3x_reset(void __iomem * acp3x_base)55*4882a593Smuzhiyun static int acp3x_reset(void __iomem *acp3x_base)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	u32 val;
58*4882a593Smuzhiyun 	int timeout;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	rv_writel(1, acp3x_base + mmACP_SOFT_RESET);
61*4882a593Smuzhiyun 	timeout = 0;
62*4882a593Smuzhiyun 	while (++timeout < 500) {
63*4882a593Smuzhiyun 		val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
64*4882a593Smuzhiyun 		if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK)
65*4882a593Smuzhiyun 			break;
66*4882a593Smuzhiyun 		cpu_relax();
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 	rv_writel(0, acp3x_base + mmACP_SOFT_RESET);
69*4882a593Smuzhiyun 	timeout = 0;
70*4882a593Smuzhiyun 	while (++timeout < 500) {
71*4882a593Smuzhiyun 		val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
72*4882a593Smuzhiyun 		if (!val)
73*4882a593Smuzhiyun 			return 0;
74*4882a593Smuzhiyun 		cpu_relax();
75*4882a593Smuzhiyun 	}
76*4882a593Smuzhiyun 	return -ETIMEDOUT;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
acp3x_enable_interrupts(void __iomem * acp_base)79*4882a593Smuzhiyun static void acp3x_enable_interrupts(void __iomem *acp_base)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	rv_writel(0x01, acp_base + mmACP_EXTERNAL_INTR_ENB);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
acp3x_disable_interrupts(void __iomem * acp_base)84*4882a593Smuzhiyun static void acp3x_disable_interrupts(void __iomem *acp_base)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	rv_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
87*4882a593Smuzhiyun 		  mmACP_EXTERNAL_INTR_STAT);
88*4882a593Smuzhiyun 	rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_CNTL);
89*4882a593Smuzhiyun 	rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_ENB);
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
acp3x_init(struct acp3x_dev_data * adata)92*4882a593Smuzhiyun static int acp3x_init(struct acp3x_dev_data *adata)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	void __iomem *acp3x_base = adata->acp3x_base;
95*4882a593Smuzhiyun 	int ret;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/* power on */
98*4882a593Smuzhiyun 	ret = acp3x_power_on(adata);
99*4882a593Smuzhiyun 	if (ret) {
100*4882a593Smuzhiyun 		pr_err("ACP3x power on failed\n");
101*4882a593Smuzhiyun 		return ret;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 	/* Reset */
104*4882a593Smuzhiyun 	ret = acp3x_reset(acp3x_base);
105*4882a593Smuzhiyun 	if (ret) {
106*4882a593Smuzhiyun 		pr_err("ACP3x reset failed\n");
107*4882a593Smuzhiyun 		return ret;
108*4882a593Smuzhiyun 	}
109*4882a593Smuzhiyun 	acp3x_enable_interrupts(acp3x_base);
110*4882a593Smuzhiyun 	return 0;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
acp3x_deinit(void __iomem * acp3x_base)113*4882a593Smuzhiyun static int acp3x_deinit(void __iomem *acp3x_base)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	int ret;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	acp3x_disable_interrupts(acp3x_base);
118*4882a593Smuzhiyun 	/* Reset */
119*4882a593Smuzhiyun 	ret = acp3x_reset(acp3x_base);
120*4882a593Smuzhiyun 	if (ret) {
121*4882a593Smuzhiyun 		pr_err("ACP3x reset failed\n");
122*4882a593Smuzhiyun 		return ret;
123*4882a593Smuzhiyun 	}
124*4882a593Smuzhiyun 	return 0;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
snd_acp3x_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)127*4882a593Smuzhiyun static int snd_acp3x_probe(struct pci_dev *pci,
128*4882a593Smuzhiyun 			   const struct pci_device_id *pci_id)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	struct acp3x_dev_data *adata;
131*4882a593Smuzhiyun 	struct platform_device_info pdevinfo[ACP3x_DEVS];
132*4882a593Smuzhiyun 	unsigned int irqflags;
133*4882a593Smuzhiyun 	int ret, i;
134*4882a593Smuzhiyun 	u32 addr, val;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	/* Raven device detection */
137*4882a593Smuzhiyun 	if (pci->revision != 0x00)
138*4882a593Smuzhiyun 		return -ENODEV;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	if (pci_enable_device(pci)) {
141*4882a593Smuzhiyun 		dev_err(&pci->dev, "pci_enable_device failed\n");
142*4882a593Smuzhiyun 		return -ENODEV;
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	ret = pci_request_regions(pci, "AMD ACP3x audio");
146*4882a593Smuzhiyun 	if (ret < 0) {
147*4882a593Smuzhiyun 		dev_err(&pci->dev, "pci_request_regions failed\n");
148*4882a593Smuzhiyun 		goto disable_pci;
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
152*4882a593Smuzhiyun 			     GFP_KERNEL);
153*4882a593Smuzhiyun 	if (!adata) {
154*4882a593Smuzhiyun 		ret = -ENOMEM;
155*4882a593Smuzhiyun 		goto release_regions;
156*4882a593Smuzhiyun 	}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* check for msi interrupt support */
159*4882a593Smuzhiyun 	ret = pci_enable_msi(pci);
160*4882a593Smuzhiyun 	if (ret)
161*4882a593Smuzhiyun 		/* msi is not enabled */
162*4882a593Smuzhiyun 		irqflags = IRQF_SHARED;
163*4882a593Smuzhiyun 	else
164*4882a593Smuzhiyun 		/* msi is enabled */
165*4882a593Smuzhiyun 		irqflags = 0;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	addr = pci_resource_start(pci, 0);
168*4882a593Smuzhiyun 	adata->acp3x_base = devm_ioremap(&pci->dev, addr,
169*4882a593Smuzhiyun 					pci_resource_len(pci, 0));
170*4882a593Smuzhiyun 	if (!adata->acp3x_base) {
171*4882a593Smuzhiyun 		ret = -ENOMEM;
172*4882a593Smuzhiyun 		goto disable_msi;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 	pci_set_master(pci);
175*4882a593Smuzhiyun 	pci_set_drvdata(pci, adata);
176*4882a593Smuzhiyun 	/* Save ACP_PME_EN state */
177*4882a593Smuzhiyun 	adata->pme_en = rv_readl(adata->acp3x_base + mmACP_PME_EN);
178*4882a593Smuzhiyun 	ret = acp3x_init(adata);
179*4882a593Smuzhiyun 	if (ret)
180*4882a593Smuzhiyun 		goto disable_msi;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
183*4882a593Smuzhiyun 	switch (val) {
184*4882a593Smuzhiyun 	case I2S_MODE:
185*4882a593Smuzhiyun 		adata->res = devm_kzalloc(&pci->dev,
186*4882a593Smuzhiyun 					  sizeof(struct resource) * 4,
187*4882a593Smuzhiyun 					  GFP_KERNEL);
188*4882a593Smuzhiyun 		if (!adata->res) {
189*4882a593Smuzhiyun 			ret = -ENOMEM;
190*4882a593Smuzhiyun 			goto de_init;
191*4882a593Smuzhiyun 		}
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 		adata->res[0].name = "acp3x_i2s_iomem";
194*4882a593Smuzhiyun 		adata->res[0].flags = IORESOURCE_MEM;
195*4882a593Smuzhiyun 		adata->res[0].start = addr;
196*4882a593Smuzhiyun 		adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 		adata->res[1].name = "acp3x_i2s_sp";
199*4882a593Smuzhiyun 		adata->res[1].flags = IORESOURCE_MEM;
200*4882a593Smuzhiyun 		adata->res[1].start = addr + ACP3x_I2STDM_REG_START;
201*4882a593Smuzhiyun 		adata->res[1].end = addr + ACP3x_I2STDM_REG_END;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 		adata->res[2].name = "acp3x_i2s_bt";
204*4882a593Smuzhiyun 		adata->res[2].flags = IORESOURCE_MEM;
205*4882a593Smuzhiyun 		adata->res[2].start = addr + ACP3x_BT_TDM_REG_START;
206*4882a593Smuzhiyun 		adata->res[2].end = addr + ACP3x_BT_TDM_REG_END;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 		adata->res[3].name = "acp3x_i2s_irq";
209*4882a593Smuzhiyun 		adata->res[3].flags = IORESOURCE_IRQ;
210*4882a593Smuzhiyun 		adata->res[3].start = pci->irq;
211*4882a593Smuzhiyun 		adata->res[3].end = adata->res[3].start;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 		adata->acp3x_audio_mode = ACP3x_I2S_MODE;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 		memset(&pdevinfo, 0, sizeof(pdevinfo));
216*4882a593Smuzhiyun 		pdevinfo[0].name = "acp3x_rv_i2s_dma";
217*4882a593Smuzhiyun 		pdevinfo[0].id = 0;
218*4882a593Smuzhiyun 		pdevinfo[0].parent = &pci->dev;
219*4882a593Smuzhiyun 		pdevinfo[0].num_res = 4;
220*4882a593Smuzhiyun 		pdevinfo[0].res = &adata->res[0];
221*4882a593Smuzhiyun 		pdevinfo[0].data = &irqflags;
222*4882a593Smuzhiyun 		pdevinfo[0].size_data = sizeof(irqflags);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 		pdevinfo[1].name = "acp3x_i2s_playcap";
225*4882a593Smuzhiyun 		pdevinfo[1].id = 0;
226*4882a593Smuzhiyun 		pdevinfo[1].parent = &pci->dev;
227*4882a593Smuzhiyun 		pdevinfo[1].num_res = 1;
228*4882a593Smuzhiyun 		pdevinfo[1].res = &adata->res[1];
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 		pdevinfo[2].name = "acp3x_i2s_playcap";
231*4882a593Smuzhiyun 		pdevinfo[2].id = 1;
232*4882a593Smuzhiyun 		pdevinfo[2].parent = &pci->dev;
233*4882a593Smuzhiyun 		pdevinfo[2].num_res = 1;
234*4882a593Smuzhiyun 		pdevinfo[2].res = &adata->res[1];
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 		pdevinfo[3].name = "acp3x_i2s_playcap";
237*4882a593Smuzhiyun 		pdevinfo[3].id = 2;
238*4882a593Smuzhiyun 		pdevinfo[3].parent = &pci->dev;
239*4882a593Smuzhiyun 		pdevinfo[3].num_res = 1;
240*4882a593Smuzhiyun 		pdevinfo[3].res = &adata->res[2];
241*4882a593Smuzhiyun 		for (i = 0; i < ACP3x_DEVS; i++) {
242*4882a593Smuzhiyun 			adata->pdev[i] =
243*4882a593Smuzhiyun 				platform_device_register_full(&pdevinfo[i]);
244*4882a593Smuzhiyun 			if (IS_ERR(adata->pdev[i])) {
245*4882a593Smuzhiyun 				dev_err(&pci->dev, "cannot register %s device\n",
246*4882a593Smuzhiyun 					pdevinfo[i].name);
247*4882a593Smuzhiyun 				ret = PTR_ERR(adata->pdev[i]);
248*4882a593Smuzhiyun 				goto unregister_devs;
249*4882a593Smuzhiyun 			}
250*4882a593Smuzhiyun 		}
251*4882a593Smuzhiyun 		break;
252*4882a593Smuzhiyun 	default:
253*4882a593Smuzhiyun 		dev_err(&pci->dev, "Invalid ACP audio mode : %d\n", val);
254*4882a593Smuzhiyun 		ret = -ENODEV;
255*4882a593Smuzhiyun 		goto disable_msi;
256*4882a593Smuzhiyun 	}
257*4882a593Smuzhiyun 	pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
258*4882a593Smuzhiyun 	pm_runtime_use_autosuspend(&pci->dev);
259*4882a593Smuzhiyun 	pm_runtime_put_noidle(&pci->dev);
260*4882a593Smuzhiyun 	pm_runtime_allow(&pci->dev);
261*4882a593Smuzhiyun 	return 0;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun unregister_devs:
264*4882a593Smuzhiyun 	if (val == I2S_MODE)
265*4882a593Smuzhiyun 		for (i = 0; i < ACP3x_DEVS; i++)
266*4882a593Smuzhiyun 			platform_device_unregister(adata->pdev[i]);
267*4882a593Smuzhiyun de_init:
268*4882a593Smuzhiyun 	if (acp3x_deinit(adata->acp3x_base))
269*4882a593Smuzhiyun 		dev_err(&pci->dev, "ACP de-init failed\n");
270*4882a593Smuzhiyun disable_msi:
271*4882a593Smuzhiyun 	pci_disable_msi(pci);
272*4882a593Smuzhiyun release_regions:
273*4882a593Smuzhiyun 	pci_release_regions(pci);
274*4882a593Smuzhiyun disable_pci:
275*4882a593Smuzhiyun 	pci_disable_device(pci);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	return ret;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun 
snd_acp3x_suspend(struct device * dev)280*4882a593Smuzhiyun static int snd_acp3x_suspend(struct device *dev)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	int ret;
283*4882a593Smuzhiyun 	struct acp3x_dev_data *adata;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	adata = dev_get_drvdata(dev);
286*4882a593Smuzhiyun 	ret = acp3x_deinit(adata->acp3x_base);
287*4882a593Smuzhiyun 	if (ret)
288*4882a593Smuzhiyun 		dev_err(dev, "ACP de-init failed\n");
289*4882a593Smuzhiyun 	else
290*4882a593Smuzhiyun 		dev_dbg(dev, "ACP de-initialized\n");
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	return 0;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
snd_acp3x_resume(struct device * dev)295*4882a593Smuzhiyun static int snd_acp3x_resume(struct device *dev)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	int ret;
298*4882a593Smuzhiyun 	struct acp3x_dev_data *adata;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	adata = dev_get_drvdata(dev);
301*4882a593Smuzhiyun 	ret = acp3x_init(adata);
302*4882a593Smuzhiyun 	if (ret) {
303*4882a593Smuzhiyun 		dev_err(dev, "ACP init failed\n");
304*4882a593Smuzhiyun 		return ret;
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun 	return 0;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun static const struct dev_pm_ops acp3x_pm = {
310*4882a593Smuzhiyun 	.runtime_suspend = snd_acp3x_suspend,
311*4882a593Smuzhiyun 	.runtime_resume =  snd_acp3x_resume,
312*4882a593Smuzhiyun 	.resume =	snd_acp3x_resume,
313*4882a593Smuzhiyun };
314*4882a593Smuzhiyun 
snd_acp3x_remove(struct pci_dev * pci)315*4882a593Smuzhiyun static void snd_acp3x_remove(struct pci_dev *pci)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	struct acp3x_dev_data *adata;
318*4882a593Smuzhiyun 	int i, ret;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	adata = pci_get_drvdata(pci);
321*4882a593Smuzhiyun 	if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) {
322*4882a593Smuzhiyun 		for (i = 0; i < ACP3x_DEVS; i++)
323*4882a593Smuzhiyun 			platform_device_unregister(adata->pdev[i]);
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 	ret = acp3x_deinit(adata->acp3x_base);
326*4882a593Smuzhiyun 	if (ret)
327*4882a593Smuzhiyun 		dev_err(&pci->dev, "ACP de-init failed\n");
328*4882a593Smuzhiyun 	pm_runtime_forbid(&pci->dev);
329*4882a593Smuzhiyun 	pm_runtime_get_noresume(&pci->dev);
330*4882a593Smuzhiyun 	pci_disable_msi(pci);
331*4882a593Smuzhiyun 	pci_release_regions(pci);
332*4882a593Smuzhiyun 	pci_disable_device(pci);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun static const struct pci_device_id snd_acp3x_ids[] = {
336*4882a593Smuzhiyun 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2),
337*4882a593Smuzhiyun 	.class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
338*4882a593Smuzhiyun 	.class_mask = 0xffffff },
339*4882a593Smuzhiyun 	{ 0, },
340*4882a593Smuzhiyun };
341*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, snd_acp3x_ids);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun static struct pci_driver acp3x_driver  = {
344*4882a593Smuzhiyun 	.name = KBUILD_MODNAME,
345*4882a593Smuzhiyun 	.id_table = snd_acp3x_ids,
346*4882a593Smuzhiyun 	.probe = snd_acp3x_probe,
347*4882a593Smuzhiyun 	.remove = snd_acp3x_remove,
348*4882a593Smuzhiyun 	.driver = {
349*4882a593Smuzhiyun 		.pm = &acp3x_pm,
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun };
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun module_pci_driver(acp3x_driver);
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
356*4882a593Smuzhiyun MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
357*4882a593Smuzhiyun MODULE_DESCRIPTION("AMD ACP3x PCI driver");
358*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
359