sony-laptop: add locking on accesses to the ioport and global vars

Better avoid having ioport commands mixing and global variables reading/writing.

Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
malattia@linux.it 2007-04-28 23:19:36 +09:00 committed by Len Brown
parent 5f3d2898d7
commit 9f9f076171

View file

@ -928,6 +928,7 @@ struct sony_pic_dev {
struct sony_pic_ioport *cur_ioport; struct sony_pic_ioport *cur_ioport;
struct list_head interrupts; struct list_head interrupts;
struct list_head ioports; struct list_head ioports;
struct mutex lock;
}; };
static struct sony_pic_dev spic_dev = { static struct sony_pic_dev spic_dev = {
@ -1224,7 +1225,7 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
#define SONYPI_CAMERA_STATUS_READY 0x2 #define SONYPI_CAMERA_STATUS_READY 0x2
#define SONYPI_CAMERA_STATUS_POSITION 0x4 #define SONYPI_CAMERA_STATUS_POSITION 0x4
static int sony_pic_camera_ready(void) static int __sony_pic_camera_ready(void)
{ {
u8 v; u8 v;
@ -1239,6 +1240,7 @@ static int sony_pic_camera_off(void)
return -ENODEV; return -ENODEV;
} }
mutex_lock(&spic_dev.lock);
wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE,
SONYPI_CAMERA_MUTE_MASK), SONYPI_CAMERA_MUTE_MASK),
ITERATIONS_SHORT); ITERATIONS_SHORT);
@ -1247,20 +1249,23 @@ static int sony_pic_camera_off(void)
sony_pic_call2(0x91, 0); sony_pic_call2(0x91, 0);
spic_dev.camera_power = 0; spic_dev.camera_power = 0;
} }
mutex_unlock(&spic_dev.lock);
return 0; return 0;
} }
static int sony_pic_camera_on(void) static int sony_pic_camera_on(void)
{ {
int i, j, x; int i, j, x;
int result = 0;
if (!camera) { if (!camera) {
printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
return -ENODEV; return -ENODEV;
} }
mutex_lock(&spic_dev.lock);
if (spic_dev.camera_power) if (spic_dev.camera_power)
return 0; goto out_unlock;
for (j = 5; j > 0; j--) { for (j = 5; j > 0; j--) {
@ -1269,7 +1274,7 @@ static int sony_pic_camera_on(void)
sony_pic_call1(0x93); sony_pic_call1(0x93);
for (i = 400; i > 0; i--) { for (i = 400; i > 0; i--) {
if (sony_pic_camera_ready()) if (__sony_pic_camera_ready())
break; break;
msleep(10); msleep(10);
} }
@ -1279,7 +1284,8 @@ static int sony_pic_camera_on(void)
if (j == 0) { if (j == 0) {
printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); printk(KERN_WARNING DRV_PFX "failed to power on camera\n");
return -ENODEV; result = -ENODEV;
goto out_unlock;
} }
wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL,
@ -1287,6 +1293,9 @@ static int sony_pic_camera_on(void)
ITERATIONS_SHORT); ITERATIONS_SHORT);
spic_dev.camera_power = 1; spic_dev.camera_power = 1;
out_unlock:
mutex_unlock(&spic_dev.lock);
return 0; return 0;
} }
@ -1314,11 +1323,15 @@ static ssize_t sony_pic_camerapower_store(struct device *dev,
static ssize_t sony_pic_camerapower_show(struct device *dev, static ssize_t sony_pic_camerapower_show(struct device *dev,
struct device_attribute *attr, char *buffer) struct device_attribute *attr, char *buffer)
{ {
return snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.camera_power); ssize_t count;
mutex_lock(&spic_dev.lock);
count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.camera_power);
mutex_unlock(&spic_dev.lock);
return count;
} }
/* bluetooth subsystem power state */ /* bluetooth subsystem power state */
static void sony_pic_set_bluetoothpower(u8 state) static void __sony_pic_set_bluetoothpower(u8 state)
{ {
state = !!state; state = !!state;
if (spic_dev.bluetooth_power == state) if (spic_dev.bluetooth_power == state)
@ -1337,7 +1350,9 @@ static ssize_t sony_pic_bluetoothpower_store(struct device *dev,
return -EINVAL; return -EINVAL;
value = simple_strtoul(buffer, NULL, 10); value = simple_strtoul(buffer, NULL, 10);
sony_pic_set_bluetoothpower(value); mutex_lock(&spic_dev.lock);
__sony_pic_set_bluetoothpower(value);
mutex_unlock(&spic_dev.lock);
return count; return count;
} }
@ -1345,7 +1360,11 @@ static ssize_t sony_pic_bluetoothpower_store(struct device *dev,
static ssize_t sony_pic_bluetoothpower_show(struct device *dev, static ssize_t sony_pic_bluetoothpower_show(struct device *dev,
struct device_attribute *attr, char *buffer) struct device_attribute *attr, char *buffer)
{ {
return snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power); ssize_t count = 0;
mutex_lock(&spic_dev.lock);
count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power);
mutex_unlock(&spic_dev.lock);
return count;
} }
/* fan speed */ /* fan speed */
@ -1518,7 +1537,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
u16 val16; u16 val16;
int value; int value;
/*down(&sonypi_device.lock);*/ mutex_lock(&spic_dev.lock);
switch (cmd) { switch (cmd) {
case SONYPI_IOCGBRT: case SONYPI_IOCGBRT:
if (sony_backlight_device == NULL) { if (sony_backlight_device == NULL) {
@ -1602,7 +1621,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
ret = -EFAULT; ret = -EFAULT;
break; break;
} }
sony_pic_set_bluetoothpower(val8); __sony_pic_set_bluetoothpower(val8);
break; break;
/* FAN Controls */ /* FAN Controls */
case SONYPI_IOCGFAN: case SONYPI_IOCGFAN:
@ -1633,7 +1652,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
/*up(&sonypi_device.lock);*/ mutex_unlock(&spic_dev.lock);
return ret; return ret;
} }
@ -1673,7 +1692,6 @@ static int sonypi_compat_init(void)
} }
init_waitqueue_head(&sonypi_compat.fifo_proc_list); init_waitqueue_head(&sonypi_compat.fifo_proc_list);
/*init_MUTEX(&sonypi_device.lock);*/
if (minor != -1) if (minor != -1)
sonypi_misc_device.minor = minor; sonypi_misc_device.minor = minor;
@ -2004,6 +2022,7 @@ static int sony_pic_add(struct acpi_device *device)
spic_dev.acpi_dev = device; spic_dev.acpi_dev = device;
strcpy(acpi_device_class(device), "sony/hotkey"); strcpy(acpi_device_class(device), "sony/hotkey");
spic_dev.model = sony_pic_detect_device_type(); spic_dev.model = sony_pic_detect_device_type();
mutex_init(&spic_dev.lock);
/* read _PRS resources */ /* read _PRS resources */
result = sony_pic_possible_resources(device); result = sony_pic_possible_resources(device);