mfd: Fix twl-core oops while calling twl_i2c_* for unbound driver
[linux-2.6.git] / drivers / mfd / da903x.c
index 0b5bd85..2fadbae 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/mfd/da903x.h>
+#include <linux/slab.h>
 
 #define DA9030_CHIP_ID         0x00
 #define DA9030_EVENT_A         0x01
@@ -151,12 +152,24 @@ int da903x_write(struct device *dev, int reg, uint8_t val)
 }
 EXPORT_SYMBOL_GPL(da903x_write);
 
+int da903x_writes(struct device *dev, int reg, int len, uint8_t *val)
+{
+       return __da903x_writes(to_i2c_client(dev), reg, len, val);
+}
+EXPORT_SYMBOL_GPL(da903x_writes);
+
 int da903x_read(struct device *dev, int reg, uint8_t *val)
 {
        return __da903x_read(to_i2c_client(dev), reg, val);
 }
 EXPORT_SYMBOL_GPL(da903x_read);
 
+int da903x_reads(struct device *dev, int reg, int len, uint8_t *val)
+{
+       return __da903x_reads(to_i2c_client(dev), reg, len, val);
+}
+EXPORT_SYMBOL_GPL(da903x_reads);
+
 int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
 {
        struct da903x_chip *chip = dev_get_drvdata(dev);
@@ -401,7 +414,7 @@ static void da903x_irq_work(struct work_struct *work)
        enable_irq(chip->client->irq);
 }
 
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
 {
        struct da903x_chip *chip = data;
 
@@ -435,13 +448,13 @@ static const struct i2c_device_id da903x_id_table[] = {
 };
 MODULE_DEVICE_TABLE(i2c, da903x_id_table);
 
-static int __devexit __remove_subdev(struct device *dev, void *unused)
+static int __remove_subdev(struct device *dev, void *unused)
 {
        platform_device_unregister(to_platform_device(dev));
        return 0;
 }
 
-static int __devexit da903x_remove_subdevs(struct da903x_chip *chip)
+static int da903x_remove_subdevs(struct da903x_chip *chip)
 {
        return device_for_each_child(chip->dev, NULL, __remove_subdev);
 }
@@ -457,13 +470,19 @@ static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
                subdev = &pdata->subdevs[i];
 
                pdev = platform_device_alloc(subdev->name, subdev->id);
+               if (!pdev) {
+                       ret = -ENOMEM;
+                       goto failed;
+               }
 
                pdev->dev.parent = chip->dev;
                pdev->dev.platform_data = subdev->platform_data;
 
                ret = platform_device_add(pdev);
-               if (ret)
+               if (ret) {
+                       platform_device_put(pdev);
                        goto failed;
+               }
        }
        return 0;
 
@@ -521,7 +540,6 @@ static int __devinit da903x_probe(struct i2c_client *client,
 out_free_irq:
        free_irq(client->irq, chip);
 out_free_chip:
-       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return ret;
 }
@@ -549,7 +567,7 @@ static int __init da903x_init(void)
 {
        return i2c_add_driver(&da903x_driver);
 }
-module_init(da903x_init);
+subsys_initcall(da903x_init);
 
 static void __exit da903x_exit(void)
 {