summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h5
-rw-r--r--include/sound/soc.h1
-rw-r--r--include/trace/events/asoc.h22
-rw-r--r--sound/soc/soc-dapm.c17
4 files changed, 45 insertions, 0 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 350b1b395ca..0e2d01713cb 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -537,4 +537,9 @@ struct snd_soc_dapm_widget_list {
struct snd_soc_dapm_widget *widgets[0];
};
+struct snd_soc_dapm_stats {
+ int power_checks;
+ int path_checks;
+};
+
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 24e17be38c1..006f4f633c5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -828,6 +828,7 @@ struct snd_soc_card {
/* Generic DAPM context for the card */
struct snd_soc_dapm_context dapm;
+ struct snd_soc_dapm_stats dapm_stats;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_card_root;
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index 603f5a0f036..2e1adf62e0a 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -216,6 +216,28 @@ DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done,
);
+TRACE_EVENT(snd_soc_dapm_walk_done,
+
+ TP_PROTO(struct snd_soc_card *card),
+
+ TP_ARGS(card),
+
+ TP_STRUCT__entry(
+ __string( name, card->name )
+ __field( int, power_checks )
+ __field( int, path_checks )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, card->name);
+ __entry->power_checks = card->dapm_stats.power_checks;
+ __entry->path_checks = card->dapm_stats.path_checks;
+ ),
+
+ TP_printk("%s: %d power checks, %d path checks", __get_str(name),
+ (int)__entry->power_checks, (int)__entry->path_checks)
+);
+
TRACE_EVENT(snd_soc_jack_irq,
TP_PROTO(const char *name),
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 4a440b52dd7..6a1e13ea996 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -48,6 +48,8 @@
#include <trace/events/asoc.h>
+#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
+
/* dapm power sequences - make this per codec in the future */
static int dapm_up_seq[] = {
[snd_soc_dapm_pre] = 0,
@@ -649,6 +651,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
struct snd_soc_dapm_path *path;
int con = 0;
+ DAPM_UPDATE_STAT(widget, path_checks);
+
if (widget->id == snd_soc_dapm_supply)
return 0;
@@ -697,6 +701,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
struct snd_soc_dapm_path *path;
int con = 0;
+ DAPM_UPDATE_STAT(widget, path_checks);
+
if (widget->id == snd_soc_dapm_supply)
return 0;
@@ -767,6 +773,8 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
{
int in, out;
+ DAPM_UPDATE_STAT(w, power_checks);
+
in = is_connected_input_ep(w);
dapm_clear_walk(w->dapm);
out = is_connected_output_ep(w);
@@ -779,6 +787,8 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
{
int in;
+ DAPM_UPDATE_STAT(w, power_checks);
+
if (w->active) {
in = is_connected_input_ep(w);
dapm_clear_walk(w->dapm);
@@ -793,6 +803,8 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
{
int out;
+ DAPM_UPDATE_STAT(w, power_checks);
+
if (w->active) {
out = is_connected_output_ep(w);
dapm_clear_walk(w->dapm);
@@ -808,6 +820,8 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
struct snd_soc_dapm_path *path;
int power = 0;
+ DAPM_UPDATE_STAT(w, power_checks);
+
/* Check if one of our outputs is connected */
list_for_each_entry(path, &w->sinks, list_source) {
if (path->weak)
@@ -1208,6 +1222,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
}
}
+ memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
+
/* Check which widgets we need to power and store them in
* lists indicating if they should be powered up or down.
*/
@@ -1299,6 +1315,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
list_for_each_entry(d, &card->dapm_list, list)
d->target_bias_level = bias;
+ trace_snd_soc_dapm_walk_done(card);
/* Run all the bias changes in parallel */
list_for_each_entry(d, &dapm->card->dapm_list, list)