Răsfoiți Sursa

Merge ../linux-2.6/

Dave Airlie 20 ani în urmă
părinte
comite
727e6e932d

+ 15 - 1
Documentation/fb/vesafb.txt

@@ -144,7 +144,21 @@ vgapal	Use the standard vga registers for palette changes.
 	This is the default.
 	This is the default.
 pmipal	Use the protected mode interface for palette changes.
 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
 vremap:n
         remap 'n' MiB of video RAM. If 0 or not specified, remap memory
         remap 'n' MiB of video RAM. If 0 or not specified, remap memory

+ 7 - 0
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c

@@ -442,6 +442,13 @@ acpi_cpufreq_cpu_init (
 			(u32) data->acpi_data.states[i].transition_latency);
 			(u32) data->acpi_data.states[i].transition_latency);
 
 
 	cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
 	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);
 	return (result);
 
 
  err_freqfree:
  err_freqfree:

+ 1 - 0
arch/i386/pci/acpi.c

@@ -30,6 +30,7 @@ static int __init pci_acpi_init(void)
 	acpi_irq_penalty_init();
 	acpi_irq_penalty_init();
 	pcibios_scanned++;
 	pcibios_scanned++;
 	pcibios_enable_irq = acpi_pci_irq_enable;
 	pcibios_enable_irq = acpi_pci_irq_enable;
+	pcibios_disable_irq = acpi_pci_irq_disable;
 
 
 	if (pci_routeirq) {
 	if (pci_routeirq) {
 		/*
 		/*

+ 6 - 0
arch/i386/pci/common.c

@@ -254,3 +254,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
 
 	return pcibios_enable_irq(dev);
 	return pcibios_enable_irq(dev);
 }
 }
+
+void pcibios_disable_device (struct pci_dev *dev)
+{
+	if (pcibios_disable_irq)
+		pcibios_disable_irq(dev);
+}

+ 1 - 0
arch/i386/pci/irq.c

@@ -56,6 +56,7 @@ struct irq_router_handler {
 };
 };
 
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
 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
  *  Check passed address for the PCI IRQ Routing Table signature

+ 1 - 0
arch/i386/pci/pci.h

@@ -73,3 +73,4 @@ extern int pcibios_scanned;
 extern spinlock_t pci_config_lock;
 extern spinlock_t pci_config_lock;
 
 
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
+extern void (*pcibios_disable_irq)(struct pci_dev *dev);

+ 6 - 6
arch/ppc/kernel/head_44x.S

@@ -179,14 +179,14 @@ skpinv:	addi	r4,r4,1				/* Increment */
 4:
 4:
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 #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 */
  	/* pageid fields */
 	lis	r3,UART0_IO_BASE@h
 	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 */
 	/* xlat fields */
 	lis	r4,UART0_PHYS_IO_BASE@h		/* RPN depends on SoC */
 	lis	r4,UART0_PHYS_IO_BASE@h		/* RPN depends on SoC */
@@ -196,7 +196,7 @@ skpinv:	addi	r4,r4,1				/* Increment */
 	li	r5,0
 	li	r5,0
 	ori	r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
 	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	r3,r0,PPC44x_TLB_PAGEID	/* Load the pageid fields */
 	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
 	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */

+ 3 - 0
arch/ppc/kernel/misc.S

@@ -1451,3 +1451,6 @@ _GLOBAL(sys_call_table)
 	.long sys_waitid
 	.long sys_waitid
 	.long sys_ioprio_set
 	.long sys_ioprio_set
 	.long sys_ioprio_get
 	.long sys_ioprio_get
+	.long sys_inotify_init		/* 275 */
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch

+ 5 - 1
arch/ppc/platforms/4xx/ebony.c

@@ -7,7 +7,7 @@
  * Copyright 2002-2005 MontaVista Software Inc.
  * Copyright 2002-2005 MontaVista Software Inc.
  *
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  * 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
  * 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
  * under  the terms of  the GNU General  Public License as published by the
@@ -50,6 +50,7 @@
 #include <asm/bootinfo.h>
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 
 #include <syslib/gen550.h>
 #include <syslib/gen550.h>
 #include <syslib/ibm440gp_common.h>
 #include <syslib/ibm440gp_common.h>
@@ -248,6 +249,9 @@ ebony_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	/* Configure debug serial access */
 	/* Configure debug serial access */
 	gen550_init(0, &port);
 	gen550_init(0, &port);
+
+	/* Purge TLB entry added in head_44x.S for early serial access */
+	_tlbie(UART0_IO_BASE);
 #endif
 #endif
 
 
 	port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
 	port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);

+ 11 - 2
arch/ppc/platforms/4xx/ebony.h

@@ -56,9 +56,18 @@
  * Serial port defines
  * 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 UART0_IO_BASE	0xE0000200
 #define UART1_IO_BASE	0xE0000300
 #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 */
 /* external Epson SG-615P */
 #define BASE_BAUD	691200
 #define BASE_BAUD	691200
@@ -66,7 +75,7 @@
 #define STD_UART_OP(num)					\
 #define STD_UART_OP(num)					\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
-		iomem_base: UART##num##_IO_BASE,		\
+		iomem_base: (void*)UART##num##_IO_BASE,		\
 		io_type: SERIAL_IO_MEM},
 		io_type: SERIAL_IO_MEM},
 
 
 #define SERIAL_PORT_DFNS	\
 #define SERIAL_PORT_DFNS	\

+ 4 - 0
arch/ppc/platforms/4xx/ocotea.c

@@ -48,6 +48,7 @@
 #include <asm/bootinfo.h>
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 
 #include <syslib/gen550.h>
 #include <syslib/gen550.h>
 #include <syslib/ibm440gx_common.h>
 #include <syslib/ibm440gx_common.h>
@@ -266,6 +267,9 @@ ocotea_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	/* Configure debug serial access */
 	/* Configure debug serial access */
 	gen550_init(0, &port);
 	gen550_init(0, &port);
+
+	/* Purge TLB entry added in head_44x.S for early serial access */
+	_tlbie(UART0_IO_BASE);
 #endif
 #endif
 
 
 	port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
 	port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);

+ 11 - 2
arch/ppc/platforms/4xx/ocotea.h

@@ -55,15 +55,24 @@
  */
  */
 #define RS_TABLE_SIZE	2
 #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 UART0_IO_BASE	0xE0000200
 #define UART1_IO_BASE	0xE0000300
 #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 BASE_BAUD	11059200/16
 #define STD_UART_OP(num)					\
 #define STD_UART_OP(num)					\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
-		iomem_base: UART##num##_IO_BASE,		\
+		iomem_base: (void*)UART##num##_IO_BASE,		\
 		io_type: SERIAL_IO_MEM},
 		io_type: SERIAL_IO_MEM},
 
 
 #define SERIAL_PORT_DFNS	\
 #define SERIAL_PORT_DFNS	\

+ 6 - 0
arch/ppc64/kernel/misc.S

@@ -1129,6 +1129,9 @@ _GLOBAL(sys_call_table32)
 	.llong .compat_sys_waitid
 	.llong .compat_sys_waitid
 	.llong .sys32_ioprio_set
 	.llong .sys32_ioprio_set
 	.llong .sys32_ioprio_get
 	.llong .sys32_ioprio_get
+	.llong .sys_inotify_init	/* 275 */
+	.llong .sys_inotify_add_watch
+	.llong .sys_inotify_rm_watch
 
 
 	.balign 8
 	.balign 8
 _GLOBAL(sys_call_table)
 _GLOBAL(sys_call_table)
@@ -1407,3 +1410,6 @@ _GLOBAL(sys_call_table)
 	.llong .sys_waitid
 	.llong .sys_waitid
 	.llong .sys_ioprio_set
 	.llong .sys_ioprio_set
 	.llong .sys_ioprio_get
 	.llong .sys_ioprio_get
+	.llong .sys_inotify_init	/* 275 */
+	.llong .sys_inotify_add_watch
+	.llong .sys_inotify_rm_watch

+ 15 - 2
arch/x86_64/kernel/mpparse.c

@@ -970,8 +970,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
 		 * due to unused I/O APIC pins.
 		 * due to unused I/O APIC pins.
 		 */
 		 */
 		int irq = gsi;
 		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,
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,

+ 1 - 1
arch/x86_64/lib/csum-copy.S

@@ -188,8 +188,8 @@ csum_partial_copy_generic:
 	source
 	source
 	movw (%rdi),%bx
 	movw (%rdi),%bx
 	adcl %ebx,%eax
 	adcl %ebx,%eax
-	dest
 	decl %ecx
 	decl %ecx
+	dest
 	movw %bx,(%rsi)
 	movw %bx,(%rsi)
 	leaq 2(%rdi),%rdi
 	leaq 2(%rdi),%rdi
 	leaq 2(%rsi),%rsi
 	leaq 2(%rsi),%rsi

+ 722 - 171
drivers/acpi/ec.c

@@ -59,76 +59,185 @@ ACPI_MODULE_NAME		("acpi_ec")
 #define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */
 #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_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_READ	0x80
 #define ACPI_EC_COMMAND_WRITE	0x81
 #define ACPI_EC_COMMAND_WRITE	0x81
 #define ACPI_EC_BURST_ENABLE	0x82
 #define ACPI_EC_BURST_ENABLE	0x82
 #define ACPI_EC_BURST_DISABLE	0x83
 #define ACPI_EC_BURST_DISABLE	0x83
 #define ACPI_EC_COMMAND_QUERY	0x84
 #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_remove (struct acpi_device *device, int type);
 static int acpi_ec_start (struct acpi_device *device);
 static int acpi_ec_start (struct acpi_device *device);
 static int acpi_ec_stop (struct acpi_device *device, int type);
 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 = {
 static struct acpi_driver acpi_ec_driver = {
 	.name =		ACPI_EC_DRIVER_NAME,
 	.name =		ACPI_EC_DRIVER_NAME,
 	.class =	ACPI_EC_CLASS,
 	.class =	ACPI_EC_CLASS,
 	.ids =		ACPI_EC_HID,
 	.ids =		ACPI_EC_HID,
 	.ops =		{
 	.ops =		{
-				.add =		acpi_ec_add,
+				.add =		acpi_ec_burst_add,
 				.remove =	acpi_ec_remove,
 				.remove =	acpi_ec_remove,
 				.start =	acpi_ec_start,
 				.start =	acpi_ec_start,
 				.stop =		acpi_ec_stop,
 				.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 */
 /* 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 */
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
 static struct acpi_device *first_ec;
+static int acpi_ec_polling_mode;
 
 
 /* --------------------------------------------------------------------------
 /* --------------------------------------------------------------------------
                              Transaction Management
                              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;
 	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;
 	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;
 	int	result = 0;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_wait");
 	ACPI_FUNCTION_TRACE("acpi_ec_wait");
 
 
-	ec->expect_event = event;
+	ec->burst.expect_event = event;
 	smp_mb();
 	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));
 					msecs_to_jiffies(ACPI_EC_DELAY));
 	
 	
-	ec->expect_event = 0;
+	ec->burst.expect_event = 0;
 	smp_mb();
 	smp_mb();
 
 
 	if (result < 0){
 	if (result < 0){
@@ -160,7 +269,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
 
 
 static int
 static int
 acpi_ec_enter_burst_mode (
 acpi_ec_enter_burst_mode (
-	struct acpi_ec		*ec)
+	union acpi_ec		*ec)
 {
 {
 	u32			tmp = 0;
 	u32			tmp = 0;
 	int			status = 0;
 	int			status = 0;
@@ -170,43 +279,43 @@ acpi_ec_enter_burst_mode (
 	status = acpi_ec_read_status(ec);
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL &&
 	if (status != -EINVAL &&
 		!(status & ACPI_EC_FLAG_BURST)){
 		!(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);
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 		if (status){
 		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);
 			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*/
 		if(tmp != 0x90 ) {/* Burst ACK byte*/
 			return_VALUE(-EINVAL);
 			return_VALUE(-EINVAL);
 		}
 		}
 	}
 	}
 
 
-	atomic_set(&ec->leaving_burst , 0);
+	atomic_set(&ec->burst.leaving_burst , 0);
 	return_VALUE(0);
 	return_VALUE(0);
 }
 }
 
 
 static int
 static int
 acpi_ec_leave_burst_mode (
 acpi_ec_leave_burst_mode (
-	struct acpi_ec		*ec)
+	union acpi_ec		*ec)
 {
 {
 	int			status =0;
 	int			status =0;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
 	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);
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL &&
 	if (status != -EINVAL &&
 		(status & ACPI_EC_FLAG_BURST)){
 		(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);
 		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
 		if (status){
 		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"));
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
 			return_VALUE(-EINVAL);
 			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);
 		status = acpi_ec_read_status(ec);
 	}
 	}
 
 
@@ -215,7 +324,131 @@ acpi_ec_leave_burst_mode (
 
 
 static int
 static int
 acpi_ec_read (
 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,
 	u8			address,
 	u32			*data)
 	u32			*data)
 {
 {
@@ -230,51 +463,51 @@ acpi_ec_read (
 retry:
 retry:
 	*data = 0;
 	*data = 0;
 
 
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 			return_VALUE(-ENODEV);
 	}
 	}
 
 
 	WARN_ON(in_interrupt());
 	WARN_ON(in_interrupt());
-	down(&ec->sem);
+	down(&ec->burst.sem);
 
 
 	if(acpi_ec_enter_burst_mode(ec))
 	if(acpi_ec_enter_burst_mode(ec))
 		goto end;
 		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);
 	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) {
 	if (status) {
 		goto end;
 		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);
 	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
 	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;
 		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",
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
 		*data, address));
 	
 	
 end:
 end:
 	acpi_ec_leave_burst_mode(ec);
 	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);
 		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_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->pending_gpe)){
+		while(atomic_read(&ec->burst.pending_gpe)){
 			msleep(1);	
 			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;
 		goto retry;
 	}
 	}
 
 
@@ -283,8 +516,8 @@ acpi_ec_read (
 
 
 
 
 static int
 static int
-acpi_ec_write (
-	struct acpi_ec		*ec,
+acpi_ec_burst_write (
+	union acpi_ec		*ec,
 	u8			address,
 	u8			address,
 	u8			data)
 	u8			data)
 {
 {
@@ -297,14 +530,14 @@ acpi_ec_write (
 	if (!ec)
 	if (!ec)
 		return_VALUE(-EINVAL);
 		return_VALUE(-EINVAL);
 retry:
 retry:
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 			return_VALUE(-ENODEV);
 	}
 	}
 
 
 	WARN_ON(in_interrupt());
 	WARN_ON(in_interrupt());
-	down(&ec->sem);
+	down(&ec->burst.sem);
 
 
 	if(acpi_ec_enter_burst_mode(ec))
 	if(acpi_ec_enter_burst_mode(ec))
 		goto end;
 		goto end;
@@ -312,33 +545,33 @@ acpi_ec_write (
 	status = acpi_ec_read_status(ec);
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL &&
 	if (status != -EINVAL &&
 		!(status & ACPI_EC_FLAG_BURST)){
 		!(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);
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 		if (status)
 		if (status)
 			goto end;
 			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*/
 		if(tmp != 0x90 ) /* Burst ACK byte*/
 			goto end;
 			goto end;
 	}
 	}
 	/*Now we are in burst mode*/
 	/*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);
 	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){
 	if (status){
 		goto end;
 		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);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status){
 	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;
 		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);
 	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)
 	if (status)
 		goto end;
 		goto end;
 
 
@@ -347,17 +580,17 @@ acpi_ec_write (
 
 
 end:
 end:
 	acpi_ec_leave_burst_mode(ec);
 	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);
 		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_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->pending_gpe)){
+		while(atomic_read(&ec->burst.pending_gpe)){
 			msleep(1);	
 			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;
 		goto retry;
 	}
 	}
 
 
@@ -370,7 +603,7 @@ acpi_ec_write (
 int
 int
 ec_read(u8 addr, u8 *val)
 ec_read(u8 addr, u8 *val)
 {
 {
-	struct acpi_ec *ec;
+	union acpi_ec *ec;
 	int err;
 	int err;
 	u32 temp_data;
 	u32 temp_data;
 
 
@@ -393,7 +626,7 @@ EXPORT_SYMBOL(ec_read);
 int
 int
 ec_write(u8 addr, u8 val)
 ec_write(u8 addr, u8 val)
 {
 {
-	struct acpi_ec *ec;
+	union acpi_ec *ec;
 	int err;
 	int err;
 
 
 	if (!first_ec)
 	if (!first_ec)
@@ -407,10 +640,66 @@ ec_write(u8 addr, u8 val)
 }
 }
 EXPORT_SYMBOL(ec_write);
 EXPORT_SYMBOL(ec_write);
 
 
-
 static int
 static int
 acpi_ec_query (
 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)
 	u32			*data)
 {
 {
 	int			status = 0;
 	int			status = 0;
@@ -422,13 +711,13 @@ acpi_ec_query (
 		return_VALUE(-EINVAL);
 		return_VALUE(-EINVAL);
 	*data = 0;
 	*data = 0;
 
 
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 			return_VALUE(-ENODEV);
 	}
 	}
 
 
-	down(&ec->sem);
+	down(&ec->burst.sem);
 	if(acpi_ec_enter_burst_mode(ec))
 	if(acpi_ec_enter_burst_mode(ec))
 		goto end;
 		goto end;
 	/*
 	/*
@@ -436,28 +725,28 @@ acpi_ec_query (
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 * 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);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
 	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;
 		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)
 	if (!*data)
 		status = -ENODATA;
 		status = -ENODATA;
 
 
 end:
 end:
 	acpi_ec_leave_burst_mode(ec);
 	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);
 		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_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;
 		status = -ENODATA;
 	}
 	}
 	return_VALUE(status);
 	return_VALUE(status);
@@ -468,7 +757,7 @@ acpi_ec_query (
                                 Event Management
                                 Event Management
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */
 
 
-struct acpi_ec_query_data {
+union acpi_ec_query_data {
 	acpi_handle		handle;
 	acpi_handle		handle;
 	u8			data;
 	u8			data;
 };
 };
@@ -477,7 +766,59 @@ static void
 acpi_ec_gpe_query (
 acpi_ec_gpe_query (
 	void			*ec_cxt)
 	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;
 	u32			value;
 	int			result = -ENODATA;
 	int			result = -ENODATA;
 	static char		object_name[5] = {'_','Q','0','0','\0'};
 	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_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:	
 end:	
-	atomic_dec(&ec->pending_gpe);
+	atomic_dec(&ec->burst.pending_gpe);
 	return;
 	return;
 }
 }
 
 
 static u32
 static u32
 acpi_ec_gpe_handler (
 acpi_ec_gpe_handler (
 	void			*data)
 	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;
 	acpi_status		status = AE_OK;
 	u32			value;
 	u32			value;
-	struct acpi_ec		*ec = (struct acpi_ec *) data;
+	union acpi_ec		*ec = (union acpi_ec *) data;
 
 
 	if (!ec)
 	if (!ec)
 		return ACPI_INTERRUPT_NOT_HANDLED;
 		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);
 	value = acpi_ec_read_status(ec);
 
 
 	if((value & ACPI_EC_FLAG_IBF) &&
 	if((value & ACPI_EC_FLAG_IBF) &&
 		!(value & ACPI_EC_FLAG_BURST) &&
 		!(value & ACPI_EC_FLAG_BURST) &&
-			(atomic_read(&ec->leaving_burst) == 0)) { 
+			(atomic_read(&ec->burst.leaving_burst) == 0)) { 
 	/*
 	/*
 	 * the embedded controller disables 
 	 * the embedded controller disables 
 	 * burst mode for any reason other 
 	 * burst mode for any reason other 
 	 * than the burst disable command
 	 * than the burst disable command
 	 * to process critical event.
 	 * 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 */
 					and retry */
-		wake_up(&ec->wait);
+		wake_up(&ec->burst.wait);
 	}else {
 	}else {
-		if ((ec->expect_event == ACPI_EC_EVENT_OBF &&
+		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
 				(value & ACPI_EC_FLAG_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))) {
 				!(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;
 			return ACPI_INTERRUPT_HANDLED;
 		}
 		}
 	}
 	}
 
 
 	if (value & ACPI_EC_FLAG_SCI){
 	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,
 		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
 						acpi_ec_gpe_query, ec);
 						acpi_ec_gpe_query, ec);
 		return status == AE_OK ?
 		return status == AE_OK ?
 		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 		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 ?
 	return status == AE_OK ?
 		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
 }
@@ -585,7 +955,7 @@ acpi_ec_space_handler (
 	void			*region_context)
 	void			*region_context)
 {
 {
 	int			result = 0;
 	int			result = 0;
-	struct acpi_ec		*ec = NULL;
+	union acpi_ec		*ec = NULL;
 	u64			temp = *value;
 	u64			temp = *value;
 	acpi_integer		f_v = 0;
 	acpi_integer		f_v = 0;
 	int 			i = 0;
 	int 			i = 0;
@@ -600,7 +970,7 @@ acpi_ec_space_handler (
 		return_VALUE(AE_BAD_PARAMETER);
 		return_VALUE(AE_BAD_PARAMETER);
 	}
 	}
 
 
-	ec = (struct acpi_ec *) handler_context;
+	ec = (union acpi_ec *) handler_context;
 
 
 next_byte:
 next_byte:
 	switch (function) {
 	switch (function) {
@@ -661,7 +1031,7 @@ static struct proc_dir_entry	*acpi_ec_dir;
 static int
 static int
 acpi_ec_read_info (struct seq_file *seq, void *offset)
 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");
 	ACPI_FUNCTION_TRACE("acpi_ec_read_info");
 
 
@@ -669,12 +1039,12 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
 		goto end;
 		goto end;
 
 
 	seq_printf(seq, "gpe bit:                 0x%02x\n",
 	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",
 	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",
 	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:
 end:
 	return_VALUE(0);
 	return_VALUE(0);
@@ -697,7 +1067,7 @@ static int
 acpi_ec_add_fs (
 acpi_ec_add_fs (
 	struct acpi_device	*device)
 	struct acpi_device	*device)
 {
 {
-	struct proc_dir_entry	*entry;
+	struct proc_dir_entry	*entry = NULL;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
 	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
 
 
@@ -744,13 +1114,82 @@ acpi_ec_remove_fs (
                                Driver Interface
                                Driver Interface
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */
 
 
+
 static int
 static int
-acpi_ec_add (
+acpi_ec_polling_add (
 	struct acpi_device	*device)
 	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;
 	unsigned long		uid;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_add");
 	ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -758,39 +1197,39 @@ acpi_ec_add (
 	if (!device)
 	if (!device)
 		return_VALUE(-EINVAL);
 		return_VALUE(-EINVAL);
 
 
-	ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
 	if (!ec)
 	if (!ec)
 		return_VALUE(-ENOMEM);
 		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_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
 	acpi_driver_data(device) = ec;
 
 
 	/* Use the global lock for all EC transactions? */
 	/* 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,
 	/* If our UID matches the UID for the ECDT-enumerated EC,
 	   we now have the *real* EC info, so kill the makeshift one.*/
 	   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_remove_address_space_handler(ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 			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);
 		kfree(ec_ecdt);
 	}
 	}
 
 
 	/* Get GPE bit assignment (EC events). */
 	/* Get GPE bit assignment (EC events). */
 	/* TODO: Add support for _GPE returning a package */
 	/* 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)) {
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 			"Error obtaining GPE bit assignment\n"));
 			"Error obtaining GPE bit assignment\n"));
@@ -804,7 +1243,7 @@ acpi_ec_add (
 
 
 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
 		acpi_device_name(device), acpi_device_bid(device),
 		acpi_device_name(device), acpi_device_bid(device),
-		(u32) ec->gpe_bit);
+		(u32) ec->common.gpe_bit);
 
 
 	if (!first_ec)
 	if (!first_ec)
 		first_ec = device;
 		first_ec = device;
@@ -822,7 +1261,7 @@ acpi_ec_remove (
 	struct acpi_device	*device,
 	struct acpi_device	*device,
 	int			type)
 	int			type)
 {
 {
-	struct acpi_ec		*ec;
+	union acpi_ec		*ec = NULL;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_remove");
 	ACPI_FUNCTION_TRACE("acpi_ec_remove");
 
 
@@ -844,7 +1283,7 @@ acpi_ec_io_ports (
 	struct acpi_resource	*resource,
 	struct acpi_resource	*resource,
 	void			*context)
 	void			*context)
 {
 {
-	struct acpi_ec		*ec = (struct acpi_ec *) context;
+	union acpi_ec		*ec = (union acpi_ec *) context;
 	struct acpi_generic_address *addr;
 	struct acpi_generic_address *addr;
 
 
 	if (resource->id != ACPI_RSTYPE_IO) {
 	if (resource->id != ACPI_RSTYPE_IO) {
@@ -856,10 +1295,10 @@ acpi_ec_io_ports (
 	 * the second address region returned is the status/command
 	 * the second address region returned is the status/command
 	 * port.
 	 * 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 {
 	} else {
 		return AE_CTRL_TERMINATE;
 		return AE_CTRL_TERMINATE;
 	}
 	}
@@ -877,8 +1316,8 @@ static int
 acpi_ec_start (
 acpi_ec_start (
 	struct acpi_device	*device)
 	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");
 	ACPI_FUNCTION_TRACE("acpi_ec_start");
 
 
@@ -893,35 +1332,36 @@ acpi_ec_start (
 	/*
 	/*
 	 * Get I/O port addresses. Convert to GAS format.
 	 * 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);
 		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"));
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
 		return_VALUE(-ENODEV);
 		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",
 	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
 	 * 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);
 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status)) {
 	if (ACPI_FAILURE(status)) {
 		return_VALUE(-ENODEV);
 		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_ADR_SPACE_EC, &acpi_ec_space_handler,
 			&acpi_ec_space_setup, ec);
 			&acpi_ec_space_setup, ec);
 	if (ACPI_FAILURE(status)) {
 	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);
 		return_VALUE(-ENODEV);
 	}
 	}
 
 
@@ -934,8 +1374,8 @@ acpi_ec_stop (
 	struct acpi_device	*device,
 	struct acpi_device	*device,
 	int			type)
 	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");
 	ACPI_FUNCTION_TRACE("acpi_ec_stop");
 
 
@@ -944,12 +1384,12 @@ acpi_ec_stop (
 
 
 	ec = acpi_driver_data(device);
 	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);
 		ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 	if (ACPI_FAILURE(status))
 	if (ACPI_FAILURE(status))
 		return_VALUE(-ENODEV);
 		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))
 	if (ACPI_FAILURE(status))
 		return_VALUE(-ENODEV);
 		return_VALUE(-ENODEV);
 
 
@@ -963,26 +1403,76 @@ acpi_fake_ecdt_callback (
 	void		*context,
 	void		*context,
 	void		**retval)
 	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;
 	acpi_status	status;
 
 
+	init_MUTEX(&ec_ecdt->burst.sem);
+	init_waitqueue_head(&ec_ecdt->burst.wait);
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 		acpi_ec_io_ports, ec_ecdt);
 		acpi_ec_io_ports, ec_ecdt);
 	if (ACPI_FAILURE(status))
 	if (ACPI_FAILURE(status))
 		return 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))
 	if (ACPI_FAILURE(status))
 		return 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",
 	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;
 	return AE_CTRL_TERMINATE;
 }
 }
@@ -1005,12 +1495,12 @@ acpi_ec_fake_ecdt(void)
 
 
 	printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
 	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) {
 	if (!ec_ecdt) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto error;
 		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,
 	status = acpi_get_devices (ACPI_EC_HID,
 				acpi_fake_ecdt_callback,
 				acpi_fake_ecdt_callback,
@@ -1030,6 +1520,60 @@ acpi_ec_fake_ecdt(void)
 
 
 static int __init
 static int __init
 acpi_ec_get_real_ecdt(void)
 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;
 	acpi_status		status;
 	struct acpi_table_ecdt 	*ecdt_ptr;
 	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
 	 * 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)
 	if (!ec_ecdt)
 		return -ENOMEM;
 		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 */
 	/* 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)) {
 	if (ACPI_FAILURE(status)) {
 		goto error;
 		goto error;
 	}
 	}
@@ -1092,20 +1636,20 @@ acpi_ec_ecdt_probe (void)
 	/*
 	/*
 	 * Install GPE handler
 	 * 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,
 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
 		ec_ecdt);
 		ec_ecdt);
 	if (ACPI_FAILURE(status)) {
 	if (ACPI_FAILURE(status)) {
 		goto error;
 		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,
 	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
 			&acpi_ec_space_setup, ec_ecdt);
 			&acpi_ec_space_setup, ec_ecdt);
 	if (ACPI_FAILURE(status)) {
 	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);
 			&acpi_ec_gpe_handler);
 		goto error;
 		goto error;
 	}
 	}
@@ -1123,7 +1667,7 @@ acpi_ec_ecdt_probe (void)
 
 
 static int __init acpi_ec_init (void)
 static int __init acpi_ec_init (void)
 {
 {
-	int			result;
+	int			result = 0;
 
 
 	ACPI_FUNCTION_TRACE("acpi_ec_init");
 	ACPI_FUNCTION_TRACE("acpi_ec_init");
 
 
@@ -1167,3 +1711,10 @@ static int __init acpi_fake_ecdt_setup(char *str)
 	return 0;
 	return 0;
 }
 }
 __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
 __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);

+ 59 - 26
drivers/acpi/pci_irq.c

@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int bus)
 /* --------------------------------------------------------------------------
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
                           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
  * acpi_pci_irq_lookup
  * success: return IRQ >= 0
  * success: return IRQ >= 0
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup (
 	int			pin,
 	int			pin,
 	int			*edge_level,
 	int			*edge_level,
 	int			*active_high_low,
 	int			*active_high_low,
-	char			**link)
+	char			**link,
+	irq_lookup_func		func)
 {
 {
 	struct acpi_prt_entry	*entry = NULL;
 	struct acpi_prt_entry	*entry = NULL;
 	int segment = pci_domain_nr(bus);
 	int segment = pci_domain_nr(bus);
 	int bus_nr = bus->number;
 	int bus_nr = bus->number;
-	int irq;
+	int ret;
 
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
 
 
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup (
 		return_VALUE(-1);
 		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			pin,
 	int			*edge_level,
 	int			*edge_level,
 	int			*active_high_low,
 	int			*active_high_low,
-	char			**link)
+	char			**link,
+	irq_lookup_func		func)
 {
 {
 	struct pci_dev		*bridge = dev;
 	struct pci_dev		*bridge = dev;
 	int			irq = -1;
 	int			irq = -1;
@@ -363,7 +395,7 @@ acpi_pci_irq_derive (
 		}
 		}
 
 
 		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
 		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) {
 	if (irq < 0) {
@@ -415,7 +447,7 @@ acpi_pci_irq_enable (
 	 * values override any BIOS-assigned IRQs set during boot.
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
 	 */
  	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
  	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
 	 * 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)
 	if (irq < 0)
  		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
  		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 / 
 	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
@@ -462,7 +494,9 @@ acpi_pci_irq_enable (
 EXPORT_SYMBOL(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
 void
 acpi_pci_irq_disable (
 acpi_pci_irq_disable (
 	struct pci_dev		*dev)
 	struct pci_dev		*dev)
@@ -489,14 +523,14 @@ acpi_pci_irq_disable (
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
 	 */
  	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
  	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
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 * device's parent bridge.
 	 */
 	 */
 	if (gsi < 0)
 	if (gsi < 0)
  		gsi = acpi_pci_irq_derive(dev, pin,
  		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)
 	if (gsi < 0)
 		return_VOID;
 		return_VOID;
 
 
@@ -512,4 +546,3 @@ acpi_pci_irq_disable (
 
 
 	return_VOID;
 	return_VOID;
 }
 }
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */

+ 87 - 16
drivers/acpi/pci_link.c

@@ -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 {
 struct acpi_pci_link_irq {
 	u8			active;			/* Current IRQ */
 	u8			active;			/* Current IRQ */
 	u8			edge_level;		/* All IRQs */
 	u8			edge_level;		/* All IRQs */
@@ -76,8 +80,7 @@ struct acpi_pci_link_irq {
 	u8			possible_count;
 	u8			possible_count;
 	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 	u8			initialized:1;
 	u8			initialized:1;
-	u8			suspend_resume:1;
-	u8			reserved:6;
+	u8			reserved:7;
 };
 };
 
 
 struct acpi_pci_link {
 struct acpi_pci_link {
@@ -85,12 +88,14 @@ struct acpi_pci_link {
 	struct acpi_device	*device;
 	struct acpi_device	*device;
 	acpi_handle		handle;
 	acpi_handle		handle;
 	struct acpi_pci_link_irq irq;
 	struct acpi_pci_link_irq irq;
+	int			refcnt;
 };
 };
 
 
 static struct {
 static struct {
 	int			count;
 	int			count;
 	struct list_head	entries;
 	struct list_head	entries;
 }				acpi_link;
 }				acpi_link;
+DECLARE_MUTEX(acpi_link_lock);
 
 
 
 
 /* --------------------------------------------------------------------------
 /* --------------------------------------------------------------------------
@@ -532,12 +537,12 @@ static int acpi_pci_link_allocate(
 
 
 	ACPI_FUNCTION_TRACE("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);
 		return_VALUE(0);
+	}
 
 
 	/*
 	/*
 	 * search for active IRQ in list of possible IRQs.
 	 * 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
  * success: return IRQ >= 0
  * failure: return -1
  * failure: return -1
  */
  */
 
 
 int
 int
-acpi_pci_link_get_irq (
+acpi_pci_link_allocate_irq (
 	acpi_handle		handle,
 	acpi_handle		handle,
 	int			index,
 	int			index,
 	int			*edge_level,
 	int			*edge_level,
@@ -613,7 +618,7 @@ acpi_pci_link_get_irq (
 	struct acpi_device	*device = NULL;
 	struct acpi_device	*device = NULL;
 	struct acpi_pci_link	*link = 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);
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
 	if (result) {
@@ -633,21 +638,70 @@ acpi_pci_link_get_irq (
 		return_VALUE(-1);
 		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);
 		return_VALUE(-1);
+	}
 	   
 	   
 	if (!link->irq.active) {
 	if (!link->irq.active) {
+		up(&acpi_link_lock);
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
 		return_VALUE(-1);
 		return_VALUE(-1);
 	}
 	}
+	link->refcnt ++;
+	up(&acpi_link_lock);
 
 
 	if (edge_level) *edge_level = link->irq.edge_level;
 	if (edge_level) *edge_level = link->irq.edge_level;
 	if (active_high_low) *active_high_low = link->irq.active_high_low;
 	if (active_high_low) *active_high_low = link->irq.active_high_low;
 	if (name) *name = acpi_device_bid(link->device);
 	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);
 	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
                                  Driver Interface
    -------------------------------------------------------------------------- */
    -------------------------------------------------------------------------- */
@@ -677,6 +731,7 @@ acpi_pci_link_add (
 	strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
 	strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
 	acpi_driver_data(device) = link;
 	acpi_driver_data(device) = link;
 
 
+	down(&acpi_link_lock);
 	result = acpi_pci_link_get_possible(link);
 	result = acpi_pci_link_get_possible(link);
 	if (result)
 	if (result)
 		goto end;
 		goto end;
@@ -712,6 +767,7 @@ acpi_pci_link_add (
 end:
 end:
 	/* disable all links -- to be activated on use */
 	/* disable all links -- to be activated on use */
 	acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
 	acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+	up(&acpi_link_lock);
 
 
 	if (result)
 	if (result)
 		kfree(link);
 		kfree(link);
@@ -726,19 +782,32 @@ irqrouter_suspend(
 {
 {
 	struct list_head        *node = NULL;
 	struct list_head        *node = NULL;
 	struct acpi_pci_link    *link = NULL;
 	struct acpi_pci_link    *link = NULL;
+	int			ret = 0;
 
 
 	ACPI_FUNCTION_TRACE("irqrouter_suspend");
 	ACPI_FUNCTION_TRACE("irqrouter_suspend");
 
 
 	list_for_each(node, &acpi_link.entries) {
 	list_for_each(node, &acpi_link.entries) {
 		link = list_entry(node, struct acpi_pci_link, node);
 		link = list_entry(node, struct acpi_pci_link, node);
 		if (!link) {
 		if (!link) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Invalid link context\n"));
 			continue;
 			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);
 	link = (struct acpi_pci_link *) acpi_driver_data(device);
 
 
-	/* TBD: Acquire/release lock */
+	down(&acpi_link_lock);
 	list_del(&link->node);
 	list_del(&link->node);
+	up(&acpi_link_lock);
 
 
 	kfree(link);
 	kfree(link);
 
 
@@ -849,6 +919,7 @@ int __init acpi_irq_balance_set(char *str)
 __setup("acpi_irq_balance", acpi_irq_balance_set);
 __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 = {
 static struct sysdev_class irqrouter_sysdev_class = {
         set_kset_name("irqrouter"),
         set_kset_name("irqrouter"),
         .suspend = irqrouter_suspend,
         .suspend = irqrouter_suspend,

+ 17 - 14
drivers/acpi/processor_idle.c

@@ -81,30 +81,33 @@ module_param(bm_history, uint, 0644);
  *
  *
  * To skip this limit, boot/load with a large max_cstate limit.
  * 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)
 	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
 		return 0;
 		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,
 		" Override with \"processor.max_cstate=%d\"\n", id->ident,
+		((int)id->driver_data == 1)? "C2,C3":"C3",
 	       ACPI_PROCESSOR_MAX_POWER + 1);
 	       ACPI_PROCESSOR_MAX_POWER + 1);
 
 
-	max_cstate = 1;
+	max_cstate = (int)id->driver_data;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 
 
-
-
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
 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_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_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");
 	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
 
 
 	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
 	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 */
 	/* if info is obtained from pblk/fadt, type equals state */
 	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
 	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;
 	pr->power.count = 0;
 	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
 	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);
 	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
 	if (ACPI_FAILURE(status)) {
@@ -763,7 +768,6 @@ static void acpi_processor_power_verify_c3(
 	}
 	}
 
 
 	if (pr->flags.bm_check) {
 	if (pr->flags.bm_check) {
-		printk("Disabling BM access before entering C3\n");
 		/* bus mastering control is necessary */
 		/* bus mastering control is necessary */
 		if (!pr->flags.bm_control) {
 		if (!pr->flags.bm_control) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -771,7 +775,6 @@ static void acpi_processor_power_verify_c3(
 			return_VOID;
 			return_VOID;
 		}
 		}
 	} else {
 	} else {
-		printk("Invalidating cache before entering C3\n");
 		/*
 		/*
 		 * WBINVD should be set in fadt, for C3 state to be
 		 * WBINVD should be set in fadt, for C3 state to be
 		 * supported on when bm_check is not required.
 		 * 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);
 	result = acpi_processor_get_power_info_cst(pr);
 	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
 	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
 		result = acpi_processor_get_power_info_fadt(pr);
 		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);
 			result = acpi_processor_get_power_info_default_c1(pr);
 	}
 	}
 
 

+ 77 - 0
drivers/net/sk98lin/skge.c

@@ -5133,6 +5133,81 @@ static void __devexit skge_remove_one(struct pci_dev *pdev)
 	kfree(pAC);
 	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[] = {
 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, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_3COM, 0x80eb, 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,
 	.id_table	= skge_pci_tbl,
 	.probe		= skge_probe_one,
 	.probe		= skge_probe_one,
 	.remove		= __devexit_p(skge_remove_one),
 	.remove		= __devexit_p(skge_remove_one),
+	.suspend	= skge_suspend,
+	.resume		= skge_resume,
 };
 };
 
 
 static int __init skge_init(void)
 static int __init skge_init(void)

+ 0 - 9
drivers/pcmcia/yenta_socket.c

@@ -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_read_config_dword(dev, 17*4, &socket->saved_state[1]);
 		pci_disable_device(dev);
 		pci_disable_device(dev);
 
 
-		free_irq(dev->irq, socket);
-
 		/*
 		/*
 		 * Some laptops (IBM T22) do not like us putting the Cardbus
 		 * Some laptops (IBM T22) do not like us putting the Cardbus
 		 * bridge into D3.  At a guess, some other laptop will
 		 * 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_enable_device(dev);
 		pci_set_master(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)
 		if (socket->type && socket->type->restore_state)
 			socket->type->restore_state(socket);
 			socket->type->restore_state(socket);
 	}
 	}

+ 2 - 1
include/acpi/acpi_drivers.h

@@ -56,8 +56,9 @@
 /* ACPI PCI Interrupt Link (pci_link.c) */
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
 
 int acpi_irq_penalty_init (void);
 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 *active_high_low, char **name);
+int acpi_pci_link_free_irq(acpi_handle handle);
 
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
 

+ 4 - 1
include/asm-ppc/unistd.h

@@ -279,8 +279,11 @@
 #define __NR_waitid		272
 #define __NR_waitid		272
 #define __NR_ioprio_set		273
 #define __NR_ioprio_set		273
 #define __NR_ioprio_get		274
 #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
 #define __NR(n)	#n
 
 

+ 4 - 1
include/asm-ppc64/unistd.h

@@ -285,8 +285,11 @@
 #define __NR_waitid		272
 #define __NR_waitid		272
 #define __NR_ioprio_set		273
 #define __NR_ioprio_set		273
 #define __NR_ioprio_get		274
 #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__
 #ifdef __KERNEL__
 #define NR_syscalls	__NR_syscalls
 #define NR_syscalls	__NR_syscalls
 #endif
 #endif

+ 0 - 4
include/linux/acpi.h

@@ -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
  * If this matches the last registration, any IRQ resources for gsi
  * are freed.
  * are freed.
  */
  */
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_unregister_gsi (u32 gsi);
 void acpi_unregister_gsi (u32 gsi);
-#endif
 
 
 #ifdef CONFIG_ACPI_PCI
 #ifdef CONFIG_ACPI_PCI
 
 
@@ -480,9 +478,7 @@ struct pci_dev;
 int acpi_pci_irq_enable (struct pci_dev *dev);
 int acpi_pci_irq_enable (struct pci_dev *dev);
 void acpi_penalize_isa_irq(int irq, int active);
 void acpi_penalize_isa_irq(int irq, int active);
 
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_pci_irq_disable (struct pci_dev *dev);
 void acpi_pci_irq_disable (struct pci_dev *dev);
-#endif
 
 
 struct acpi_pci_driver {
 struct acpi_pci_driver {
 	struct acpi_pci_driver *next;
 	struct acpi_pci_driver *next;

+ 2 - 2
kernel/softirq.c

@@ -86,7 +86,7 @@ asmlinkage void __do_softirq(void)
 	/* Reset the pending bitmask before enabling irqs */
 	/* Reset the pending bitmask before enabling irqs */
 	local_softirq_pending() = 0;
 	local_softirq_pending() = 0;
 
 
-	//local_irq_enable();
+	local_irq_enable();
 
 
 	h = softirq_vec;
 	h = softirq_vec;
 
 
@@ -99,7 +99,7 @@ asmlinkage void __do_softirq(void)
 		pending >>= 1;
 		pending >>= 1;
 	} while (pending);
 	} while (pending);
 
 
-	//local_irq_disable();
+	local_irq_disable();
 
 
 	pending = local_softirq_pending();
 	pending = local_softirq_pending();
 	if (pending && --max_restart)
 	if (pending && --max_restart)

+ 10 - 11
mm/page_alloc.c

@@ -1061,20 +1061,19 @@ unsigned int nr_free_pages_pgdat(pg_data_t *pgdat)
 
 
 static unsigned int nr_free_zone_pages(int offset)
 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;
 	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;
 	return sum;

+ 6 - 1
sound/pci/intel8x0.c

@@ -2376,6 +2376,9 @@ static int intel8x0_suspend(snd_card_t *card, pm_message_t state)
 			snd_ac97_suspend(chip->ac97[i]);
 			snd_ac97_suspend(chip->ac97[i]);
 	if (chip->device_type == DEVICE_INTEL_ICH4)
 	if (chip->device_type == DEVICE_INTEL_ICH4)
 		chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
 		chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
+
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
 	pci_disable_device(chip->pci);
 	pci_disable_device(chip->pci);
 	return 0;
 	return 0;
 }
 }
@@ -2387,7 +2390,9 @@ static int intel8x0_resume(snd_card_t *card)
 
 
 	pci_enable_device(chip->pci);
 	pci_enable_device(chip->pci);
 	pci_set_master(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 */
 	/* re-initialize mixer stuff */
 	if (chip->device_type == DEVICE_INTEL_ICH4) {
 	if (chip->device_type == DEVICE_INTEL_ICH4) {