Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
d807500a
Commit
d807500a
authored
Mar 24, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/pcm-cleanup' into for-linus
parents
c7ccfd06
8b22d943
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
102 additions
and
61 deletions
+102
-61
include/sound/pcm.h
include/sound/pcm.h
+0
-1
sound/core/pcm.c
sound/core/pcm.c
+0
-1
sound/core/pcm_lib.c
sound/core/pcm_lib.c
+102
-53
sound/core/pcm_timer.c
sound/core/pcm_timer.c
+0
-6
No files found.
include/sound/pcm.h
View file @
d807500a
...
...
@@ -364,7 +364,6 @@ struct snd_pcm_substream {
/* -- timer section -- */
struct
snd_timer
*
timer
;
/* timer */
unsigned
timer_running
:
1
;
/* time is running */
spinlock_t
timer_lock
;
/* -- next substream -- */
struct
snd_pcm_substream
*
next
;
/* -- linked substreams -- */
...
...
sound/core/pcm.c
View file @
d807500a
...
...
@@ -667,7 +667,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
spin_lock_init
(
&
substream
->
self_group
.
lock
);
INIT_LIST_HEAD
(
&
substream
->
self_group
.
substreams
);
list_add_tail
(
&
substream
->
link_list
,
&
substream
->
self_group
.
substreams
);
spin_lock_init
(
&
substream
->
timer_lock
);
atomic_set
(
&
substream
->
mmap_count
,
0
);
prev
=
substream
;
}
...
...
sound/core/pcm_lib.c
View file @
d807500a
...
...
@@ -125,23 +125,32 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
}
}
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#define xrun_debug(substream) ((substream)->pstr->xrun_debug)
#else
#define xrun_debug(substream) 0
#endif
#define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream) > 1) \
dump_stack(); \
} while (0)
static
void
xrun
(
struct
snd_pcm_substream
*
substream
)
{
snd_pcm_stop
(
substream
,
SNDRV_PCM_STATE_XRUN
);
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if
(
substream
->
pstr
->
xrun_debug
)
{
if
(
xrun_debug
(
substream
))
{
snd_printd
(
KERN_DEBUG
"XRUN: pcmC%dD%d%c
\n
"
,
substream
->
pcm
->
card
->
number
,
substream
->
pcm
->
device
,
substream
->
stream
?
'c'
:
'p'
);
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
dump_stack_on_xrun
(
substream
);
}
#endif
}
static
inline
snd_pcm_uframes_t
snd_pcm_update_hw_ptr_pos
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_runtime
*
runtime
)
static
snd_pcm_uframes_t
snd_pcm_update_hw_ptr_pos
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_runtime
*
runtime
)
{
snd_pcm_uframes_t
pos
;
...
...
@@ -150,17 +159,21 @@ static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substre
pos
=
substream
->
ops
->
pointer
(
substream
);
if
(
pos
==
SNDRV_PCM_POS_XRUN
)
return
pos
;
/* XRUN */
#ifdef CONFIG_SND_DEBUG
if
(
pos
>=
runtime
->
buffer_size
)
{
snd_printk
(
KERN_ERR
"BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx
\n
"
,
substream
->
stream
,
pos
,
runtime
->
buffer_size
,
runtime
->
period_size
);
if
(
printk_ratelimit
())
{
snd_printd
(
KERN_ERR
"BUG: stream = %i, pos = 0x%lx, "
"buffer size = 0x%lx, period size = 0x%lx
\n
"
,
substream
->
stream
,
pos
,
runtime
->
buffer_size
,
runtime
->
period_size
);
}
pos
=
0
;
}
#endif
pos
-=
pos
%
runtime
->
min_align
;
return
pos
;
}
static
in
line
in
t
snd_pcm_update_hw_ptr_post
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_runtime
*
runtime
)
static
int
snd_pcm_update_hw_ptr_post
(
struct
snd_pcm_substream
*
substream
,
struct
snd_pcm_runtime
*
runtime
)
{
snd_pcm_uframes_t
avail
;
...
...
@@ -182,11 +195,21 @@ static inline int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream
return
0
;
}
static
inline
int
snd_pcm_update_hw_ptr_interrupt
(
struct
snd_pcm_substream
*
substream
)
#define hw_ptr_error(substream, fmt, args...) \
do { \
if (xrun_debug(substream)) { \
if (printk_ratelimit()) { \
snd_printd("PCM: " fmt, ##args); \
} \
dump_stack_on_xrun(substream); \
} \
} while (0)
static
int
snd_pcm_update_hw_ptr_interrupt
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
snd_pcm_uframes_t
pos
;
snd_pcm_uframes_t
new_hw_ptr
,
hw_ptr_interrupt
;
snd_pcm_uframes_t
new_hw_ptr
,
hw_ptr_interrupt
,
hw_base
;
snd_pcm_sframes_t
delta
;
pos
=
snd_pcm_update_hw_ptr_pos
(
substream
,
runtime
);
...
...
@@ -194,36 +217,53 @@ static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *subs
xrun
(
substream
);
return
-
EPIPE
;
}
if
(
runtime
->
period_size
==
runtime
->
buffer_size
)
goto
__next_buf
;
new_hw_ptr
=
runtime
->
hw_ptr_base
+
pos
;
hw_base
=
runtime
->
hw_ptr_base
;
new_hw_ptr
=
hw_base
+
pos
;
hw_ptr_interrupt
=
runtime
->
hw_ptr_interrupt
+
runtime
->
period_size
;
delta
=
hw_ptr_interrupt
-
new_hw_ptr
;
if
(
delta
>
0
)
{
if
((
snd_pcm_uframes_t
)
delta
<
runtime
->
buffer_size
/
2
)
{
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if
(
runtime
->
periods
>
1
&&
substream
->
pstr
->
xrun_debug
)
{
snd_printd
(
KERN_ERR
"Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?
\n
"
,
substream
->
stream
,
(
long
)
delta
,
runtime
->
buffer_size
/
2
);
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
}
#endif
return
0
;
delta
=
new_hw_ptr
-
hw_ptr_interrupt
;
if
(
hw_ptr_interrupt
>=
runtime
->
boundary
)
{
hw_ptr_interrupt
-=
runtime
->
boundary
;
if
(
hw_base
<
runtime
->
boundary
/
2
)
/* hw_base was already lapped; recalc delta */
delta
=
new_hw_ptr
-
hw_ptr_interrupt
;
}
if
(
delta
<
0
)
{
delta
+=
runtime
->
buffer_size
;
if
(
delta
<
0
)
{
hw_ptr_error
(
substream
,
"Unexpected hw_pointer value "
"(stream=%i, pos=%ld, intr_ptr=%ld)
\n
"
,
substream
->
stream
,
(
long
)
pos
,
(
long
)
hw_ptr_interrupt
);
/* rebase to interrupt position */
hw_base
=
new_hw_ptr
=
hw_ptr_interrupt
;
/* align hw_base to buffer_size */
hw_base
-=
hw_base
%
runtime
->
buffer_size
;
delta
=
0
;
}
else
{
hw_base
+=
runtime
->
buffer_size
;
if
(
hw_base
>=
runtime
->
boundary
)
hw_base
=
0
;
new_hw_ptr
=
hw_base
+
pos
;
}
__next_buf:
runtime
->
hw_ptr_base
+=
runtime
->
buffer_size
;
if
(
runtime
->
hw_ptr_base
==
runtime
->
boundary
)
runtime
->
hw_ptr_base
=
0
;
new_hw_ptr
=
runtime
->
hw_ptr_base
+
pos
;
}
if
(
delta
>
runtime
->
period_size
)
{
hw_ptr_error
(
substream
,
"Lost interrupts? "
"(stream=%i, delta=%ld, intr_ptr=%ld)
\n
"
,
substream
->
stream
,
(
long
)
delta
,
(
long
)
hw_ptr_interrupt
);
/* rebase hw_ptr_interrupt */
hw_ptr_interrupt
=
new_hw_ptr
-
new_hw_ptr
%
runtime
->
period_size
;
}
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
&&
runtime
->
silence_size
>
0
)
snd_pcm_playback_silence
(
substream
,
new_hw_ptr
);
runtime
->
hw_ptr_base
=
hw_base
;
runtime
->
status
->
hw_ptr
=
new_hw_ptr
;
runtime
->
hw_ptr_interrupt
=
new_hw_ptr
-
new_hw_ptr
%
runtime
->
period_size
;
runtime
->
hw_ptr_interrupt
=
hw_ptr_interrupt
;
return
snd_pcm_update_hw_ptr_post
(
substream
,
runtime
);
}
...
...
@@ -233,7 +273,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
snd_pcm_uframes_t
pos
;
snd_pcm_uframes_t
old_hw_ptr
,
new_hw_ptr
;
snd_pcm_uframes_t
old_hw_ptr
,
new_hw_ptr
,
hw_base
;
snd_pcm_sframes_t
delta
;
old_hw_ptr
=
runtime
->
status
->
hw_ptr
;
...
...
@@ -242,29 +282,38 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
xrun
(
substream
);
return
-
EPIPE
;
}
new_hw_ptr
=
runtime
->
hw_ptr_base
+
pos
;
delta
=
old_hw_ptr
-
new_hw_ptr
;
if
(
delta
>
0
)
{
if
((
snd_pcm_uframes_t
)
delta
<
runtime
->
buffer_size
/
2
)
{
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if
(
runtime
->
periods
>
2
&&
substream
->
pstr
->
xrun_debug
)
{
snd_printd
(
KERN_ERR
"Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?
\n
"
,
substream
->
stream
,
(
long
)
delta
,
runtime
->
buffer_size
/
2
);
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
}
#endif
hw_base
=
runtime
->
hw_ptr_base
;
new_hw_ptr
=
hw_base
+
pos
;
delta
=
new_hw_ptr
-
old_hw_ptr
;
if
(
delta
<
0
)
{
delta
+=
runtime
->
buffer_size
;
if
(
delta
<
0
)
{
hw_ptr_error
(
substream
,
"Unexpected hw_pointer value [2] "
"(stream=%i, pos=%ld, old_ptr=%ld)
\n
"
,
substream
->
stream
,
(
long
)
pos
,
(
long
)
old_hw_ptr
);
return
0
;
}
runtime
->
hw_ptr_base
+=
runtime
->
buffer_size
;
if
(
runtime
->
hw_ptr_base
==
runtime
->
boundary
)
runtime
->
hw_ptr_base
=
0
;
new_hw_ptr
=
runtime
->
hw_ptr_base
+
pos
;
hw_base
+=
runtime
->
buffer_size
;
if
(
hw_base
>=
runtime
->
boundary
)
hw_base
=
0
;
new_hw_ptr
=
hw_base
+
pos
;
}
if
(
delta
>
runtime
->
period_size
&&
runtime
->
periods
>
1
)
{
hw_ptr_error
(
substream
,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld)
\n
"
,
(
long
)
pos
,
(
long
)
delta
,
(
long
)
runtime
->
period_size
);
return
0
;
}
if
(
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
&&
runtime
->
silence_size
>
0
)
snd_pcm_playback_silence
(
substream
,
new_hw_ptr
);
runtime
->
hw_ptr_base
=
hw_base
;
runtime
->
status
->
hw_ptr
=
new_hw_ptr
;
return
snd_pcm_update_hw_ptr_post
(
substream
,
runtime
);
...
...
sound/core/pcm_timer.c
View file @
d807500a
...
...
@@ -85,25 +85,19 @@ static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
static
int
snd_pcm_timer_start
(
struct
snd_timer
*
timer
)
{
unsigned
long
flags
;
struct
snd_pcm_substream
*
substream
;
substream
=
snd_timer_chip
(
timer
);
spin_lock_irqsave
(
&
substream
->
timer_lock
,
flags
);
substream
->
timer_running
=
1
;
spin_unlock_irqrestore
(
&
substream
->
timer_lock
,
flags
);
return
0
;
}
static
int
snd_pcm_timer_stop
(
struct
snd_timer
*
timer
)
{
unsigned
long
flags
;
struct
snd_pcm_substream
*
substream
;
substream
=
snd_timer_chip
(
timer
);
spin_lock_irqsave
(
&
substream
->
timer_lock
,
flags
);
substream
->
timer_running
=
0
;
spin_unlock_irqrestore
(
&
substream
->
timer_lock
,
flags
);
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment