diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-24 06:45:57 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-24 09:24:52 -0500 |
| commit | 50f3beb50abe0cc0228363af804e50e710b3e5b0 (patch) | |
| tree | fe189ffd9fd3caf67202a6f417d2da7e5ffe03d5 | |
| parent | 7a8f4ccfd572a11f609439dc6a75165b441641bc (diff) | |
V4L/DVB (9742): em28xx-alsa: implement another locking schema
Instead of using a spinlock, it is better to call the proper pcm stream
locking schema.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index ac3292d7646c..dfac2e042a52 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
| @@ -75,7 +75,9 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 75 | struct em28xx *dev = urb->context; | 75 | struct em28xx *dev = urb->context; |
| 76 | int i; | 76 | int i; |
| 77 | unsigned int oldptr; | 77 | unsigned int oldptr; |
| 78 | #ifdef NO_PCM_LOCK | ||
| 78 | unsigned long flags; | 79 | unsigned long flags; |
| 80 | #endif | ||
| 79 | int period_elapsed = 0; | 81 | int period_elapsed = 0; |
| 80 | int status; | 82 | int status; |
| 81 | unsigned char *cp; | 83 | unsigned char *cp; |
| @@ -96,9 +98,26 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 96 | if (!length) | 98 | if (!length) |
| 97 | continue; | 99 | continue; |
| 98 | 100 | ||
| 101 | #ifdef NO_PCM_LOCK | ||
| 99 | spin_lock_irqsave(&dev->adev->slock, flags); | 102 | spin_lock_irqsave(&dev->adev->slock, flags); |
| 100 | 103 | #endif | |
| 101 | oldptr = dev->adev->hwptr_done_capture; | 104 | oldptr = dev->adev->hwptr_done_capture; |
| 105 | if (oldptr + length >= runtime->buffer_size) { | ||
| 106 | unsigned int cnt = | ||
| 107 | runtime->buffer_size - oldptr; | ||
| 108 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 109 | cnt * stride); | ||
| 110 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
| 111 | length * stride - cnt * stride); | ||
| 112 | } else { | ||
| 113 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 114 | length * stride); | ||
| 115 | } | ||
| 116 | |||
| 117 | #ifndef NO_PCM_LOCK | ||
| 118 | snd_pcm_stream_lock(substream); | ||
| 119 | #endif | ||
| 120 | |||
| 102 | dev->adev->hwptr_done_capture += length; | 121 | dev->adev->hwptr_done_capture += length; |
| 103 | if (dev->adev->hwptr_done_capture >= | 122 | if (dev->adev->hwptr_done_capture >= |
| 104 | runtime->buffer_size) | 123 | runtime->buffer_size) |
| @@ -113,19 +132,11 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 113 | period_elapsed = 1; | 132 | period_elapsed = 1; |
| 114 | } | 133 | } |
| 115 | 134 | ||
| 135 | #ifdef NO_PCM_LOCK | ||
| 116 | spin_unlock_irqrestore(&dev->adev->slock, flags); | 136 | spin_unlock_irqrestore(&dev->adev->slock, flags); |
| 117 | 137 | #else | |
| 118 | if (oldptr + length >= runtime->buffer_size) { | 138 | snd_pcm_stream_unlock(substream); |
| 119 | unsigned int cnt = | 139 | #endif |
| 120 | runtime->buffer_size - oldptr; | ||
| 121 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 122 | cnt * stride); | ||
| 123 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
| 124 | length * stride - cnt * stride); | ||
| 125 | } else { | ||
| 126 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
| 127 | length * stride); | ||
| 128 | } | ||
| 129 | } | 140 | } |
| 130 | if (period_elapsed) | 141 | if (period_elapsed) |
| 131 | snd_pcm_period_elapsed(substream); | 142 | snd_pcm_period_elapsed(substream); |
