]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 18:52:52 +0000 (11:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 18:52:52 +0000 (11:52 -0700)
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits)
  ACPI: Fix acpi_processor_idle and idle= boot parameters interaction
  acpi: fix section mismatch warning in pnpacpi
  intel_menlo: fix build warning
  ACPI: Cleanup: Remove unneeded, multiple local dummy variables
  ACPI: video - fix permissions on some proc entries
  ACPI: video - properly handle errors when registering proc elements
  ACPI: video - do not store invalid entries in attached_array list
  ACPI: re-name acpi_pm_ops to acpi_suspend_ops
  ACER_WMI/ASUS_LAPTOP: fix build bug
  thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed
  ACPI: check a return value correctly in acpi_power_get_context()
  #if 0 acpi/bay.c:eject_removable_drive()
  eeepc-laptop: add hwmon fan control
  eeepc-laptop: add backlight
  eeepc-laptop: add base driver
  ACPI: thinkpad-acpi: bump up version to 0.20
  ACPI: thinkpad-acpi: fix selects in Kconfig
  ACPI: thinkpad-acpi: use a private workqueue
  ACPI: thinkpad-acpi: fluff really minor fix
  ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
  ...

Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c
manually.

1  2 
MAINTAINERS
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/pnp/pnpbios/proc.c
include/linux/pnp.h

diff --combined MAINTAINERS
index f8d6de111479dad7fc91561bba6ae22298b1f64a,37debda366616e11afb337d3866e2827225815e5..c3a533d5d3824ce0bd7d4c78e1a5d5a6824e1078
@@@ -752,13 -752,11 +752,13 @@@ W:      http://atmelwlandriver.sourceforge.n
  S:    Maintained
  
  AUDIT SUBSYSTEM
 -P:    David Woodhouse
 -M:    dwmw2@infradead.org
 +P:    Al Viro
 +M:    viro@zeniv.linux.org.uk
 +P:    Eric Paris
 +M:    eparis@redhat.com
  L:    linux-audit@redhat.com (subscribers-only)
  W:    http://people.redhat.com/sgrubb/audit/
 -T:    git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git
 +T:    git git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git
  S:    Maintained
  
  AUXILIARY DISPLAY DRIVERS
@@@ -1039,7 -1037,7 +1039,7 @@@ P:      Urs Thuerman
  M:    urs.thuermann@volkswagen.de
  P:    Oliver Hartkopp
  M:    oliver.hartkopp@volkswagen.de
 -L:    socketcan-core@lists.berlios.de
 +L:    socketcan-core@lists.berlios.de (subscribers-only)
  W:    http://developer.berlios.de/projects/socketcan/
  S:    Maintained
  
@@@ -1533,6 -1531,13 +1533,13 @@@ L:    bluesmoke-devel@lists.sourceforge.ne
  W:    bluesmoke.sourceforge.net
  S:    Maintained
  
+ EEEPC LAPTOP EXTRAS DRIVER
+ P:    Corentin Chary
+ M:    corentincj@iksaif.net
+ L:    acpi4asus-user@lists.sourceforge.net
+ W:    http://sourceforge.net/projects/acpi4asus
+ S:    Maintained
  EEPRO100 NETWORK DRIVER
  P:    Andrey V. Savochkin
  M:    saw@saw.sw.com.sg
@@@ -2696,7 -2701,7 +2703,7 @@@ P:      David Howell
  M:    dhowells@redhat.com
  P:    Koichi Yasutake
  M:    yasutake.koichi@jp.panasonic.com
 -L:    linux-am33-list@redhat.com
 +L:    linux-am33-list@redhat.com (moderated for non-subscribers)
  W:    ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/
  S:    Maintained
  
@@@ -2759,7 -2764,7 +2766,7 @@@ M:      rubini@ipvvis.unipv.i
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  
 -MOXA SMARTIO/INDUSTIO SERIAL CARD (MXSER 2.0)
 +MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
  P:    Jiri Slaby
  M:    jirislaby@gmail.com
  L:    linux-kernel@vger.kernel.org
@@@ -3116,7 -3121,6 +3123,7 @@@ P:      Jesse Barne
  M:    jbarnes@virtuousgeek.org
  L:    linux-kernel@vger.kernel.org
  L:    linux-pci@atrey.karlin.mff.cuni.cz
 +T:    git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
  S:    Supported
  
  PCI HOTPLUG CORE
@@@ -3577,13 -3581,6 +3584,13 @@@ M:    pfg@sgi.co
  L:    linux-ia64@vger.kernel.org
  S:    Supported
  
 +SFC NETWORK DRIVER
 +P:    Steve Hodgson
 +P:    Ben Hutchings
 +P:    Robert Stonehouse
 +M:    linux-net-drivers@solarflare.com
 +S:    Supported
 +
  SGI VISUAL WORKSTATION 320 AND 540
  P:    Andrey Panin
  M:    pazke@donpac.ru
@@@ -3750,6 -3747,42 +3757,6 @@@ M:     chrisw@sous-sol.or
  L:    stable@kernel.org
  S:    Maintained
  
 -TPM DEVICE DRIVER
 -P:    Kylene Hall
 -M:    tpmdd-devel@lists.sourceforge.net
 -W:    http://tpmdd.sourceforge.net
 -P:    Marcel Selhorst
 -M:    tpm@selhorst.net
 -W:    http://www.prosec.rub.de/tpm/
 -L:    tpmdd-devel@lists.sourceforge.net
 -S:    Maintained
 -
 -Telecom Clock Driver for MCPL0010
 -P:    Mark Gross
 -M:    mark.gross@intel.com
 -S:    Supported
 -
 -TENSILICA XTENSA PORT (xtensa):
 -P:    Chris Zankel
 -M:    chris@zankel.net
 -S:    Maintained
 -
 -THINKPAD ACPI EXTRAS DRIVER
 -P:    Henrique de Moraes Holschuh
 -M:    ibm-acpi@hmh.eng.br
 -L:    ibm-acpi-devel@lists.sourceforge.net
 -W:    http://ibm-acpi.sourceforge.net
 -W:    http://thinkwiki.org/wiki/Ibm-acpi
 -T:    git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
 -S:    Maintained
 -
 -UltraSPARC (sparc64):
 -P:    David S. Miller
 -M:    davem@davemloft.net
 -L:    sparclinux@vger.kernel.org
 -T:    git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
 -S:    Maintained
 -
  SHARP LH SUPPORT (LH7952X & LH7A40X)
  P:    Marc Singer
  M:    elf@buici.com
@@@ -3846,12 -3879,6 +3853,12 @@@ P:    Christoph Hellwi
  M:    hch@infradead.org
  S:    Maintained
  
 +TASKSTATS STATISTICS INTERFACE
 +P:    Shailabh Nagar
 +M:    nagar@watson.ibm.com
 +L:    linux-kernel@vger.kernel.org
 +S:    Maintained
 +
  TC CLASSIFIER
  P:    Jamal Hadi Salim
  M:    hadi@cyberus.ca
@@@ -3874,25 -3901,6 +3881,25 @@@ M:    andy@greyhouse.ne
  L:    netdev@vger.kernel.org
  S:    Supported
  
 +Telecom Clock Driver for MCPL0010
 +P:    Mark Gross
 +M:    mark.gross@intel.com
 +S:    Supported
 +
 +TENSILICA XTENSA PORT (xtensa):
 +P:    Chris Zankel
 +M:    chris@zankel.net
 +S:    Maintained
 +
 +THINKPAD ACPI EXTRAS DRIVER
 +P:    Henrique de Moraes Holschuh
 +M:    ibm-acpi@hmh.eng.br
 +L:    ibm-acpi-devel@lists.sourceforge.net
 +W:    http://ibm-acpi.sourceforge.net
 +W:    http://thinkwiki.org/wiki/Ibm-acpi
 +T:    git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
 +S:    Maintained
 +
  TI FLASH MEDIA INTERFACE DRIVER
  P:      Alex Dubov
  M:      oakad@yahoo.com
@@@ -3910,6 -3918,12 +3917,6 @@@ P:     Deepak Saxen
  M:    dsaxena@plexity.net
  S:    Maintained
  
 -TASKSTATS STATISTICS INTERFACE
 -P:    Shailabh Nagar
 -M:    nagar@watson.ibm.com
 -L:    linux-kernel@vger.kernel.org
 -S:    Maintained
 -
  TIPC NETWORK LAYER
  P:    Per Liden
  M:    per.liden@ericsson.com
@@@ -3943,16 -3957,6 +3950,16 @@@ L:    tlinux-users@tce.toshiba-dme.co.j
  W:    http://www.buzzard.org.uk/toshiba/
  S:    Maintained
  
 +TPM DEVICE DRIVER
 +P:    Kylene Hall
 +M:    tpmdd-devel@lists.sourceforge.net
 +W:    http://tpmdd.sourceforge.net
 +P:    Marcel Selhorst
 +M:    tpm@selhorst.net
 +W:    http://www.prosec.rub.de/tpm/
 +L:    tpmdd-devel@lists.sourceforge.net
 +S:    Maintained
 +
  TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
  P:    Muli Ben-Yehuda
  M:    mulix@mulix.org
@@@ -3965,12 -3969,6 +3972,12 @@@ M:    trivial@kernel.or
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  
 +TTY LAYER
 +P:    Alan Cox
 +M:    alan@lxorguk.ukuu.org.uk
 +L:    linux-kernel@vger.kernel.org
 +S:    Maintained
 +
  TULIP NETWORK DRIVERS
  P:    Grant Grundler
  M:    grundler@parisc-linux.org
@@@ -4139,20 -4137,6 +4146,20 @@@ L:      linux-usb@vger.kernel.or
  W:    http://www.chello.nl/~j.vreeken/se401/
  S:    Maintained
  
 +USB SERIAL BELKIN F5U103 DRIVER
 +P:    William Greathouse
 +M:    wgreathouse@smva.com
 +L:      linux-usb@vger.kernel.org
 +S:    Maintained
 +
 +USB SERIAL CYPRESS M8 DRIVER
 +P:    Lonnie Mendez
 +M:    dignome@gmail.com
 +L:      linux-usb@vger.kernel.org
 +S:    Maintained
 +W:    http://geocities.com/i0xox0i
 +W:    http://firstlight.net/cvs
 +
  USB SERIAL CYBERJACK DRIVER
  P:    Matthias Bruestle and Harald Welte
  M:    support@reiner-sct.com
@@@ -4172,6 -4156,20 +4179,6 @@@ M:     gregkh@suse.d
  L:      linux-usb@vger.kernel.org
  S:    Supported
  
 -USB SERIAL BELKIN F5U103 DRIVER
 -P:    William Greathouse
 -M:    wgreathouse@smva.com
 -L:      linux-usb@vger.kernel.org
 -S:    Maintained
 -
 -USB SERIAL CYPRESS M8 DRIVER
 -P:    Lonnie Mendez
 -M:    dignome@gmail.com
 -L:      linux-usb@vger.kernel.org
 -S:    Maintained
 -W:    http://geocities.com/i0xox0i
 -W:    http://firstlight.net/cvs
 -
  USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
  P:    Gary Brubaker
  M:    xavyer@ix.netcom.com
@@@ -4274,7 -4272,7 +4281,7 @@@ M:      gregkh@suse.d
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  
 -FAT/VFAT/MSDOS FILESYSTEM:
 +VFAT/FAT/MSDOS FILESYSTEM:
  P:    OGAWA Hirofumi
  M:    hirofumi@mail.parknet.co.jp
  L:    linux-kernel@vger.kernel.org
@@@ -4319,13 -4317,6 +4326,13 @@@ M:    dushistov@mail.r
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  
 +UltraSPARC (sparc64):
 +P:    David S. Miller
 +M:    davem@davemloft.net
 +L:    sparclinux@vger.kernel.org
 +T:    git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
 +S:    Maintained
 +
  USB DIAMOND RIO500 DRIVER
  P:    Cesar Miquel
  M:    miquel@df.uba.ar
diff --combined drivers/acpi/ec.c
index e3f04b272f3f23829cac4a555677c495ea290cc5,3d93621408315dbf76a3b734b46239471d3647ac..0924992187e87031809bf70c1b75c6367cc38a64
@@@ -73,38 -73,14 +73,14 @@@ enum ec_event 
  
  #define ACPI_EC_DELAY         500     /* Wait 500ms max. during EC ops */
  #define ACPI_EC_UDELAY_GLK    1000    /* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY                100     /* Wait 100us before polling EC again */
  
  enum {
        EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
        EC_FLAGS_QUERY_PENDING,         /* Query is pending */
        EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
-       EC_FLAGS_NO_ADDRESS_GPE,        /* Expect GPE only for non-address event */
-       EC_FLAGS_ADDRESS,               /* Address is being written */
-       EC_FLAGS_NO_WDATA_GPE,          /* Don't expect WDATA GPE event */
-       EC_FLAGS_WDATA,                 /* Data is being written */
-       EC_FLAGS_NO_OBF1_GPE,           /* Don't expect GPE before read */
- };
- 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_add(struct acpi_device *device);
- static const struct acpi_device_id ec_device_ids[] = {
-       {"PNP0C09", 0},
-       {"", 0},
- };
- static struct acpi_driver acpi_ec_driver = {
-       .name = "ec",
-       .class = ACPI_EC_CLASS,
-       .ids = ec_device_ids,
-       .ops = {
-               .add = acpi_ec_add,
-               .remove = acpi_ec_remove,
-               .start = acpi_ec_start,
-               .stop = acpi_ec_stop,
-               },
+       EC_FLAGS_NO_GPE,                /* Don't use GPE mode */
+       EC_FLAGS_RESCHEDULE_POLL        /* Re-schedule poll */
  };
  
  /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@@ -129,6 -105,8 +105,8 @@@ static struct acpi_ec 
        struct mutex lock;
        wait_queue_head_t wait;
        struct list_head list;
+       struct delayed_work work;
+       atomic_t irq_count;
        u8 handlers_installed;
  } *boot_ec, *first_ec;
  
@@@ -177,65 -155,52 +155,52 @@@ static inline int acpi_ec_check_status(
        return 0;
  }
  
- static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+ static void ec_schedule_ec_poll(struct acpi_ec *ec)
  {
-       int ret = 0;
+       if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
+               schedule_delayed_work(&ec->work,
+                                     msecs_to_jiffies(ACPI_EC_DELAY));
+ }
  
-       if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
-                    test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
-               force_poll = 1;
-       if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
-                    test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
-               force_poll = 1;
-       if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) &&
-                    test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags)))
-               force_poll = 1;
+ static void ec_switch_to_poll_mode(struct acpi_ec *ec)
+ {
+       set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+ }
+ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
+ {
+       atomic_set(&ec->irq_count, 0);
        if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
            likely(!force_poll)) {
                if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
                                       msecs_to_jiffies(ACPI_EC_DELAY)))
-                       goto end;
+                       return 0;
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                if (acpi_ec_check_status(ec, event)) {
-                       if (event == ACPI_EC_EVENT_OBF_1) {
-                               /* miss OBF_1 GPE, don't expect it */
-                               pr_info(PREFIX "missing OBF confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
-                       } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
-                               /* miss address GPE, don't expect it anymore */
-                               pr_info(PREFIX "missing address confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
-                       } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) {
-                               /* miss write data GPE, don't expect it */
-                               pr_info(PREFIX "missing write data confirmation, "
-                                       "don't expect it any longer.\n");
-                               set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags);
-                       } else {
-                               /* missing GPEs, switch back to poll mode */
-                               if (printk_ratelimit())
-                                       pr_info(PREFIX "missing confirmations, "
+                       /* missing GPEs, switch back to poll mode */
+                       if (printk_ratelimit())
+                               pr_info(PREFIX "missing confirmations, "
                                                "switch off interrupt mode.\n");
-                               clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
-                       }
-                       goto end;
+                       ec_switch_to_poll_mode(ec);
+                       ec_schedule_ec_poll(ec);
+                       return 0;
                }
        } else {
                unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
                clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                while (time_before(jiffies, delay)) {
                        if (acpi_ec_check_status(ec, event))
-                               goto end;
+                               return 0;
+                       udelay(ACPI_EC_UDELAY);
                }
        }
-       pr_err(PREFIX "acpi_ec_wait timeout,"
-                              " status = %d, expect_event = %d\n",
-                              acpi_ec_read_status(ec), event);
-       ret = -ETIME;
-       end:
-       clear_bit(EC_FLAGS_ADDRESS, &ec->flags);
-       return ret;
+       pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
+               acpi_ec_read_status(ec),
+               (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
+       return -ETIME;
  }
  
  static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
  {
        int result = 0;
        set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
-       acpi_ec_write_cmd(ec, command);
        pr_debug(PREFIX "transaction start\n");
+       acpi_ec_write_cmd(ec, command);
        for (; wdata_len > 0; --wdata_len) {
                result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
                               "write_cmd timeout, command = %d\n", command);
                        goto end;
                }
-               /* mark the address byte written to EC */
-               if (rdata_len + wdata_len > 1)
-                       set_bit(EC_FLAGS_ADDRESS, &ec->flags);
                set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                acpi_ec_write_data(ec, *(wdata++));
        }
  
        if (!rdata_len) {
-               set_bit(EC_FLAGS_WDATA, &ec->flags);
                result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
                        pr_err(PREFIX
@@@ -527,46 -488,50 +488,50 @@@ static u32 acpi_ec_gpe_handler(void *da
  {
        acpi_status status = AE_OK;
        struct acpi_ec *ec = data;
+       u8 state = acpi_ec_read_status(ec);
  
        pr_debug(PREFIX "~~~> interrupt\n");
+       atomic_inc(&ec->irq_count);
+       if (atomic_read(&ec->irq_count) > 5) {
+               pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
+               ec_switch_to_poll_mode(ec);
+               goto end;
+       }
        clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
        if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
                wake_up(&ec->wait);
  
-       if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) {
+       if (state & ACPI_EC_FLAG_SCI) {
                if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
                        status = acpi_os_execute(OSL_EC_BURST_HANDLER,
                                acpi_ec_gpe_query, ec);
-       } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
+       } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+                  !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
+                  in_interrupt()) {
                /* this is non-query, must be confirmation */
                if (printk_ratelimit())
                        pr_info(PREFIX "non-query interrupt received,"
                                " switching to interrupt mode\n");
                set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+               clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
        }
+ end:
+       ec_schedule_ec_poll(ec);
        return ACPI_SUCCESS(status) ?
            ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
  }
  
+ static void do_ec_poll(struct work_struct *work)
+ {
+       struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
+       atomic_set(&ec->irq_count, 0);
+       (void)acpi_ec_gpe_handler(ec);
+ }
  /* --------------------------------------------------------------------------
                               Address Space Management
     -------------------------------------------------------------------------- */
  
- static acpi_status
- acpi_ec_space_setup(acpi_handle region_handle,
-                   u32 function, void *handler_context, void **return_context)
- {
-       /*
-        * The EC object is in the handler context and is needed
-        * when calling the acpi_ec_space_handler.
-        */
-       *return_context = (function != ACPI_REGION_DEACTIVATE) ?
-           handler_context : NULL;
-       return AE_OK;
- }
  static acpi_status
  acpi_ec_space_handler(u32 function, acpi_physical_address address,
                      u32 bits, acpi_integer *value,
@@@ -669,11 -634,16 +634,11 @@@ static int acpi_ec_add_fs(struct acpi_d
                        return -ENODEV;
        }
  
 -      entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO,
 +                               acpi_device_dir(device),
 +                               &acpi_ec_info_ops, acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_ec_info_ops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
 -
        return 0;
  }
  
@@@ -704,6 -674,8 +669,8 @@@ static struct acpi_ec *make_acpi_ec(voi
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
+       INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
+       atomic_set(&ec->irq_count, 0);
        return ec;
  }
  
@@@ -736,17 -708,21 +703,21 @@@ ec_parse_device(acpi_handle handle, u3
        status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
        if (ACPI_FAILURE(status))
                return status;
-       /* Find and register all query methods */
-       acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
-                           acpi_ec_register_query_methods, ec, NULL);
        /* Use the global lock for all EC transactions? */
        acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
        ec->handle = handle;
        return AE_CTRL_TERMINATE;
  }
  
+ static void ec_poll_stop(struct acpi_ec *ec)
+ {
+       clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+       cancel_delayed_work(&ec->work);
+ }
  static void ec_remove_handlers(struct acpi_ec *ec)
  {
+       ec_poll_stop(ec);
        if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
                                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
                pr_err(PREFIX "failed to remove space handler\n");
@@@ -766,31 -742,28 +737,28 @@@ static int acpi_ec_add(struct acpi_devi
        strcpy(acpi_device_class(device), ACPI_EC_CLASS);
  
        /* Check for boot EC */
-       if (boot_ec) {
-               if (boot_ec->handle == device->handle) {
-                       /* Pre-loaded EC from DSDT, just move pointer */
-                       ec = boot_ec;
-                       boot_ec = NULL;
-                       goto end;
-               } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
-                       /* ECDT-based EC, time to shut it down */
-                       ec_remove_handlers(boot_ec);
-                       kfree(boot_ec);
-                       first_ec = boot_ec = NULL;
+       if (boot_ec &&
+           (boot_ec->handle == device->handle ||
+            boot_ec->handle == ACPI_ROOT_OBJECT)) {
+               ec = boot_ec;
+               boot_ec = NULL;
+       } else {
+               ec = make_acpi_ec();
+               if (!ec)
+                       return -ENOMEM;
+               if (ec_parse_device(device->handle, 0, ec, NULL) !=
+                   AE_CTRL_TERMINATE) {
+                       kfree(ec);
+                       return -EINVAL;
                }
        }
  
-       ec = make_acpi_ec();
-       if (!ec)
-               return -ENOMEM;
-       if (ec_parse_device(device->handle, 0, ec, NULL) !=
-           AE_CTRL_TERMINATE) {
-               kfree(ec);
-               return -EINVAL;
-       }
        ec->handle = device->handle;
-       end:
+       /* Find and register all query methods */
+       acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
+                           acpi_ec_register_query_methods, ec, NULL);
        if (!first_ec)
                first_ec = ec;
        acpi_driver_data(device) = ec;
@@@ -865,7 -838,7 +833,7 @@@ static int ec_install_handlers(struct a
        status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
-                                                   &acpi_ec_space_setup, ec);
+                                                   NULL, ec);
        if (ACPI_FAILURE(status)) {
                acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
                return -ENODEV;
@@@ -892,6 -865,7 +860,7 @@@ static int acpi_ec_start(struct acpi_de
  
        /* EC is fully operational, allow queries */
        clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+       ec_schedule_ec_poll(ec);
        return ret;
  }
  
@@@ -919,6 -893,11 +888,11 @@@ int __init acpi_boot_ec_enable(void
        return -EFAULT;
  }
  
+ static const struct acpi_device_id ec_device_ids[] = {
+       {"PNP0C09", 0},
+       {"", 0},
+ };
  int __init acpi_ec_ecdt_probe(void)
  {
        int ret;
                boot_ec->data_addr = ecdt_ptr->data.address;
                boot_ec->gpe = ecdt_ptr->gpe;
                boot_ec->handle = ACPI_ROOT_OBJECT;
+               acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
        } else {
                /* This workaround is needed only on some broken machines,
                 * which require early EC, but fail to provide ECDT */
        return -ENODEV;
  }
  
+ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
+ {
+       struct acpi_ec *ec = acpi_driver_data(device);
+       /* Stop using GPE */
+       set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+       acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       return 0;
+ }
+ static int acpi_ec_resume(struct acpi_device *device)
+ {
+       struct acpi_ec *ec = acpi_driver_data(device);
+       /* Enable use of GPE back */
+       clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
+       acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+       return 0;
+ }
+ static struct acpi_driver acpi_ec_driver = {
+       .name = "ec",
+       .class = ACPI_EC_CLASS,
+       .ids = ec_device_ids,
+       .ops = {
+               .add = acpi_ec_add,
+               .remove = acpi_ec_remove,
+               .start = acpi_ec_start,
+               .stop = acpi_ec_stop,
+               .suspend = acpi_ec_suspend,
+               .resume = acpi_ec_resume,
+               },
+ };
  static int __init acpi_ec_init(void)
  {
        int result = 0;
diff --combined drivers/acpi/fan.c
index 194077ab9b85859c5077a9ec26ccf6a94d89be56,cf635cde836bba1d1cd288462eb3f0a3238a94a6..6cf10cbc1eee41687e462d14168827d6830b4cb0
@@@ -192,13 -192,17 +192,13 @@@ static int acpi_fan_add_fs(struct acpi_
        }
  
        /* 'status' [R/W] */
 -      entry = create_proc_entry(ACPI_FAN_FILE_STATE,
 -                                S_IFREG | S_IRUGO | S_IWUSR,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_FAN_FILE_STATE,
 +                               S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_fan_state_ops,
 +                               device);
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_fan_state_ops;
 -              entry->data = device;
 -              entry->owner = THIS_MODULE;
 -      }
 -
        return 0;
  }
  
@@@ -256,24 -260,23 +256,23 @@@ static int acpi_fan_add(struct acpi_dev
                result = PTR_ERR(cdev);
                goto end;
        }
-       if (cdev) {
-               printk(KERN_INFO PREFIX
-                       "%s is registered as cooling_device%d\n",
-                       device->dev.bus_id, cdev->id);
-               acpi_driver_data(device) = cdev;
-               result = sysfs_create_link(&device->dev.kobj,
-                                          &cdev->device.kobj,
-                                          "thermal_cooling");
-               if (result)
-                       return result;
-               result = sysfs_create_link(&cdev->device.kobj,
-                                          &device->dev.kobj,
-                                          "device");
-               if (result)
-                       return result;
-       }
+       printk(KERN_INFO PREFIX
+               "%s is registered as cooling_device%d\n",
+               device->dev.bus_id, cdev->id);
+       acpi_driver_data(device) = cdev;
+       result = sysfs_create_link(&device->dev.kobj,
+                                  &cdev->device.kobj,
+                                  "thermal_cooling");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
+       result = sysfs_create_link(&cdev->device.kobj,
+                                  &device->dev.kobj,
+                                  "device");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
  
        result = acpi_fan_add_fs(device);
        if (result)
diff --combined drivers/acpi/power.c
index 21fc8bf0d31f953e5bb1310bf5e9e9e65668f8ae,f2a76acecfcd45383432adbfd41c52775e12a3f2..81e4f081a4aefd2d53d3004fae15d0935610bb90
@@@ -93,7 -93,6 +93,7 @@@ struct acpi_power_resource 
  static struct list_head acpi_power_resource_list;
  
  static const struct file_operations acpi_power_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_power_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@@ -122,7 -121,7 +122,7 @@@ acpi_power_get_context(acpi_handle hand
        }
  
        *resource = acpi_driver_data(device);
-       if (!resource)
+       if (!*resource)
                return -ENODEV;
  
        return 0;
@@@ -544,11 -543,15 +544,11 @@@ static int acpi_power_add_fs(struct acp
        }
  
        /* 'status' [R] */
 -      entry = create_proc_entry(ACPI_POWER_FILE_STATUS,
 -                                S_IRUGO, acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_POWER_FILE_STATUS,
 +                               S_IRUGO, acpi_device_dir(device),
 +                               &acpi_power_fops, acpi_driver_data(device));
        if (!entry)
                return -EIO;
 -      else {
 -              entry->proc_fops = &acpi_power_fops;
 -              entry->data = acpi_driver_data(device);
 -      }
 -
        return 0;
  }
  
index 5241e3ff50803f6048e5084f6c3135678f7465b2,ea5f628dcc15d4430c1d8c8ce60635d9995e5cd4..386e5aa48834cc087ccf2e2ac6757bc14ee5a566
@@@ -112,7 -112,6 +112,7 @@@ static struct acpi_driver acpi_processo
  #define UNINSTALL_NOTIFY_HANDLER      2
  
  static const struct file_operations acpi_processor_info_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_processor_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@@ -327,30 -326,40 +327,30 @@@ static int acpi_processor_add_fs(struc
        acpi_device_dir(device)->owner = THIS_MODULE;
  
        /* 'info' [R] */
 -      entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
 -                                S_IRUGO, acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
 +                               S_IRUGO, acpi_device_dir(device),
 +                               &acpi_processor_info_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -EIO;
 -      else {
 -              entry->proc_fops = &acpi_processor_info_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'throttling' [R/W] */
 -      entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
 -                                S_IFREG | S_IRUGO | S_IWUSR,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
 +                               S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_processor_throttling_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -EIO;
 -      else {
 -              entry->proc_fops = &acpi_processor_throttling_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'limit' [R/W] */
 -      entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
 -                                S_IFREG | S_IRUGO | S_IWUSR,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
 +                               S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_processor_limit_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -EIO;
 -      else {
 -              entry->proc_fops = &acpi_processor_limit_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
 -
        return 0;
  }
  
@@@ -603,15 -612,6 +603,15 @@@ static int acpi_processor_get_info(stru
                request_region(pr->throttling.address, 6, "ACPI CPU throttle");
        }
  
 +      /*
 +       * If ACPI describes a slot number for this CPU, we can use it
 +       * ensure we get the right value in the "physical id" field
 +       * of /proc/cpuinfo
 +       */
 +      status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
 +      if (ACPI_SUCCESS(status))
 +              arch_fix_phys_package_id(pr->id, object.integer.value);
 +
        return 0;
  }
  
@@@ -674,22 -674,21 +674,21 @@@ static int __cpuinit acpi_processor_sta
                result = PTR_ERR(pr->cdev);
                goto end;
        }
-       if (pr->cdev) {
-               printk(KERN_INFO PREFIX
-                       "%s is registered as cooling_device%d\n",
-                       device->dev.bus_id, pr->cdev->id);
-               result = sysfs_create_link(&device->dev.kobj,
-                                          &pr->cdev->device.kobj,
-                                          "thermal_cooling");
-               if (result)
-                       return result;
-               result = sysfs_create_link(&pr->cdev->device.kobj,
-                                          &device->dev.kobj,
-                                          "device");
-               if (result)
-                       return result;
-       }
+       printk(KERN_INFO PREFIX
+               "%s is registered as cooling_device%d\n",
+               device->dev.bus_id, pr->cdev->id);
+       result = sysfs_create_link(&device->dev.kobj,
+                                  &pr->cdev->device.kobj,
+                                  "thermal_cooling");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
+       result = sysfs_create_link(&pr->cdev->device.kobj,
+                                  &device->dev.kobj,
+                                  "device");
+       if (result)
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
  
        if (pr->flags.throttling) {
                printk(KERN_INFO PREFIX "%s [%s] (supports",
index 789d4947ed31db9929c83c931435b067821b8f59,55d69dce47c4e2da1090a80ab7c36235a5c9ded8..2dd2c1f3a01ca11bf10ae1543d57f9d3fcd71dea
@@@ -847,6 -847,7 +847,7 @@@ static int acpi_processor_get_power_inf
                /* all processors need to support C1 */
                pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
                pr->power.states[ACPI_STATE_C1].valid = 1;
+               pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
        }
        /* the C0 state only exists as a filler in our array */
        pr->power.states[ACPI_STATE_C0].valid = 1;
@@@ -959,6 -960,9 +960,9 @@@ static int acpi_processor_get_power_inf
                                 cx.address);
                }
  
+               if (cx.type == ACPI_STATE_C1) {
+                       cx.valid = 1;
+               }
  
                obj = &(element->package.elements[2]);
                if (obj->type != ACPI_TYPE_INTEGER)
@@@ -1282,7 -1286,6 +1286,7 @@@ static int acpi_processor_power_open_fs
  }
  
  static const struct file_operations acpi_processor_power_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_processor_power_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@@ -1295,6 -1298,8 +1299,8 @@@ int acpi_processor_cst_has_changed(stru
  {
        int result = 0;
  
+       if (boot_option_idle_override)
+               return 0;
  
        if (!pr)
                return -EINVAL;
@@@ -1734,6 -1739,9 +1740,9 @@@ int acpi_processor_cst_has_changed(stru
  {
        int ret;
  
+       if (boot_option_idle_override)
+               return 0;
        if (!pr)
                return -EINVAL;
  
@@@ -1764,6 -1772,8 +1773,8 @@@ int __cpuinit acpi_processor_power_init
        struct proc_dir_entry *entry = NULL;
        unsigned int i;
  
+       if (boot_option_idle_override)
+               return 0;
  
        if (!first_run) {
                dmi_check_system(processor_power_dmi_table);
         * Note that we use previously set idle handler will be used on
         * platforms that only support C1.
         */
-       if ((pr->flags.power) && (!boot_option_idle_override)) {
+       if (pr->flags.power) {
  #ifdef CONFIG_CPU_IDLE
                acpi_processor_setup_cpuidle(pr);
                pr->power.dev.cpu = pr->id;
        }
  
        /* 'power' [R] */
 -      entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER,
 -                                S_IRUGO, acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER,
 +                               S_IRUGO, acpi_device_dir(device),
 +                               &acpi_processor_power_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -EIO;
 -      else {
 -              entry->proc_fops = &acpi_processor_power_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
 -
        return 0;
  }
  
  int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device)
  {
+       if (boot_option_idle_override)
+               return 0;
  #ifdef CONFIG_CPU_IDLE
-       if ((pr->flags.power) && (!boot_option_idle_override))
+       if (pr->flags.power)
                cpuidle_unregister_device(&pr->power.dev);
  #endif
        pr->flags.power_setup_done = 0;
diff --combined drivers/acpi/thermal.c
index 0815ac3ae3d6c49a1a46282b0cfaea2418ddca6b,782c2250443efde3258026c313f511826451864a..504385b1f2116614bd8e53e598b5c093414b2841
@@@ -198,7 -198,6 +198,7 @@@ struct acpi_thermal 
  };
  
  static const struct file_operations acpi_thermal_state_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_thermal_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  };
  
  static const struct file_operations acpi_thermal_temp_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_thermal_temp_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  };
  
  static const struct file_operations acpi_thermal_trip_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_thermal_trip_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  };
  
  static const struct file_operations acpi_thermal_cooling_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_thermal_cooling_open_fs,
        .read = seq_read,
        .write = acpi_thermal_write_cooling_mode,
  };
  
  static const struct file_operations acpi_thermal_polling_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_thermal_polling_open_fs,
        .read = seq_read,
        .write = acpi_thermal_write_polling,
@@@ -889,10 -884,15 +889,15 @@@ static void acpi_thermal_check(void *da
  static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
  {
        struct acpi_thermal *tz = thermal->devdata;
+       int result;
  
        if (!tz)
                return -EINVAL;
  
+       result = acpi_thermal_get_temperature(tz);
+       if (result)
+               return result;
        return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
  }
  
@@@ -1017,6 -1017,18 +1022,18 @@@ static int thermal_get_trip_temp(struc
        return -EINVAL;
  }
  
+ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
+                               unsigned long *temperature) {
+       struct acpi_thermal *tz = thermal->devdata;
+       if (tz->trips.critical.flags.valid) {
+               *temperature = KELVIN_TO_MILLICELSIUS(
+                               tz->trips.critical.temperature);
+               return 0;
+       } else
+               return -EINVAL;
+ }
  typedef int (*cb)(struct thermal_zone_device *, int,
                  struct thermal_cooling_device *);
  static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@@ -1108,6 -1120,7 +1125,7 @@@ static struct thermal_zone_device_ops a
        .set_mode = thermal_set_mode,
        .get_trip_type = thermal_get_trip_type,
        .get_trip_temp = thermal_get_trip_temp,
+       .get_crit_temp = thermal_get_crit_temp,
  };
  
  static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
  
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
                        tz->trips.active[i].flags.valid; i++, trips++);
-       tz->thermal_zone = thermal_zone_device_register("ACPI thermal zone",
+       tz->thermal_zone = thermal_zone_device_register("acpitz",
                                        trips, tz, &acpi_thermal_zone_ops);
        if (IS_ERR(tz->thermal_zone))
                return -ENODEV;
@@@ -1424,47 -1437,63 +1442,47 @@@ static int acpi_thermal_add_fs(struct a
        }
  
        /* 'state' [R] */
 -      entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
 -                                S_IRUGO, acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
 +                               S_IRUGO, acpi_device_dir(device),
 +                               &acpi_thermal_state_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_thermal_state_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'temperature' [R] */
 -      entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
 -                                S_IRUGO, acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
 +                               S_IRUGO, acpi_device_dir(device),
 +                               &acpi_thermal_temp_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_thermal_temp_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'trip_points' [R] */
 -      entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
 -                                S_IRUGO,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
 +                               S_IRUGO,
 +                               acpi_device_dir(device),
 +                               &acpi_thermal_trip_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_thermal_trip_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'cooling_mode' [R/W] */
 -      entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
 -                                S_IFREG | S_IRUGO | S_IWUSR,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
 +                               S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_thermal_cooling_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_thermal_cooling_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
  
        /* 'polling_frequency' [R/W] */
 -      entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
 -                                S_IFREG | S_IRUGO | S_IWUSR,
 -                                acpi_device_dir(device));
 +      entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
 +                               S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_thermal_polling_fops,
 +                               acpi_driver_data(device));
        if (!entry)
                return -ENODEV;
 -      else {
 -              entry->proc_fops = &acpi_thermal_polling_fops;
 -              entry->data = acpi_driver_data(device);
 -              entry->owner = THIS_MODULE;
 -      }
 -
        return 0;
  }
  
diff --combined drivers/acpi/video.c
index 43b228314a86c656c0f7e189906b8cd4e772a854,33c502e560269e0678ab726508f36f13de9c6a6d..f7eb12e55602ecc1f0dc8c9b93ff2e01d3e8a824
@@@ -57,8 -57,6 +57,6 @@@
  #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS     0x88
  #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF         0x89
  
- #define ACPI_VIDEO_HEAD_INVALID               (~0u - 1)
- #define ACPI_VIDEO_HEAD_END           (~0u)
  #define MAX_NAME_LEN  20
  
  #define ACPI_VIDEO_DISPLAY_CRT        1
@@@ -192,7 -190,6 +190,7 @@@ struct acpi_video_device 
  /* bus */
  static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
  static struct file_operations acpi_video_bus_info_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_bus_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  
  static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
  static struct file_operations acpi_video_bus_ROM_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_bus_ROM_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
                                            struct file *file);
  static struct file_operations acpi_video_bus_POST_info_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  
  static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
  static struct file_operations acpi_video_bus_POST_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  
  static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
  static struct file_operations acpi_video_bus_DOS_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_bus_DOS_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  static int acpi_video_device_info_open_fs(struct inode *inode,
                                          struct file *file);
  static struct file_operations acpi_video_device_info_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_device_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  static int acpi_video_device_state_open_fs(struct inode *inode,
                                           struct file *file);
  static struct file_operations acpi_video_device_state_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_device_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  static int acpi_video_device_brightness_open_fs(struct inode *inode,
                                                struct file *file);
  static struct file_operations acpi_video_device_brightness_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_device_brightness_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
  static int acpi_video_device_EDID_open_fs(struct inode *inode,
                                          struct file *file);
  static struct file_operations acpi_video_device_EDID_fops = {
 +      .owner = THIS_MODULE,
        .open = acpi_video_device_EDID_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@@ -743,21 -732,19 +741,19 @@@ static void acpi_video_device_find_cap(
                if (IS_ERR(device->cdev))
                        return;
  
-               if (device->cdev) {
-                       printk(KERN_INFO PREFIX
-                               "%s is registered as cooling_device%d\n",
-                               device->dev->dev.bus_id, device->cdev->id);
-                       result = sysfs_create_link(&device->dev->dev.kobj,
-                                         &device->cdev->device.kobj,
-                                         "thermal_cooling");
-                       if (result)
-                               printk(KERN_ERR PREFIX "Create sysfs link\n");
-                       result = sysfs_create_link(&device->cdev->device.kobj,
-                                         &device->dev->dev.kobj,
-                                         "device");
-                         if (result)
-                               printk(KERN_ERR PREFIX "Create sysfs link\n");
-               }
+               printk(KERN_INFO PREFIX
+                       "%s is registered as cooling_device%d\n",
+                       device->dev->dev.bus_id, device->cdev->id);
+               result = sysfs_create_link(&device->dev->dev.kobj,
+                               &device->cdev->device.kobj,
+                               "thermal_cooling");
+               if (result)
+                       printk(KERN_ERR PREFIX "Create sysfs link\n");
+               result = sysfs_create_link(&device->cdev->device.kobj,
+                               &device->dev->dev.kobj, "device");
+               if (result)
+                       printk(KERN_ERR PREFIX "Create sysfs link\n");
        }
        if (device->cap._DCS && device->cap._DSS){
                static int count = 0;
@@@ -1059,72 -1046,90 +1055,80 @@@ acpi_video_device_EDID_open_fs(struct i
  
  static int acpi_video_device_add_fs(struct acpi_device *device)
  {
-       struct proc_dir_entry *entry = NULL;
+       struct proc_dir_entry *entry, *device_dir;
        struct acpi_video_device *vid_dev;
  
-       if (!device)
-               return -ENODEV;
        vid_dev = acpi_driver_data(device);
        if (!vid_dev)
                return -ENODEV;
  
-       if (!acpi_device_dir(device)) {
-               acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
-                                                    vid_dev->video->dir);
-               if (!acpi_device_dir(device))
-                       return -ENODEV;
-               acpi_device_dir(device)->owner = THIS_MODULE;
-       }
+       device_dir = proc_mkdir(acpi_device_bid(device),
+                               vid_dev->video->dir);
+       if (!device_dir)
+               return -ENOMEM;
+       device_dir->owner = THIS_MODULE;
  
        /* 'info' [R] */
 -      entry = create_proc_entry("info", S_IRUGO, device_dir);
 +      entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
 +                      &acpi_video_device_info_fops, acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_dir;
  
 -      entry->proc_fops = &acpi_video_device_info_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'state' [R/W] */
 -      entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
 -                                device_dir);
 +      acpi_video_device_state_fops.write = acpi_video_device_write_state;
 +      entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_video_device_state_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_info;
  
 -      acpi_video_device_state_fops.write = acpi_video_device_write_state;
 -      entry->proc_fops = &acpi_video_device_state_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'brightness' [R/W] */
 -      entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
 -                                device_dir);
 +      acpi_video_device_brightness_fops.write =
 +              acpi_video_device_write_brightness;
 +      entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_video_device_brightness_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_state;
  
 -      acpi_video_device_brightness_fops.write =
 -                      acpi_video_device_write_brightness;
 -      entry->proc_fops = &acpi_video_device_brightness_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'EDID' [R] */
 -      entry = create_proc_entry("EDID", S_IRUGO, device_dir);
 +      entry = proc_create_data("EDID", S_IRUGO, acpi_device_dir(device),
 +                               &acpi_video_device_EDID_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_brightness;
 -      entry->proc_fops = &acpi_video_device_EDID_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
 -      acpi_device_dir(device) = device_dir;
        return 0;
+  err_remove_brightness:
+       remove_proc_entry("brightness", device_dir);
+  err_remove_state:
+       remove_proc_entry("state", device_dir);
+  err_remove_info:
+       remove_proc_entry("info", device_dir);
+  err_remove_dir:
+       remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
+       return -ENOMEM;
  }
  
  static int acpi_video_device_remove_fs(struct acpi_device *device)
  {
        struct acpi_video_device *vid_dev;
+       struct proc_dir_entry *device_dir;
  
        vid_dev = acpi_driver_data(device);
        if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
                return -ENODEV;
  
-       if (acpi_device_dir(device)) {
-               remove_proc_entry("info", acpi_device_dir(device));
-               remove_proc_entry("state", acpi_device_dir(device));
-               remove_proc_entry("brightness", acpi_device_dir(device));
-               remove_proc_entry("EDID", acpi_device_dir(device));
+       device_dir = acpi_device_dir(device);
+       if (device_dir) {
+               remove_proc_entry("info", device_dir);
+               remove_proc_entry("state", device_dir);
+               remove_proc_entry("brightness", device_dir);
+               remove_proc_entry("EDID", device_dir);
                remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
                acpi_device_dir(device) = NULL;
        }
@@@ -1331,76 -1336,91 +1335,81 @@@ acpi_video_bus_write_DOS(struct file *f
  
  static int acpi_video_bus_add_fs(struct acpi_device *device)
  {
-       struct proc_dir_entry *entry = NULL;
-       struct acpi_video_bus *video;
+       struct acpi_video_bus *video = acpi_driver_data(device);
+       struct proc_dir_entry *device_dir;
+       struct proc_dir_entry *entry;
  
-       video = acpi_driver_data(device);
+       device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
+       if (!device_dir)
+               return -ENOMEM;
  
-       if (!acpi_device_dir(device)) {
-               acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
-                                                    acpi_video_dir);
-               if (!acpi_device_dir(device))
-                       return -ENODEV;
-               video->dir = acpi_device_dir(device);
-               acpi_device_dir(device)->owner = THIS_MODULE;
-       }
+       device_dir->owner = THIS_MODULE;
  
        /* 'info' [R] */
 -      entry = create_proc_entry("info", S_IRUGO, device_dir);
 +      entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
 +                               &acpi_video_bus_info_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_dir;
  
 -      entry->proc_fops = &acpi_video_bus_info_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'ROM' [R] */
 -      entry = create_proc_entry("ROM", S_IRUGO, device_dir);
 +      entry = proc_create_data("ROM", S_IRUGO, acpi_device_dir(device),
 +                               &acpi_video_bus_ROM_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_info;
  
 -      entry->proc_fops = &acpi_video_bus_ROM_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'POST_info' [R] */
 -      entry = create_proc_entry("POST_info", S_IRUGO, device_dir);
 +      entry = proc_create_data("POST_info", S_IRUGO, acpi_device_dir(device),
 +                               &acpi_video_bus_POST_info_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_rom;
  
 -      entry->proc_fops = &acpi_video_bus_POST_info_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'POST' [R/W] */
 -      entry = create_proc_entry("POST", S_IFREG | S_IRUGO | S_IWUSR,
 -                                device_dir);
 +      acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
-       entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IRUSR,
++      entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_video_bus_POST_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_post_info;
  
 -      acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
 -      entry->proc_fops = &acpi_video_bus_POST_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
        /* 'DOS' [R/W] */
 -      entry = create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IWUSR,
 -                            device_dir);
 +      acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
-       entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IRUSR,
++      entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
 +                               acpi_device_dir(device),
 +                               &acpi_video_bus_DOS_fops,
 +                               acpi_driver_data(device));
        if (!entry)
-               return -ENODEV;
+               goto err_remove_post;
  
 -      acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
 -      entry->proc_fops = &acpi_video_bus_DOS_fops;
 -      entry->data = acpi_driver_data(device);
 -      entry->owner = THIS_MODULE;
 -
+       video->dir = acpi_device_dir(device) = device_dir;
        return 0;
+  err_remove_post:
+       remove_proc_entry("POST", device_dir);
+  err_remove_post_info:
+       remove_proc_entry("POST_info", device_dir);
+  err_remove_rom:
+       remove_proc_entry("ROM", device_dir);
+  err_remove_info:
+       remove_proc_entry("info", device_dir);
+  err_remove_dir:
+       remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
+       return -ENOMEM;
  }
  
  static int acpi_video_bus_remove_fs(struct acpi_device *device)
  {
-       struct acpi_video_bus *video;
-       video = acpi_driver_data(device);
-       if (acpi_device_dir(device)) {
-               remove_proc_entry("info", acpi_device_dir(device));
-               remove_proc_entry("ROM", acpi_device_dir(device));
-               remove_proc_entry("POST_info", acpi_device_dir(device));
-               remove_proc_entry("POST", acpi_device_dir(device));
-               remove_proc_entry("DOS", acpi_device_dir(device));
+       struct proc_dir_entry *device_dir = acpi_device_dir(device);
+       if (device_dir) {
+               remove_proc_entry("info", device_dir);
+               remove_proc_entry("ROM", device_dir);
+               remove_proc_entry("POST_info", device_dir);
+               remove_proc_entry("POST", device_dir);
+               remove_proc_entry("DOS", device_dir);
                remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
                acpi_device_dir(device) = NULL;
        }
  static struct acpi_video_device_attrib*
  acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
  {
-       int count;
+       struct acpi_video_enumerated_device *ids;
+       int i;
+       for (i = 0; i < video->attached_count; i++) {
+               ids = &video->attached_array[i];
+               if ((ids->value.int_val & 0xffff) == device_id)
+                       return &ids->value.attrib;
+       }
  
-       for(count = 0; count < video->attached_count; count++)
-               if((video->attached_array[count].value.int_val & 0xffff) == device_id)
-                       return &(video->attached_array[count].value.attrib);
        return NULL;
  }
  
@@@ -1547,20 -1571,16 +1560,16 @@@ static voi
  acpi_video_device_bind(struct acpi_video_bus *video,
                       struct acpi_video_device *device)
  {
+       struct acpi_video_enumerated_device *ids;
        int i;
  
- #define IDS_VAL(i) video->attached_array[i].value.int_val
- #define IDS_BIND(i) video->attached_array[i].bind_info
-       for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&
-            i < video->attached_count; i++) {
-               if (device->device_id == (IDS_VAL(i) & 0xffff)) {
-                       IDS_BIND(i) = device;
+       for (i = 0; i < video->attached_count; i++) {
+               ids = &video->attached_array[i];
+               if (device->device_id == (ids->value.int_val & 0xffff)) {
+                       ids->bind_info = device;
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
                }
        }
- #undef IDS_VAL
- #undef IDS_BIND
  }
  
  /*
@@@ -1579,7 -1599,7 +1588,7 @@@ static int acpi_video_device_enumerate(
        int status;
        int count;
        int i;
-       struct acpi_video_enumerated_device *active_device_list;
+       struct acpi_video_enumerated_device *active_list;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *dod = NULL;
        union acpi_object *obj;
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
                          dod->package.count));
  
-       active_device_list = kmalloc((1 +
-                                     dod->package.count) *
-                                    sizeof(struct
-                                           acpi_video_enumerated_device),
-                                    GFP_KERNEL);
-       if (!active_device_list) {
+       active_list = kcalloc(1 + dod->package.count,
+                             sizeof(struct acpi_video_enumerated_device),
+                             GFP_KERNEL);
+       if (!active_list) {
                status = -ENOMEM;
                goto out;
        }
                obj = &dod->package.elements[i];
  
                if (obj->type != ACPI_TYPE_INTEGER) {
-                       printk(KERN_ERR PREFIX "Invalid _DOD data\n");
-                       active_device_list[i].value.int_val =
-                           ACPI_VIDEO_HEAD_INVALID;
+                       printk(KERN_ERR PREFIX
+                               "Invalid _DOD data in element %d\n", i);
+                       continue;
                }
-               active_device_list[i].value.int_val = obj->integer.value;
-               active_device_list[i].bind_info = NULL;
+               active_list[count].value.int_val = obj->integer.value;
+               active_list[count].bind_info = NULL;
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
                                  (int)obj->integer.value));
                count++;
        }
-       active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
  
        kfree(video->attached_array);
  
-       video->attached_array = active_device_list;
+       video->attached_array = active_list;
        video->attached_count = count;
-       out:
+  out:
        kfree(buffer.pointer);
        return status;
  }
index 46d506f66259f502605e4965adc1b779afb73d80,4f89f1677e69371760b74163289f3d82971bf86f..b35d921bac6e47a0bc79b5d99e3dbbe14a31e6df
@@@ -23,7 -23,7 +23,7 @@@
  #include <linux/slab.h>
  #include <linux/types.h>
  #include <linux/proc_fs.h>
- #include <linux/pnpbios.h>
+ #include <linux/pnp.h>
  #include <linux/init.h>
  
  #include <asm/uaccess.h>
@@@ -256,7 -256,7 +256,7 @@@ int pnpbios_interface_attach_device(str
   */
  int __init pnpbios_proc_init(void)
  {
 -      proc_pnp = proc_mkdir("pnp", proc_bus);
 +      proc_pnp = proc_mkdir("bus/pnp", NULL);
        if (!proc_pnp)
                return -EIO;
        proc_pnp_boot = proc_mkdir("boot", proc_pnp);
@@@ -294,5 -294,5 +294,5 @@@ void __exit pnpbios_proc_exit(void
        remove_proc_entry("configuration_info", proc_pnp);
        remove_proc_entry("devices", proc_pnp);
        remove_proc_entry("boot", proc_pnp);
 -      remove_proc_entry("pnp", proc_bus);
 +      remove_proc_entry("bus/pnp", NULL);
  }
diff --combined include/linux/pnp.h
index 2f3bcf73052cc0de06a42db578920e1a3f8207f6,e3b2c0068de752f7ac00d73d82c9c53e8da193ef..63b128d512fb5f413085b8b13d144d97cf41477f
  #ifndef _LINUX_PNP_H
  #define _LINUX_PNP_H
  
 -#ifdef __KERNEL__
 -
  #include <linux/device.h>
  #include <linux/list.h>
  #include <linux/errno.h>
  #include <linux/mod_devicetable.h>
  
- #define PNP_MAX_PORT          40
- #define PNP_MAX_MEM           24
- #define PNP_MAX_IRQ           2
- #define PNP_MAX_DMA           2
  #define PNP_NAME_LEN          50
  
  struct pnp_protocol;
  struct pnp_dev;
+ struct pnp_resource_table;
  
  /*
   * Resource Management
   */
+ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
+ static inline int pnp_resource_valid(struct resource *res)
+ {
+       if (res && !(res->flags & IORESOURCE_UNSET))
+               return 1;
+       return 0;
+ }
+ static inline resource_size_t pnp_resource_len(struct resource *res)
+ {
+       if (res->start == 0 && res->end == 0)
+               return 0;
+       return res->end - res->start + 1;
+ }
+ static inline resource_size_t pnp_port_start(struct pnp_dev *dev,
+                                            unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_IO, bar)->start;
+ }
+ static inline resource_size_t pnp_port_end(struct pnp_dev *dev,
+                                          unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_IO, bar)->end;
+ }
+ static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
+                                          unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags;
+ }
+ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_IO, bar));
+ }
+ static inline resource_size_t pnp_port_len(struct pnp_dev *dev,
+                                          unsigned int bar)
+ {
+       return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar));
+ }
+ static inline resource_size_t pnp_mem_start(struct pnp_dev *dev,
+                                           unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start;
+ }
+ static inline resource_size_t pnp_mem_end(struct pnp_dev *dev,
+                                         unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end;
+ }
+ static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags;
+ }
+ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_MEM, bar));
+ }
+ static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
+                                         unsigned int bar)
+ {
+       return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar));
+ }
+ static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start;
+ }
+ static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags;
+ }
+ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_IRQ, bar));
+ }
+ static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start;
+ }
+ static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags;
+ }
+ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
+ {
+       return pnp_resource_valid(pnp_get_resource(dev, IORESOURCE_DMA, bar));
+ }
  
- /* Use these instead of directly reading pnp_dev to get resource information */
- #define pnp_port_start(dev,bar)   ((dev)->res.port_resource[(bar)].start)
- #define pnp_port_end(dev,bar)     ((dev)->res.port_resource[(bar)].end)
- #define pnp_port_flags(dev,bar)   ((dev)->res.port_resource[(bar)].flags)
- #define pnp_port_valid(dev,bar) \
-       ((pnp_port_flags((dev),(bar)) & (IORESOURCE_IO | IORESOURCE_UNSET)) \
-               == IORESOURCE_IO)
- #define pnp_port_len(dev,bar) \
-       ((pnp_port_start((dev),(bar)) == 0 &&   \
-         pnp_port_end((dev),(bar)) ==          \
-         pnp_port_start((dev),(bar))) ? 0 :    \
-                                               \
-        (pnp_port_end((dev),(bar)) -           \
-         pnp_port_start((dev),(bar)) + 1))
- #define pnp_mem_start(dev,bar)   ((dev)->res.mem_resource[(bar)].start)
- #define pnp_mem_end(dev,bar)     ((dev)->res.mem_resource[(bar)].end)
- #define pnp_mem_flags(dev,bar)   ((dev)->res.mem_resource[(bar)].flags)
- #define pnp_mem_valid(dev,bar) \
-       ((pnp_mem_flags((dev),(bar)) & (IORESOURCE_MEM | IORESOURCE_UNSET)) \
-               == IORESOURCE_MEM)
- #define pnp_mem_len(dev,bar) \
-       ((pnp_mem_start((dev),(bar)) == 0 &&    \
-         pnp_mem_end((dev),(bar)) ==           \
-         pnp_mem_start((dev),(bar))) ? 0 :     \
-                                               \
-        (pnp_mem_end((dev),(bar)) -            \
-         pnp_mem_start((dev),(bar)) + 1))
- #define pnp_irq(dev,bar)       ((dev)->res.irq_resource[(bar)].start)
- #define pnp_irq_flags(dev,bar)         ((dev)->res.irq_resource[(bar)].flags)
- #define pnp_irq_valid(dev,bar) \
-       ((pnp_irq_flags((dev),(bar)) & (IORESOURCE_IRQ | IORESOURCE_UNSET)) \
-               == IORESOURCE_IRQ)
- #define pnp_dma(dev,bar)       ((dev)->res.dma_resource[(bar)].start)
- #define pnp_dma_flags(dev,bar)         ((dev)->res.dma_resource[(bar)].flags)
- #define pnp_dma_valid(dev,bar) \
-       ((pnp_dma_flags((dev),(bar)) & (IORESOURCE_DMA | IORESOURCE_UNSET)) \
-               == IORESOURCE_DMA)
  
  #define PNP_PORT_FLAG_16BITADDR       (1<<0)
  #define PNP_PORT_FLAG_FIXED   (1<<1)
@@@ -116,13 -181,6 +179,6 @@@ struct pnp_option 
        struct pnp_option *next;        /* used to chain dependent resources */
  };
  
- struct pnp_resource_table {
-       struct resource port_resource[PNP_MAX_PORT];
-       struct resource mem_resource[PNP_MAX_MEM];
-       struct resource dma_resource[PNP_MAX_DMA];
-       struct resource irq_resource[PNP_MAX_IRQ];
- };
  /*
   * Device Management
   */
@@@ -192,10 -250,9 +248,9 @@@ struct pnp_dev 
        int capabilities;
        struct pnp_option *independent;
        struct pnp_option *dependent;
-       struct pnp_resource_table res;
+       struct pnp_resource_table *res;
  
        char name[PNP_NAME_LEN];        /* contains a human-readable name */
-       unsigned short regs;            /* ISAPnP: supported registers */
        int flags;                      /* used by protocols */
        struct proc_dir_entry *procent; /* device entry in /proc/bus/isapnp */
        void *data;
@@@ -326,8 -383,8 +381,8 @@@ struct pnp_protocol 
        char *name;
  
        /* resource control functions */
-       int (*get) (struct pnp_dev *dev, struct pnp_resource_table *res);
-       int (*set) (struct pnp_dev *dev, struct pnp_resource_table *res);
+       int (*get) (struct pnp_dev *dev);
+       int (*set) (struct pnp_dev *dev);
        int (*disable) (struct pnp_dev *dev);
  
        /* protocol specific suspend/resume */
@@@ -356,20 -413,12 +411,12 @@@ extern struct bus_type pnp_bus_type
  #if defined(CONFIG_PNP)
  
  /* device management */
- int pnp_register_protocol(struct pnp_protocol *protocol);
- void pnp_unregister_protocol(struct pnp_protocol *protocol);
- int pnp_add_device(struct pnp_dev *dev);
  int pnp_device_attach(struct pnp_dev *pnp_dev);
  void pnp_device_detach(struct pnp_dev *pnp_dev);
  extern struct list_head pnp_global;
  extern int pnp_platform_devices;
  
  /* multidevice card support */
- int pnp_add_card(struct pnp_card *card);
- void pnp_remove_card(struct pnp_card *card);
- int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
- void pnp_remove_card_device(struct pnp_dev *dev);
- int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card);
  struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink,
                                        const char *id, struct pnp_dev *from);
  void pnp_release_card_device(struct pnp_dev *dev);
@@@ -378,77 -427,42 +425,42 @@@ void pnp_unregister_card_driver(struct 
  extern struct list_head pnp_cards;
  
  /* resource management */
- struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
- struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
-                                                int priority);
- int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data);
- int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data);
- int pnp_register_port_resource(struct pnp_option *option,
-                              struct pnp_port *data);
- int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data);
- void pnp_init_resource_table(struct pnp_resource_table *table);
- int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
-                         int mode);
  int pnp_auto_config_dev(struct pnp_dev *dev);
- int pnp_validate_config(struct pnp_dev *dev);
  int pnp_start_dev(struct pnp_dev *dev);
  int pnp_stop_dev(struct pnp_dev *dev);
  int pnp_activate_dev(struct pnp_dev *dev);
  int pnp_disable_dev(struct pnp_dev *dev);
- void pnp_resource_change(struct resource *resource, resource_size_t start,
-                        resource_size_t size);
  
  /* protocol helpers */
  int pnp_is_active(struct pnp_dev *dev);
  int compare_pnp_id(struct pnp_id *pos, const char *id);
- int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
  int pnp_register_driver(struct pnp_driver *drv);
  void pnp_unregister_driver(struct pnp_driver *drv);
  
  #else
  
  /* device management */
- static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
- static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
- static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
- static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
  static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { }
  
  #define pnp_platform_devices 0
  
  /* multidevice card support */
- static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
- static inline void pnp_remove_card(struct pnp_card *card) { }
- static inline int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
- static inline void pnp_remove_card_device(struct pnp_dev *dev) { }
- static inline int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) { return -ENODEV; }
  static inline struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, const char *id, struct pnp_dev *from) { return NULL; }
  static inline void pnp_release_card_device(struct pnp_dev *dev) { }
  static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return -ENODEV; }
  static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
  
  /* resource management */
- static inline struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) { return NULL; }
- static inline struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int priority) { return NULL; }
- static inline int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { return -ENODEV; }
- static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; }
- static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; }
- static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; }
- static inline void pnp_init_resource_table(struct pnp_resource_table *table) { }
- static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
  static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
- static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
- static inline void pnp_resource_change(struct resource *resource, resource_size_t start, resource_size_t size) { }
  
  /* protocol helpers */
  static inline int pnp_is_active(struct pnp_dev *dev) { return 0; }
  static inline int compare_pnp_id(struct pnp_id *pos, const char *id) { return -ENODEV; }
- static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
  static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
  static inline void pnp_unregister_driver(struct pnp_driver *drv) { }
  
  #define pnp_dbg(format, arg...) do {} while (0)
  #endif
  
 -#endif /* __KERNEL__ */
 -
  #endif /* _LINUX_PNP_H */