Merge git://git.infradead.org/mtd-2.6
[pandora-kernel.git] / sound / soc / soc-cache.c
index 5143984..8c2a21a 100644 (file)
@@ -85,7 +85,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
        msg[1] = data[0];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -166,7 +166,7 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
        msg[1] = data[1];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -246,7 +246,7 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
        msg[1] = data[1];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -326,7 +326,7 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data,
        msg[2] = data[2];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -513,7 +513,7 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
        msg[2] = data[2];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -633,7 +633,7 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data,
        msg[3] = data[3];
 
        spi_message_init(&m);
-       memset(&t, 0, (sizeof t));
+       memset(&t, 0, sizeof t);
 
        t.tx_buf = &msg[0];
        t.len = len;
@@ -728,8 +728,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       codec->driver->write = io_types[i].write;
-       codec->driver->read = io_types[i].read;
+       codec->write = io_types[i].write;
+       codec->read = io_types[i].read;
 
        switch (control) {
        case SND_SOC_CUSTOM:
@@ -933,7 +933,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
        rbtree_ctx = codec->reg_cache;
        rbtree_ctx->root = RB_ROOT;
 
-       if (!codec->driver->reg_cache_default)
+       if (!codec->reg_def_copy)
                return 0;
 
 /*
@@ -951,7 +951,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
        struct snd_soc_rbtree_node *rbtree_node;                        \
                                                                        \
        ret = 0;                                                        \
-       cache = codec->driver->reg_cache_default;                       \
+       cache = codec->reg_def_copy;                                    \
        for (i = 0; i < codec->driver->reg_cache_size; ++i) {           \
                if (!cache[i])                                          \
                        continue;                                       \
@@ -988,6 +988,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
        return 0;
 }
 
+#ifdef CONFIG_SND_SOC_CACHE_LZO
 struct snd_soc_lzo_ctx {
        void *wmem;
        void *dst;
@@ -1078,7 +1079,7 @@ static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
 static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
                unsigned int reg)
 {
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        size_t reg_size;
 
        codec_drv = codec->driver;
@@ -1090,7 +1091,7 @@ static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
 static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
                unsigned int reg)
 {
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        size_t reg_size;
 
        codec_drv = codec->driver;
@@ -1101,7 +1102,7 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
 
 static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
 {
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        size_t reg_size;
 
        codec_drv = codec->driver;
@@ -1301,7 +1302,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
 {
        struct snd_soc_lzo_ctx **lzo_blocks;
        size_t reg_size, bmp_size;
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        int ret, tofree, i, blksize, blkcount;
        const char *p, *end;
        unsigned long *sync_bmp;
@@ -1316,13 +1317,13 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
         * and remember to free it afterwards.
         */
        tofree = 0;
-       if (!codec_drv->reg_cache_default)
+       if (!codec->reg_def_copy)
                tofree = 1;
 
-       if (!codec_drv->reg_cache_default) {
-               codec_drv->reg_cache_default = kzalloc(reg_size,
+       if (!codec->reg_def_copy) {
+               codec->reg_def_copy = kzalloc(reg_size,
                                                       GFP_KERNEL);
-               if (!codec_drv->reg_cache_default)
+               if (!codec->reg_def_copy)
                        return -ENOMEM;
        }
 
@@ -1342,7 +1343,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
         * that register.
         */
        bmp_size = codec_drv->reg_cache_size;
-       sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof (long),
+       sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
                           GFP_KERNEL);
        if (!sync_bmp) {
                ret = -ENOMEM;
@@ -1360,7 +1361,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
                        goto err;
                }
                lzo_blocks[i]->sync_bmp = sync_bmp;
-               lzo_blocks[i]->sync_bmp_nbits = reg_size;
+               lzo_blocks[i]->sync_bmp_nbits = bmp_size;
                /* alloc the working space for the compressed block */
                ret = snd_soc_lzo_prepare(lzo_blocks[i]);
                if (ret < 0)
@@ -1368,8 +1369,8 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
        }
 
        blksize = snd_soc_lzo_get_blksize(codec);
-       p = codec_drv->reg_cache_default;
-       end = codec_drv->reg_cache_default + reg_size;
+       p = codec->reg_def_copy;
+       end = codec->reg_def_copy + reg_size;
        /* compress the register map and fill the lzo blocks */
        for (i = 0; i < blkcount; ++i, p += blksize) {
                lzo_blocks[i]->src = p;
@@ -1385,22 +1386,27 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
                        lzo_blocks[i]->src_len;
        }
 
-       if (tofree)
-               kfree(codec_drv->reg_cache_default);
+       if (tofree) {
+               kfree(codec->reg_def_copy);
+               codec->reg_def_copy = NULL;
+       }
        return 0;
 err:
        snd_soc_cache_exit(codec);
 err_tofree:
-       if (tofree)
-               kfree(codec_drv->reg_cache_default);
+       if (tofree) {
+               kfree(codec->reg_def_copy);
+               codec->reg_def_copy = NULL;
+       }
        return ret;
 }
+#endif
 
 static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
 {
        int i;
        int ret;
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        unsigned int val;
 
        codec_drv = codec->driver;
@@ -1500,12 +1506,20 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
 
 static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
 {
-       struct snd_soc_codec_driver *codec_drv;
+       const struct snd_soc_codec_driver *codec_drv;
        size_t reg_size;
 
        codec_drv = codec->driver;
        reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
 
+       /*
+        * for flat compression, we don't need to keep a copy of the
+        * original defaults register cache as it will definitely not
+        * be marked as __devinitconst
+        */
+       kfree(codec->reg_def_copy);
+       codec->reg_def_copy = NULL;
+
        if (codec_drv->reg_cache_default)
                codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
                                           reg_size, GFP_KERNEL);
@@ -1519,24 +1533,30 @@ static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
 
 /* an array of all supported compression types */
 static const struct snd_soc_cache_ops cache_types[] = {
+       /* Flat *must* be the first entry for fallback */
        {
                .id = SND_SOC_FLAT_COMPRESSION,
+               .name = "flat",
                .init = snd_soc_flat_cache_init,
                .exit = snd_soc_flat_cache_exit,
                .read = snd_soc_flat_cache_read,
                .write = snd_soc_flat_cache_write,
                .sync = snd_soc_flat_cache_sync
        },
+#ifdef CONFIG_SND_SOC_CACHE_LZO
        {
                .id = SND_SOC_LZO_COMPRESSION,
+               .name = "LZO",
                .init = snd_soc_lzo_cache_init,
                .exit = snd_soc_lzo_cache_exit,
                .read = snd_soc_lzo_cache_read,
                .write = snd_soc_lzo_cache_write,
                .sync = snd_soc_lzo_cache_sync
        },
+#endif
        {
                .id = SND_SOC_RBTREE_COMPRESSION,
+               .name = "rbtree",
                .init = snd_soc_rbtree_cache_init,
                .exit = snd_soc_rbtree_cache_exit,
                .read = snd_soc_rbtree_cache_read,
@@ -1550,19 +1570,25 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
-               if (cache_types[i].id == codec->driver->compress_type)
+               if (cache_types[i].id == codec->compress_type)
                        break;
+
+       /* Fall back to flat compression */
        if (i == ARRAY_SIZE(cache_types)) {
-               dev_err(codec->dev, "Could not match compress type: %d\n",
-                       codec->driver->compress_type);
-               return -EINVAL;
+               dev_warn(codec->dev, "Could not match compress type: %d\n",
+                        codec->compress_type);
+               i = 0;
        }
 
        mutex_init(&codec->cache_rw_mutex);
        codec->cache_ops = &cache_types[i];
 
-       if (codec->cache_ops->init)
+       if (codec->cache_ops->init) {
+               if (codec->cache_ops->name)
+                       dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
+                               codec->cache_ops->name, codec->name);
                return codec->cache_ops->init(codec);
+       }
        return -EINVAL;
 }
 
@@ -1572,8 +1598,12 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
  */
 int snd_soc_cache_exit(struct snd_soc_codec *codec)
 {
-       if (codec->cache_ops && codec->cache_ops->exit)
+       if (codec->cache_ops && codec->cache_ops->exit) {
+               if (codec->cache_ops->name)
+                       dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
+                               codec->cache_ops->name, codec->name);
                return codec->cache_ops->exit(codec);
+       }
        return -EINVAL;
 }
 
@@ -1645,6 +1675,9 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
        }
 
        if (codec->cache_ops && codec->cache_ops->sync) {
+               if (codec->cache_ops->name)
+                       dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
+                               codec->cache_ops->name, codec->name);
                ret = codec->cache_ops->sync(codec);
                if (!ret)
                        codec->cache_sync = 0;