Merge head 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@g5.osdl.org>
Sun, 31 Jul 2005 23:49:07 +0000 (16:49 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 31 Jul 2005 23:49:07 +0000 (16:49 -0700)
37 files changed:
Documentation/fb/vesafb.txt
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/pci/acpi.c
arch/i386/pci/common.c
arch/i386/pci/irq.c
arch/i386/pci/pci.h
arch/ppc/kernel/head_44x.S
arch/ppc/kernel/misc.S
arch/ppc/platforms/4xx/ebony.c
arch/ppc/platforms/4xx/ebony.h
arch/ppc/platforms/4xx/ocotea.c
arch/ppc/platforms/4xx/ocotea.h
arch/ppc64/kernel/misc.S
arch/x86_64/kernel/mpparse.c
arch/x86_64/lib/csum-copy.S
drivers/acpi/ec.c
drivers/acpi/pci_irq.c
drivers/acpi/pci_link.c
drivers/acpi/processor_idle.c
drivers/net/sk98lin/skge.c
drivers/pcmcia/yenta_socket.c
drivers/scsi/Kconfig
drivers/video/fbsysfs.c
include/acpi/acpi_drivers.h
include/asm-ppc/unistd.h
include/asm-ppc64/unistd.h
include/linux/acpi.h
include/net/tcp.h
kernel/softirq.c
mm/page_alloc.c
net/core/dst.c
net/ipv4/ip_gre.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv6/sit.c
sound/pci/intel8x0.c

index 814e2f56a6ad35ce367e2d542769664c8b6641f3..62db6758d1c1050db42b638ad4d42dc06809c68b 100644 (file)
@@ -144,7 +144,21 @@ vgapal     Use the standard vga registers for palette changes.
        This is the default.
 pmipal Use the protected mode interface for palette changes.
 
-mtrr   setup memory type range registers for the vesafb framebuffer.
+mtrr:n setup memory type range registers for the vesafb framebuffer
+       where n:
+             0 - disabled (equivalent to nomtrr)
+             1 - uncachable
+             2 - write-back
+             3 - write-combining (default)
+             4 - write-through
+
+       If you see the following in dmesg, choose the type that matches the
+       old one. In this example, use "mtrr:2".
+...
+mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
+...
+
+nomtrr  disable mtrr
 
 vremap:n
         remap 'n' MiB of video RAM. If 0 or not specified, remap memory
index 963e17aa205d60ea91977887c622e6c4cb4c2701..60a9e54dd20ee25d223385d2fcc47c7858a5893b 100644 (file)
@@ -442,6 +442,13 @@ acpi_cpufreq_cpu_init (
                        (u32) data->acpi_data.states[i].transition_latency);
 
        cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
+       
+       /*
+        * the first call to ->target() should result in us actually
+        * writing something to the appropriate registers.
+        */
+       data->resume = 1;
+       
        return (result);
 
  err_freqfree:
index 2db65ec45dc353340d575e49cf4dec23b66e882d..42913f43feb0edca0015a1f2013c609cc361d802 100644 (file)
@@ -30,6 +30,7 @@ static int __init pci_acpi_init(void)
        acpi_irq_penalty_init();
        pcibios_scanned++;
        pcibios_enable_irq = acpi_pci_irq_enable;
+       pcibios_disable_irq = acpi_pci_irq_disable;
 
        if (pci_routeirq) {
                /*
index 70bcd53451f68873a9bfaa14a07ecf6142ea94f9..ade5bc57c34ceffc54c0e1f3a79f52879bc062e9 100644 (file)
@@ -254,3 +254,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
        return pcibios_enable_irq(dev);
 }
+
+void pcibios_disable_device (struct pci_dev *dev)
+{
+       if (pcibios_disable_irq)
+               pcibios_disable_irq(dev);
+}
index d291fb7f13571b2a45e54e42668ccd25423509e8..86348b68fda1a0e5621e48c1b3edb15f173f5cc0 100644 (file)
@@ -56,6 +56,7 @@ struct irq_router_handler {
 };
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
 
 /*
  *  Check passed address for the PCI IRQ Routing Table signature
index a80f0f55ff51b0dcea1c1d33670c5baae924a541..127d53ad16bef02f65cd8011cbd1c5ec6fd70e7a 100644 (file)
@@ -73,3 +73,4 @@ extern int pcibios_scanned;
 extern spinlock_t pci_config_lock;
 
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
+extern void (*pcibios_disable_irq)(struct pci_dev *dev);
index 6c7ae6052464f3d28f7cc754487e8aaa6fba1361..72ee8f33bde465471f9dd90b5341d7cc4d1aea6d 100644 (file)
@@ -179,14 +179,14 @@ skpinv:   addi    r4,r4,1                         /* Increment */
 4:
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
        /*
-        * Add temporary UART mapping for early debug.  This
-        * mapping must be identical to that used by the early
-        * bootloader code since the same asm/serial.h parameters
-        * are used for polled operation.
+        * Add temporary UART mapping for early debug.
+        * We can map UART registers wherever we want as long as they don't
+        * interfere with other system mappings (e.g. with pinned entries).
+        * For an example of how we handle this - see ocotea.h.       --ebs
         */
        /* pageid fields */
        lis     r3,UART0_IO_BASE@h
-       ori     r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
+       ori     r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
 
        /* xlat fields */
        lis     r4,UART0_PHYS_IO_BASE@h         /* RPN depends on SoC */
@@ -196,7 +196,7 @@ skpinv:     addi    r4,r4,1                         /* Increment */
        li      r5,0
        ori     r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
 
-        li      r0,1                    /* TLB slot 1 */
+        li      r0,0                    /* TLB slot 0 */
 
        tlbwe   r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
        tlbwe   r4,r0,PPC44x_TLB_XLAT   /* Load the translation fields */
index 191a8def3bdba1c9b7739cbde931322838daaf0c..c2fb85b49a11ae1a1f2f319478d96dffbdbee1f7 100644 (file)
@@ -1451,3 +1451,6 @@ _GLOBAL(sys_call_table)
        .long sys_waitid
        .long sys_ioprio_set
        .long sys_ioprio_get
+       .long sys_inotify_init          /* 275 */
+       .long sys_inotify_add_watch
+       .long sys_inotify_rm_watch
index cd11734ef7c504a0e34cf190ab4f436e61e7ccf6..509e69a095f0a43b2ff4069b7995f121bb76e77f 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2002-2005 MontaVista Software Inc.
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003, 2004 Zultys Technologies
+ * Copyright (c) 2003-2005 Zultys Technologies
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -50,6 +50,7 @@
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 #include <syslib/gen550.h>
 #include <syslib/ibm440gp_common.h>
@@ -248,6 +249,9 @@ ebony_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        /* Configure debug serial access */
        gen550_init(0, &port);
+
+       /* Purge TLB entry added in head_44x.S for early serial access */
+       _tlbie(UART0_IO_BASE);
 #endif
 
        port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
index 47c391c9174d158a72aa615750b78c49d9cf6d17..d08faa46a0aef5b9e5e49a1761145ddaec9e175a 100644 (file)
  * Serial port defines
  */
 
-/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#if defined(__BOOTER__)
+/* OpenBIOS defined UART mappings, used by bootloader shim */
 #define UART0_IO_BASE  0xE0000200
 #define UART1_IO_BASE  0xE0000300
+#else
+/* head_44x.S created UART mapping, used before early_serial_setup.
+ * We cannot use default OpenBIOS UART mappings because they
+ * don't work for configurations with more than 512M RAM.    --ebs
+ */
+#define UART0_IO_BASE  0xF0000200
+#define UART1_IO_BASE  0xF0000300
+#endif
 
 /* external Epson SG-615P */
 #define BASE_BAUD      691200
@@ -66,7 +75,7 @@
 #define STD_UART_OP(num)                                       \
        { 0, BASE_BAUD, 0, UART##num##_INT,                     \
                (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),        \
-               iomem_base: UART##num##_IO_BASE,                \
+               iomem_base: (void*)UART##num##_IO_BASE,         \
                io_type: SERIAL_IO_MEM},
 
 #define SERIAL_PORT_DFNS       \
index 5f82a6bc7046b3c0dcb4d93eb9cb2e817a4158b7..8fc34a3447694afc2ebb95c3f5d60357c29fbb7a 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 #include <syslib/gen550.h>
 #include <syslib/ibm440gx_common.h>
@@ -266,6 +267,9 @@ ocotea_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        /* Configure debug serial access */
        gen550_init(0, &port);
+
+       /* Purge TLB entry added in head_44x.S for early serial access */
+       _tlbie(UART0_IO_BASE);
 #endif
 
        port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
index 202dc8251190869c4e5d4dee47c9020b52230463..33251153ac5fff23187de3ecc48d6ec7e5c1f844 100644 (file)
  */
 #define RS_TABLE_SIZE  2
 
-/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#if defined(__BOOTER__)
+/* OpenBIOS defined UART mappings, used by bootloader shim */
 #define UART0_IO_BASE  0xE0000200
 #define UART1_IO_BASE  0xE0000300
+#else
+/* head_44x.S created UART mapping, used before early_serial_setup.
+ * We cannot use default OpenBIOS UART mappings because they
+ * don't work for configurations with more than 512M RAM.    --ebs
+ */
+#define UART0_IO_BASE  0xF0000200
+#define UART1_IO_BASE  0xF0000300
+#endif
 
 #define BASE_BAUD      11059200/16
 #define STD_UART_OP(num)                                       \
        { 0, BASE_BAUD, 0, UART##num##_INT,                     \
                (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),        \
-               iomem_base: UART##num##_IO_BASE,                \
+               iomem_base: (void*)UART##num##_IO_BASE,         \
                io_type: SERIAL_IO_MEM},
 
 #define SERIAL_PORT_DFNS       \
index 59f4f99738189f5b2078eee806d0b46a06ba78bb..a05b50b738e97b1c55ff1eb8013ae24d6abd929d 100644 (file)
@@ -1129,6 +1129,9 @@ _GLOBAL(sys_call_table32)
        .llong .compat_sys_waitid
        .llong .sys32_ioprio_set
        .llong .sys32_ioprio_get
+       .llong .sys_inotify_init        /* 275 */
+       .llong .sys_inotify_add_watch
+       .llong .sys_inotify_rm_watch
 
        .balign 8
 _GLOBAL(sys_call_table)
@@ -1407,3 +1410,6 @@ _GLOBAL(sys_call_table)
        .llong .sys_waitid
        .llong .sys_ioprio_set
        .llong .sys_ioprio_get
+       .llong .sys_inotify_init        /* 275 */
+       .llong .sys_inotify_add_watch
+       .llong .sys_inotify_rm_watch
index 08abf9f5b159276b43efd3b19b930e50ebbc22ab..79c362d03e2e8badd0602a2fbb7fba7fd1c5a6bf 100644 (file)
@@ -970,8 +970,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
                 * due to unused I/O APIC pins.
                 */
                int irq = gsi;
-               gsi = pci_irq++;
-               gsi_to_irq[irq] = gsi;
+               if (gsi < MAX_GSI_NUM) {
+                       if (gsi > 15)
+                               gsi = pci_irq++;
+#ifdef CONFIG_ACPI_BUS
+                       /*
+                        * Don't assign IRQ used by ACPI SCI
+                        */
+                       if (gsi == acpi_fadt.sci_int)
+                               gsi = pci_irq++;
+#endif
+                       gsi_to_irq[irq] = gsi;
+               } else {
+                       printk(KERN_ERR "GSI %u is too high\n", gsi);
+                       return gsi;
+               }
        }
 
        io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
index 01808ec378363eefc1314281fb72563c929f5699..72fd55ee896ee1c4bd7064dc588573c7926e63d8 100644 (file)
@@ -188,8 +188,8 @@ csum_partial_copy_generic:
        source
        movw (%rdi),%bx
        adcl %ebx,%eax
-       dest
        decl %ecx
+       dest
        movw %bx,(%rsi)
        leaq 2(%rdi),%rdi
        leaq 2(%rsi),%rsi
index fca4140a50a949b07feb32d0b028cf9f033aa977..2dadb7f632693e0edc03c522a914a1dff5deab35 100644 (file)
@@ -59,76 +59,185 @@ ACPI_MODULE_NAME           ("acpi_ec")
 #define ACPI_EC_DELAY          50      /* Wait 50ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
 
+#define ACPI_EC_UDELAY         100     /* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT   1000    /* Wait 10ms max. during EC ops */
+
 #define ACPI_EC_COMMAND_READ   0x80
 #define ACPI_EC_COMMAND_WRITE  0x81
 #define ACPI_EC_BURST_ENABLE   0x82
 #define ACPI_EC_BURST_DISABLE  0x83
 #define ACPI_EC_COMMAND_QUERY  0x84
 
-static int acpi_ec_add (struct acpi_device *device);
+#define EC_POLLING             0xFF
+#define EC_BURST               0x00
+
+
 static int acpi_ec_remove (struct acpi_device *device, int type);
 static int acpi_ec_start (struct acpi_device *device);
 static int acpi_ec_stop (struct acpi_device *device, int type);
+static int acpi_ec_burst_add ( struct acpi_device *device);
 
 static struct acpi_driver acpi_ec_driver = {
        .name =         ACPI_EC_DRIVER_NAME,
        .class =        ACPI_EC_CLASS,
        .ids =          ACPI_EC_HID,
        .ops =          {
-                               .add =          acpi_ec_add,
+                               .add =          acpi_ec_burst_add,
                                .remove =       acpi_ec_remove,
                                .start =        acpi_ec_start,
                                .stop =         acpi_ec_stop,
                        },
 };
-
-struct acpi_ec {
-       acpi_handle                     handle;
-       unsigned long                   uid;
-       unsigned long                   gpe_bit;
-       struct acpi_generic_address     status_addr;
-       struct acpi_generic_address     command_addr;
-       struct acpi_generic_address     data_addr;
-       unsigned long                   global_lock;
-       unsigned int                    expect_event;
-       atomic_t                        leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
-       atomic_t                        pending_gpe;
-       struct semaphore                sem;
-       wait_queue_head_t               wait;
+union acpi_ec {
+       struct {
+               u32                             mode;
+               acpi_handle                     handle;
+               unsigned long                   uid;
+               unsigned long                   gpe_bit;
+               struct acpi_generic_address     status_addr;
+               struct acpi_generic_address     command_addr;
+               struct acpi_generic_address     data_addr;
+               unsigned long                   global_lock;
+       } common;
+
+       struct {
+               u32                             mode;
+               acpi_handle                     handle;
+               unsigned long                   uid;
+               unsigned long                   gpe_bit;
+               struct acpi_generic_address     status_addr;
+               struct acpi_generic_address     command_addr;
+               struct acpi_generic_address     data_addr;
+               unsigned long                   global_lock;
+               unsigned int                    expect_event;
+               atomic_t                        leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
+               atomic_t                        pending_gpe;
+               struct semaphore                sem;
+               wait_queue_head_t               wait;
+       }burst;
+
+       struct {
+               u32                             mode;
+               acpi_handle                     handle;
+               unsigned long                   uid;
+               unsigned long                   gpe_bit;
+               struct acpi_generic_address     status_addr;
+               struct acpi_generic_address     command_addr;
+               struct acpi_generic_address     data_addr;
+               unsigned long                   global_lock;
+                       spinlock_t                      lock;
+       }polling;
 };
 
+static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event); 
+static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event);
+static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data);
+static int acpi_ec_burst_read( union acpi_ec *ec, u8 address, u32 *data);
+static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data);
+static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data);
+static void acpi_ec_gpe_polling_query ( void *ec_cxt);
+static void acpi_ec_gpe_burst_query ( void *ec_cxt);
+static u32 acpi_ec_gpe_polling_handler ( void *data);
+static u32 acpi_ec_gpe_burst_handler ( void *data);
+static acpi_status __init
+acpi_fake_ecdt_polling_callback (
+       acpi_handle     handle,
+       u32             Level,
+       void            *context,
+       void            **retval);
+
+static acpi_status __init
+acpi_fake_ecdt_burst_callback (
+       acpi_handle     handle,
+       u32             Level,
+       void            *context,
+       void            **retval);
+
+static int __init
+acpi_ec_polling_get_real_ecdt(void);
+static int __init
+acpi_ec_burst_get_real_ecdt(void);
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
-static struct acpi_ec  *ec_ecdt;
+static union acpi_ec   *ec_ecdt;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
+static int acpi_ec_polling_mode;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
    -------------------------------------------------------------------------- */
 
-static inline u32 acpi_ec_read_status(struct acpi_ec *ec)
+static inline u32 acpi_ec_read_status(union acpi_ec *ec)
 {
        u32     status = 0;
 
-       acpi_hw_low_level_read(8, &status, &ec->status_addr);
+       acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
        return status;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
+static int
+acpi_ec_wait (
+       union acpi_ec           *ec,
+       u8                      event)
+{
+       if (acpi_ec_polling_mode) 
+               return acpi_ec_polling_wait (ec, event);
+       else
+               return acpi_ec_burst_wait (ec, event);
+}
+
+static int
+acpi_ec_polling_wait (
+       union acpi_ec           *ec,
+       u8                      event)
+{
+       u32                     acpi_ec_status = 0;
+       u32                     i = ACPI_EC_UDELAY_COUNT;
+
+       if (!ec)
+               return -EINVAL;
+
+       /* Poll the EC status register waiting for the event to occur. */
+       switch (event) {
+       case ACPI_EC_EVENT_OBF:
+               do {
+                       acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
+                       if (acpi_ec_status & ACPI_EC_FLAG_OBF)
+                               return 0;
+                       udelay(ACPI_EC_UDELAY);
+               } while (--i>0);
+               break;
+       case ACPI_EC_EVENT_IBE:
+               do {
+                       acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
+                       if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
+                               return 0;
+                       udelay(ACPI_EC_UDELAY);
+               } while (--i>0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return -ETIME;
+}
+static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
 {
        int     result = 0;
 
        ACPI_FUNCTION_TRACE("acpi_ec_wait");
 
-       ec->expect_event = event;
+       ec->burst.expect_event = event;
        smp_mb();
 
-       result = wait_event_interruptible_timeout(ec->wait,
-                                       !ec->expect_event,
+       result = wait_event_interruptible_timeout(ec->burst.wait,
+                                       !ec->burst.expect_event,
                                        msecs_to_jiffies(ACPI_EC_DELAY));
        
-       ec->expect_event = 0;
+       ec->burst.expect_event = 0;
        smp_mb();
 
        if (result < 0){
@@ -160,7 +269,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
 
 static int
 acpi_ec_enter_burst_mode (
-       struct acpi_ec          *ec)
+       union acpi_ec           *ec)
 {
        u32                     tmp = 0;
        int                     status = 0;
@@ -170,43 +279,43 @@ acpi_ec_enter_burst_mode (
        status = acpi_ec_read_status(ec);
        if (status != -EINVAL &&
                !(status & ACPI_EC_FLAG_BURST)){
-               acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+               acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
                status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
                if (status){
-                       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+                       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                        return_VALUE(-EINVAL);
                }
-               acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                if(tmp != 0x90 ) {/* Burst ACK byte*/
                        return_VALUE(-EINVAL);
                }
        }
 
-       atomic_set(&ec->leaving_burst , 0);
+       atomic_set(&ec->burst.leaving_burst , 0);
        return_VALUE(0);
 }
 
 static int
 acpi_ec_leave_burst_mode (
-       struct acpi_ec          *ec)
+       union acpi_ec           *ec)
 {
        int                     status =0;
 
        ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
 
-       atomic_set(&ec->leaving_burst , 1);
+       atomic_set(&ec->burst.leaving_burst , 1);
        status = acpi_ec_read_status(ec);
        if (status != -EINVAL &&
                (status & ACPI_EC_FLAG_BURST)){
-               acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr);
+               acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
                status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
                if (status){
-                       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+                       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                        ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
                        return_VALUE(-EINVAL);
                }
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                status = acpi_ec_read_status(ec);
        }
 
@@ -215,7 +324,131 @@ acpi_ec_leave_burst_mode (
 
 static int
 acpi_ec_read (
-       struct acpi_ec          *ec,
+       union acpi_ec           *ec,
+       u8                      address,
+       u32                     *data)
+{
+       if (acpi_ec_polling_mode) 
+               return acpi_ec_polling_read(ec, address, data);
+       else
+               return acpi_ec_burst_read(ec, address, data);
+}
+static int
+acpi_ec_write (
+       union acpi_ec           *ec,
+       u8                      address,
+       u8                      data)
+{
+       if (acpi_ec_polling_mode) 
+               return acpi_ec_polling_write(ec, address, data);
+       else
+               return acpi_ec_burst_write(ec, address, data);
+}
+static int
+acpi_ec_polling_read (
+       union acpi_ec           *ec,
+       u8                      address,
+       u32                     *data)
+{
+       acpi_status             status = AE_OK;
+       int                     result = 0;
+       unsigned long           flags = 0;
+       u32                     glk = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_ec_read");
+
+       if (!ec || !data)
+               return_VALUE(-EINVAL);
+
+       *data = 0;
+
+       if (ec->common.global_lock) {
+               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+               if (ACPI_FAILURE(status))
+                       return_VALUE(-ENODEV);
+       }
+
+       spin_lock_irqsave(&ec->polling.lock, flags);
+
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+       if (result)
+               goto end;
+
+       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+       if (result)
+               goto end;
+
+       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
+               *data, address));
+       
+end:
+       spin_unlock_irqrestore(&ec->polling.lock, flags);
+
+       if (ec->common.global_lock)
+               acpi_release_global_lock(glk);
+
+       return_VALUE(result);
+}
+
+
+static int
+acpi_ec_polling_write (
+       union acpi_ec           *ec,
+       u8                      address,
+       u8                      data)
+{
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       unsigned long           flags = 0;
+       u32                     glk = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_ec_write");
+
+       if (!ec)
+               return_VALUE(-EINVAL);
+
+       if (ec->common.global_lock) {
+               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+               if (ACPI_FAILURE(status))
+                       return_VALUE(-ENODEV);
+       }
+
+       spin_lock_irqsave(&ec->polling.lock, flags);
+
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+       if (result)
+               goto end;
+
+       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+       if (result)
+               goto end;
+
+       acpi_hw_low_level_write(8, data, &ec->common.data_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+       if (result)
+               goto end;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
+               data, address));
+
+end:
+       spin_unlock_irqrestore(&ec->polling.lock, flags);
+
+       if (ec->common.global_lock)
+               acpi_release_global_lock(glk);
+
+       return_VALUE(result);
+}
+
+static int
+acpi_ec_burst_read (
+       union acpi_ec           *ec,
        u8                      address,
        u32                     *data)
 {
@@ -230,51 +463,51 @@ acpi_ec_read (
 retry:
        *data = 0;
 
-       if (ec->global_lock) {
+       if (ec->common.global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status))
                        return_VALUE(-ENODEV);
        }
 
        WARN_ON(in_interrupt());
-       down(&ec->sem);
+       down(&ec->burst.sem);
 
        if(acpi_ec_enter_burst_mode(ec))
                goto end;
 
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
        if (status) {
                goto end;
        }
 
-       acpi_hw_low_level_write(8, address, &ec->data_addr);
+       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
        status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
        if (status){
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                goto end;
        }
 
-       acpi_hw_low_level_read(8, data, &ec->data_addr);
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
                *data, address));
        
 end:
        acpi_ec_leave_burst_mode(ec);
-       up(&ec->sem);
+       up(&ec->burst.sem);
 
-       if (ec->global_lock)
+       if (ec->common.global_lock)
                acpi_release_global_lock(glk);
 
-       if(atomic_read(&ec->leaving_burst) == 2){
+       if(atomic_read(&ec->burst.leaving_burst) == 2){
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-               while(atomic_read(&ec->pending_gpe)){
+               while(atomic_read(&ec->burst.pending_gpe)){
                        msleep(1);      
                }
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                goto retry;
        }
 
@@ -283,8 +516,8 @@ end:
 
 
 static int
-acpi_ec_write (
-       struct acpi_ec          *ec,
+acpi_ec_burst_write (
+       union acpi_ec           *ec,
        u8                      address,
        u8                      data)
 {
@@ -297,14 +530,14 @@ acpi_ec_write (
        if (!ec)
                return_VALUE(-EINVAL);
 retry:
-       if (ec->global_lock) {
+       if (ec->common.global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status))
                        return_VALUE(-ENODEV);
        }
 
        WARN_ON(in_interrupt());
-       down(&ec->sem);
+       down(&ec->burst.sem);
 
        if(acpi_ec_enter_burst_mode(ec))
                goto end;
@@ -312,33 +545,33 @@ retry:
        status = acpi_ec_read_status(ec);
        if (status != -EINVAL &&
                !(status & ACPI_EC_FLAG_BURST)){
-               acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+               acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
                status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
                if (status)
                        goto end;
-               acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
+               acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
                if(tmp != 0x90 ) /* Burst ACK byte*/
                        goto end;
        }
        /*Now we are in burst mode*/
 
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
        if (status){
                goto end;
        }
 
-       acpi_hw_low_level_write(8, address, &ec->data_addr);
+       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
        if (status){
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                goto end;
        }
 
-       acpi_hw_low_level_write(8, data, &ec->data_addr);
+       acpi_hw_low_level_write(8, data, &ec->common.data_addr);
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
        if (status)
                goto end;
 
@@ -347,17 +580,17 @@ retry:
 
 end:
        acpi_ec_leave_burst_mode(ec);
-       up(&ec->sem);
+       up(&ec->burst.sem);
 
-       if (ec->global_lock)
+       if (ec->common.global_lock)
                acpi_release_global_lock(glk);
 
-       if(atomic_read(&ec->leaving_burst) == 2){
+       if(atomic_read(&ec->burst.leaving_burst) == 2){
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-               while(atomic_read(&ec->pending_gpe)){
+               while(atomic_read(&ec->burst.pending_gpe)){
                        msleep(1);      
                }
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                goto retry;
        }
 
@@ -370,7 +603,7 @@ end:
 int
 ec_read(u8 addr, u8 *val)
 {
-       struct acpi_ec *ec;
+       union acpi_ec *ec;
        int err;
        u32 temp_data;
 
@@ -393,7 +626,7 @@ EXPORT_SYMBOL(ec_read);
 int
 ec_write(u8 addr, u8 val)
 {
-       struct acpi_ec *ec;
+       union acpi_ec *ec;
        int err;
 
        if (!first_ec)
@@ -407,10 +640,66 @@ ec_write(u8 addr, u8 val)
 }
 EXPORT_SYMBOL(ec_write);
 
-
 static int
 acpi_ec_query (
-       struct acpi_ec          *ec,
+       union acpi_ec           *ec,
+       u32                     *data)
+{
+       if (acpi_ec_polling_mode) 
+               return acpi_ec_polling_query(ec, data);
+       else
+               return acpi_ec_burst_query(ec, data);
+}
+static int
+acpi_ec_polling_query (
+       union acpi_ec           *ec,
+       u32                     *data)
+{
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       unsigned long           flags = 0;
+       u32                     glk = 0;
+
+       ACPI_FUNCTION_TRACE("acpi_ec_query");
+
+       if (!ec || !data)
+               return_VALUE(-EINVAL);
+
+       *data = 0;
+
+       if (ec->common.global_lock) {
+               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+               if (ACPI_FAILURE(status))
+                       return_VALUE(-ENODEV);
+       }
+
+       /*
+        * Query the EC to find out which _Qxx method we need to evaluate.
+        * Note that successful completion of the query causes the ACPI_EC_SCI
+        * bit to be cleared (and thus clearing the interrupt source).
+        */
+       spin_lock_irqsave(&ec->polling.lock, flags);
+
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
+       result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+       if (result)
+               goto end;
+
+       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+       if (!*data)
+               result = -ENODATA;
+
+end:
+       spin_unlock_irqrestore(&ec->polling.lock, flags);
+
+       if (ec->common.global_lock)
+               acpi_release_global_lock(glk);
+
+       return_VALUE(result);
+}
+static int
+acpi_ec_burst_query (
+       union acpi_ec           *ec,
        u32                     *data)
 {
        int                     status = 0;
@@ -422,13 +711,13 @@ acpi_ec_query (
                return_VALUE(-EINVAL);
        *data = 0;
 
-       if (ec->global_lock) {
+       if (ec->common.global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status))
                        return_VALUE(-ENODEV);
        }
 
-       down(&ec->sem);
+       down(&ec->burst.sem);
        if(acpi_ec_enter_burst_mode(ec))
                goto end;
        /*
@@ -436,28 +725,28 @@ acpi_ec_query (
         * Note that successful completion of the query causes the ACPI_EC_SCI
         * bit to be cleared (and thus clearing the interrupt source).
         */
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
+       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
        if (status){
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                goto end;
        }
 
-       acpi_hw_low_level_read(8, data, &ec->data_addr);
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
        if (!*data)
                status = -ENODATA;
 
 end:
        acpi_ec_leave_burst_mode(ec);
-       up(&ec->sem);
+       up(&ec->burst.sem);
 
-       if (ec->global_lock)
+       if (ec->common.global_lock)
                acpi_release_global_lock(glk);
 
-       if(atomic_read(&ec->leaving_burst) == 2){
+       if(atomic_read(&ec->burst.leaving_burst) == 2){
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-               acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
                status = -ENODATA;
        }
        return_VALUE(status);
@@ -468,7 +757,7 @@ end:
                                 Event Management
    -------------------------------------------------------------------------- */
 
-struct acpi_ec_query_data {
+union acpi_ec_query_data {
        acpi_handle             handle;
        u8                      data;
 };
@@ -477,7 +766,59 @@ static void
 acpi_ec_gpe_query (
        void                    *ec_cxt)
 {
-       struct acpi_ec          *ec = (struct acpi_ec *) ec_cxt;
+       if (acpi_ec_polling_mode) 
+               acpi_ec_gpe_polling_query(ec_cxt);
+       else
+               acpi_ec_gpe_burst_query(ec_cxt);
+}
+
+static void
+acpi_ec_gpe_polling_query (
+       void                    *ec_cxt)
+{
+       union acpi_ec           *ec = (union acpi_ec *) ec_cxt;
+       u32                     value = 0;
+       unsigned long           flags = 0;
+       static char             object_name[5] = {'_','Q','0','0','\0'};
+       const char              hex[] = {'0','1','2','3','4','5','6','7',
+                                        '8','9','A','B','C','D','E','F'};
+
+       ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
+
+       if (!ec_cxt)
+               goto end;
+
+       spin_lock_irqsave(&ec->polling.lock, flags);
+       acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
+       spin_unlock_irqrestore(&ec->polling.lock, flags);
+
+       /* TBD: Implement asynch events!
+        * NOTE: All we care about are EC-SCI's.  Other EC events are
+        * handled via polling (yuck!).  This is because some systems
+        * treat EC-SCIs as level (versus EDGE!) triggered, preventing
+        *  a purely interrupt-driven approach (grumble, grumble).
+        */
+       if (!(value & ACPI_EC_FLAG_SCI))
+               goto end;
+
+       if (acpi_ec_query(ec, &value))
+               goto end;
+
+       object_name[2] = hex[((value >> 4) & 0x0F)];
+       object_name[3] = hex[(value & 0x0F)];
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
+
+       acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
+
+end:   
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+}
+static void
+acpi_ec_gpe_burst_query (
+       void                    *ec_cxt)
+{
+       union acpi_ec           *ec = (union acpi_ec *) ec_cxt;
        u32                     value;
        int                     result = -ENODATA;
        static char             object_name[5] = {'_','Q','0','0','\0'};
@@ -497,58 +838,87 @@ acpi_ec_gpe_query (
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
 
-       acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
+       acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
 end:   
-       atomic_dec(&ec->pending_gpe);
+       atomic_dec(&ec->burst.pending_gpe);
        return;
 }
 
 static u32
 acpi_ec_gpe_handler (
        void                    *data)
+{
+       if (acpi_ec_polling_mode) 
+               return acpi_ec_gpe_polling_handler(data);
+       else
+               return acpi_ec_gpe_burst_handler(data); 
+}
+static u32
+acpi_ec_gpe_polling_handler (
+       void                    *data)
+{
+       acpi_status             status = AE_OK;
+       union acpi_ec           *ec = (union acpi_ec *) data;
+
+       if (!ec)
+               return ACPI_INTERRUPT_NOT_HANDLED;
+
+       acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+
+       status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+               acpi_ec_gpe_query, ec);
+
+       if (status == AE_OK)
+               return ACPI_INTERRUPT_HANDLED;
+       else
+               return ACPI_INTERRUPT_NOT_HANDLED;
+}
+static u32
+acpi_ec_gpe_burst_handler (
+       void                    *data)
 {
        acpi_status             status = AE_OK;
        u32                     value;
-       struct acpi_ec          *ec = (struct acpi_ec *) data;
+       union acpi_ec           *ec = (union acpi_ec *) data;
 
        if (!ec)
                return ACPI_INTERRUPT_NOT_HANDLED;
 
-       acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+       acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
 
        value = acpi_ec_read_status(ec);
 
        if((value & ACPI_EC_FLAG_IBF) &&
                !(value & ACPI_EC_FLAG_BURST) &&
-                       (atomic_read(&ec->leaving_burst) == 0)) { 
+                       (atomic_read(&ec->burst.leaving_burst) == 0)) { 
        /*
         * the embedded controller disables 
         * burst mode for any reason other 
         * than the burst disable command
         * to process critical event.
         */
-               atomic_set(&ec->leaving_burst , 2); /* block current pending transaction
+               atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
                                        and retry */
-               wake_up(&ec->wait);
+               wake_up(&ec->burst.wait);
        }else {
-               if ((ec->expect_event == ACPI_EC_EVENT_OBF &&
+               if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
                                (value & ACPI_EC_FLAG_OBF)) ||
-                               (ec->expect_event == ACPI_EC_EVENT_IBE &&
+                               (ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
                                !(value & ACPI_EC_FLAG_IBF))) {
-                       ec->expect_event = 0;
-                       wake_up(&ec->wait);
+                       ec->burst.expect_event = 0;
+                       wake_up(&ec->burst.wait);
                        return ACPI_INTERRUPT_HANDLED;
                }
        }
 
        if (value & ACPI_EC_FLAG_SCI){
-               atomic_add(1, &ec->pending_gpe) ;
+               atomic_add(1, &ec->burst.pending_gpe) ;
                status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
                                                acpi_ec_gpe_query, ec);
                return status == AE_OK ?
                ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
        } 
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
        return status == AE_OK ?
                ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
@@ -585,7 +955,7 @@ acpi_ec_space_handler (
        void                    *region_context)
 {
        int                     result = 0;
-       struct acpi_ec          *ec = NULL;
+       union acpi_ec           *ec = NULL;
        u64                     temp = *value;
        acpi_integer            f_v = 0;
        int                     i = 0;
@@ -600,7 +970,7 @@ acpi_ec_space_handler (
                return_VALUE(AE_BAD_PARAMETER);
        }
 
-       ec = (struct acpi_ec *) handler_context;
+       ec = (union acpi_ec *) handler_context;
 
 next_byte:
        switch (function) {
@@ -661,7 +1031,7 @@ static struct proc_dir_entry       *acpi_ec_dir;
 static int
 acpi_ec_read_info (struct seq_file *seq, void *offset)
 {
-       struct acpi_ec          *ec = (struct acpi_ec *) seq->private;
+       union acpi_ec           *ec = (union acpi_ec *) seq->private;
 
        ACPI_FUNCTION_TRACE("acpi_ec_read_info");
 
@@ -669,12 +1039,12 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
                goto end;
 
        seq_printf(seq, "gpe bit:                 0x%02x\n",
-               (u32) ec->gpe_bit);
+               (u32) ec->common.gpe_bit);
        seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
-               (u32) ec->status_addr.address, (u32) ec->data_addr.address);
+               (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address);
        seq_printf(seq, "use global lock:         %s\n",
-               ec->global_lock?"yes":"no");
-       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+               ec->common.global_lock?"yes":"no");
+       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 
 end:
        return_VALUE(0);
@@ -697,7 +1067,7 @@ static int
 acpi_ec_add_fs (
        struct acpi_device      *device)
 {
-       struct proc_dir_entry   *entry;
+       struct proc_dir_entry   *entry = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
 
@@ -744,13 +1114,82 @@ acpi_ec_remove_fs (
                                Driver Interface
    -------------------------------------------------------------------------- */
 
+
 static int
-acpi_ec_add (
+acpi_ec_polling_add (
        struct acpi_device      *device)
 {
-       int                     result;
-       acpi_status             status;
-       struct acpi_ec          *ec;
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       union acpi_ec           *ec = NULL;
+       unsigned long           uid;
+
+       ACPI_FUNCTION_TRACE("acpi_ec_add");
+
+       if (!device)
+               return_VALUE(-EINVAL);
+
+       ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+       if (!ec)
+               return_VALUE(-ENOMEM);
+       memset(ec, 0, sizeof(union acpi_ec));
+
+       ec->common.handle = device->handle;
+       ec->common.uid = -1;
+       spin_lock_init(&ec->polling.lock);
+       strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
+       strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+       acpi_driver_data(device) = ec;
+
+       /* Use the global lock for all EC transactions? */
+       acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
+
+       /* If our UID matches the UID for the ECDT-enumerated EC,
+          we now have the *real* EC info, so kill the makeshift one.*/
+       acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
+       if (ec_ecdt && ec_ecdt->common.uid == uid) {
+               acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
+                       ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+       
+               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
+
+               kfree(ec_ecdt);
+       }
+
+       /* Get GPE bit assignment (EC events). */
+       /* TODO: Add support for _GPE returning a package */
+       status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                       "Error obtaining GPE bit assignment\n"));
+               result = -ENODEV;
+               goto end;
+       }
+
+       result = acpi_ec_add_fs(device);
+       if (result)
+               goto end;
+
+       printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
+               acpi_device_name(device), acpi_device_bid(device),
+               (u32) ec->common.gpe_bit);
+
+       if (!first_ec)
+               first_ec = device;
+
+end:
+       if (result)
+               kfree(ec);
+
+       return_VALUE(result);
+}
+static int
+acpi_ec_burst_add (
+       struct acpi_device      *device)
+{
+       int                     result = 0;
+       acpi_status             status = AE_OK;
+       union acpi_ec           *ec = NULL;
        unsigned long           uid;
 
        ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -758,39 +1197,39 @@ acpi_ec_add (
        if (!device)
                return_VALUE(-EINVAL);
 
-       ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+       ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
        if (!ec)
                return_VALUE(-ENOMEM);
-       memset(ec, 0, sizeof(struct acpi_ec));
-
-       ec->handle = device->handle;
-       ec->uid = -1;
-       atomic_set(&ec->pending_gpe, 0);
-       atomic_set(&ec->leaving_burst , 1);
-       init_MUTEX(&ec->sem);
-       init_waitqueue_head(&ec->wait);
+       memset(ec, 0, sizeof(union acpi_ec));
+
+       ec->common.handle = device->handle;
+       ec->common.uid = -1;
+       atomic_set(&ec->burst.pending_gpe, 0);
+       atomic_set(&ec->burst.leaving_burst , 1);
+       init_MUTEX(&ec->burst.sem);
+       init_waitqueue_head(&ec->burst.wait);
        strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_EC_CLASS);
        acpi_driver_data(device) = ec;
 
        /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
+       acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
 
        /* If our UID matches the UID for the ECDT-enumerated EC,
           we now have the *real* EC info, so kill the makeshift one.*/
-       acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
-       if (ec_ecdt && ec_ecdt->uid == uid) {
+       acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
+       if (ec_ecdt && ec_ecdt->common.uid == uid) {
                acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
                        ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 
-               acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
+               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
 
                kfree(ec_ecdt);
        }
 
        /* Get GPE bit assignment (EC events). */
        /* TODO: Add support for _GPE returning a package */
-       status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
+       status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
        if (ACPI_FAILURE(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                        "Error obtaining GPE bit assignment\n"));
@@ -804,7 +1243,7 @@ acpi_ec_add (
 
        printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
                acpi_device_name(device), acpi_device_bid(device),
-               (u32) ec->gpe_bit);
+               (u32) ec->common.gpe_bit);
 
        if (!first_ec)
                first_ec = device;
@@ -822,7 +1261,7 @@ acpi_ec_remove (
        struct acpi_device      *device,
        int                     type)
 {
-       struct acpi_ec          *ec;
+       union acpi_ec           *ec = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_ec_remove");
 
@@ -844,7 +1283,7 @@ acpi_ec_io_ports (
        struct acpi_resource    *resource,
        void                    *context)
 {
-       struct acpi_ec          *ec = (struct acpi_ec *) context;
+       union acpi_ec           *ec = (union acpi_ec *) context;
        struct acpi_generic_address *addr;
 
        if (resource->id != ACPI_RSTYPE_IO) {
@@ -856,10 +1295,10 @@ acpi_ec_io_ports (
         * the second address region returned is the status/command
         * port.
         */
-       if (ec->data_addr.register_bit_width == 0) {
-               addr = &ec->data_addr;
-       } else if (ec->command_addr.register_bit_width == 0) {
-               addr = &ec->command_addr;
+       if (ec->common.data_addr.register_bit_width == 0) {
+               addr = &ec->common.data_addr;
+       } else if (ec->common.command_addr.register_bit_width == 0) {
+               addr = &ec->common.command_addr;
        } else {
                return AE_CTRL_TERMINATE;
        }
@@ -877,8 +1316,8 @@ static int
 acpi_ec_start (
        struct acpi_device      *device)
 {
-       acpi_status             status;
-       struct acpi_ec          *ec;
+       acpi_status             status = AE_OK;
+       union acpi_ec           *ec = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_ec_start");
 
@@ -893,35 +1332,36 @@ acpi_ec_start (
        /*
         * Get I/O port addresses. Convert to GAS format.
         */
-       status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
+       status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
                acpi_ec_io_ports, ec);
-       if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
+       if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
                return_VALUE(-ENODEV);
        }
 
-       ec->status_addr = ec->command_addr;
+       ec->common.status_addr = ec->common.command_addr;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
-               (u32) ec->gpe_bit, (u32) ec->command_addr.address,
-               (u32) ec->data_addr.address));
+               (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address,
+               (u32) ec->common.data_addr.address));
+
 
        /*
         * Install GPE handler
         */
-       status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
+       status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
                ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
        if (ACPI_FAILURE(status)) {
                return_VALUE(-ENODEV);
        }
-       acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-       acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR);
+       acpi_set_gpe_type (NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+       acpi_enable_gpe (NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 
-       status = acpi_install_address_space_handler (ec->handle,
+       status = acpi_install_address_space_handler (ec->common.handle,
                        ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
                        &acpi_ec_space_setup, ec);
        if (ACPI_FAILURE(status)) {
-               acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+               acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
                return_VALUE(-ENODEV);
        }
 
@@ -934,8 +1374,8 @@ acpi_ec_stop (
        struct acpi_device      *device,
        int                     type)
 {
-       acpi_status             status;
-       struct acpi_ec          *ec;
+       acpi_status             status = AE_OK;
+       union acpi_ec           *ec = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_ec_stop");
 
@@ -944,12 +1384,12 @@ acpi_ec_stop (
 
        ec = acpi_driver_data(device);
 
-       status = acpi_remove_address_space_handler(ec->handle,
+       status = acpi_remove_address_space_handler(ec->common.handle,
                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
        if (ACPI_FAILURE(status))
                return_VALUE(-ENODEV);
 
-       status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+       status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
        if (ACPI_FAILURE(status))
                return_VALUE(-ENODEV);
 
@@ -963,26 +1403,76 @@ acpi_fake_ecdt_callback (
        void            *context,
        void            **retval)
 {
+
+       if (acpi_ec_polling_mode)
+               return acpi_fake_ecdt_polling_callback(handle,
+                       Level, context, retval);
+       else
+               return acpi_fake_ecdt_burst_callback(handle,
+                       Level, context, retval);
+}
+
+static acpi_status __init
+acpi_fake_ecdt_polling_callback (
+       acpi_handle     handle,
+       u32             Level,
+       void            *context,
+       void            **retval)
+{
+       acpi_status     status;
+
+       status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+               acpi_ec_io_ports, ec_ecdt);
+       if (ACPI_FAILURE(status))
+               return status;
+       ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
+
+       ec_ecdt->common.uid = -1;
+       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
+
+       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
+       if (ACPI_FAILURE(status))
+               return status;
+       spin_lock_init(&ec_ecdt->polling.lock);
+       ec_ecdt->common.global_lock = TRUE;
+       ec_ecdt->common.handle = handle;
+
+       printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
+               (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
+               (u32) ec_ecdt->common.data_addr.address);
+
+       return AE_CTRL_TERMINATE;
+}
+
+static acpi_status __init
+acpi_fake_ecdt_burst_callback (
+       acpi_handle     handle,
+       u32             Level,
+       void            *context,
+       void            **retval)
+{
        acpi_status     status;
 
+       init_MUTEX(&ec_ecdt->burst.sem);
+       init_waitqueue_head(&ec_ecdt->burst.wait);
        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
                acpi_ec_io_ports, ec_ecdt);
        if (ACPI_FAILURE(status))
                return status;
-       ec_ecdt->status_addr = ec_ecdt->command_addr;
+       ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
 
-       ec_ecdt->uid = -1;
-       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
+       ec_ecdt->common.uid = -1;
+       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
 
-       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
+       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
        if (ACPI_FAILURE(status))
                return status;
-       ec_ecdt->global_lock = TRUE;
-       ec_ecdt->handle = handle;
+       ec_ecdt->common.global_lock = TRUE;
+       ec_ecdt->common.handle = handle;
 
        printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
-               (u32) ec_ecdt->gpe_bit, (u32) ec_ecdt->command_addr.address,
-               (u32) ec_ecdt->data_addr.address);
+               (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
+               (u32) ec_ecdt->common.data_addr.address);
 
        return AE_CTRL_TERMINATE;
 }
@@ -1005,12 +1495,12 @@ acpi_ec_fake_ecdt(void)
 
        printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
 
-       ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
        if (!ec_ecdt) {
                ret = -ENOMEM;
                goto error;
        }
-       memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+       memset(ec_ecdt, 0, sizeof(union acpi_ec));
 
        status = acpi_get_devices (ACPI_EC_HID,
                                acpi_fake_ecdt_callback,
@@ -1030,6 +1520,60 @@ error:
 
 static int __init
 acpi_ec_get_real_ecdt(void)
+{
+       if (acpi_ec_polling_mode)
+               return acpi_ec_polling_get_real_ecdt();
+       else
+               return acpi_ec_burst_get_real_ecdt();
+}
+
+static int __init
+acpi_ec_polling_get_real_ecdt(void)
+{
+       acpi_status             status;
+       struct acpi_table_ecdt  *ecdt_ptr;
+
+       status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
+               (struct acpi_table_header **) &ecdt_ptr);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       printk(KERN_INFO PREFIX "Found ECDT\n");
+
+       /*
+        * Generate a temporary ec context to use until the namespace is scanned
+        */
+       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+       if (!ec_ecdt)
+               return -ENOMEM;
+       memset(ec_ecdt, 0, sizeof(union acpi_ec));
+
+       ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
+       ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
+       ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
+       ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
+       spin_lock_init(&ec_ecdt->polling.lock);
+       /* use the GL just to be safe */
+       ec_ecdt->common.global_lock = TRUE;
+       ec_ecdt->common.uid = ecdt_ptr->uid;
+
+       status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+       if (ACPI_FAILURE(status)) {
+               goto error;
+       }
+
+       return 0;
+error:
+       printk(KERN_ERR PREFIX "Could not use ECDT\n");
+       kfree(ec_ecdt);
+       ec_ecdt = NULL;
+
+       return -ENODEV;
+}
+
+
+static int __init
+acpi_ec_burst_get_real_ecdt(void)
 {
        acpi_status             status;
        struct acpi_table_ecdt  *ecdt_ptr;
@@ -1044,22 +1588,22 @@ acpi_ec_get_real_ecdt(void)
        /*
         * Generate a temporary ec context to use until the namespace is scanned
         */
-       ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
        if (!ec_ecdt)
                return -ENOMEM;
-       memset(ec_ecdt, 0, sizeof(struct acpi_ec));
-
-       init_MUTEX(&ec_ecdt->sem);
-       init_waitqueue_head(&ec_ecdt->wait);
-       ec_ecdt->command_addr = ecdt_ptr->ec_control;
-       ec_ecdt->status_addr = ecdt_ptr->ec_control;
-       ec_ecdt->data_addr = ecdt_ptr->ec_data;
-       ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
+       memset(ec_ecdt, 0, sizeof(union acpi_ec));
+
+       init_MUTEX(&ec_ecdt->burst.sem);
+       init_waitqueue_head(&ec_ecdt->burst.wait);
+       ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
+       ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
+       ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
+       ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
        /* use the GL just to be safe */
-       ec_ecdt->global_lock = TRUE;
-       ec_ecdt->uid = ecdt_ptr->uid;
+       ec_ecdt->common.global_lock = TRUE;
+       ec_ecdt->common.uid = ecdt_ptr->uid;
 
-       status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
+       status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
        if (ACPI_FAILURE(status)) {
                goto error;
        }
@@ -1092,20 +1636,20 @@ acpi_ec_ecdt_probe (void)
        /*
         * Install GPE handler
         */
-       status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
+       status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
                ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
                ec_ecdt);
        if (ACPI_FAILURE(status)) {
                goto error;
        }
-       acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-       acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
+       acpi_set_gpe_type (NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+       acpi_enable_gpe (NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
 
        status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
                        ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
                        &acpi_ec_space_setup, ec_ecdt);
        if (ACPI_FAILURE(status)) {
-               acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
                        &acpi_ec_gpe_handler);
                goto error;
        }
@@ -1123,7 +1667,7 @@ error:
 
 static int __init acpi_ec_init (void)
 {
-       int                     result;
+       int                     result = 0;
 
        ACPI_FUNCTION_TRACE("acpi_ec_init");
 
@@ -1167,3 +1711,10 @@ static int __init acpi_fake_ecdt_setup(char *str)
        return 0;
 }
 __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
+static int __init acpi_ec_set_polling_mode(char *str)
+{
+       acpi_ec_polling_mode = EC_POLLING;
+       acpi_ec_driver.ops.add = acpi_ec_polling_add;
+       return 0;
+}
+__setup("ec_polling", acpi_ec_set_polling_mode);
index d1f42b9728214cb31a7a2584b802325029d3fed5..bb973d2109a11e7404f1d3fa788f1d0655038d5e 100644 (file)
@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int bus)
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
+typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **);
 
+static int
+acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
+       int     *edge_level,
+       int     *active_high_low,
+       char    **link)
+{
+       int     irq;
+
+       ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq");
+
+       if (entry->link.handle) {
+               irq = acpi_pci_link_allocate_irq(entry->link.handle,
+                       entry->link.index, edge_level, active_high_low, link);
+               if (irq < 0) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
+                       return_VALUE(-1);
+               }
+       } else {
+               irq = entry->link.index;
+               *edge_level = ACPI_LEVEL_SENSITIVE;
+               *active_high_low = ACPI_ACTIVE_LOW;
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
+       return_VALUE(irq);
+}
+
+static int
+acpi_pci_free_irq(struct acpi_prt_entry *entry,
+       int     *edge_level,
+       int     *active_high_low,
+       char    **link)
+{
+       int     irq;
+
+       ACPI_FUNCTION_TRACE("acpi_pci_free_irq");
+       if (entry->link.handle) {
+               irq = acpi_pci_link_free_irq(entry->link.handle);
+       } else {
+               irq = entry->link.index;
+       }
+       return_VALUE(irq);
+}
 /*
  * acpi_pci_irq_lookup
  * success: return IRQ >= 0
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup (
        int                     pin,
        int                     *edge_level,
        int                     *active_high_low,
-       char                    **link)
+       char                    **link,
+       irq_lookup_func         func)
 {
        struct acpi_prt_entry   *entry = NULL;
        int segment = pci_domain_nr(bus);
        int bus_nr = bus->number;
-       int irq;
+       int ret;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
 
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup (
                return_VALUE(-1);
        }
        
-       if (entry->link.handle) {
-               irq = acpi_pci_link_get_irq(entry->link.handle,
-                       entry->link.index, edge_level, active_high_low, link);
-               if (irq < 0) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
-                       return_VALUE(-1);
-               }
-       } else {
-               irq = entry->link.index;
-               *edge_level = ACPI_LEVEL_SENSITIVE;
-               *active_high_low = ACPI_ACTIVE_LOW;
-       }
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
-
-       return_VALUE(irq);
+       ret = func(entry, edge_level, active_high_low, link);
+       return_VALUE(ret);
 }
 
 /*
@@ -330,7 +361,8 @@ acpi_pci_irq_derive (
        int                     pin,
        int                     *edge_level,
        int                     *active_high_low,
-       char                    **link)
+       char                    **link,
+       irq_lookup_func         func)
 {
        struct pci_dev          *bridge = dev;
        int                     irq = -1;
@@ -363,7 +395,7 @@ acpi_pci_irq_derive (
                }
 
                irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
-                       pin, edge_level, active_high_low, link);
+                       pin, edge_level, active_high_low, link, func);
        }
 
        if (irq < 0) {
@@ -415,7 +447,7 @@ acpi_pci_irq_enable (
         * values override any BIOS-assigned IRQs set during boot.
         */
        irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-               &edge_level, &active_high_low, &link);
+               &edge_level, &active_high_low, &link, acpi_pci_allocate_irq);
 
        /*
         * If no PRT entry was found, we'll try to derive an IRQ from the
@@ -423,7 +455,7 @@ acpi_pci_irq_enable (
         */
        if (irq < 0)
                irq = acpi_pci_irq_derive(dev, pin, &edge_level,
-                       &active_high_low, &link);
+                       &active_high_low, &link, acpi_pci_allocate_irq);
  
        /*
         * No IRQ known to the ACPI subsystem - maybe the BIOS / 
@@ -462,7 +494,9 @@ acpi_pci_irq_enable (
 EXPORT_SYMBOL(acpi_pci_irq_enable);
 
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+/* FIXME: implement x86/x86_64 version */
+void __attribute__((weak)) acpi_unregister_gsi(u32 i) {}
+
 void
 acpi_pci_irq_disable (
        struct pci_dev          *dev)
@@ -489,14 +523,14 @@ acpi_pci_irq_disable (
         * First we check the PCI IRQ routing table (PRT) for an IRQ.
         */
        gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-                                 &edge_level, &active_high_low, NULL);
+                       &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
        /*
         * If no PRT entry was found, we'll try to derive an IRQ from the
         * device's parent bridge.
         */
        if (gsi < 0)
                gsi = acpi_pci_irq_derive(dev, pin,
-                                         &edge_level, &active_high_low, NULL);
+                       &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
        if (gsi < 0)
                return_VOID;
 
@@ -512,4 +546,3 @@ acpi_pci_irq_disable (
 
        return_VOID;
 }
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
index 6ad0e77df9b320ca2661fc483778f10ced28d4c9..6a29610edc112f6a047b229a2fd4bbeb051b1309 100644 (file)
@@ -68,6 +68,10 @@ static struct acpi_driver acpi_pci_link_driver = {
                        },
 };
 
+/*
+ * If a link is initialized, we never change its active and initialized
+ * later even the link is disable. Instead, we just repick the active irq
+ */
 struct acpi_pci_link_irq {
        u8                      active;                 /* Current IRQ */
        u8                      edge_level;             /* All IRQs */
@@ -76,8 +80,7 @@ struct acpi_pci_link_irq {
        u8                      possible_count;
        u8                      possible[ACPI_PCI_LINK_MAX_POSSIBLE];
        u8                      initialized:1;
-       u8                      suspend_resume:1;
-       u8                      reserved:6;
+       u8                      reserved:7;
 };
 
 struct acpi_pci_link {
@@ -85,12 +88,14 @@ struct acpi_pci_link {
        struct acpi_device      *device;
        acpi_handle             handle;
        struct acpi_pci_link_irq irq;
+       int                     refcnt;
 };
 
 static struct {
        int                     count;
        struct list_head        entries;
 }                              acpi_link;
+DECLARE_MUTEX(acpi_link_lock);
 
 
 /* --------------------------------------------------------------------------
@@ -532,12 +537,12 @@ static int acpi_pci_link_allocate(
 
        ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
 
-       if (link->irq.suspend_resume) {
-               acpi_pci_link_set(link, link->irq.active);
-               link->irq.suspend_resume = 0;
-       }
-       if (link->irq.initialized)
+       if (link->irq.initialized) {
+               if (link->refcnt == 0)
+                       /* This means the link is disabled but initialized */
+                       acpi_pci_link_set(link, link->irq.active);
                return_VALUE(0);
+       }
 
        /*
         * search for active IRQ in list of possible IRQs.
@@ -596,13 +601,13 @@ static int acpi_pci_link_allocate(
 }
 
 /*
- * acpi_pci_link_get_irq
+ * acpi_pci_link_allocate_irq
  * success: return IRQ >= 0
  * failure: return -1
  */
 
 int
-acpi_pci_link_get_irq (
+acpi_pci_link_allocate_irq (
        acpi_handle             handle,
        int                     index,
        int                     *edge_level,
@@ -613,7 +618,7 @@ acpi_pci_link_get_irq (
        struct acpi_device      *device = NULL;
        struct acpi_pci_link    *link = NULL;
 
-       ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq");
+       ACPI_FUNCTION_TRACE("acpi_pci_link_allocate_irq");
 
        result = acpi_bus_get_device(handle, &device);
        if (result) {
@@ -633,21 +638,70 @@ acpi_pci_link_get_irq (
                return_VALUE(-1);
        }
 
-       if (acpi_pci_link_allocate(link))
+       down(&acpi_link_lock);
+       if (acpi_pci_link_allocate(link)) {
+               up(&acpi_link_lock);
                return_VALUE(-1);
+       }
           
        if (!link->irq.active) {
+               up(&acpi_link_lock);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
                return_VALUE(-1);
        }
+       link->refcnt ++;
+       up(&acpi_link_lock);
 
        if (edge_level) *edge_level = link->irq.edge_level;
        if (active_high_low) *active_high_low = link->irq.active_high_low;
        if (name) *name = acpi_device_bid(link->device);
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+               "Link %s is referenced\n", acpi_device_bid(link->device)));
        return_VALUE(link->irq.active);
 }
 
+/*
+ * We don't change link's irq information here.  After it is reenabled, we
+ * continue use the info
+ */
+int
+acpi_pci_link_free_irq(acpi_handle handle)
+{
+       struct acpi_device      *device = NULL;
+       struct acpi_pci_link    *link = NULL;
+       acpi_status             result;
+
+       ACPI_FUNCTION_TRACE("acpi_pci_link_free_irq");
+
+       result = acpi_bus_get_device(handle, &device);
+       if (result) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n"));
+               return_VALUE(-1);
+       }
 
+       link = (struct acpi_pci_link *) acpi_driver_data(device);
+       if (!link) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+               return_VALUE(-1);
+       }
+
+       down(&acpi_link_lock);
+       if (!link->irq.initialized) {
+               up(&acpi_link_lock);
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n"));
+               return_VALUE(-1);
+       }
+
+       link->refcnt --;
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+               "Link %s is dereferenced\n", acpi_device_bid(link->device)));
+
+       if (link->refcnt == 0) {
+               acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+       }
+       up(&acpi_link_lock);
+       return_VALUE(link->irq.active);
+}
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -677,6 +731,7 @@ acpi_pci_link_add (
        strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
        acpi_driver_data(device) = link;
 
+       down(&acpi_link_lock);
        result = acpi_pci_link_get_possible(link);
        if (result)
                goto end;
@@ -712,6 +767,7 @@ acpi_pci_link_add (
 end:
        /* disable all links -- to be activated on use */
        acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+       up(&acpi_link_lock);
 
        if (result)
                kfree(link);
@@ -726,19 +782,32 @@ irqrouter_suspend(
 {
        struct list_head        *node = NULL;
        struct acpi_pci_link    *link = NULL;
+       int                     ret = 0;
 
        ACPI_FUNCTION_TRACE("irqrouter_suspend");
 
        list_for_each(node, &acpi_link.entries) {
                link = list_entry(node, struct acpi_pci_link, node);
                if (!link) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                               "Invalid link context\n"));
                        continue;
                }
-               if (link->irq.active && link->irq.initialized)
-                       link->irq.suspend_resume = 1;
+               if (link->irq.initialized && link->refcnt != 0
+                       /* We ignore legacy IDE device irq */
+                       && link->irq.active != 14 && link->irq.active !=15) {
+                       printk(KERN_WARNING PREFIX
+                               "%d drivers with interrupt %d neglected to call"
+                               " pci_disable_device at .suspend\n",
+                               link->refcnt,
+                               link->irq.active);
+                       printk(KERN_WARNING PREFIX
+                               "Fix the driver, or rmmod before suspend\n");
+                       link->refcnt = 0;
+                       ret = -EINVAL;
+               }
        }
-       return_VALUE(0);
+       return_VALUE(ret);
 }
 
 
@@ -756,8 +825,9 @@ acpi_pci_link_remove (
 
        link = (struct acpi_pci_link *) acpi_driver_data(device);
 
-       /* TBD: Acquire/release lock */
+       down(&acpi_link_lock);
        list_del(&link->node);
+       up(&acpi_link_lock);
 
        kfree(link);
 
@@ -849,6 +919,7 @@ int __init acpi_irq_balance_set(char *str)
 __setup("acpi_irq_balance", acpi_irq_balance_set);
 
 
+/* FIXME: we will remove this interface after all drivers call pci_disable_device */
 static struct sysdev_class irqrouter_sysdev_class = {
         set_kset_name("irqrouter"),
         .suspend = irqrouter_suspend,
index 893b074e3d1a48a4390cf84b4c1a10ef6be2460c..af271d994f15a6db56a94f4f801bf71dc5d15c86 100644 (file)
@@ -81,30 +81,33 @@ module_param(bm_history, uint, 0644);
  *
  * To skip this limit, boot/load with a large max_cstate limit.
  */
-static int no_c2c3(struct dmi_system_id *id)
+static int set_max_cstate(struct dmi_system_id *id)
 {
        if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
                return 0;
 
-       printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
+       printk(KERN_NOTICE PREFIX "%s detected - %s disabled."
                " Override with \"processor.max_cstate=%d\"\n", id->ident,
+               ((int)id->driver_data == 1)? "C2,C3":"C3",
               ACPI_PROCESSOR_MAX_POWER + 1);
 
-       max_cstate = 1;
+       max_cstate = (int)id->driver_data;
 
        return 0;
 }
 
 
-
-
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
-       { no_c2c3, "IBM ThinkPad R40e", {
+       { set_max_cstate, "IBM ThinkPad R40e", {
          DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-         DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
-       { no_c2c3, "Medion 41700", {
+         DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
+       { set_max_cstate, "Medion 41700", {
+         DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+         DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }, (void*)1},
+       { set_max_cstate, "Clevo 5600D", {
          DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-         DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
+         DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307") },
+         (void*)2},
        {},
 };
 
@@ -549,7 +552,8 @@ static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
        ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
 
        for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-               memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+               memset(&(pr->power.states[i]), 0, 
+                      sizeof(struct acpi_processor_cx));
 
        /* if info is obtained from pblk/fadt, type equals state */
        pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@ -580,7 +584,8 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
 
        pr->power.count = 0;
        for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-               memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+               memset(&(pr->power.states[i]), 0, 
+                      sizeof(struct acpi_processor_cx));
 
        status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
@@ -763,7 +768,6 @@ static void acpi_processor_power_verify_c3(
        }
 
        if (pr->flags.bm_check) {
-               printk("Disabling BM access before entering C3\n");
                /* bus mastering control is necessary */
                if (!pr->flags.bm_control) {
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -771,7 +775,6 @@ static void acpi_processor_power_verify_c3(
                        return_VOID;
                }
        } else {
-               printk("Invalidating cache before entering C3\n");
                /*
                 * WBINVD should be set in fadt, for C3 state to be
                 * supported on when bm_check is not required.
@@ -842,7 +845,7 @@ static int acpi_processor_get_power_info (
        result = acpi_processor_get_power_info_cst(pr);
        if ((result) || (acpi_processor_power_verify(pr) < 2)) {
                result = acpi_processor_get_power_info_fadt(pr);
-               if (result)
+               if ((result) || (acpi_processor_power_verify(pr) < 2))
                        result = acpi_processor_get_power_info_default_c1(pr);
        }
 
index 82570ec44d8eefea84aa2b7721ac9f3eafa7bd3e..49bd8c7c3f7dba789f87799236d0b7d6d355ab21 100644 (file)
@@ -5133,6 +5133,81 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
        kfree(pAC);
 }
 
+#ifdef CONFIG_PM
+static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+       struct net_device *otherdev = pAC->dev[1];
+
+       if (netif_running(dev)) {
+               netif_carrier_off(dev);
+               DoPrintInterfaceChange = SK_FALSE;
+               SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
+               netif_device_detach(dev);
+       }
+       if (otherdev != dev) {
+               if (netif_running(otherdev)) {
+                       netif_carrier_off(otherdev);
+                       DoPrintInterfaceChange = SK_FALSE;
+                       SkDrvDeInitAdapter(pAC, 1);  /* performs SkGeClose */
+                       netif_device_detach(otherdev);
+               }
+       }
+
+       pci_save_state(pdev);
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+       if (pAC->AllocFlag & SK_ALLOC_IRQ) {
+               free_irq(dev->irq, dev);
+       }
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+static int skge_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+       struct net_device *otherdev = pAC->dev[1];
+       int ret;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
+       if (pAC->GIni.GIMacsFound == 2)
+               ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+       else
+               ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+       if (ret) {
+               printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
+               pAC->AllocFlag &= ~SK_ALLOC_IRQ;
+               dev->irq = 0;
+               pci_disable_device(pdev);
+               return -EBUSY;
+       }
+
+       netif_device_attach(dev);
+       if (netif_running(dev)) {
+               DoPrintInterfaceChange = SK_FALSE;
+               SkDrvInitAdapter(pAC, 0);    /* first device  */
+       }
+       if (otherdev != dev) {
+               netif_device_attach(otherdev);
+               if (netif_running(otherdev)) {
+                       DoPrintInterfaceChange = SK_FALSE;
+                       SkDrvInitAdapter(pAC, 1);    /* second device  */
+               }
+       }
+
+       return 0;
+}
+#endif
+
 static struct pci_device_id skge_pci_tbl[] = {
        { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
        { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
@@ -5158,6 +5233,8 @@ static struct pci_driver skge_driver = {
        .id_table       = skge_pci_tbl,
        .probe          = skge_probe_one,
        .remove         = __devexit_p(skge_remove_one),
+       .suspend        = skge_suspend,
+       .resume         = skge_resume,
 };
 
 static int __init skge_init(void)
index 744e469a9eda6cca3e0e45457706442e99f3f687..6837491f021c0b813aee8681cc73eb33dd0a21cd 100644 (file)
@@ -1107,8 +1107,6 @@ static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
                pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
                pci_disable_device(dev);
 
-               free_irq(dev->irq, socket);
-
                /*
                 * Some laptops (IBM T22) do not like us putting the Cardbus
                 * bridge into D3.  At a guess, some other laptop will
@@ -1134,13 +1132,6 @@ static int yenta_dev_resume (struct pci_dev *dev)
                pci_enable_device(dev);
                pci_set_master(dev);
 
-               if (socket->cb_irq)
-                       if (request_irq(socket->cb_irq, yenta_interrupt,
-                                       SA_SHIRQ, "yenta", socket)) {
-                               printk(KERN_WARNING "Yenta: request_irq() failed on resume!\n");
-                               socket->cb_irq = 0;
-                       }
-
                if (socket->type && socket->type->restore_state)
                        socket->type->restore_state(socket);
        }
index 96df148ed96967f06e544893ae415ba2bb18699d..f1e8c4223ed1d2f11d1ee3485875502cf9bf2629 100644 (file)
@@ -424,7 +424,7 @@ config SCSI_IN2000
 source "drivers/scsi/megaraid/Kconfig.megaraid"
 
 config SCSI_SATA
-       bool "Serial ATA (SATA) support"
+       tristate "Serial ATA (SATA) support"
        depends on SCSI
        help
          This driver family supports Serial ATA host controllers
index ed1d4d1ac4f709bed6172bb827cb892c369311d2..1147b899f007d71eaebde3ff7d58d32ff27f935a 100644 (file)
@@ -414,6 +414,13 @@ static ssize_t show_pan(struct class_device *class_device, char *buf)
                        fb_info->var.xoffset);
 }
 
+static ssize_t show_name(struct class_device *class_device, char *buf)
+{
+       struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
+}
+
 static struct class_device_attribute class_device_attrs[] = {
        __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
        __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
@@ -424,6 +431,7 @@ static struct class_device_attribute class_device_attrs[] = {
        __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
        __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
        __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
+       __ATTR(name, S_IRUGO, show_name, NULL),
 };
 
 int fb_init_class_device(struct fb_info *fb_info)
index caeaa71a566399171a7aacf7047110b3daa34cfc..579fe191b7e7d3415fe9163568b575403e409a6a 100644 (file)
@@ -56,8 +56,9 @@
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
 int acpi_irq_penalty_init (void);
-int acpi_pci_link_get_irq (acpi_handle handle, int index, int *edge_level,
+int acpi_pci_link_allocate_irq (acpi_handle handle, int index, int *edge_level,
        int *active_high_low, char **name);
+int acpi_pci_link_free_irq(acpi_handle handle);
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
index a7894e0fbbb1a8d1e7f7719a2b7d4fda940ef263..3173ab3d2eb9a477af7b308db22ce82b0d3d0421 100644 (file)
 #define __NR_waitid            272
 #define __NR_ioprio_set                273
 #define __NR_ioprio_get                274
+#define __NR_inotify_init      275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch  277
 
-#define __NR_syscalls          275
+#define __NR_syscalls          278
 
 #define __NR(n)        #n
 
index 4a94acf6bfedd52c403b56b3ac1eb1fa99d415a3..977bc980c1af641681a1283df2094e9ea4733734 100644 (file)
 #define __NR_waitid            272
 #define __NR_ioprio_set                273
 #define __NR_ioprio_get                274
+#define __NR_inotify_init      275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch  277
 
-#define __NR_syscalls          275
+#define __NR_syscalls          278
 #ifdef __KERNEL__
 #define NR_syscalls    __NR_syscalls
 #endif
index f85cbe919e132de0a147961de241939003f10148..b46a5205ee7b1ce25f327cc07759220142d7f34d 100644 (file)
@@ -453,9 +453,7 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
  * If this matches the last registration, any IRQ resources for gsi
  * are freed.
  */
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_unregister_gsi (u32 gsi);
-#endif
 
 #ifdef CONFIG_ACPI_PCI
 
@@ -480,9 +478,7 @@ struct pci_dev;
 int acpi_pci_irq_enable (struct pci_dev *dev);
 void acpi_penalize_isa_irq(int irq, int active);
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_pci_irq_disable (struct pci_dev *dev);
-#endif
 
 struct acpi_pci_driver {
        struct acpi_pci_driver *next;
index f4f9aba07ac2ae59c6830f95ce7ae392d3bc2c42..5010f0c5a56e32c8492723d8342b99bde0df7d67 100644 (file)
@@ -1236,7 +1236,7 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp)
        tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-/* Set slow start threshould and cwnd not falling to slow start */
+/* Set slow start threshold and cwnd not falling to slow start */
 static inline void __tcp_enter_cwr(struct tcp_sock *tp)
 {
        tp->undo_marker = 0;
index 31007d6542cccbf6c4df2607a848802d13b5fd63..b4ab6af1dea8513147c19694a8eff8a4353c69e0 100644 (file)
@@ -86,7 +86,7 @@ restart:
        /* Reset the pending bitmask before enabling irqs */
        local_softirq_pending() = 0;
 
-       //local_irq_enable();
+       local_irq_enable();
 
        h = softirq_vec;
 
@@ -99,7 +99,7 @@ restart:
                pending >>= 1;
        } while (pending);
 
-       //local_irq_disable();
+       local_irq_disable();
 
        pending = local_softirq_pending();
        if (pending && --max_restart)
index 42bccfb8464d1421d721e3a108c439ccd36b1983..8d088371196a559b5baa5a8dc02e2d07253fd50c 100644 (file)
@@ -1061,20 +1061,19 @@ unsigned int nr_free_pages_pgdat(pg_data_t *pgdat)
 
 static unsigned int nr_free_zone_pages(int offset)
 {
-       pg_data_t *pgdat;
+       /* Just pick one node, since fallback list is circular */
+       pg_data_t *pgdat = NODE_DATA(numa_node_id());
        unsigned int sum = 0;
 
-       for_each_pgdat(pgdat) {
-               struct zonelist *zonelist = pgdat->node_zonelists + offset;
-               struct zone **zonep = zonelist->zones;
-               struct zone *zone;
+       struct zonelist *zonelist = pgdat->node_zonelists + offset;
+       struct zone **zonep = zonelist->zones;
+       struct zone *zone;
 
-               for (zone = *zonep++; zone; zone = *zonep++) {
-                       unsigned long size = zone->present_pages;
-                       unsigned long high = zone->pages_high;
-                       if (size > high)
-                               sum += size - high;
-               }
+       for (zone = *zonep++; zone; zone = *zonep++) {
+               unsigned long size = zone->present_pages;
+               unsigned long high = zone->pages_high;
+               if (size > high)
+                       sum += size - high;
        }
 
        return sum;
index fc434ade5270e1b99770a9a5f91b2a8747a50093..334790da9f160cd6852a35e5186db16cbb3d14b1 100644 (file)
@@ -45,6 +45,7 @@ static struct timer_list dst_gc_timer =
 static void dst_run_gc(unsigned long dummy)
 {
        int    delayed = 0;
+       int    work_performed;
        struct dst_entry * dst, **dstp;
 
        if (!spin_trylock(&dst_lock)) {
@@ -52,9 +53,9 @@ static void dst_run_gc(unsigned long dummy)
                return;
        }
 
-
        del_timer(&dst_gc_timer);
        dstp = &dst_garbage_list;
+       work_performed = 0;
        while ((dst = *dstp) != NULL) {
                if (atomic_read(&dst->__refcnt)) {
                        dstp = &dst->next;
@@ -62,6 +63,7 @@ static void dst_run_gc(unsigned long dummy)
                        continue;
                }
                *dstp = dst->next;
+               work_performed = 1;
 
                dst = dst_destroy(dst);
                if (dst) {
@@ -86,9 +88,14 @@ static void dst_run_gc(unsigned long dummy)
                dst_gc_timer_inc = DST_GC_MAX;
                goto out;
        }
-       if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX)
-               dst_gc_timer_expires = DST_GC_MAX;
-       dst_gc_timer_inc += DST_GC_INC;
+       if (!work_performed) {
+               if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX)
+                       dst_gc_timer_expires = DST_GC_MAX;
+               dst_gc_timer_inc += DST_GC_INC;
+       } else {
+               dst_gc_timer_inc = DST_GC_INC;
+               dst_gc_timer_expires = DST_GC_MIN;
+       }
        dst_gc_timer.expires = jiffies + dst_gc_timer_expires;
 #if RT_CACHE_DEBUG >= 2
        printk("dst_total: %d/%d %ld\n",
index 8848355222241cbd1763330a88183a2b45b34966..f0d5740d7e220f5675602ee43682c526f4dfbf8c 100644 (file)
@@ -290,7 +290,6 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
 
        dev_hold(dev);
        ipgre_tunnel_link(nt);
-       /* Do not decrement MOD_USE_COUNT here. */
        return nt;
 
 failed:
@@ -1277,12 +1276,28 @@ err1:
        goto out;
 }
 
-static void ipgre_fini(void)
+static void __exit ipgre_destroy_tunnels(void)
+{
+       int prio;
+
+       for (prio = 0; prio < 4; prio++) {
+               int h;
+               for (h = 0; h < HASH_SIZE; h++) {
+                       struct ip_tunnel *t;
+                       while ((t = tunnels[prio][h]) != NULL)
+                               unregister_netdevice(t->dev);
+               }
+       }
+}
+
+static void __exit ipgre_fini(void)
 {
        if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
                printk(KERN_INFO "ipgre close: can't remove protocol\n");
 
-       unregister_netdev(ipgre_fb_tunnel_dev);
+       rtnl_lock();
+       ipgre_destroy_tunnels();
+       rtnl_unlock();
 }
 
 module_init(ipgre_init);
index c3947cd566b7a6c0e421dfab418ac09976221d30..c05c1df0bb045e17f92b9cbe5dcad23ed8df2c6e 100644 (file)
@@ -255,7 +255,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
 
        dev_hold(dev);
        ipip_tunnel_link(nt);
-       /* Do not decrement MOD_USE_COUNT here. */
        return nt;
 
 failed:
@@ -920,12 +919,29 @@ static int __init ipip_init(void)
        goto out;
 }
 
+static void __exit ipip_destroy_tunnels(void)
+{
+       int prio;
+
+       for (prio = 1; prio < 4; prio++) {
+               int h;
+               for (h = 0; h < HASH_SIZE; h++) {
+                       struct ip_tunnel *t;
+                       while ((t = tunnels[prio][h]) != NULL)
+                               unregister_netdevice(t->dev);
+               }
+       }
+}
+
 static void __exit ipip_fini(void)
 {
        if (ipip_unregister() < 0)
                printk(KERN_INFO "ipip close: can't deregister tunnel\n");
 
-       unregister_netdev(ipip_fb_tunnel_dev);
+       rtnl_lock();
+       ipip_destroy_tunnels();
+       unregister_netdevice(ipip_fb_tunnel_dev);
+       rtnl_unlock();
 }
 
 module_init(ipip_init);
index 7833d920bdba02fad46b1853374b11f01d3396b2..dc806b57842705ac97f6a294a8a426f4f711b5aa 100644 (file)
@@ -362,7 +362,7 @@ out:
 
 /* Fill oifs list. It is called under write locked mrt_lock. */
 
-static void ipmr_update_threshoulds(struct mfc_cache *cache, unsigned char *ttls)
+static void ipmr_update_thresholds(struct mfc_cache *cache, unsigned char *ttls)
 {
        int vifi;
 
@@ -727,7 +727,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
        if (c != NULL) {
                write_lock_bh(&mrt_lock);
                c->mfc_parent = mfc->mfcc_parent;
-               ipmr_update_threshoulds(c, mfc->mfcc_ttls);
+               ipmr_update_thresholds(c, mfc->mfcc_ttls);
                if (!mrtsock)
                        c->mfc_flags |= MFC_STATIC;
                write_unlock_bh(&mrt_lock);
@@ -744,7 +744,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
        c->mfc_origin=mfc->mfcc_origin.s_addr;
        c->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr;
        c->mfc_parent=mfc->mfcc_parent;
-       ipmr_update_threshoulds(c, mfc->mfcc_ttls);
+       ipmr_update_thresholds(c, mfc->mfcc_ttls);
        if (!mrtsock)
                c->mfc_flags |= MFC_STATIC;
 
index 86f04e41dd8efb13bbca229cd83fe5f63aa87104..a7f0c821a9b2025483ee6636ab2e6df95147c182 100644 (file)
@@ -512,6 +512,11 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
                conntrack->master = exp->master;
 #ifdef CONFIG_IP_NF_CONNTRACK_MARK
                conntrack->mark = exp->master->mark;
+#endif
+#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+    defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+               /* this is ugly, but there is no other place where to put it */
+               conntrack->nat.masq_index = exp->master->nat.masq_index;
 #endif
                nf_conntrack_get(&conntrack->master->ct_general);
                CONNTRACK_STAT_INC(expect_new);
index b788f55e139b80756e23ef024335c3d2024d9f63..e553e5b80d6e3ed78124073c5163ec17dc0143b6 100644 (file)
@@ -195,7 +195,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
        dev_hold(dev);
 
        ipip6_tunnel_link(nt);
-       /* Do not decrement MOD_USE_COUNT here. */
        return nt;
 
 failed:
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol = {
        .err_handler    =       ipip6_err,
 };
 
+static void __exit sit_destroy_tunnels(void)
+{
+       int prio;
+
+       for (prio = 1; prio < 4; prio++) {
+               int h;
+               for (h = 0; h < HASH_SIZE; h++) {
+                       struct ip_tunnel *t;
+                       while ((t = tunnels[prio][h]) != NULL)
+                               unregister_netdevice(t->dev);
+               }
+       }
+}
+
 void __exit sit_cleanup(void)
 {
        inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
-       unregister_netdev(ipip6_fb_tunnel_dev);
+
+       rtnl_lock();
+       sit_destroy_tunnels();
+       unregister_netdevice(ipip6_fb_tunnel_dev);
+       rtnl_unlock();
 }
 
 int __init sit_init(void)
index 7c806bd9cc90a7c647ac128270366f440f0c8b48..d7af3e47443263810fc075e1b7e9e513c01996fc 100644 (file)
@@ -2376,6 +2376,9 @@ static int intel8x0_suspend(snd_card_t *card, pm_message_t state)
                        snd_ac97_suspend(chip->ac97[i]);
        if (chip->device_type == DEVICE_INTEL_ICH4)
                chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
+
+       if (chip->irq >= 0)
+               free_irq(chip->irq, (void *)chip);
        pci_disable_device(chip->pci);
        return 0;
 }
@@ -2387,7 +2390,9 @@ static int intel8x0_resume(snd_card_t *card)
 
        pci_enable_device(chip->pci);
        pci_set_master(chip->pci);
-       snd_intel8x0_chip_init(chip, 0);
+       request_irq(chip->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip);
+       synchronize_irq(chip->irq);
+       snd_intel8x0_chip_init(chip, 1);
 
        /* re-initialize mixer stuff */
        if (chip->device_type == DEVICE_INTEL_ICH4) {