wl1251: improve PS report handling
[pandora-kernel.git] / drivers / mfd / twl-core.c
index bfbd660..eb714fd 100644 (file)
@@ -363,13 +363,13 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
                pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
                return -EPERM;
        }
-       sid = twl_map[mod_no].sid;
-       twl = &twl_modules[sid];
-
        if (unlikely(!inuse)) {
-               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+               pr_err("%s: not initialized\n", DRIVER_NAME);
                return -EPERM;
        }
+       sid = twl_map[mod_no].sid;
+       twl = &twl_modules[sid];
+
        mutex_lock(&twl->xfer_lock);
        /*
         * [MSG1]: fill the register address data
@@ -420,13 +420,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
                pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
                return -EPERM;
        }
-       sid = twl_map[mod_no].sid;
-       twl = &twl_modules[sid];
-
        if (unlikely(!inuse)) {
-               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+               pr_err("%s: not initialized\n", DRIVER_NAME);
                return -EPERM;
        }
+       sid = twl_map[mod_no].sid;
+       twl = &twl_modules[sid];
+
        mutex_lock(&twl->xfer_lock);
        /* [MSG1] fill the register address data */
        msg = &twl->xfer_msg[0];
@@ -561,7 +561,6 @@ add_numbered_child(unsigned chip, const char *name, int num,
                goto err;
        }
 
-       device_init_wakeup(&pdev->dev, can_wakeup);
        pdev->dev.parent = &twl->client->dev;
 
        if (pdata) {
@@ -586,6 +585,8 @@ add_numbered_child(unsigned chip, const char *name, int num,
        }
 
        status = platform_device_add(pdev);
+       if (status == 0)
+               device_init_wakeup(&pdev->dev, can_wakeup);
 
 err:
        if (status < 0) {
@@ -610,6 +611,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
                unsigned num_consumers, unsigned long features)
 {
        unsigned sub_chip_id;
+       struct twl_regulator_driver_data drv_data;
+
        /* regulator framework demands init_data ... */
        if (!pdata)
                return NULL;
@@ -619,7 +622,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
                pdata->num_consumer_supplies = num_consumers;
        }
 
-       pdata->driver_data = (void *)features;
+       if (pdata->driver_data) {
+               /* If we have existing drv_data, just add the flags */
+               struct twl_regulator_driver_data *tmp;
+               tmp = pdata->driver_data;
+               tmp->features |= features;
+       } else {
+               /* add new driver data struct, used only during init */
+               drv_data.features = features;
+               drv_data.set_voltage = NULL;
+               drv_data.get_voltage = NULL;
+               drv_data.data = NULL;
+               pdata->driver_data = &drv_data;
+       }
 
        /* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
        sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
@@ -694,8 +709,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
                static struct regulator_consumer_supply usb1v8 = {
                        .supply =       "usb1v8",
                };
-               static struct regulator_consumer_supply usb3v1 = {
-                       .supply =       "usb3v1",
+               static struct regulator_consumer_supply usb3v1[] = {
+                       { .supply =     "usb3v1" },
+                       { .supply =     "bci3v1" },
                };
 
        /* First add the regulators so that they can be used by transceiver */
@@ -723,7 +739,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
                                return PTR_ERR(child);
 
                        child = add_regulator_linked(TWL4030_REG_VUSB3V1,
-                                                     &usb_fixed, &usb3v1, 1,
+                                                     &usb_fixed, usb3v1, 2,
                                                      features);
                        if (IS_ERR(child))
                                return PTR_ERR(child);
@@ -744,7 +760,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
                if (twl_has_regulator() && child) {
                        usb1v5.dev = child;
                        usb1v8.dev = child;
-                       usb3v1.dev = child;
+                       usb3v1[0].dev = child;
                }
        }
        if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
@@ -926,6 +942,21 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
        /* twl6030 regulators */
        if (twl_has_regulator() && twl_class_is_6030() &&
                        !(features & TWL6025_SUBCLASS)) {
+               child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
+                                       features);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL6030_REG_VDD2, pdata->vdd2,
+                                       features);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL6030_REG_VDD3, pdata->vdd3,
+                                       features);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
                child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc,
                                        features);
                if (IS_ERR(child))