perf: Do not export power_frequency, but power_start event
[linux-2.6.git] / drivers / mfd / wm8400-core.c
index 6a0cedb..1bfef48 100644 (file)
 #include <linux/bug.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/mfd/core.h>
 #include <linux/mfd/wm8400-private.h>
 #include <linux/mfd/wm8400-audio.h>
+#include <linux/slab.h>
 
 static struct {
        u16  readable;    /* Mask of readable bits */
@@ -116,7 +118,7 @@ static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest)
 {
        int i, ret = 0;
 
-       BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache));
+       BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache));
 
        /* If there are any volatile reads then read back the entire block */
        for (i = reg; i < reg + num_regs; i++)
@@ -142,7 +144,7 @@ static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs,
 {
        int ret, i;
 
-       BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache));
+       BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache));
 
        for (i = 0; i < num_regs; i++) {
                BUG_ON(!reg_data[reg + i].writable);
@@ -239,6 +241,16 @@ void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400)
 }
 EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache);
 
+static int wm8400_register_codec(struct wm8400 *wm8400)
+{
+       struct mfd_cell cell = {
+               .name = "wm8400-codec",
+               .driver_data = wm8400,
+       };
+
+       return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
+}
+
 /*
  * wm8400_init - Generic initialisation
  *
@@ -254,7 +266,7 @@ static int wm8400_init(struct wm8400 *wm8400,
 
        mutex_init(&wm8400->io_lock);
 
-       wm8400->dev->driver_data = wm8400;
+       dev_set_drvdata(wm8400->dev, wm8400);
 
        /* Check that this is actually a WM8400 */
        ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, &reg);
@@ -296,24 +308,32 @@ static int wm8400_init(struct wm8400 *wm8400,
        reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
        dev_info(wm8400->dev, "WM8400 revision %x\n", reg);
 
+       ret = wm8400_register_codec(wm8400);
+       if (ret != 0) {
+               dev_err(wm8400->dev, "Failed to register codec\n");
+               goto err_children;
+       }
+
        if (pdata && pdata->platform_init) {
                ret = pdata->platform_init(wm8400->dev);
-               if (ret != 0)
+               if (ret != 0) {
                        dev_err(wm8400->dev, "Platform init failed: %d\n",
                                ret);
+                       goto err_children;
+               }
        } else
                dev_warn(wm8400->dev, "No platform initialisation supplied\n");
 
+       return 0;
+
+err_children:
+       mfd_remove_devices(wm8400->dev);
        return ret;
 }
 
 static void wm8400_release(struct wm8400 *wm8400)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(wm8400->regulators); i++)
-               if (wm8400->regulators[i].name)
-                       platform_device_unregister(&wm8400->regulators[i]);
+       mfd_remove_devices(wm8400->dev);
 }
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -395,7 +415,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
        return 0;
 
 struct_err:
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8400);
 err:
        return ret;
@@ -406,7 +425,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
        struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
 
        wm8400_release(wm8400);
-       i2c_set_clientdata(i2c, NULL);
        kfree(wm8400);
 
        return 0;
@@ -441,7 +459,7 @@ static int __init wm8400_module_init(void)
 
        return ret;
 }
-module_init(wm8400_module_init);
+subsys_initcall(wm8400_module_init);
 
 static void __exit wm8400_module_exit(void)
 {