diff options
author | Dima Zavin <dima@android.com> | 2011-01-05 21:22:43 -0800 |
---|---|---|
committer | Dima Zavin <dima@android.com> | 2011-01-05 21:22:56 -0800 |
commit | 1187a9f3f53a7292aa945220ba6415d513e85f43 (patch) | |
tree | 401905ec88f43e881b1eb7747a955dafc77557cf | |
parent | 41b1834c5198a139f41a106352ddea2dac31d3e9 (diff) | |
download | experimental-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.c | 62 |
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, }; |