]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
sony-laptop: fix bug in event handling
authorMattia Dongili <malattia@linux.it>
Sun, 15 Jul 2007 17:44:58 +0000 (02:44 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 9 Aug 2007 21:27:41 +0000 (14:27 -0700)
The rewritten event reading code from sonypi was absolutely wrong,
this patche makes things functional for type2 and type1 models.

Cc: Andrei Paskevich <andrei@capet.iut-fbleau.fr>
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/misc/sony-laptop.c

index 8ee0321ef1c8f6226a62ad5a20680a8866b69773..ab2ca634cfeca9cb346c675d5611912edea3a9b0 100644 (file)
@@ -908,7 +908,9 @@ static struct acpi_driver sony_nc_driver = {
 #define SONYPI_DEVICE_TYPE2    0x00000002
 #define SONYPI_DEVICE_TYPE3    0x00000004
 
-#define SONY_PIC_EV_MASK       0xff
+#define SONYPI_TYPE1_OFFSET    0x04
+#define SONYPI_TYPE2_OFFSET    0x12
+#define SONYPI_TYPE3_OFFSET    0x12
 
 struct sony_pic_ioport {
        struct acpi_resource_io io;
@@ -922,6 +924,7 @@ struct sony_pic_irq {
 
 struct sony_pic_dev {
        int                     model;
+       u16                     evport_offset;
        u8                      camera_power;
        u8                      bluetooth_power;
        u8                      wwan_power;
@@ -1998,20 +2001,17 @@ end:
 static irqreturn_t sony_pic_irq(int irq, void *dev_id)
 {
        int i, j;
-       u32 port_val = 0;
        u8 ev = 0;
        u8 data_mask = 0;
        u8 device_event = 0;
 
        struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
 
-       acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val,
-                       dev->cur_ioport->io.address_length);
-       ev = port_val & SONY_PIC_EV_MASK;
-       data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8));
+       ev = inb_p(dev->cur_ioport->io.minimum);
+       data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
 
-       dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n",
-                       port_val, ev, data_mask, dev->cur_ioport->io.minimum);
+       dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
+                       ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
 
        if (ev == 0x00 || ev == 0xff)
                return IRQ_HANDLED;
@@ -2102,6 +2102,20 @@ static int sony_pic_add(struct acpi_device *device)
        spic_dev.model = sony_pic_detect_device_type();
        mutex_init(&spic_dev.lock);
 
+       /* model specific characteristics */
+       switch(spic_dev.model) {
+               case SONYPI_DEVICE_TYPE1:
+                       spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
+                       break;
+               case SONYPI_DEVICE_TYPE3:
+                       spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
+                       break;
+               case SONYPI_DEVICE_TYPE2:
+               default:
+                       spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
+                       break;
+       }
+
        /* read _PRS resources */
        result = sony_pic_possible_resources(device);
        if (result) {