misc: nct1008: modify shutdown functionality
Gaurav Batra [Tue, 26 Feb 2013 21:59:10 +0000 (13:59 -0800)]
Bug 1234272

The shutdown function acquires the lock and waits on
the worker function to finish which itself needs the lock.
This results in the deadlock. Moved the lock call after
the wait on workers to finish.

Change-Id: I894d6b7342f9d42d86946d592ce912ddb0e476d9
Signed-off-by: Gaurav Batra <gbatra@nvidia.com>
Reviewed-on: http://git-master/r/204282
Reviewed-by: Sang-Hun Lee <sanlee@nvidia.com>
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-by: Sri Krishna Chowdary <schowdary@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>

drivers/misc/nct1008.c

index abafc77..61cbdca 100644 (file)
@@ -126,11 +126,11 @@ static int nct1008_write_reg(struct i2c_client *client, u8 reg, u16 value)
        }
 
        ret = i2c_smbus_write_byte_data(client, reg, value);
+       mutex_unlock(&data->mutex);
 
        if (ret < 0)
                dev_err(&client->dev, "%s: err %d\n", __func__, ret);
 
-       mutex_unlock(&data->mutex);
        return ret;
 }
 
@@ -145,11 +145,11 @@ static int nct1008_read_reg(struct i2c_client *client, u8 reg)
        }
 
        ret = i2c_smbus_read_byte_data(client, reg);
+       mutex_unlock(&data->mutex);
 
        if (ret < 0)
                dev_err(&client->dev, "%s: err %d\n", __func__, ret);
 
-       mutex_unlock(&data->mutex);
        return ret;
 }
 
@@ -1213,12 +1213,12 @@ static int __devexit nct1008_remove(struct i2c_client *client)
 static void nct1008_shutdown(struct i2c_client *client)
 {
        struct nct1008_data *data = i2c_get_clientdata(client);
-       mutex_lock(&data->mutex);
        if (client->irq)
                disable_irq(client->irq);
 
        cancel_work_sync(&data->work);
 
+       mutex_lock(&data->mutex);
        data->shutdown_complete = 1;
        mutex_unlock(&data->mutex);
 }