diff options
author | malattia@linux.it <malattia@linux.it> | 2007-04-28 10:19:36 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-04-28 22:05:53 -0400 |
commit | 9f9f0761712928768198278c6cbc5cafe5502d38 (patch) | |
tree | b4673b760e7d10a5b78c95191633b758633b69fd /drivers/misc | |
parent | 5f3d2898d79520bc8d8706ed3859060f9cbb969e (diff) |
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>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/sony-laptop.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 09e75390ac98..56413435c531 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -928,6 +928,7 @@ struct sony_pic_dev { | |||
928 | struct sony_pic_ioport *cur_ioport; | 928 | struct sony_pic_ioport *cur_ioport; |
929 | struct list_head interrupts; | 929 | struct list_head interrupts; |
930 | struct list_head ioports; | 930 | struct list_head ioports; |
931 | struct mutex lock; | ||
931 | }; | 932 | }; |
932 | 933 | ||
933 | static struct sony_pic_dev spic_dev = { | 934 | static struct sony_pic_dev spic_dev = { |
@@ -1224,7 +1225,7 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) | |||
1224 | #define SONYPI_CAMERA_STATUS_READY 0x2 | 1225 | #define SONYPI_CAMERA_STATUS_READY 0x2 |
1225 | #define SONYPI_CAMERA_STATUS_POSITION 0x4 | 1226 | #define SONYPI_CAMERA_STATUS_POSITION 0x4 |
1226 | 1227 | ||
1227 | static int sony_pic_camera_ready(void) | 1228 | static int __sony_pic_camera_ready(void) |
1228 | { | 1229 | { |
1229 | u8 v; | 1230 | u8 v; |
1230 | 1231 | ||
@@ -1239,6 +1240,7 @@ static int sony_pic_camera_off(void) | |||
1239 | return -ENODEV; | 1240 | return -ENODEV; |
1240 | } | 1241 | } |
1241 | 1242 | ||
1243 | mutex_lock(&spic_dev.lock); | ||
1242 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, | 1244 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, |
1243 | SONYPI_CAMERA_MUTE_MASK), | 1245 | SONYPI_CAMERA_MUTE_MASK), |
1244 | ITERATIONS_SHORT); | 1246 | ITERATIONS_SHORT); |
@@ -1247,20 +1249,23 @@ static int sony_pic_camera_off(void) | |||
1247 | sony_pic_call2(0x91, 0); | 1249 | sony_pic_call2(0x91, 0); |
1248 | spic_dev.camera_power = 0; | 1250 | spic_dev.camera_power = 0; |
1249 | } | 1251 | } |
1252 | mutex_unlock(&spic_dev.lock); | ||
1250 | return 0; | 1253 | return 0; |
1251 | } | 1254 | } |
1252 | 1255 | ||
1253 | static int sony_pic_camera_on(void) | 1256 | static int sony_pic_camera_on(void) |
1254 | { | 1257 | { |
1255 | int i, j, x; | 1258 | int i, j, x; |
1259 | int result = 0; | ||
1256 | 1260 | ||
1257 | if (!camera) { | 1261 | if (!camera) { |
1258 | printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); | 1262 | printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); |
1259 | return -ENODEV; | 1263 | return -ENODEV; |
1260 | } | 1264 | } |
1261 | 1265 | ||
1266 | mutex_lock(&spic_dev.lock); | ||
1262 | if (spic_dev.camera_power) | 1267 | if (spic_dev.camera_power) |
1263 | return 0; | 1268 | goto out_unlock; |
1264 | 1269 | ||
1265 | for (j = 5; j > 0; j--) { | 1270 | for (j = 5; j > 0; j--) { |
1266 | 1271 | ||
@@ -1269,7 +1274,7 @@ static int sony_pic_camera_on(void) | |||
1269 | sony_pic_call1(0x93); | 1274 | sony_pic_call1(0x93); |
1270 | 1275 | ||
1271 | for (i = 400; i > 0; i--) { | 1276 | for (i = 400; i > 0; i--) { |
1272 | if (sony_pic_camera_ready()) | 1277 | if (__sony_pic_camera_ready()) |
1273 | break; | 1278 | break; |
1274 | msleep(10); | 1279 | msleep(10); |
1275 | } | 1280 | } |
@@ -1279,7 +1284,8 @@ static int sony_pic_camera_on(void) | |||
1279 | 1284 | ||
1280 | if (j == 0) { | 1285 | if (j == 0) { |
1281 | printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); | 1286 | printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); |
1282 | return -ENODEV; | 1287 | result = -ENODEV; |
1288 | goto out_unlock; | ||
1283 | } | 1289 | } |
1284 | 1290 | ||
1285 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, | 1291 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, |
@@ -1287,6 +1293,9 @@ static int sony_pic_camera_on(void) | |||
1287 | ITERATIONS_SHORT); | 1293 | ITERATIONS_SHORT); |
1288 | 1294 | ||
1289 | spic_dev.camera_power = 1; | 1295 | spic_dev.camera_power = 1; |
1296 | |||
1297 | out_unlock: | ||
1298 | mutex_unlock(&spic_dev.lock); | ||
1290 | return 0; | 1299 | return 0; |
1291 | } | 1300 | } |
1292 | 1301 | ||
@@ -1314,11 +1323,15 @@ static ssize_t sony_pic_camerapower_store(struct device *dev, | |||
1314 | static ssize_t sony_pic_camerapower_show(struct device *dev, | 1323 | static ssize_t sony_pic_camerapower_show(struct device *dev, |
1315 | struct device_attribute *attr, char *buffer) | 1324 | struct device_attribute *attr, char *buffer) |
1316 | { | 1325 | { |
1317 | return snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.camera_power); | 1326 | ssize_t count; |
1327 | mutex_lock(&spic_dev.lock); | ||
1328 | count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.camera_power); | ||
1329 | mutex_unlock(&spic_dev.lock); | ||
1330 | return count; | ||
1318 | } | 1331 | } |
1319 | 1332 | ||
1320 | /* bluetooth subsystem power state */ | 1333 | /* bluetooth subsystem power state */ |
1321 | static void sony_pic_set_bluetoothpower(u8 state) | 1334 | static void __sony_pic_set_bluetoothpower(u8 state) |
1322 | { | 1335 | { |
1323 | state = !!state; | 1336 | state = !!state; |
1324 | if (spic_dev.bluetooth_power == state) | 1337 | if (spic_dev.bluetooth_power == state) |
@@ -1337,7 +1350,9 @@ static ssize_t sony_pic_bluetoothpower_store(struct device *dev, | |||
1337 | return -EINVAL; | 1350 | return -EINVAL; |
1338 | 1351 | ||
1339 | value = simple_strtoul(buffer, NULL, 10); | 1352 | value = simple_strtoul(buffer, NULL, 10); |
1340 | sony_pic_set_bluetoothpower(value); | 1353 | mutex_lock(&spic_dev.lock); |
1354 | __sony_pic_set_bluetoothpower(value); | ||
1355 | mutex_unlock(&spic_dev.lock); | ||
1341 | 1356 | ||
1342 | return count; | 1357 | return count; |
1343 | } | 1358 | } |
@@ -1345,7 +1360,11 @@ static ssize_t sony_pic_bluetoothpower_store(struct device *dev, | |||
1345 | static ssize_t sony_pic_bluetoothpower_show(struct device *dev, | 1360 | static ssize_t sony_pic_bluetoothpower_show(struct device *dev, |
1346 | struct device_attribute *attr, char *buffer) | 1361 | struct device_attribute *attr, char *buffer) |
1347 | { | 1362 | { |
1348 | return snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power); | 1363 | ssize_t count = 0; |
1364 | mutex_lock(&spic_dev.lock); | ||
1365 | count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power); | ||
1366 | mutex_unlock(&spic_dev.lock); | ||
1367 | return count; | ||
1349 | } | 1368 | } |
1350 | 1369 | ||
1351 | /* fan speed */ | 1370 | /* fan speed */ |
@@ -1518,7 +1537,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | |||
1518 | u16 val16; | 1537 | u16 val16; |
1519 | int value; | 1538 | int value; |
1520 | 1539 | ||
1521 | /*down(&sonypi_device.lock);*/ | 1540 | mutex_lock(&spic_dev.lock); |
1522 | switch (cmd) { | 1541 | switch (cmd) { |
1523 | case SONYPI_IOCGBRT: | 1542 | case SONYPI_IOCGBRT: |
1524 | if (sony_backlight_device == NULL) { | 1543 | if (sony_backlight_device == NULL) { |
@@ -1602,7 +1621,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | |||
1602 | ret = -EFAULT; | 1621 | ret = -EFAULT; |
1603 | break; | 1622 | break; |
1604 | } | 1623 | } |
1605 | sony_pic_set_bluetoothpower(val8); | 1624 | __sony_pic_set_bluetoothpower(val8); |
1606 | break; | 1625 | break; |
1607 | /* FAN Controls */ | 1626 | /* FAN Controls */ |
1608 | case SONYPI_IOCGFAN: | 1627 | case SONYPI_IOCGFAN: |
@@ -1633,7 +1652,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | |||
1633 | default: | 1652 | default: |
1634 | ret = -EINVAL; | 1653 | ret = -EINVAL; |
1635 | } | 1654 | } |
1636 | /*up(&sonypi_device.lock);*/ | 1655 | mutex_unlock(&spic_dev.lock); |
1637 | return ret; | 1656 | return ret; |
1638 | } | 1657 | } |
1639 | 1658 | ||
@@ -1673,7 +1692,6 @@ static int sonypi_compat_init(void) | |||
1673 | } | 1692 | } |
1674 | 1693 | ||
1675 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); | 1694 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); |
1676 | /*init_MUTEX(&sonypi_device.lock);*/ | ||
1677 | 1695 | ||
1678 | if (minor != -1) | 1696 | if (minor != -1) |
1679 | sonypi_misc_device.minor = minor; | 1697 | sonypi_misc_device.minor = minor; |
@@ -2004,6 +2022,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
2004 | spic_dev.acpi_dev = device; | 2022 | spic_dev.acpi_dev = device; |
2005 | strcpy(acpi_device_class(device), "sony/hotkey"); | 2023 | strcpy(acpi_device_class(device), "sony/hotkey"); |
2006 | spic_dev.model = sony_pic_detect_device_type(); | 2024 | spic_dev.model = sony_pic_detect_device_type(); |
2025 | mutex_init(&spic_dev.lock); | ||
2007 | 2026 | ||
2008 | /* read _PRS resources */ | 2027 | /* read _PRS resources */ |
2009 | result = sony_pic_possible_resources(device); | 2028 | result = sony_pic_possible_resources(device); |