diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2011-07-24 15:59:27 -0400 |
---|---|---|
committer | Paolo Pisati <paolo.pisati@canonical.com> | 2012-08-17 04:18:13 -0400 |
commit | 3cb2da7b7dca34c86a66f3617f96fcf37daac3b2 (patch) | |
tree | d8bef8fdf9a9a10c5e6ffc11d062cd788a715541 | |
parent | a8232e7afef8dc27349cd9969664133330e49561 (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.c | 37 |
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 | ||
493 | struct snd_soc_rbtree_ctx { | 493 | struct 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 | ||
497 | static inline void snd_soc_rbtree_get_base_top_reg( | 498 | static 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; |