power: bq2419x: resolve mutex lock issue
Rohith Seelaboyina [Sat, 2 Feb 2013 12:40:54 +0000 (17:40 +0530)]
resolve the issue where same mutex variable is being
used to lock twice in the driver.

Bug 1228632

Change-Id: Ibddb84820a46514a215b05592649da1ca5991a6b
Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com>
Signed-off-by: Syed Rafiuddin <srafiuddin@nvidia.com>
Reviewed-on: http://git-master/r/196742
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

drivers/power/bq2419x-charger.c

index b240ad0..d08d1a2 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
-struct bq2419x_charger *bq_charger;
 /* input current limit */
 static const unsigned int iinlim[] = {
        100, 150, 500, 900, 1200, 1500, 2000, 3000,
@@ -61,12 +60,14 @@ struct bq2419x_charger {
        struct regulator_init_data      reg_init_data;
        int                     shutdown_complete;
        struct mutex            mutex;
+       struct mutex            chrg_mutex;
 };
 
+struct bq2419x_charger *bq_charger;
+
 static enum power_supply_property bq2419x_psy_props[] = {
        POWER_SUPPLY_PROP_ONLINE,
 };
-
 static int current_to_reg(const unsigned int *tbl,
                        size_t size, unsigned int val)
 {
@@ -81,35 +82,37 @@ static int current_to_reg(const unsigned int *tbl,
 static int bq2419x_charger_enable(struct bq2419x_charger *charger)
 {
        int ret;
-       mutex_lock(&bq_charger->mutex);
-       if (bq_charger && bq_charger->shutdown_complete) {
-               mutex_unlock(&bq_charger->mutex);
+       mutex_lock(&charger->mutex);
+       if (charger && charger->shutdown_complete) {
+               mutex_unlock(&charger->mutex);
                return -ENODEV;
        }
+       mutex_unlock(&charger->mutex);
+
        dev_info(charger->dev, "Charging enabled\n");
        ret = regmap_update_bits(charger->chip->regmap, BQ2419X_PWR_ON_REG,
                                ENABLE_CHARGE_MASK, ENABLE_CHARGE);
        if (ret < 0)
                dev_err(charger->dev, "register update failed, err %d\n", ret);
-       mutex_unlock(&bq_charger->mutex);
        return ret;
 }
 
 static int bq2419x_charger_disable(struct bq2419x_charger *charger)
 {
        int ret;
-       mutex_lock(&bq_charger->mutex);
-       if (bq_charger && bq_charger->shutdown_complete) {
-               mutex_unlock(&bq_charger->mutex);
+
+       mutex_lock(&charger->mutex);
+       if (charger && charger->shutdown_complete) {
+               mutex_unlock(&charger->mutex);
                return -ENODEV;
        }
+       mutex_unlock(&charger->mutex);
 
        dev_info(charger->dev, "Charging disabled\n");
        ret = regmap_update_bits(charger->chip->regmap, BQ2419X_PWR_ON_REG,
                                ENABLE_CHARGE_MASK, 0);
        if (ret < 0)
                dev_err(charger->dev, "register update failed, err %d\n", ret);
-       mutex_unlock(&bq_charger->mutex);
        return ret;
 }
 
@@ -144,11 +147,12 @@ static int bq2419x_init(struct bq2419x_charger *charger)
 {
        int val, ret = 0;
 
-       mutex_lock(&bq_charger->mutex);
-       if (bq_charger && bq_charger->shutdown_complete) {
-               mutex_unlock(&bq_charger->mutex);
+       mutex_lock(&charger->mutex);
+       if (charger && charger->shutdown_complete) {
+               mutex_unlock(&charger->mutex);
                return -ENODEV;
        }
+       mutex_unlock(&charger->mutex);
 
        if (charger->usb_online) {
                val = current_to_reg(iinlim, ARRAY_SIZE(iinlim),
@@ -175,7 +179,6 @@ static int bq2419x_init(struct bq2419x_charger *charger)
                        dev_err(charger->dev, "error reading reg: 0x%x\n",
                                BQ2419X_INPUT_SRC_REG);
        }
-       mutex_unlock(&bq_charger->mutex);
        return ret;
 }
 
@@ -190,21 +193,20 @@ static int bq2419x_enable_charger(struct regulator_dev *rdev,
        bq_charger->ac_online = 0;
        bq_charger->status = 0;
 
-       mutex_lock(&bq_charger->mutex);
+       mutex_lock(&bq_charger->chrg_mutex);
        if (bq_charger && bq_charger->shutdown_complete) {
-               mutex_unlock(&bq_charger->mutex);
+               mutex_unlock(&bq_charger->chrg_mutex);
                return -ENODEV;
        }
+       mutex_unlock(&bq_charger->chrg_mutex);
 
        ret = regmap_read(bq_charger->chip->regmap, BQ2419X_SYS_STAT_REG, &val);
        if (ret < 0)
                dev_err(bq_charger->dev, "error reading reg: 0x%x\n",
                                BQ2419X_SYS_STAT_REG);
 
-       if (max_uA == 0 && val != 0) {
-               mutex_unlock(&bq_charger->mutex);
+       if (max_uA == 0 && val != 0)
                return ret;
-       }
 
        if ((val & BQ2419x_VBUS_STAT) == BQ2419x_VBUS_UNKNOWN) {
                bq_charger->status = 0;
@@ -243,11 +245,9 @@ static int bq2419x_enable_charger(struct regulator_dev *rdev,
                if (bq_charger->use_usb)
                        power_supply_changed(&bq_charger->usb);
        }
-       mutex_unlock(&bq_charger->mutex);
        return 0;
 error:
        dev_err(bq_charger->dev, "Charger enable failed, err = %d\n", ret);
-       mutex_unlock(&bq_charger->mutex);
        return ret;
 }
 
@@ -297,17 +297,15 @@ static int __devinit bq2419x_charger_probe(struct platform_device *pdev)
        charger->shutdown_complete = 0;
        bq_charger = charger;
        platform_set_drvdata(pdev, charger);
-       mutex_init(&bq_charger->mutex);
+       mutex_init(&charger->mutex);
+       mutex_init(&charger->chrg_mutex);
 
-       mutex_lock(&bq_charger->mutex);
        ret = regmap_read(charger->chip->regmap, BQ2419X_REVISION_REG, &val);
        if (ret < 0) {
                dev_err(charger->dev, "error reading reg: 0x%x, err = %d\n",
                                        BQ2419X_REVISION_REG, ret);
-               mutex_unlock(&bq_charger->mutex);
                return ret;
        }
-       mutex_unlock(&bq_charger->mutex);
 
        if ((val & BQ24190_IC_VER) == BQ24190_IC_VER)
                dev_info(charger->dev, "chip type BQ24190 detected\n");
@@ -411,7 +409,8 @@ psy_error:
 free_gpio_status:
        if (gpio_is_valid(charger->gpio_status))
                gpio_free(charger->gpio_status);
-       mutex_destroy(&bq_charger->mutex);
+       mutex_destroy(&charger->mutex);
+       mutex_destroy(&charger->chrg_mutex);
        return ret;
 }
 
@@ -425,7 +424,8 @@ static int __devexit bq2419x_charger_remove(struct platform_device *pdev)
                power_supply_unregister(&charger->ac);
        if (gpio_is_valid(charger->gpio_status))
                gpio_free(charger->gpio_status);
-       mutex_destroy(&bq_charger->mutex);
+       mutex_destroy(&charger->mutex);
+       mutex_destroy(&charger->chrg_mutex);
        return 0;
 }