aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDima Zavin <dima@android.com>2011-01-05 21:22:43 -0800
committerDima Zavin <dima@android.com>2011-01-05 21:22:56 -0800
commit1187a9f3f53a7292aa945220ba6415d513e85f43 (patch)
tree401905ec88f43e881b1eb7747a955dafc77557cf
parent41b1834c5198a139f41a106352ddea2dac31d3e9 (diff)
downloadexperimental-sandbox/dima/android-msm-2.6.37-tmp.tar.gz
misc: akm8973: convert ioctl to unlocked_ioctl, add mutexsandbox/dima/android-msm-2.6.37-tmp
Change-Id: Id99d79a5fd2451acf7bacbf65f2ab8d4325a279a Signed-off-by: Dima Zavin <dima@android.com>
-rw-r--r--drivers/misc/akm8973.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/misc/akm8973.c b/drivers/misc/akm8973.c
index 723eac70d98..79454b4b8be 100644
--- a/drivers/misc/akm8973.c
+++ b/drivers/misc/akm8973.c
@@ -27,8 +27,9 @@
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include <linux/akm8973.h>
+#include <linux/mutex.h>
-#define DEBUG 0
+#define DEBUG 1
#define MAX_FAILURE_COUNT 3
static struct i2c_client *this_client;
@@ -288,29 +289,38 @@ static void AKECS_Report_Value(short *rbuf)
input_sync(data->input_dev);
}
+static DEFINE_MUTEX(akmd_lock);
+
static int AKECS_GetOpenStatus(void)
{
+ mutex_unlock(&akmd_lock);
wait_event_interruptible(open_wq, (atomic_read(&open_flag) != 0));
+ mutex_lock(&akmd_lock);
return atomic_read(&open_flag);
}
static int AKECS_GetCloseStatus(void)
{
+ mutex_unlock(&akmd_lock);
wait_event_interruptible(open_wq, (atomic_read(&open_flag) <= 0));
+ mutex_lock(&akmd_lock);
return atomic_read(&open_flag);
}
static void AKECS_CloseDone(void)
{
+ mutex_lock(&akmd_lock);
atomic_set(&m_flag, 1);
atomic_set(&a_flag, 1);
atomic_set(&t_flag, 1);
atomic_set(&mv_flag, 1);
+ mutex_unlock(&akmd_lock);
}
static int akm_aot_open(struct inode *inode, struct file *file)
{
int ret = -1;
+ mutex_lock(&akmd_lock);
if (atomic_cmpxchg(&open_count, 0, 1) == 0) {
if (atomic_cmpxchg(&open_flag, 0, 1) == 0) {
atomic_set(&reserve_open_flag, 1);
@@ -319,22 +329,24 @@ static int akm_aot_open(struct inode *inode, struct file *file)
ret = 0;
}
}
+ mutex_unlock(&akmd_lock);
return ret;
}
static int akm_aot_release(struct inode *inode, struct file *file)
{
+ mutex_lock(&akmd_lock);
atomic_set(&reserve_open_flag, 0);
atomic_set(&open_flag, 0);
atomic_set(&open_count, 0);
wake_up(&open_wq);
disable_irq(this_client->irq);
+ mutex_unlock(&akmd_lock);
return 0;
}
-static int
-akm_aot_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long
+akm_aot_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
short flag;
@@ -357,6 +369,7 @@ akm_aot_ioctl(struct inode *inode, struct file *file,
break;
}
+ mutex_lock(&akmd_lock);
switch (cmd) {
case ECS_IOCTL_APP_SET_MFLAG:
atomic_set(&m_flag, flag);
@@ -389,8 +402,10 @@ akm_aot_ioctl(struct inode *inode, struct file *file,
flag = akmd_delay;
break;
default:
+ mutex_unlock(&akmd_lock);
return -ENOTTY;
}
+ mutex_unlock(&akmd_lock);
switch (cmd) {
case ECS_IOCTL_APP_GET_MFLAG:
@@ -419,9 +434,8 @@ static int akmd_release(struct inode *inode, struct file *file)
return 0;
}
-static int
-akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+static long
+akmd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
@@ -433,7 +447,6 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
short layouts[4][3][3];
int i, j, k;
-
switch (cmd) {
case ECS_IOCTL_WRITE:
case ECS_IOCTL_READ:
@@ -452,20 +465,25 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break;
}
+ mutex_lock(&akmd_lock);
switch (cmd) {
case ECS_IOCTL_WRITE:
- if (rwbuf[0] < 2)
- return -EINVAL;
+ if (rwbuf[0] < 2) {
+ ret = -EINVAL;
+ goto err;
+ }
ret = AKI2C_TxData(&rwbuf[1], rwbuf[0]);
if (ret < 0)
- return ret;
+ goto err;
break;
case ECS_IOCTL_READ:
- if (rwbuf[0] < 1)
- return -EINVAL;
+ if (rwbuf[0] < 1) {
+ ret = -EINVAL;
+ goto err;
+ }
ret = AKI2C_RxData(&rwbuf[1], rwbuf[0]);
if (ret < 0)
- return ret;
+ goto err;
break;
case ECS_IOCTL_RESET:
AKECS_Reset();
@@ -473,12 +491,12 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case ECS_IOCTL_SET_MODE:
ret = AKECS_SetMode((char)mode);
if (ret < 0)
- return ret;
+ goto err;
break;
case ECS_IOCTL_GETDATA:
ret = AKECS_TransRBuff(msg, RBUFF_SIZE);
if (ret < 0)
- return ret;
+ goto err;
break;
case ECS_IOCTL_SET_YPR:
AKECS_Report_Value(value);
@@ -503,8 +521,10 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
break;
default:
- return -ENOTTY;
+ ret = -ENOTTY;
+ goto err;
}
+ mutex_unlock(&akmd_lock);
switch (cmd) {
case ECS_IOCTL_READ:
@@ -537,6 +557,10 @@ akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
return 0;
+
+err:
+ mutex_unlock(&akmd_lock);
+ return ret;
}
static void akm_work_func(struct work_struct *work)
@@ -558,14 +582,14 @@ static struct file_operations akmd_fops = {
.owner = THIS_MODULE,
.open = akmd_open,
.release = akmd_release,
- .ioctl = akmd_ioctl,
+ .unlocked_ioctl = akmd_ioctl,
};
static struct file_operations akm_aot_fops = {
.owner = THIS_MODULE,
.open = akm_aot_open,
.release = akm_aot_release,
- .ioctl = akm_aot_ioctl,
+ .unlocked_ioctl = akm_aot_ioctl,
};