Signed-off-by: Takashi Iwai tiwai@suse.de ---
Erm, subject might be wrong, but I'm too dizzy now.
And this kind of change isn't always optimal indeed. But, it improves the readability, and often readability wins over a few byte performance win. Moreover, it makes easier to change word_size extension to 3 or 4 (if any in future).
sound/soc/soc-cache.c | 213 +++++++++++++++---------------------------------- 1 files changed, 65 insertions(+), 148 deletions(-) f diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index a3d448d..1e721d5 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -516,6 +516,35 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
+static inline bool set_cache_val(void *base, unsigned int idx, + unsigned int val, unsigned int word_size) +{ + if (word_size == 1) { + u8 *cache = base; + if (cache[idx] == val) + return true; + cache[idx] = val; + } else { + u16 *cache = base; + if (cache[idx] == val) + return true; + cache[idx] = val; + } + return false; +} + +static inline unsigned int get_cache_val(const void *base, unsigned int idx, + unsigned int word_size) +{ + if (word_size == 1) { + const u8 *cache = base; + return cache[idx]; + } else { + const u16 *cache = base; + return cache[idx]; + } +} + struct snd_soc_rbtree_node { struct rb_node node; unsigned int reg; @@ -680,7 +709,9 @@ static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec) static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) { struct snd_soc_rbtree_ctx *rbtree_ctx; - + int i, word_size; + struct snd_soc_rbtree_node *rbtree_node; + \ codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); if (!codec->reg_cache) return -ENOMEM; @@ -691,55 +722,27 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) if (!codec->reg_def_copy) return 0;
-/* - * populate the rbtree with the initialized registers. All other - * registers will be inserted into the tree when they are first written. - * - * The reasoning behind this, is that we need to step through and - * dereference the cache in u8/u16 increments without sacrificing - * portability. This could also be done using memcpy() but that would - * be slightly more cryptic. - */ -#define snd_soc_rbtree_populate(cache) \ -({ \ - int ret, i; \ - struct snd_soc_rbtree_node *rbtree_node; \ - \ - ret = 0; \ - cache = codec->reg_def_copy; \ - for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ - if (!cache[i]) \ - continue; \ - rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \ - if (!rbtree_node) { \ - ret = -ENOMEM; \ - snd_soc_cache_exit(codec); \ - break; \ - } \ - rbtree_node->reg = i; \ - rbtree_node->value = cache[i]; \ - rbtree_node->defval = cache[i]; \ - snd_soc_rbtree_insert(&rbtree_ctx->root, \ - rbtree_node); \ - } \ - ret; \ -}) - - switch (codec->driver->reg_word_size) { - case 1: { - const u8 *cache; - - return snd_soc_rbtree_populate(cache); - } - case 2: { - const u16 *cache; - - return snd_soc_rbtree_populate(cache); - } - default: - BUG(); + /* + * populate the rbtree with the initialized registers. All other + * registers will be inserted into the tree when they are first written. + */ + word_size = codec->driver->reg_word_size; + for (i = 0; i < codec->driver->reg_cache_size; ++i) { + unsigned int val; + val = get_cache_val(codec->reg_def_copy, i, word_size); + if (!val) + continue; + rbtree_node = kzalloc(sizeof(*rbtree_node), GFP_KERNEL); + if (!rbtree_node) { + snd_soc_cache_exit(codec); + return -ENOMEM; + break; + } + rbtree_node->reg = i; + rbtree_node->value = val; + rbtree_node->defval = val; + snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node); } - return 0; }
@@ -919,29 +922,10 @@ static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec, }
/* write the new value to the cache */ - switch (codec->driver->reg_word_size) { - case 1: { - u8 *cache; - cache = lzo_block->dst; - if (cache[blkpos] == value) { - kfree(lzo_block->dst); - goto out; - } - cache[blkpos] = value; - } - break; - case 2: { - u16 *cache; - cache = lzo_block->dst; - if (cache[blkpos] == value) { - kfree(lzo_block->dst); - goto out; - } - cache[blkpos] = value; - } - break; - default: - BUG(); + if (set_cache_val(lzo_block->dst, blkpos, value, + codec->driver->reg_word_size)) { + kfree(lzo_block->dst); + goto out; }
/* prepare the source to be the decompressed block */ @@ -995,25 +979,9 @@ static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
/* decompress the block */ ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); - if (ret >= 0) { - /* fetch the value from the cache */ - switch (codec->driver->reg_word_size) { - case 1: { - u8 *cache; - cache = lzo_block->dst; - *value = cache[blkpos]; - } - break; - case 2: { - u16 *cache; - cache = lzo_block->dst; - *value = cache[blkpos]; - } - break; - default: - BUG(); - } - } + if (ret >= 0) + *value = get_cache_val(lzo_block->dst, blkpos, + codec->driver->reg_word_size);
kfree(lzo_block->dst); /* restore the pointer and length of the compressed block */ @@ -1168,26 +1136,9 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) if (ret) return ret; if (codec_drv->reg_cache_default) { - switch (codec_drv->reg_word_size) { - case 1: { - const u8 *cache; - - cache = codec_drv->reg_cache_default; - if (cache[i] == val) - continue; - } - break; - case 2: { - const u16 *cache; - - cache = codec_drv->reg_cache_default; - if (cache[i] == val) + if (get_cache_val(codec_drv->reg_cache_default, i, + codec_drv->reg_word_size) == val) continue; - } - break; - default: - BUG(); - } } ret = snd_soc_write(codec, i, val); if (ret) @@ -1201,50 +1152,16 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - switch (codec->driver->reg_word_size) { - case 1: { - u8 *cache; - - cache = codec->reg_cache; - cache[reg] = value; - } - break; - case 2: { - u16 *cache; - - cache = codec->reg_cache; - cache[reg] = value; - } - break; - default: - BUG(); - } - + set_cache_val(codec->reg_cache, reg, value, + codec->driver->reg_word_size); return 0; }
static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, unsigned int reg, unsigned int *value) { - switch (codec->driver->reg_word_size) { - case 1: { - u8 *cache; - - cache = codec->reg_cache; - *value = cache[reg]; - } - break; - case 2: { - u16 *cache; - - cache = codec->reg_cache; - *value = cache[reg]; - } - break; - default: - BUG(); - } - + *value = get_cache_val(codec->reg_cache, reg, + codec->driver->reg_word_size); return 0; }