aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitris Papastamos <dp@opensource.wolfsonmicro.com>2011-07-24 15:59:27 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:18:13 -0400
commit3cb2da7b7dca34c86a66f3617f96fcf37daac3b2 (patch)
treed8bef8fdf9a9a10c5e6ffc11d062cd788a715541
parenta8232e7afef8dc27349cd9969664133330e49561 (diff)
Subject: [PATCH 002/104] ASoC: soc-cache: Cache a pointer to the last accessed rbnode
Whenever we are doing a read or a write through the rbtree code, we'll cache a pointer to the rbnode. To avoid looking up the register everytime we do a read or a write, we first check if it can be found in the cached register block, otherwise we traverse the rbtree and finally cache the rbnode for future use. Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/soc-cache.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index aa161703d9b..984533c2fad 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -492,6 +492,7 @@ struct snd_soc_rbtree_node {
492 492
493struct snd_soc_rbtree_ctx { 493struct snd_soc_rbtree_ctx {
494 struct rb_root root; 494 struct rb_root root;
495 struct snd_soc_rbtree_node *cached_rbnode;
495}; 496};
496 497
497static inline void snd_soc_rbtree_get_base_top_reg( 498static inline void snd_soc_rbtree_get_base_top_reg(
@@ -668,11 +669,28 @@ static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
668 struct rb_node *node; 669 struct rb_node *node;
669 unsigned int val; 670 unsigned int val;
670 unsigned int reg_tmp; 671 unsigned int reg_tmp;
672 unsigned int base_reg, top_reg;
671 unsigned int pos; 673 unsigned int pos;
672 int i; 674 int i;
673 int ret; 675 int ret;
674 676
675 rbtree_ctx = codec->reg_cache; 677 rbtree_ctx = codec->reg_cache;
678 /* look up the required register in the cached rbnode */
679 rbnode = rbtree_ctx->cached_rbnode;
680 if (rbnode) {
681 snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
682 if (reg >= base_reg && reg <= top_reg) {
683 reg_tmp = reg - base_reg;
684 val = snd_soc_rbtree_get_register(rbnode, reg_tmp);
685 if (val == value)
686 return 0;
687 snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
688 return 0;
689 }
690 }
691 /* if we can't locate it in the cached rbnode we'll have
692 * to traverse the rbtree looking for it.
693 */
676 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); 694 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
677 if (rbnode) { 695 if (rbnode) {
678 reg_tmp = reg - rbnode->base_reg; 696 reg_tmp = reg - rbnode->base_reg;
@@ -680,6 +698,7 @@ static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
680 if (val == value) 698 if (val == value)
681 return 0; 699 return 0;
682 snd_soc_rbtree_set_register(rbnode, reg_tmp, value); 700 snd_soc_rbtree_set_register(rbnode, reg_tmp, value);
701 rbtree_ctx->cached_rbnode = rbnode;
683 } else { 702 } else {
684 /* bail out early, no need to create the rbnode yet */ 703 /* bail out early, no need to create the rbnode yet */
685 if (!value) 704 if (!value)
@@ -701,6 +720,7 @@ static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
701 reg, value); 720 reg, value);
702 if (ret) 721 if (ret)
703 return ret; 722 return ret;
723 rbtree_ctx->cached_rbnode = rbnode_tmp;
704 return 0; 724 return 0;
705 } 725 }
706 } 726 }
@@ -723,6 +743,7 @@ static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
723 } 743 }
724 snd_soc_rbtree_set_register(rbnode, 0, value); 744 snd_soc_rbtree_set_register(rbnode, 0, value);
725 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode); 745 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
746 rbtree_ctx->cached_rbnode = rbnode;
726 } 747 }
727 748
728 return 0; 749 return 0;
@@ -733,13 +754,28 @@ static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
733{ 754{
734 struct snd_soc_rbtree_ctx *rbtree_ctx; 755 struct snd_soc_rbtree_ctx *rbtree_ctx;
735 struct snd_soc_rbtree_node *rbnode; 756 struct snd_soc_rbtree_node *rbnode;
757 unsigned int base_reg, top_reg;
736 unsigned int reg_tmp; 758 unsigned int reg_tmp;
737 759
738 rbtree_ctx = codec->reg_cache; 760 rbtree_ctx = codec->reg_cache;
761 /* look up the required register in the cached rbnode */
762 rbnode = rbtree_ctx->cached_rbnode;
763 if (rbnode) {
764 snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg);
765 if (reg >= base_reg && reg <= top_reg) {
766 reg_tmp = reg - base_reg;
767 *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
768 return 0;
769 }
770 }
771 /* if we can't locate it in the cached rbnode we'll have
772 * to traverse the rbtree looking for it.
773 */
739 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); 774 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
740 if (rbnode) { 775 if (rbnode) {
741 reg_tmp = reg - rbnode->base_reg; 776 reg_tmp = reg - rbnode->base_reg;
742 *value = snd_soc_rbtree_get_register(rbnode, reg_tmp); 777 *value = snd_soc_rbtree_get_register(rbnode, reg_tmp);
778 rbtree_ctx->cached_rbnode = rbnode;
743 } else { 779 } else {
744 /* uninitialized registers default to 0 */ 780 /* uninitialized registers default to 0 */
745 *value = 0; 781 *value = 0;
@@ -790,6 +826,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
790 826
791 rbtree_ctx = codec->reg_cache; 827 rbtree_ctx = codec->reg_cache;
792 rbtree_ctx->root = RB_ROOT; 828 rbtree_ctx->root = RB_ROOT;
829 rbtree_ctx->cached_rbnode = NULL;
793 830
794 if (!codec->reg_def_copy) 831 if (!codec->reg_def_copy)
795 return 0; 832 return 0;