[alsa-devel] [PATCH 4/4] ASoC: clean up cache accesser

Takashi Iwai tiwai at suse.de
Mon Dec 20 17:05:51 CET 2010


Signed-off-by: Takashi Iwai <tiwai at 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;
 }
 
-- 
1.7.3.4



More information about the Alsa-devel mailing list