aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/sonypi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/sonypi.c')
-rw-r--r--drivers/char/sonypi.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 78237577b05a..3ef593a9015f 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * Sony Programmable I/O Control Device driver for VAIO 2 * Sony Programmable I/O Control Device driver for VAIO
3 * 3 *
4 * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
5 *
4 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net> 6 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
5 * 7 *
6 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org> 8 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
@@ -95,6 +97,11 @@ module_param(useinput, int, 0444);
95MODULE_PARM_DESC(useinput, 97MODULE_PARM_DESC(useinput,
96 "set this if you would like sonypi to feed events to the input subsystem"); 98 "set this if you would like sonypi to feed events to the input subsystem");
97 99
100static int check_ioport = 1;
101module_param(check_ioport, int, 0444);
102MODULE_PARM_DESC(check_ioport,
103 "set this to 0 if you think the automatic ioport check for sony-laptop is wrong");
104
98#define SONYPI_DEVICE_MODEL_TYPE1 1 105#define SONYPI_DEVICE_MODEL_TYPE1 1
99#define SONYPI_DEVICE_MODEL_TYPE2 2 106#define SONYPI_DEVICE_MODEL_TYPE2 2
100#define SONYPI_DEVICE_MODEL_TYPE3 3 107#define SONYPI_DEVICE_MODEL_TYPE3 3
@@ -477,7 +484,7 @@ static struct sonypi_device {
477 u16 evtype_offset; 484 u16 evtype_offset;
478 int camera_power; 485 int camera_power;
479 int bluetooth_power; 486 int bluetooth_power;
480 struct semaphore lock; 487 struct mutex lock;
481 struct kfifo *fifo; 488 struct kfifo *fifo;
482 spinlock_t fifo_lock; 489 spinlock_t fifo_lock;
483 wait_queue_head_t fifo_proc_list; 490 wait_queue_head_t fifo_proc_list;
@@ -884,7 +891,7 @@ int sonypi_camera_command(int command, u8 value)
884 if (!camera) 891 if (!camera)
885 return -EIO; 892 return -EIO;
886 893
887 down(&sonypi_device.lock); 894 mutex_lock(&sonypi_device.lock);
888 895
889 switch (command) { 896 switch (command) {
890 case SONYPI_COMMAND_SETCAMERA: 897 case SONYPI_COMMAND_SETCAMERA:
@@ -919,7 +926,7 @@ int sonypi_camera_command(int command, u8 value)
919 command); 926 command);
920 break; 927 break;
921 } 928 }
922 up(&sonypi_device.lock); 929 mutex_unlock(&sonypi_device.lock);
923 return 0; 930 return 0;
924} 931}
925 932
@@ -938,20 +945,20 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on)
938static int sonypi_misc_release(struct inode *inode, struct file *file) 945static int sonypi_misc_release(struct inode *inode, struct file *file)
939{ 946{
940 sonypi_misc_fasync(-1, file, 0); 947 sonypi_misc_fasync(-1, file, 0);
941 down(&sonypi_device.lock); 948 mutex_lock(&sonypi_device.lock);
942 sonypi_device.open_count--; 949 sonypi_device.open_count--;
943 up(&sonypi_device.lock); 950 mutex_unlock(&sonypi_device.lock);
944 return 0; 951 return 0;
945} 952}
946 953
947static int sonypi_misc_open(struct inode *inode, struct file *file) 954static int sonypi_misc_open(struct inode *inode, struct file *file)
948{ 955{
949 down(&sonypi_device.lock); 956 mutex_lock(&sonypi_device.lock);
950 /* Flush input queue on first open */ 957 /* Flush input queue on first open */
951 if (!sonypi_device.open_count) 958 if (!sonypi_device.open_count)
952 kfifo_reset(sonypi_device.fifo); 959 kfifo_reset(sonypi_device.fifo);
953 sonypi_device.open_count++; 960 sonypi_device.open_count++;
954 up(&sonypi_device.lock); 961 mutex_unlock(&sonypi_device.lock);
955 return 0; 962 return 0;
956} 963}
957 964
@@ -1001,7 +1008,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
1001 u8 val8; 1008 u8 val8;
1002 u16 val16; 1009 u16 val16;
1003 1010
1004 down(&sonypi_device.lock); 1011 mutex_lock(&sonypi_device.lock);
1005 switch (cmd) { 1012 switch (cmd) {
1006 case SONYPI_IOCGBRT: 1013 case SONYPI_IOCGBRT:
1007 if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) { 1014 if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
@@ -1101,7 +1108,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
1101 default: 1108 default:
1102 ret = -EINVAL; 1109 ret = -EINVAL;
1103 } 1110 }
1104 up(&sonypi_device.lock); 1111 mutex_unlock(&sonypi_device.lock);
1105 return ret; 1112 return ret;
1106} 1113}
1107 1114
@@ -1260,6 +1267,28 @@ static int __devinit sonypi_create_input_devices(void)
1260static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, 1267static int __devinit sonypi_setup_ioports(struct sonypi_device *dev,
1261 const struct sonypi_ioport_list *ioport_list) 1268 const struct sonypi_ioport_list *ioport_list)
1262{ 1269{
1270 /* try to detect if sony-laptop is being used and thus
1271 * has already requested one of the known ioports.
1272 * As in the deprecated check_region this is racy has we have
1273 * multiple ioports available and one of them can be requested
1274 * between this check and the subsequent request. Anyway, as an
1275 * attempt to be some more user-friendly as we currently are,
1276 * this is enough.
1277 */
1278 const struct sonypi_ioport_list *check = ioport_list;
1279 while (check_ioport && check->port1) {
1280 if (!request_region(check->port1,
1281 sonypi_device.region_size,
1282 "Sony Programable I/O Device Check")) {
1283 printk(KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? "
1284 "if not use check_ioport=0\n",
1285 check->port1);
1286 return -EBUSY;
1287 }
1288 release_region(check->port1, sonypi_device.region_size);
1289 check++;
1290 }
1291
1263 while (ioport_list->port1) { 1292 while (ioport_list->port1) {
1264 1293
1265 if (request_region(ioport_list->port1, 1294 if (request_region(ioport_list->port1,
@@ -1321,6 +1350,10 @@ static int __devinit sonypi_probe(struct platform_device *dev)
1321 struct pci_dev *pcidev; 1350 struct pci_dev *pcidev;
1322 int error; 1351 int error;
1323 1352
1353 printk(KERN_WARNING "sonypi: please try the sony-laptop module instead "
1354 "and report failures, see also "
1355 "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
1356
1324 spin_lock_init(&sonypi_device.fifo_lock); 1357 spin_lock_init(&sonypi_device.fifo_lock);
1325 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, 1358 sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
1326 &sonypi_device.fifo_lock); 1359 &sonypi_device.fifo_lock);
@@ -1330,7 +1363,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
1330 } 1363 }
1331 1364
1332 init_waitqueue_head(&sonypi_device.fifo_proc_list); 1365 init_waitqueue_head(&sonypi_device.fifo_proc_list);
1333 init_MUTEX(&sonypi_device.lock); 1366 mutex_init(&sonypi_device.lock);
1334 sonypi_device.bluetooth_power = -1; 1367 sonypi_device.bluetooth_power = -1;
1335 1368
1336 if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1369 if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,