summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorJin Park <jinyoungp@nvidia.com>2011-08-19 19:58:41 +0900
committerVarun Colbert <vcolbert@nvidia.com>2011-08-19 15:36:52 -0700
commitba16a9c9891fc415add3fbe1fe794a27b4213e77 (patch)
tree035b7b4dd4d69e8f3ff54cc42dbb65434f507060 /drivers/mfd
parent2cb7615e6400838bbeeb8270c7af9e85b54a134f (diff)
mfd: aat2870: Add io mutex into I2C update function.
Adding io mutex into I2C update function to prevent race condition problem. Signed-off-by: Jin Park <jinyoungp@nvidia.com> Change-Id: Ibff85a825a6716bfc88eea55704bbbcc565cf962 Reviewed-on: http://git-master/r/48136 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/aat2870-core.c99
1 files changed, 51 insertions, 48 deletions
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
index 6d7e868b8b23..9deb3f34751b 100644
--- a/drivers/mfd/aat2870-core.c
+++ b/drivers/mfd/aat2870-core.c
@@ -103,53 +103,41 @@ static struct mfd_cell aat2870_devs[] = {
},
};
-static int aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val)
+static int __aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val)
{
- struct i2c_client *client = aat2870->client;
- int ret = 0;
+ int ret;
if (addr >= AAT2870_REG_NUM) {
dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr);
return -EINVAL;
}
- mutex_lock(&aat2870->io_lock);
-
if (!aat2870->reg_cache[addr].readable) {
*val = aat2870->reg_cache[addr].value;
- goto out_unlock;
+ goto out;
}
- ret = i2c_master_send(client, &addr, 1);
+ ret = i2c_master_send(aat2870->client, &addr, 1);
if (ret < 0)
- goto out_unlock;
- if (ret != 1) {
- ret = -EIO;
- goto out_unlock;
- }
+ return ret;
+ if (ret != 1)
+ return -EIO;
- ret = i2c_master_recv(client, val, 1);
+ ret = i2c_master_recv(aat2870->client, val, 1);
if (ret < 0)
- goto out_unlock;
- if (ret != 1) {
- ret = -EIO;
- goto out_unlock;
- }
-
- ret = 0;
-
-out_unlock:
- mutex_unlock(&aat2870->io_lock);
- dev_dbg(&client->dev, "read: addr=0x%02x, val=0x%02x\n", addr, *val);
+ return ret;
+ if (ret != 1)
+ return -EIO;
- return ret;
+out:
+ dev_dbg(aat2870->dev, "read: addr=0x%02x, val=0x%02x\n", addr, *val);
+ return 0;
}
-static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
+static int __aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
{
- struct i2c_client *client = aat2870->client;
u8 msg[2];
- int ret = 0;
+ int ret;
if (addr >= AAT2870_REG_NUM) {
dev_err(aat2870->dev, "Invalid address, 0x%02x\n", addr);
@@ -162,47 +150,62 @@ static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
return -EINVAL;
}
- mutex_lock(&aat2870->io_lock);
-
msg[0] = addr;
msg[1] = val;
- ret = i2c_master_send(client, msg, 2);
+ ret = i2c_master_send(aat2870->client, msg, 2);
if (ret < 0)
- goto out_unlock;
- if (ret != 2) {
- ret = -EIO;
- goto out_unlock;
- }
+ return ret;
+ if (ret != 2)
+ return -EIO;
aat2870->reg_cache[addr].value = val;
- ret = 0;
-out_unlock:
+ dev_dbg(aat2870->dev, "write: addr=0x%02x, val=0x%02x\n", addr, val);
+ return 0;
+}
+
+static int aat2870_read(struct aat2870_data *aat2870, u8 addr, u8 *val)
+{
+ int ret;
+
+ mutex_lock(&aat2870->io_lock);
+ ret = __aat2870_read(aat2870, addr, val);
+ mutex_unlock(&aat2870->io_lock);
+
+ return ret;
+}
+
+static int aat2870_write(struct aat2870_data *aat2870, u8 addr, u8 val)
+{
+ int ret;
+
+ mutex_lock(&aat2870->io_lock);
+ ret = __aat2870_write(aat2870, addr, val);
mutex_unlock(&aat2870->io_lock);
- dev_dbg(&client->dev, "write: addr=0x%02x, val=0x%02x\n", addr, val);
return ret;
}
-static int aat2870_update_bits(struct aat2870_data *aat2870, u8 addr,
- u8 mask, u8 val)
+static int aat2870_update(struct aat2870_data *aat2870, u8 addr, u8 mask,
+ u8 val)
{
int change;
u8 old_val, new_val;
int ret;
- ret = aat2870->read(aat2870, addr, &old_val);
+ mutex_lock(&aat2870->io_lock);
+
+ ret = __aat2870_read(aat2870, addr, &old_val);
if (ret)
- return ret;
+ goto out_unlock;
new_val = (old_val & ~mask) | (val & mask);
change = old_val != new_val;
if (change)
- ret = aat2870->write(aat2870, addr, new_val);
+ ret = __aat2870_write(aat2870, addr, new_val);
- dev_dbg(&aat2870->client->dev,
- "update_bits: change=%d, addr=0x%02x, old=0x%02x, new=0x%02x\n",
- change, addr, old_val, new_val);
+out_unlock:
+ mutex_unlock(&aat2870->io_lock);
return ret;
}
@@ -396,7 +399,7 @@ static int aat2870_i2c_probe(struct i2c_client *client,
aat2870->uninit = pdata->uninit;
aat2870->read = aat2870_read;
aat2870->write = aat2870_write;
- aat2870->update_bits = aat2870_update_bits;
+ aat2870->update = aat2870_update;
mutex_init(&aat2870->io_lock);