[PATCH 2.4.21] sonypi driver update

From: Stelian Pop (stelian@popies.net)
Date: Sun Jun 15 2003 - 11:27:53 EST


Hi,

Now that a new -pre cycle is about to start, here is my latest
version of the sonypi driver.

The attached patch:
* fixes a hang problem when loading the driver on (at least) a
  PCG-FX105k. Thanks to Jozef Kruger for reporting the problem
  and testing different versions of this fix.

* tests if the ACPI subsystem is not disabled before trying to
  use its ec_read/ec_write methods.

* fixes the hangs when enabling bluetooth (thanks to Daniel K. for
  the patch).

* other miscellaneous small fixes.

Marcelo, please apply.

Stelian.

===== Documentation/sonypi.txt 1.11 vs edited =====
--- 1.11/Documentation/sonypi.txt Tue Feb 18 12:33:56 2003
+++ edited/Documentation/sonypi.txt Thu Apr 17 09:57:06 2003
@@ -130,7 +130,7 @@
           tested) when using the driver with the fnkeyinit parameter. I cannot
           reproduce it on my laptop and not all users have this problem.
           This happens because the fnkeyinit parameter enables the ACPI
- mode (but without additionnal ACPI control, like processor
+ mode (but without additional ACPI control, like processor
           speed handling etc). Use ACPI instead of APM if it works on your
           laptop.
         
===== drivers/char/sonypi.h 1.16 vs edited =====
--- 1.16/drivers/char/sonypi.h Fri Feb 21 11:22:44 2003
+++ edited/drivers/char/sonypi.h Tue Jun 10 10:55:27 2003
@@ -37,7 +37,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION 1
-#define SONYPI_DRIVER_MINORVERSION 18
+#define SONYPI_DRIVER_MINORVERSION 20
 
 #define SONYPI_DEVICE_MODEL_TYPE1 1
 #define SONYPI_DEVICE_MODEL_TYPE2 2
@@ -335,6 +335,15 @@
         unsigned char buf[SONYPI_BUF_SIZE];
 };
 
+/* We enable input subsystem event forwarding if the input
+ * subsystem is compiled in, but only if sonypi is not into the
+ * kernel and input as a module... */
+#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#if ! (defined(CONFIG_SONYPI) && defined(CONFIG_INPUT_MODULE))
+#define SONYPI_USE_INPUT
+#endif
+#endif
+
 /* The name of the Jog Dial for the input device drivers */
 #define SONYPI_INPUTNAME "Sony VAIO Jog Dial"
 
@@ -351,7 +360,7 @@
         struct sonypi_queue queue;
         int open_count;
         int model;
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
         struct input_dev jog_dev;
 #endif
 #ifdef CONFIG_PM
@@ -373,14 +382,30 @@
 #ifdef CONFIG_ACPI
 #include <linux/acpi.h>
 #if (ACPI_CA_VERSION > 0x20021121)
-#define USE_ACPI
+#ifdef CONFIG_ACPI_EC
+#define SONYPI_USE_ACPI
+#endif
 #endif
 #endif /* CONFIG_ACPI */
 
-#ifndef USE_ACPI
+#ifdef CONFIG_ACPI
+#ifdef SONYPI_USE_ACPI
+extern int acpi_disabled;
+#define SONYPI_ACPI_ACTIVE (!acpi_disabled)
+#else
+#define SONYPI_ACPI_ACTIVE 1
+#endif
+#else /* CONFIG_ACPI */
+#define SONYPI_ACPI_ACTIVE 0
+#endif /* CONFIG_ACPI */
+
 extern int verbose;
 
-static inline int ec_write(u8 addr, u8 value) {
+static inline int sonypi_ec_write(u8 addr, u8 value) {
+#ifdef SONYPI_USE_ACPI
+ if (!acpi_disabled)
+ return ec_write(addr, value);
+#endif
         wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
         outb_p(0x81, SONYPI_CST_IOPORT);
         wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
@@ -391,7 +416,11 @@
         return 0;
 }
 
-static inline int ec_read(u8 addr, u8 *value) {
+static inline int sonypi_ec_read(u8 addr, u8 *value) {
+#ifdef SONYPI_USE_ACPI
+ if (!acpi_disabled)
+ return ec_read(addr, value);
+#endif
         wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
         outb_p(0x80, SONYPI_CST_IOPORT);
         wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
@@ -400,7 +429,6 @@
         *value = inb_p(SONYPI_DATA_IOPORT);
         return 0;
 }
-#endif /* ! USE_ACPI */
 
 #endif /* __KERNEL__ */
 
===== drivers/char/sonypi.c 1.15 vs edited =====
--- 1.15/drivers/char/sonypi.c Mon Mar 31 18:39:06 2003
+++ edited/drivers/char/sonypi.c Fri Jun 13 14:30:21 2003
@@ -120,9 +120,9 @@
 
 static int ec_read16(u8 addr, u16 *value) {
         u8 val_lb, val_hb;
- if (ec_read(addr, &val_lb))
+ if (sonypi_ec_read(addr, &val_lb))
                 return -1;
- if (ec_read(addr + 1, &val_hb))
+ if (sonypi_ec_read(addr + 1, &val_hb))
                 return -1;
         *value = val_lb | (val_hb << 8);
         return 0;
@@ -152,11 +152,11 @@
 }
 
 static void __devinit sonypi_type2_srs(void) {
- if (ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
+ if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
                 printk(KERN_WARNING "ec_write failed\n");
- if (ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
+ if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
                 printk(KERN_WARNING "ec_write failed\n");
- if (ec_write(SONYPI_SIRQ, sonypi_device.bits))
+ if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits))
                 printk(KERN_WARNING "ec_write failed\n");
         udelay(10);
 }
@@ -175,11 +175,11 @@
 }
 
 static void sonypi_type2_dis(void) {
- if (ec_write(SONYPI_SHIB, 0))
+ if (sonypi_ec_write(SONYPI_SHIB, 0))
                 printk(KERN_WARNING "ec_write failed\n");
- if (ec_write(SONYPI_SLOB, 0))
+ if (sonypi_ec_write(SONYPI_SLOB, 0))
                 printk(KERN_WARNING "ec_write failed\n");
- if (ec_write(SONYPI_SIRQ, 0))
+ if (sonypi_ec_write(SONYPI_SIRQ, 0))
                 printk(KERN_WARNING "ec_write failed\n");
 }
 
@@ -265,7 +265,7 @@
 
         for (j = 5; j > 0; j--) {
 
- while (sonypi_call2(0x91, 0x1) != 0) {
+ while (sonypi_call2(0x91, 0x1)) {
                         set_current_state(TASK_UNINTERRUPTIBLE);
                         schedule_timeout(1);
                 }
@@ -277,7 +277,7 @@
                         set_current_state(TASK_UNINTERRUPTIBLE);
                         schedule_timeout(1);
                 }
- if (i != 0)
+ if (i)
                         break;
         }
         
@@ -293,14 +293,12 @@
 /* sets the bluetooth subsystem power state */
 static void sonypi_setbluetoothpower(u8 state) {
 
- state = (state != 0);
- if (sonypi_device.bluetooth_power && state)
- return;
- if (!sonypi_device.bluetooth_power && !state)
+ state = !!state;
+ if (sonypi_device.bluetooth_power == state)
                 return;
         
         sonypi_call2(0x96, state);
- sonypi_call1(0x93);
+ sonypi_call1(0x82);
         sonypi_device.bluetooth_power = state;
 }
 
@@ -312,10 +310,6 @@
         v1 = inb_p(sonypi_device.ioport1);
         v2 = inb_p(sonypi_device.ioport2);
 
- if (verbose > 1)
- printk(KERN_INFO
- "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
-
         for (i = 0; sonypi_eventtypes[i].model; i++) {
                 if (sonypi_device.model != sonypi_eventtypes[i].model)
                         continue;
@@ -337,7 +331,11 @@
         return;
 
 found:
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+ if (verbose > 1)
+ printk(KERN_INFO
+ "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
+
+#ifdef SONYPI_USE_INPUT
         if (useinput) {
                 struct input_dev *jog_dev = &sonypi_device.jog_dev;
                 if (event == SONYPI_EVENT_JOGDIAL_PRESSED)
@@ -351,7 +349,7 @@
                          (event == SONYPI_EVENT_JOGDIAL_DOWN_PRESSED))
                         input_report_rel(jog_dev, REL_WHEEL, -1);
         }
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
         sonypi_pushq(event);
 }
 
@@ -507,7 +505,7 @@
         down(&sonypi_device.lock);
         switch (cmd) {
         case SONYPI_IOCGBRT:
- if (ec_read(SONYPI_LCD_LIGHT, &val8)) {
+ if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
                         ret = -EIO;
                         break;
                 }
@@ -519,7 +517,7 @@
                         ret = -EFAULT;
                         break;
                 }
- if (ec_write(SONYPI_LCD_LIGHT, val8))
+ if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8))
                         ret = -EIO;
                 break;
         case SONYPI_IOCGBAT1CAP:
@@ -555,7 +553,7 @@
                         ret = -EFAULT;
                 break;
         case SONYPI_IOCGBATFLAGS:
- if (ec_read(SONYPI_BAT_FLAGS, &val8)) {
+ if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) {
                         ret = -EIO;
                         break;
                 }
@@ -611,18 +609,14 @@
                         sonypi_type2_dis();
                 else
                         sonypi_type1_dis();
-#ifndef CONFIG_ACPI
                 /* disable ACPI mode */
- if (fnkeyinit)
+ if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
                         outb(0xf1, 0xb2);
-#endif
                 break;
         case PM_RESUME:
-#ifndef CONFIG_ACPI
                 /* Enable ACPI mode to get Fn key events */
- if (fnkeyinit)
+ if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
                         outb(0xf0, 0xb2);
-#endif
                 if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
                         sonypi_type2_srs();
                 else
@@ -696,36 +690,44 @@
         }
 
         for (i = 0; irq_list[i].irq; i++) {
- if (!request_irq(irq_list[i].irq, sonypi_irq,
- SA_SHIRQ, "sonypi", sonypi_irq)) {
- sonypi_device.irq = irq_list[i].irq;
- sonypi_device.bits = irq_list[i].bits;
+
+ sonypi_device.irq = irq_list[i].irq;
+ sonypi_device.bits = irq_list[i].bits;
+
+ /* Enable sonypi IRQ settings */
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+ sonypi_type2_srs();
+ else
+ sonypi_type1_srs();
+
+ sonypi_call1(0x82);
+ sonypi_call2(0x81, 0xff);
+ if (compat)
+ sonypi_call1(0x92);
+ else
+ sonypi_call1(0x82);
+
+ /* Now try requesting the irq from the system */
+ if (!request_irq(sonypi_device.irq, sonypi_irq,
+ SA_SHIRQ, "sonypi", sonypi_irq))
                         break;
- }
+
+ /* If request_irq failed, disable sonypi IRQ settings */
+ if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
+ sonypi_type2_dis();
+ else
+ sonypi_type1_dis();
         }
- if (!sonypi_device.irq ) {
+
+ if (!irq_list[i].irq) {
                 printk(KERN_ERR "sonypi: request_irq failed\n");
                 ret = -ENODEV;
                 goto out3;
         }
 
-#ifndef CONFIG_ACPI
         /* Enable ACPI mode to get Fn key events */
- if (fnkeyinit)
+ if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
                 outb(0xf0, 0xb2);
-#endif
-
- if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2)
- sonypi_type2_srs();
- else
- sonypi_type1_srs();
-
- sonypi_call1(0x82);
- sonypi_call2(0x81, 0xff);
- if (compat)
- sonypi_call1(0x92);
- else
- sonypi_call1(0x82);
 
         printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver v%d.%d.\n",
                SONYPI_DRIVER_MAJORVERSION,
@@ -748,7 +750,7 @@
                 printk(KERN_INFO "sonypi: device allocated minor is %d\n",
                        sonypi_misc_device.minor);
 
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
         if (useinput) {
                 /* Initialize the Input Drivers: */
                 sonypi_device.jog_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
@@ -765,7 +767,7 @@
                         sonypi_device.jog_dev.name,
                         sonypi_device.jog_dev.number);
         }
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
 
 #ifdef CONFIG_PM
         sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback);
@@ -789,12 +791,12 @@
 
         sonypi_call2(0x81, 0); /* make sure we don't get any more events */
         
-#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
+#ifdef SONYPI_USE_INPUT
         if (useinput) {
                 input_unregister_device(&sonypi_device.jog_dev);
                 kfree(sonypi_device.jog_dev.name);
         }
-#endif /* CONFIG_INPUT || CONFIG_INPUT_MODULE */
+#endif /* SONYPI_USE_INPUT */
 
         if (camera)
                 sonypi_camera_off();
@@ -802,11 +804,9 @@
                 sonypi_type2_dis();
         else
                 sonypi_type1_dis();
-#ifndef CONFIG_ACPI
         /* disable ACPI mode */
- if (fnkeyinit)
+ if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
                 outb(0xf1, 0xb2);
-#endif
         free_irq(sonypi_device.irq, sonypi_irq);
         release_region(sonypi_device.ioport1, sonypi_device.region_size);
         misc_deregister(&sonypi_misc_device);

-- 
Stelian Pop <stelian@popies.net>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jun 15 2003 - 22:00:42 EST