Skip to content

Commit aaf7a66

Browse files
Venkata-Prasad-Potturubroonie
authored andcommitted
ASoC: amd: acp: Add new interrupt handle callbacks in acp_common_hw_ops
Add new interrupt handle callbacks in acp_common_hw_ops. Refactor and move interrupt handler registration form platform driver to pci driver. Signed-off-by: Venkata Prasad Potturu <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 6e60db7 commit aaf7a66

File tree

11 files changed

+184
-91
lines changed

11 files changed

+184
-91
lines changed

sound/soc/amd/acp/acp-i2s.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,15 +617,15 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
617617
writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
618618
writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
619619

620-
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
620+
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
621621
ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
622622
BIT(BT_RX_THRESHOLD(rsrc->offset)) |
623623
BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
624624
BIT(BT_TX_THRESHOLD(rsrc->offset)) |
625625
BIT(HS_RX_THRESHOLD(rsrc->offset)) |
626626
BIT(HS_TX_THRESHOLD(rsrc->offset));
627627

628-
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
628+
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
629629

630630
return 0;
631631
}

sound/soc/amd/acp/acp-legacy-common.c

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,76 @@ const struct snd_acp_hw_ops acp_common_hw_ops = {
2727
/* ACP hardware initilizations */
2828
.acp_init = acp_init,
2929
.acp_deinit = acp_deinit,
30+
31+
/* ACP Interrupts*/
32+
.irq = acp_irq_handler,
33+
.en_interrupts = acp_enable_interrupts,
34+
.dis_interrupts = acp_disable_interrupts,
3035
};
3136
EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON");
32-
void acp_enable_interrupts(struct acp_dev_data *adata)
37+
38+
irqreturn_t acp_irq_handler(int irq, void *data)
3339
{
40+
struct acp_chip_info *chip = data;
41+
struct acp_dev_data *adata = chip->adata;
3442
struct acp_resource *rsrc = adata->rsrc;
43+
struct acp_stream *stream;
44+
u16 i2s_flag = 0;
45+
u32 ext_intr_stat, ext_intr_stat1;
46+
47+
if (adata->rsrc->no_of_ctrls == 2)
48+
ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1)));
49+
50+
ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
51+
52+
spin_lock(&adata->acp_lock);
53+
list_for_each_entry(stream, &adata->stream_list, list) {
54+
if (ext_intr_stat & stream->irq_bit) {
55+
writel(stream->irq_bit,
56+
ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
57+
snd_pcm_period_elapsed(stream->substream);
58+
i2s_flag = 1;
59+
}
60+
if (adata->rsrc->no_of_ctrls == 2) {
61+
if (ext_intr_stat1 & stream->irq_bit) {
62+
writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip,
63+
(rsrc->irqp_used - 1)));
64+
snd_pcm_period_elapsed(stream->substream);
65+
i2s_flag = 1;
66+
}
67+
}
68+
}
69+
spin_unlock(&adata->acp_lock);
70+
if (i2s_flag)
71+
return IRQ_HANDLED;
72+
73+
return IRQ_NONE;
74+
}
75+
76+
int acp_enable_interrupts(struct acp_chip_info *chip)
77+
{
78+
struct acp_resource *rsrc;
3579
u32 ext_intr_ctrl;
3680

37-
writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
38-
ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
81+
rsrc = chip->rsrc;
82+
writel(0x01, ACP_EXTERNAL_INTR_ENB(chip));
83+
ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
3984
ext_intr_ctrl |= ACP_ERROR_MASK;
40-
writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
85+
writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
86+
87+
return 0;
4188
}
4289
EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON");
4390

44-
void acp_disable_interrupts(struct acp_dev_data *adata)
91+
int acp_disable_interrupts(struct acp_chip_info *chip)
4592
{
46-
struct acp_resource *rsrc = adata->rsrc;
93+
struct acp_resource *rsrc;
94+
95+
rsrc = chip->rsrc;
96+
writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
97+
writel(0x00, ACP_EXTERNAL_INTR_ENB(chip));
4798

48-
writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
49-
writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
99+
return 0;
50100
}
51101
EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON");
52102

@@ -90,19 +140,23 @@ void restore_acp_pdm_params(struct snd_pcm_substream *substream,
90140
struct acp_dev_data *adata)
91141
{
92142
struct snd_soc_dai *dai;
143+
struct device *dev;
144+
struct acp_chip_info *chip;
93145
struct snd_soc_pcm_runtime *soc_runtime;
94146
u32 ext_int_ctrl;
95147

96148
soc_runtime = snd_soc_substream_to_rtd(substream);
97149
dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
150+
dev = dai->component->dev;
151+
chip = dev_get_platdata(dev);
98152
/* Programming channel mask and sampling rate */
99153
writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
100154
writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
101155

102156
/* Enabling ACP Pdm interuppts */
103-
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
157+
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
104158
ext_int_ctrl |= PDM_DMA_INTR_MASK;
105-
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
159+
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
106160
set_acp_pdm_clk(substream, dai);
107161
}
108162
EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON");
@@ -113,6 +167,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
113167
struct device *dev = dai->component->dev;
114168
struct acp_dev_data *adata = dev_get_drvdata(dev);
115169
struct acp_resource *rsrc = adata->rsrc;
170+
struct acp_chip_info *chip = dev_get_platdata(dev);
116171
struct acp_stream *stream = substream->runtime->private_data;
117172
u32 reg_dma_size, reg_fifo_size, reg_fifo_addr;
118173
u32 phy_addr, acp_fifo_addr, ext_int_ctrl;
@@ -185,15 +240,15 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
185240
writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
186241
writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
187242

188-
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
243+
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
189244
ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
190245
BIT(BT_RX_THRESHOLD(rsrc->offset)) |
191246
BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
192247
BIT(BT_TX_THRESHOLD(rsrc->offset)) |
193248
BIT(HS_RX_THRESHOLD(rsrc->offset)) |
194249
BIT(HS_TX_THRESHOLD(rsrc->offset));
195250

196-
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
251+
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
197252
return 0;
198253
}
199254

sound/soc/amd/acp/acp-pci.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@
2626
#define ACP3x_REG_START 0x1240000
2727
#define ACP3x_REG_END 0x125C000
2828

29+
static irqreturn_t irq_handler(int irq, void *data)
30+
{
31+
struct acp_chip_info *chip = data;
32+
33+
if (chip && chip->acp_hw_ops && chip->acp_hw_ops->irq)
34+
return chip->acp_hw_ops->irq(irq, chip);
35+
36+
return IRQ_NONE;
37+
}
2938
static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo,
3039
struct device *parent,
3140
struct fwnode_handle *fw_node,
@@ -166,6 +175,13 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
166175
if (ret)
167176
goto release_regions;
168177

178+
ret = devm_request_irq(dev, pci->irq, irq_handler,
179+
IRQF_SHARED, "ACP_I2S_IRQ", chip);
180+
if (ret) {
181+
dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret);
182+
return ret;
183+
}
184+
169185
check_acp_config(pci, chip);
170186
if (!chip->is_pdm_dev && !chip->is_i2s_config)
171187
goto skip_pdev_creation;
@@ -213,20 +229,17 @@ static int __maybe_unused snd_acp_suspend(struct device *dev)
213229
static int __maybe_unused snd_acp_resume(struct device *dev)
214230
{
215231
struct acp_chip_info *chip;
216-
struct acp_dev_data *adata;
217-
struct device child;
218232
int ret;
219233

220234
chip = dev_get_drvdata(dev);
221235
ret = acp_hw_init(chip);
222236
if (ret)
223237
dev_err(dev, "ACP init failed\n");
224-
if (chip->chip_pdev) {
225-
child = chip->chip_pdev->dev;
226-
adata = dev_get_drvdata(&child);
227-
if (adata)
228-
acp_enable_interrupts(adata);
229-
}
238+
239+
ret = acp_hw_en_interrupts(chip);
240+
if (ret)
241+
dev_err(dev, "ACP en-interrupts failed\n");
242+
230243
return ret;
231244
}
232245

sound/soc/amd/acp/acp-pdm.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
145145
{
146146
struct acp_stream *stream = substream->runtime->private_data;
147147
struct device *dev = dai->component->dev;
148-
struct acp_dev_data *adata = dev_get_drvdata(dev);
148+
struct acp_chip_info *chip = dev_get_platdata(dev);
149149
u32 ext_int_ctrl;
150150

151151
stream->dai_id = DMIC_INSTANCE;
@@ -154,9 +154,9 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
154154
stream->reg_offset = ACP_REGION2_OFFSET;
155155

156156
/* Enable DMIC Interrupts */
157-
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
157+
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
158158
ext_int_ctrl |= PDM_DMA_INTR_MASK;
159-
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
159+
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
160160

161161
return 0;
162162
}
@@ -165,13 +165,13 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
165165
struct snd_soc_dai *dai)
166166
{
167167
struct device *dev = dai->component->dev;
168-
struct acp_dev_data *adata = dev_get_drvdata(dev);
168+
struct acp_chip_info *chip = dev_get_platdata(dev);
169169
u32 ext_int_ctrl;
170170

171171
/* Disable DMIC interrupts */
172-
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
172+
ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
173173
ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
174-
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
174+
writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
175175
}
176176

177177
const struct snd_soc_dai_ops acp_dmic_dai_ops = {

sound/soc/amd/acp/acp-platform.c

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -107,43 +107,6 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = {
107107
.periods_max = CAPTURE_MAX_NUM_PERIODS,
108108
};
109109

110-
static irqreturn_t i2s_irq_handler(int irq, void *data)
111-
{
112-
struct acp_dev_data *adata = data;
113-
struct acp_resource *rsrc = adata->rsrc;
114-
struct acp_stream *stream;
115-
u16 i2s_flag = 0;
116-
u32 ext_intr_stat, ext_intr_stat1;
117-
118-
if (adata->rsrc->no_of_ctrls == 2)
119-
ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1)));
120-
121-
ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
122-
123-
spin_lock(&adata->acp_lock);
124-
list_for_each_entry(stream, &adata->stream_list, list) {
125-
if (ext_intr_stat & stream->irq_bit) {
126-
writel(stream->irq_bit,
127-
ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
128-
snd_pcm_period_elapsed(stream->substream);
129-
i2s_flag = 1;
130-
}
131-
if (adata->rsrc->no_of_ctrls == 2) {
132-
if (ext_intr_stat1 & stream->irq_bit) {
133-
writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata,
134-
(rsrc->irqp_used - 1)));
135-
snd_pcm_period_elapsed(stream->substream);
136-
i2s_flag = 1;
137-
}
138-
}
139-
}
140-
spin_unlock(&adata->acp_lock);
141-
if (i2s_flag)
142-
return IRQ_HANDLED;
143-
144-
return IRQ_NONE;
145-
}
146-
147110
void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
148111
{
149112
struct acp_resource *rsrc = adata->rsrc;
@@ -278,7 +241,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
278241
}
279242
runtime->private_data = stream;
280243

281-
writel(1, ACP_EXTERNAL_INTR_ENB(adata));
244+
writel(1, ACP_EXTERNAL_INTR_ENB(chip));
282245

283246
spin_lock_irq(&adata->acp_lock);
284247
list_add_tail(&stream->list, &adata->stream_list);
@@ -363,16 +326,17 @@ static const struct snd_soc_component_driver acp_pcm_component = {
363326
int acp_platform_register(struct device *dev)
364327
{
365328
struct acp_dev_data *adata = dev_get_drvdata(dev);
329+
struct acp_chip_info *chip;
366330
struct snd_soc_dai_driver;
367331
unsigned int status;
368332

369-
status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler,
370-
IRQF_SHARED, "ACP_I2S_IRQ", adata);
371-
if (status) {
372-
dev_err(dev, "ACP I2S IRQ request failed\n");
373-
return status;
333+
chip = dev_get_platdata(dev);
334+
if (!chip || !chip->base) {
335+
dev_err(dev, "ACP chip data is NULL\n");
336+
return -ENODEV;
374337
}
375338

339+
chip->adata = adata;
376340
status = devm_snd_soc_register_component(dev, &acp_pcm_component,
377341
adata->dai_driver,
378342
adata->num_dai);

sound/soc/amd/acp/acp-rembrandt.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
192192
return -ENODEV;
193193
}
194194

195+
chip->rsrc = &rsrc;
195196
adata->i2s_irq = res->start;
196197
adata->dev = dev;
197198
adata->dai_driver = acp_rmb_dai;
@@ -208,7 +209,11 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
208209
if (ret)
209210
return ret;
210211
}
211-
acp_enable_interrupts(adata);
212+
ret = acp_hw_en_interrupts(chip);
213+
if (ret) {
214+
dev_err(dev, "ACP en-interrupts failed\n");
215+
return ret;
216+
}
212217
acp_platform_register(dev);
213218
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
214219
pm_runtime_use_autosuspend(&pdev->dev);
@@ -221,9 +226,13 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
221226
static void rembrandt_audio_remove(struct platform_device *pdev)
222227
{
223228
struct device *dev = &pdev->dev;
224-
struct acp_dev_data *adata = dev_get_drvdata(dev);
229+
struct acp_chip_info *chip = dev_get_platdata(dev);
230+
int ret;
231+
232+
ret = acp_hw_dis_interrupts(chip);
233+
if (ret)
234+
dev_err(dev, "ACP dis-interrupts failed\n");
225235

226-
acp_disable_interrupts(adata);
227236
acp_platform_unregister(dev);
228237
pm_runtime_disable(&pdev->dev);
229238
}

sound/soc/amd/acp/acp-renoir.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static int renoir_audio_probe(struct platform_device *pdev)
142142
return ret;
143143
adata->i2s_irq = ret;
144144

145+
chip->rsrc = &rsrc;
145146
adata->dev = dev;
146147
adata->dai_driver = acp_renoir_dai;
147148
adata->num_dai = ARRAY_SIZE(acp_renoir_dai);
@@ -150,7 +151,11 @@ static int renoir_audio_probe(struct platform_device *pdev)
150151
adata->flag = chip->flag;
151152

152153
dev_set_drvdata(dev, adata);
153-
acp_enable_interrupts(adata);
154+
ret = acp_hw_en_interrupts(chip);
155+
if (ret) {
156+
dev_err(dev, "ACP en-interrupts failed\n");
157+
return ret;
158+
}
154159
acp_platform_register(dev);
155160

156161
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
@@ -164,9 +169,13 @@ static int renoir_audio_probe(struct platform_device *pdev)
164169
static void renoir_audio_remove(struct platform_device *pdev)
165170
{
166171
struct device *dev = &pdev->dev;
167-
struct acp_dev_data *adata = dev_get_drvdata(dev);
172+
struct acp_chip_info *chip = dev_get_platdata(dev);
173+
int ret;
174+
175+
ret = acp_hw_dis_interrupts(chip);
176+
if (ret)
177+
dev_err(dev, "ACP dis-interrupts failed\n");
168178

169-
acp_disable_interrupts(adata);
170179
acp_platform_unregister(dev);
171180
}
172181

0 commit comments

Comments
 (0)