/[pkgs]/rpms/kernel/F-10/alsa-hda_intel-fix-unexpected-ring-buffer-positio.patch
ViewVC logotype

Contents of /rpms/kernel/F-10/alsa-hda_intel-fix-unexpected-ring-buffer-positio.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Mon Apr 13 18:21:11 2009 UTC (7 months, 1 week ago) by cebbert
Branch: MAIN
CVS Tags: kernel-2_6_29_1-41_fc10, kernel-2_6_29_3-60_fc10, kernel-2_6_29_6-99_fc10, kernel-2_6_29_1-42_fc10, kernel-2_6_29_6-93_fc10, kernel-2_6_29_2-45_rc1_fc10, kernel-2_6_29_2-48_rc1_fc10, kernel-2_6_29_6-97_fc10, kernel-2_6_29_5-84_fc10, kernel-2_6_29_2-55_fc10, kernel-2_6_29_2-52_fc10, kernel-2_6_29_1-36_fc10, kernel-2_6_29_4-72_fc10, kernel-2_6_29_5-88_fc10, kernel-2_6_29_4-75_fc10, kernel-2_6_29_4-80_fc10, kernel-2_6_29_1-30_fc10, kernel-2_6_29_1-38_fc10, HEAD
File MIME type: text/x-patch
Copy ALSA pulseaudio fixes from F-11.
1 From 8820b651ddf48830af44520a13e63f5b9c5b9f9f Mon Sep 17 00:00:00 2001
2 From: Jaroslav Kysela <perex@perex.cz>
3 Date: Fri, 10 Apr 2009 12:20:45 +0200
4 Subject: [ALSA] hda_intel: fix unexpected ring buffer positions
5
6 I found two issues with ICH7-M (it should be related to other HDA chipsets
7 as well):
8
9 - the ring buffer position is not reset when stream restarts (after xrun) -
10 solved by moving azx_stream_reset() call from open() to prepare() callback
11 and reset posbuf to zero (it might be filled with hw later than position()
12 callback is called)
13 - irq_ignore flag should be set also when ring buffer memory area is not
14 changed in prepare() callback - this patch replaces irq_ignore with
15 more universal check based on jiffies clock
16
17 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
18 ---
19 sound/pci/hda/hda_intel.c | 39 +++++++++++++++++++++++++--------------
20 1 files changed, 25 insertions(+), 14 deletions(-)
21
22 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
23 index 931a62d..7112e0e 100644
24 --- a/sound/pci/hda/hda_intel.c
25 +++ b/sound/pci/hda/hda_intel.c
26 @@ -312,6 +312,9 @@ struct azx_dev {
27 unsigned int period_bytes; /* size of the period in bytes */
28 unsigned int frags; /* number for period in the play buffer */
29 unsigned int fifo_size; /* FIFO size */
30 + unsigned int start_flag: 1; /* stream full start flag */
31 + unsigned long start_jiffies; /* start + minimum jiffies */
32 + unsigned long min_jiffies; /* minimum jiffies before position is valid */
33
34 void __iomem *sd_addr; /* stream descriptor pointer */
35
36 @@ -330,7 +333,6 @@ struct azx_dev {
37 unsigned int opened :1;
38 unsigned int running :1;
39 unsigned int irq_pending :1;
40 - unsigned int irq_ignore :1;
41 /*
42 * For VIA:
43 * A flag to ensure DMA position is 0
44 @@ -974,7 +976,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
45 struct azx *chip = dev_id;
46 struct azx_dev *azx_dev;
47 u32 status;
48 - int i;
49 + int i, ok;
50
51 spin_lock(&chip->reg_lock);
52
53 @@ -990,18 +992,14 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
54 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
55 if (!azx_dev->substream || !azx_dev->running)
56 continue;
57 - /* ignore the first dummy IRQ (due to pos_adj) */
58 - if (azx_dev->irq_ignore) {
59 - azx_dev->irq_ignore = 0;
60 - continue;
61 - }
62 /* check whether this IRQ is really acceptable */
63 - if (azx_position_ok(chip, azx_dev)) {
64 + ok = azx_position_ok(chip, azx_dev);
65 + if (ok == 1) {
66 azx_dev->irq_pending = 0;
67 spin_unlock(&chip->reg_lock);
68 snd_pcm_period_elapsed(azx_dev->substream);
69 spin_lock(&chip->reg_lock);
70 - } else if (chip->bus && chip->bus->workq) {
71 + } else if (ok == 0 && chip->bus && chip->bus->workq) {
72 /* bogus IRQ, process it later */
73 azx_dev->irq_pending = 1;
74 queue_work(chip->bus->workq,
75 @@ -1087,7 +1085,6 @@ static int azx_setup_periods(struct azx *chip,
76 bdl = (u32 *)azx_dev->bdl.area;
77 ofs = 0;
78 azx_dev->frags = 0;
79 - azx_dev->irq_ignore = 0;
80 pos_adj = bdl_pos_adj[chip->dev_index];
81 if (pos_adj > 0) {
82 struct snd_pcm_runtime *runtime = substream->runtime;
83 @@ -1108,7 +1105,6 @@ static int azx_setup_periods(struct azx *chip,
84 &bdl, ofs, pos_adj, 1);
85 if (ofs < 0)
86 goto error;
87 - azx_dev->irq_ignore = 1;
88 }
89 } else
90 pos_adj = 0;
91 @@ -1154,6 +1150,9 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
92 while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
93 --timeout)
94 ;
95 +
96 + /* reset first position - may not be synced with hw at this time */
97 + *azx_dev->posbuf = 0;
98 }
99
100 /*
101 @@ -1409,7 +1408,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
102 snd_pcm_set_sync(substream);
103 mutex_unlock(&chip->open_mutex);
104
105 - azx_stream_reset(chip, azx_dev);
106 return 0;
107 }
108
109 @@ -1474,6 +1472,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
110 unsigned int bufsize, period_bytes, format_val;
111 int err;
112
113 + azx_stream_reset(chip, azx_dev);
114 format_val = snd_hda_calc_stream_format(runtime->rate,
115 runtime->channels,
116 runtime->format,
117 @@ -1502,6 +1501,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
118 return err;
119 }
120
121 + azx_dev->min_jiffies = (runtime->period_size * HZ) /
122 + (runtime->rate * 2);
123 azx_setup_controller(chip, azx_dev);
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
125 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
126 @@ -1518,13 +1519,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
127 struct azx *chip = apcm->chip;
128 struct azx_dev *azx_dev;
129 struct snd_pcm_substream *s;
130 - int start, nsync = 0, sbits = 0;
131 + int rstart = 0, start, nsync = 0, sbits = 0;
132 int nwait, timeout;
133
134 switch (cmd) {
135 + case SNDRV_PCM_TRIGGER_START:
136 + rstart = 1;
137 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
138 case SNDRV_PCM_TRIGGER_RESUME:
139 - case SNDRV_PCM_TRIGGER_START:
140 start = 1;
141 break;
142 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
143 @@ -1554,6 +1556,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
144 if (s->pcm->card != substream->pcm->card)
145 continue;
146 azx_dev = get_azx_dev(s);
147 + if (rstart) {
148 + azx_dev->start_flag = 1;
149 + azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies;
150 + }
151 if (start)
152 azx_stream_start(chip, azx_dev);
153 else
154 @@ -1703,6 +1709,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
155 {
156 unsigned int pos;
157
158 + if (azx_dev->start_flag &&
159 + time_before_eq(jiffies, azx_dev->start_jiffies))
160 + return -1; /* bogus (too early) interrupt */
161 + azx_dev->start_flag = 0;
162 +
163 pos = azx_get_position(chip, azx_dev);
164 if (chip->position_fix == POS_FIX_AUTO) {
165 if (!pos) {
166 --
167 1.6.2.2
168

admin@fedoraproject.org
ViewVC Help
Powered by ViewVC 1.1.2