Merge branch 'linus' into release
authorLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 06:14:15 +0000 (02:14 -0400)
committerLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 06:14:15 +0000 (02:14 -0400)
Conflicts:
arch/x86/kernel/cpu/cpufreq/longhaul.c

Signed-off-by: Len Brown <len.brown@intel.com>
26 files changed:
1  2 
Documentation/kernel-parameters.txt
MAINTAINERS
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/longhaul.c
arch/x86/mm/srat_64.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/battery.c
drivers/acpi/dock.c
drivers/acpi/fan.c
drivers/acpi/osl.c
drivers/acpi/processor_core.c
drivers/acpi/processor_perflib.c
drivers/acpi/sbs.c
drivers/acpi/tables.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/pci/pci-acpi.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
include/acpi/acpiosxf.h
include/acpi/acpixf.h
include/linux/acpi.h

index 7068d0bc47c5cd80c4ccc6b963ac81fa59e8be5e,421920897a37bd4a1d3e4167b31bf0b94838d685..d1b87d26942ff3373507c4c483fa476b5d36dc16
@@@ -44,6 -44,7 +44,7 @@@ parameter is applicable
        FB      The frame buffer device is enabled.
        HW      Appropriate hardware is enabled.
        IA-64   IA-64 architecture is enabled.
+       IMA     Integrity measurement architecture is enabled.
        IOSCHED More than one I/O scheduler is enabled.
        IP_PNP  IP DHCP, BOOTP, or RARP is enabled.
        ISAPNP  ISA PnP code is enabled.
@@@ -258,22 -259,6 +259,22 @@@ and is between 256 and 4096 characters
                        to assume that this machine's pmtimer latches its value
                        and always returns good values.
  
 +      acpi_enforce_resources= [ACPI]
 +                      { strict | lax | no }
 +                      Check for resource conflicts between native drivers
 +                      and ACPI OperationRegions (SystemIO and SystemMemory
 +                      only). IO ports and memory declared in ACPI might be
 +                      used by the ACPI subsystem in arbitrary AML code and
 +                      can interfere with legacy drivers.
 +                      strict (default): access to resources claimed by ACPI
 +                      is denied; legacy drivers trying to access reserved
 +                      resources will fail to bind to device using them.
 +                      lax: access to resources claimed by ACPI is allowed;
 +                      legacy drivers trying to access reserved resources
 +                      will bind successfully but a warning message is logged.
 +                      no: ACPI OperationRegions are not marked as reserved,
 +                      no further checks are performed.
 +
        agp=            [AGP]
                        { off | try_unsupported }
                        off: disable AGP support
                        Range: 0 - 8192
                        Default: 64
  
+       dma_debug=off   If the kernel is compiled with DMA_API_DEBUG support
+                       this option disables the debugging code at boot.
+       dma_debug_entries=<number>
+                       This option allows to tune the number of preallocated
+                       entries for DMA-API debugging code. One entry is
+                       required per DMA-API allocation. Use this if the
+                       DMA-API debugging code disables itself because the
+                       architectural default is too low.
        hpet=           [X86-32,HPET] option to control HPET usage
-                       Format: { enable (default) | disable | force }
+                       Format: { enable (default) | disable | force |
+                               verbose }
                        disable: disable HPET and use PIT instead
                        force: allow force enabled of undocumented chips (ICH4,
                        VIA, nVidia)
+                       verbose: show contents of HPET registers during setup
  
        com20020=       [HW,NET] ARCnet - COM20020 chipset
                        Format:
  
        hvc_iucv=       [S390] Number of z/VM IUCV hypervisor console (HVC)
                               terminal devices. Valid values: 0..8
+       hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs.
+                              If specified, z/VM IUCV HVC accepts connections
+                              from listed z/VM user IDs only.
+       i2c_bus=        [HW] Override the default board specific I2C bus speed
+                            or register an additional I2C bus that is not
+                            registered from board initialization code.
+                            Format:
+                            <bus_id>,<clkrate>
  
        i8042.debug     [HW] Toggle i8042 debug mode
        i8042.direct    [HW] Put keyboard port into non-translated mode
        ihash_entries=  [KNL]
                        Set number of hash buckets for inode cache.
  
+       ima_audit=      [IMA]
+                       Format: { "0" | "1" }
+                       0 -- integrity auditing messages. (Default)
+                       1 -- enable informational integrity auditing messages.
+       ima_hash=       [IMA]
+                       Formt: { "sha1" | "md5" }
+                       default: "sha1"
        in2000=         [HW,SCSI]
                        See header of drivers/scsi/in2000.c.
  
  
        memtest=        [KNL,X86] Enable memtest
                        Format: <integer>
-                       range: 0,4 : pattern number
                        default : 0 <disable>
+                       Specifies the number of memtest passes to be
+                       performed. Each pass selects another test
+                       pattern from a given set of patterns. Memtest
+                       fills the memory with this pattern, validates
+                       memory contents and reserves bad memory
+                       regions that are detected.
  
        meye.*=         [HW] Set MotionEye Camera parameters
                        See Documentation/video4linux/meye.txt.
  
        noclflush       [BUGS=X86] Don't use the CLFLUSH instruction
  
-       nohlt           [BUGS=ARM,SH]
+       nohlt           [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
+                       wfi(ARM) instruction doesn't work correctly and not to
+                       use it. This is also useful when using JTAG debugger.
  
        no-hlt          [BUGS=X86-32] Tells the kernel that the hlt
                        instruction doesn't work correctly and not to
        nosoftlockup    [KNL] Disable the soft-lockup detector.
  
        noswapaccount   [KNL] Disable accounting of swap in memory resource
-                       controller. (See Documentation/controllers/memory.txt)
+                       controller. (See Documentation/cgroups/memory.txt)
  
        nosync          [HW,M68K] Disables sync negotiation for all devices.
  
                        See also Documentation/blockdev/paride.txt.
  
        pci=option[,option...]  [PCI] various PCI subsystem options:
+               earlydump       [X86] dump PCI config space before the kernel
+                               changes anything
                off             [X86] don't probe for the PCI bus
                bios            [X86-32] force use of PCI BIOS, don't access
                                the hardware directly. Use this if your machine
                cbmemsize=nn[KMG]       The fixed amount of bus space which is
                                reserved for the CardBus bridge's memory
                                window. The default value is 64 megabytes.
+               resource_alignment=
+                               Format:
+                               [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
+                               Specifies alignment and device to reassign
+                               aligned memory resources.
+                               If <order of align> is not specified,
+                               PAGE_SIZE is used as alignment.
+                               PCI-PCI bridge can be specified, if resource
+                               windows need to be expanded.
  
        pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
                        Management.
                        autoconfiguration.
                        Ranges are in pairs (memory base and size).
  
-       dynamic_printk  Enables pr_debug()/dev_dbg() calls if
-                       CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
-                       These can also be switched on/off via
-                       <debugfs>/dynamic_printk/modules
        print-fatal-signals=
                        [KNL] debug: print fatal signals
                        print-fatal-signals=1: print segfault info to
  
        relax_domain_level=
                        [KNL, SMP] Set scheduler's default relax_domain_level.
-                       See Documentation/cpusets.txt.
+                       See Documentation/cgroups/cpusets.txt.
  
        reserve=        [KNL,BUGS] Force the kernel to ignore some iomem area
  
                        If enabled at boot time, /selinux/disable can be used
                        later to disable prior to initial policy load.
  
-       selinux_compat_net =
-                       [SELINUX] Set initial selinux_compat_net flag value.
-                         Format: { "0" | "1" }
-                         0 -- use new secmark-based packet controls
-                         1 -- use legacy packet controls
-                         Default value is 0 (preferred).
-                         Value can be changed at runtime via
-                         /selinux/compat_net.
        serialnumber    [BUGS=X86-32]
  
        shapers=        [NET]
diff --combined MAINTAINERS
index e40379e31921c2e49e7f82a735f813f63b7b4dc3,6360b9b9bbbda557860ac202de5cb62cd244c43a..446821b9fac9105bdd548e1c8846d92a63ccdb6f
@@@ -357,6 -357,7 +357,7 @@@ S: Odd Fixes for 2.4; Maintained for 2.
  P:    Ivan Kokshaysky
  M:    ink@jurassic.park.msu.ru
  S:    Maintained for 2.4; PCI support for 2.6.
+ L:    linux-alpha@vger.kernel.org
  
  AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
  P:    Thomas Dahlmann
@@@ -502,6 -503,13 +503,13 @@@ P:       Richard Purdi
  M:    rpurdie@rpsys.net
  S:    Maintained
  
+ ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
+ P:    Paulius Zaleckas
+ M:    paulius.zaleckas@teltonika.lt
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ T:    git gitorious.org/linux-gemini/mainline.git
+ S:    Maintained
  ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
  P:    Daniel Ribeiro
  M:    drwyrm@gmail.com
@@@ -513,6 -521,12 +521,12 @@@ L:       openezx-devel@lists.openezx.org (sub
  W:    http://www.openezx.org/
  S:    Maintained
  
+ ARM/FARADAY FA526 PORT
+ P:    Paulius Zaleckas
+ M:    paulius.zaleckas@teltonika.lt
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ S:    Maintained
  ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
  P:    Sascha Hauer
  M:    kernel@pengutronix.de
@@@ -622,7 -636,7 +636,7 @@@ P: Dirk Opfe
  M:    dirk@opfer-online.de
  S:    Maintained
  
- ARM/PALMTX SUPPORT
+ ARM/PALMTX,PALMT5,PALMLD SUPPORT
  P:    Marek Vasut
  M:    marek.vasut@gmail.com
  W:    http://hackndev.com
@@@ -765,6 -779,14 +779,14 @@@ L:       linux-wireless@vger.kernel.or
  L:    ath9k-devel@lists.ath9k.org
  S:    Supported
  
+ ATHEROS AR9170 WIRELESS DRIVER
+ P:    Christian Lamparter
+ M:    chunkeey@web.de
+ L:    linux-wireless@vger.kernel.org
+ W:    http://wireless.kernel.org/en/users/Drivers/ar9170
+ S:    Maintained
+ F:    drivers/net/wireless/ar9170/
  ATI_REMOTE2 DRIVER
  P:    Ville Syrjala
  M:    syrjala@sci.fi
@@@ -1011,6 -1033,8 +1033,8 @@@ L:      netdev@vger.kernel.or
  S:    Supported
  
  BROADCOM TG3 GIGABIT ETHERNET DRIVER
+ P:    Matt Carlson
+ M:    mcarlson@broadcom.com
  P:    Michael Chan
  M:    mchan@broadcom.com
  L:    netdev@vger.kernel.org
@@@ -1040,7 -1064,6 +1064,6 @@@ BTTV VIDEO4LINUX DRIVE
  P:    Mauro Carvalho Chehab
  M:    mchehab@infradead.org
  L:    linux-media@vger.kernel.org
- L:    video4linux-list@redhat.com
  W:    http://linuxtv.org
  T:    git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
  S:    Maintained
@@@ -1269,6 -1292,12 +1292,12 @@@ L:    linux-crypto@vger.kernel.or
  T:    git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
  S:    Maintained
  
+ CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
+ P:    Neil Horman
+ M:    nhorman@tuxdriver.com
+ L:    linux-crypto@vger.kernel.org
+ S:    Maintained
  CS5535 Audio ALSA driver
  P:    Jaya Kumar
  M:    jayakumar.alsa@gmail.com
@@@ -1393,11 -1422,6 +1422,11 @@@ P:    Doug Warzech
  M:    Douglas_Warzecha@dell.com
  S:    Maintained
  
 +DELL WMI EXTRAS DRIVER
 +P:    Matthew Garrett
 +M:    mjg59@srcf.ucam.org
 +S:    Maintained
 +
  DEVICE NUMBER REGISTRY
  P:    Torben Mathiasen
  M:    device@lanana.org
@@@ -1739,6 -1763,12 +1768,12 @@@ M:    viro@zeniv.linux.org.u
  L:    linux-fsdevel@vger.kernel.org
  S:    Maintained
  
+ FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+ P:    Riku Voipio
+ M:    riku.vipio@iki.fi
+ L:    lm-sensors@lm-sensors.org
+ S:    Maintained
  FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
  P:    Kristian Hoegsberg, Stefan Richter
  M:    krh@redhat.com, stefanr@s5r6.in-berlin.de
@@@ -1921,6 -1951,12 +1956,12 @@@ L:    lm-sensors@lm-sensors.or
  W:    http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
  S:    Maintained
  
+ HYPERVISOR VIRTUAL CONSOLE DRIVER
+ L:    linuxppc-dev@ozlabs.org
+ L:    linux-kernel@vger.kernel.org
+ S:    Odd Fixes
+ F:    drivers/char/hvc_*
  GSPCA FINEPIX SUBDRIVER
  P:    Frank Zago
  M:    frank@zago.net
@@@ -2178,25 -2214,12 +2219,12 @@@ L:   linux-ide@vger.kernel.or
  T:    quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
  S:    Maintained
  
- IDE/ATAPI CDROM DRIVER
+ IDE/ATAPI DRIVERS
  P:    Borislav Petkov
  M:    petkovbb@gmail.com
  L:    linux-ide@vger.kernel.org
  S:    Maintained
  
- IDE/ATAPI FLOPPY DRIVERS
- P:    Paul Bristow
- M:    Paul Bristow <paul@paulbristow.net>
- W:    http://paulbristow.net/linux/idefloppy.html
- L:    linux-kernel@vger.kernel.org
- S:    Maintained
- IDE/ATAPI TAPE DRIVERS
- P:    Gadi Oxman
- M:    Gadi Oxman <gadio@netvision.net.il>
- L:    linux-kernel@vger.kernel.org
- S:    Maintained
  IDLE-I7300
  P:    Andy Henroid
  M:    andrew.d.henroid@intel.com
@@@ -2221,6 -2244,11 +2249,11 @@@ M:    stefanr@s5r6.in-berlin.d
  L:    linux1394-devel@lists.sourceforge.net
  S:    Maintained
  
+ INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
+ P:    Mimi Zohar
+ M:    zohar@us.ibm.com
+ S:    Supported
  IMS TWINTURBO FRAMEBUFFER DRIVER
  L:    linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
  S:    Orphan
@@@ -2837,7 -2865,7 +2870,7 @@@ P:      Roman Zippe
  M:    zippel@linux-m68k.org
  L:    linux-m68k@lists.linux-m68k.org
  W:    http://www.linux-m68k.org/
- W:    http://linux-m68k-cvs.ubb.ca/
+ T:    git git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git
  S:    Maintained
  
  M68K ON APPLE MACINTOSH
@@@ -3082,7 -3110,7 +3115,7 @@@ M:      shemminger@linux-foundation.or
  L:    netem@lists.linux-foundation.org
  S:    Maintained
  
- NETERION (S2IO) Xframe 10GbE DRIVER
+ NETERION (S2IO) 10GbE DRIVER (xframe/vxge)
  P:    Ramkrishna Vepa
  M:    ram.vepa@neterion.com
  P:    Rastapur Santosh
@@@ -3091,8 -3119,11 +3124,11 @@@ P:    Sivakumar Subraman
  M:    sivakumar.subramani@neterion.com
  P:    Sreenivasa Honnur
  M:    sreenivasa.honnur@neterion.com
+ P:    Anil Murthy
+ M:    anil.murthy@neterion.com
  L:    netdev@vger.kernel.org
- W:    http://trac.neterion.com/cgi-bin/trac.cgi/wiki/TitleIndex?anonymous
+ W:    http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
+ W:    http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
  S:    Supported
  
  NETFILTER/IPTABLES/IPCHAINS
@@@ -3294,6 -3325,16 +3330,16 @@@ L:    orinoco-devel@lists.sourceforge.ne
  W:    http://www.nongnu.org/orinoco/
  S:    Maintained
  
+ OSD LIBRARY
+ P:    Boaz Harrosh
+ M:    bharrosh@panasas.com
+ P:    Benny Halevy
+ M:    bhalevy@panasas.com
+ L:    osd-dev@open-osd.org
+ W:    http://open-osd.org
+ T:    git://git.open-osd.org/open-osd.git
+ S:    Maintained
  P54 WIRELESS DRIVER
  P:    Michael Wu
  M:    flamingice@sourmilk.net
@@@ -3373,6 -3414,11 +3419,11 @@@ P:    Jim Cromi
  M:    jim.cromie@gmail.com
  S:    Maintained
  
+ PCA9532 LED DRIVER
+ P:    Riku Voipio
+ M:    riku.voipio@iki.fi
+ S:    Maintained
  PCI ERROR RECOVERY
  P:    Linas Vepstas
  M:    linas@austin.ibm.com
@@@ -3544,6 -3590,22 +3595,22 @@@ M:    linux@arm.linux.org.u
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
  
+ PXA168 SUPPORT
+ P:    Eric Miao
+ M:    eric.miao@marvell.com
+ P:    Jason Chagas
+ M:    jason.chagas@marvell.com
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ T:    git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+ S:    Supported
+ PXA910 SUPPORT
+ P:    Eric Miao
+ M:    eric.miao@marvell.com
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ T:    git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+ S:    Supported
  PXA MMCI DRIVER
  S:    Orphan
  
@@@ -3594,7 -3656,7 +3661,7 @@@ S:      Maintaine
  RALINK RT2X00 WIRELESS LAN DRIVER
  P:    rt2x00 project
  L:    linux-wireless@vger.kernel.org
- L:    rt2400-devel@lists.sourceforge.net
+ L:    users@rt2x00.serialmonkey.com
  W:    http://rt2x00.serialmonkey.com/
  S:    Maintained
  T:    git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
@@@ -3640,6 -3702,12 +3707,12 @@@ M:    florian.fainelli@telecomint.e
  L:    netdev@vger.kernel.org
  S:    Maintained
  
+ RDS - RELIABLE DATAGRAM SOCKETS
+ P:    Andy Grover
+ M:    andy.grover@oracle.com
+ L:    rds-devel@oss.oracle.com
+ S:    Supported
  READ-COPY UPDATE (RCU)
  P:    Dipankar Sarma
  M:    dipankar@in.ibm.com
@@@ -3731,6 -3799,15 +3804,15 @@@ L:    linux-s390@vger.kernel.or
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
  
+ S390 ZCRYPT DRIVER
+ P:    Felix Beck
+ M:    felix.beck@de.ibm.com
+ P:    Ralph Wuerthner
+ M:    ralph.wuerthner@de.ibm.com
+ M:    linux390@de.ibm.com
+ L:    linux-s390@vger.kernel.org
+ S:    Supported
  S390 ZFCP DRIVER
  P:    Christof Schmitt
  M:    christof.schmitt@de.ibm.com
@@@ -3849,6 -3926,7 +3931,7 @@@ M:      jmorris@namei.or
  L:    linux-kernel@vger.kernel.org
  L:    linux-security-module@vger.kernel.org (suggested Cc:)
  T:    git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+ W:    http://security.wiki.kernel.org/
  S:    Supported
  
  SECURITY CONTACT
@@@ -4290,8 -4368,24 +4373,21 @@@ L:    tlan-devel@lists.sourceforge.net (su
  W:    http://sourceforge.net/projects/tlan/
  S:    Maintained
  
+ TOMOYO SECURITY MODULE
+ P:    Kentaro Takeda
+ M:    takedakn@nttdata.co.jp
+ P:    Tetsuo Handa
+ M:    penguin-kernel@I-love.SAKURA.ne.jp
+ L:    linux-kernel@vger.kernel.org (kernel issues)
+ L:    tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
+ L:    tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
+ L:    tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
+ W:    http://tomoyo.sourceforge.jp/
+ T:    quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
+ S:    Maintained
  TOSHIBA ACPI EXTRAS DRIVER
 -P:    John Belmonte
 -M:    toshiba_acpi@memebeam.org
 -W:    http://memebeam.org/toys/ToshibaAcpiDriver
 -S:    Maintained
 +S:    Orphan
  
  TOSHIBA SMM DRIVER
  P:    Jonathan Buzzard
@@@ -4748,7 -4842,6 +4844,6 @@@ VIDEO FOR LINUX (V4L
  P:    Mauro Carvalho Chehab
  M:    mchehab@infradead.org
  L:    linux-media@vger.kernel.org
- L:    video4linux-list@redhat.com
  W:    http://linuxtv.org
  T:    git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
  S:    Maintained
@@@ -4765,7 -4858,7 +4860,7 @@@ M:      lrg@slimlogic.co.u
  P:    Mark Brown
  M:    broonie@opensource.wolfsonmicro.com
  W:    http://opensource.wolfsonmicro.com/node/15
- W:    http://www.slimlogic.co.uk/?page_id=5
+ W:    http://www.slimlogic.co.uk/?p=48
  T:    git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
  S:    Supported
  
@@@ -4887,7 -4980,8 +4982,8 @@@ S:      Supporte
  
  XFS FILESYSTEM
  P:    Silicon Graphics Inc
- P:    Bill O'Donnell
+ P:    Felix Blyakher
+ M:    felixb@sgi.com
  M:    xfs-masters@oss.sgi.com
  L:    xfs@oss.sgi.com
  W:    http://oss.sgi.com/projects/xfs
index 4f942096291d6f76d8e01d12fb11424acaff7bc0,a18eb7ce223643c8c9d6f40303c8180fa7d59e47..723989d7f8029711c0a6fda92e8016101ac2ede7
  #include <asm/pgtable.h>
  #include <asm/io_apic.h>
  #include <asm/apic.h>
- #include <asm/genapic.h>
  #include <asm/io.h>
  #include <asm/mpspec.h>
  #include <asm/smp.h>
  
- #ifdef CONFIG_X86_LOCAL_APIC
- # include <mach_apic.h>
- #endif
  static int __initdata acpi_force = 0;
  u32 acpi_rsdt_forced;
  #ifdef        CONFIG_ACPI
@@@ -56,16 -51,7 +51,7 @@@ int acpi_disabled = 1
  EXPORT_SYMBOL(acpi_disabled);
  
  #ifdef        CONFIG_X86_64
- #include <asm/proto.h>
- #else                         /* X86 */
- #ifdef        CONFIG_X86_LOCAL_APIC
- #include <mach_apic.h>
- #include <mach_mpparse.h>
- #endif                                /* CONFIG_X86_LOCAL_APIC */
+ # include <asm/proto.h>
  #endif                                /* X86 */
  
  #define BAD_MADT_ENTRY(entry, end) (                                      \
@@@ -121,35 -107,18 +107,18 @@@ enum acpi_irq_model_id acpi_irq_model 
   */
  char *__init __acpi_map_table(unsigned long phys, unsigned long size)
  {
-       unsigned long base, offset, mapped_size;
-       int idx;
  
        if (!phys || !size)
                return NULL;
  
-       if (phys+size <= (max_low_pfn_mapped << PAGE_SHIFT))
-               return __va(phys);
-       offset = phys & (PAGE_SIZE - 1);
-       mapped_size = PAGE_SIZE - offset;
-       clear_fixmap(FIX_ACPI_END);
-       set_fixmap(FIX_ACPI_END, phys);
-       base = fix_to_virt(FIX_ACPI_END);
-       /*
-        * Most cases can be covered by the below.
-        */
-       idx = FIX_ACPI_END;
-       while (mapped_size < size) {
-               if (--idx < FIX_ACPI_BEGIN)
-                       return NULL;    /* cannot handle this */
-               phys += PAGE_SIZE;
-               clear_fixmap(idx);
-               set_fixmap(idx, phys);
-               mapped_size += PAGE_SIZE;
-       }
+       return early_ioremap(phys, size);
+ }
+ void __init __acpi_unmap_table(char *map, unsigned long size)
+ {
+       if (!map || !size)
+               return;
  
-       return ((unsigned char *)base + offset);
+       early_iounmap(map, size);
  }
  
  #ifdef CONFIG_PCI_MMCONFIG
@@@ -239,7 -208,8 +208,8 @@@ static int __init acpi_parse_madt(struc
                       madt->address);
        }
  
-       acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
+       default_acpi_madt_oem_check(madt->header.oem_id,
+                                   madt->header.oem_table_id);
  
        return 0;
  }
@@@ -259,35 -229,6 +229,35 @@@ static void __cpuinit acpi_register_lap
        generic_processor_info(id, ver);
  }
  
 +static int __init
 +acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 +{
 +      struct acpi_madt_local_x2apic *processor = NULL;
 +
 +      processor = (struct acpi_madt_local_x2apic *)header;
 +
 +      if (BAD_MADT_ENTRY(processor, end))
 +              return -EINVAL;
 +
 +      acpi_table_print_madt_entry(header);
 +
 +#ifdef CONFIG_X86_X2APIC
 +      /*
 +       * We need to register disabled CPU as well to permit
 +       * counting disabled CPUs. This allows us to size
 +       * cpus_possible_map more accurately, to permit
 +       * to not preallocating memory for all NR_CPUS
 +       * when we use CPU hotplug.
 +       */
 +      acpi_register_lapic(processor->local_apic_id,   /* APIC ID */
 +                          processor->lapic_flags & ACPI_MADT_ENABLED);
 +#else
 +      printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
 +#endif
 +
 +      return 0;
 +}
 +
  static int __init
  acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
  {
@@@ -347,25 -288,6 +317,25 @@@ acpi_parse_lapic_addr_ovr(struct acpi_s
        return 0;
  }
  
 +static int __init
 +acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
 +                    const unsigned long end)
 +{
 +      struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
 +
 +      x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
 +
 +      if (BAD_MADT_ENTRY(x2apic_nmi, end))
 +              return -EINVAL;
 +
 +      acpi_table_print_madt_entry(header);
 +
 +      if (x2apic_nmi->lint != 1)
 +              printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
 +
 +      return 0;
 +}
 +
  static int __init
  acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
  {
@@@ -871,7 -793,6 +841,7 @@@ static int __init early_acpi_parse_madt
  static int __init acpi_parse_madt_lapic_entries(void)
  {
        int count;
 +      int x2count = 0;
  
        if (!cpu_has_apic)
                return -ENODEV;
        count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
                                      acpi_parse_sapic, MAX_APICS);
  
 -      if (!count)
 +      if (!count) {
 +              x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
 +                                              acpi_parse_x2apic, MAX_APICS);
                count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
                                              acpi_parse_lapic, MAX_APICS);
 -      if (!count) {
 +      }
 +      if (!count && !x2count) {
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return -ENODEV;
 -      } else if (count < 0) {
 +      } else if (count < 0 || x2count < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return count;
        }
  
 +      x2count =
 +          acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
 +                                acpi_parse_x2apic_nmi, 0);
        count =
            acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
 -      if (count < 0) {
 +      if (count < 0 || x2count < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return count;
@@@ -939,7 -854,7 +909,7 @@@ static struct 
        DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
  } mp_ioapic_routing[MAX_IO_APICS];
  
static int mp_find_ioapic(int gsi)
+ int mp_find_ioapic(int gsi)
  {
        int i = 0;
  
        return -1;
  }
  
+ int mp_find_ioapic_pin(int ioapic, int gsi)
+ {
+       if (WARN_ON(ioapic == -1))
+               return -1;
+       if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end))
+               return -1;
+       return gsi - mp_ioapic_routing[ioapic].gsi_base;
+ }
  static u8 __init uniq_ioapic_id(u8 id)
  {
  #ifdef CONFIG_X86_32
        DECLARE_BITMAP(used, 256);
        bitmap_zero(used, 256);
        for (i = 0; i < nr_ioapics; i++) {
-               struct mp_config_ioapic *ia = &mp_ioapics[i];
-               __set_bit(ia->mp_apicid, used);
+               struct mpc_ioapic *ia = &mp_ioapics[i];
+               __set_bit(ia->apicid, used);
        }
        if (!test_bit(id, used))
                return id;
@@@ -1000,29 -925,29 +980,29 @@@ void __init mp_register_ioapic(int id, 
  
        idx = nr_ioapics;
  
-       mp_ioapics[idx].mp_type = MP_IOAPIC;
-       mp_ioapics[idx].mp_flags = MPC_APIC_USABLE;
-       mp_ioapics[idx].mp_apicaddr = address;
+       mp_ioapics[idx].type = MP_IOAPIC;
+       mp_ioapics[idx].flags = MPC_APIC_USABLE;
+       mp_ioapics[idx].apicaddr = address;
  
        set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-       mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id);
+       mp_ioapics[idx].apicid = uniq_ioapic_id(id);
  #ifdef CONFIG_X86_32
-       mp_ioapics[idx].mp_apicver = io_apic_get_version(idx);
+       mp_ioapics[idx].apicver = io_apic_get_version(idx);
  #else
-       mp_ioapics[idx].mp_apicver = 0;
+       mp_ioapics[idx].apicver = 0;
  #endif
        /*
         * Build basic GSI lookup table to facilitate gsi->io_apic lookups
         * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
         */
-       mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid;
+       mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
        mp_ioapic_routing[idx].gsi_base = gsi_base;
        mp_ioapic_routing[idx].gsi_end = gsi_base +
            io_apic_get_redir_entries(idx);
  
-       printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
-              "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid,
-              mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr,
+       printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
+              "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
+              mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
               mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
  
        nr_ioapics++;
@@@ -1051,19 -976,19 +1031,19 @@@ int __init acpi_probe_gsi(void
        return max_gsi + 1;
  }
  
- static void assign_to_mp_irq(struct mp_config_intsrc *m,
-                                   struct mp_config_intsrc *mp_irq)
+ static void assign_to_mp_irq(struct mpc_intsrc *m,
+                                   struct mpc_intsrc *mp_irq)
  {
-       memcpy(mp_irq, m, sizeof(struct mp_config_intsrc));
+       memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
  }
  
- static int mp_irq_cmp(struct mp_config_intsrc *mp_irq,
-                               struct mp_config_intsrc *m)
+ static int mp_irq_cmp(struct mpc_intsrc *mp_irq,
+                               struct mpc_intsrc *m)
  {
-       return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc));
+       return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
  }
  
- static void save_mp_irq(struct mp_config_intsrc *m)
+ static void save_mp_irq(struct mpc_intsrc *m)
  {
        int i;
  
@@@ -1081,7 -1006,7 +1061,7 @@@ void __init mp_override_legacy_irq(u8 b
  {
        int ioapic;
        int pin;
-       struct mp_config_intsrc mp_irq;
+       struct mpc_intsrc mp_irq;
  
        /*
         * Convert 'gsi' to 'ioapic.pin'.
        ioapic = mp_find_ioapic(gsi);
        if (ioapic < 0)
                return;
-       pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
+       pin = mp_find_ioapic_pin(ioapic, gsi);
  
        /*
         * TBD: This check is for faulty timer entries, where the override
        if ((bus_irq == 0) && (trigger == 3))
                trigger = 1;
  
-       mp_irq.mp_type = MP_INTSRC;
-       mp_irq.mp_irqtype = mp_INT;
-       mp_irq.mp_irqflag = (trigger << 2) | polarity;
-       mp_irq.mp_srcbus = MP_ISA_BUS;
-       mp_irq.mp_srcbusirq = bus_irq;  /* IRQ */
-       mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */
-       mp_irq.mp_dstirq = pin; /* INTIN# */
+       mp_irq.type = MP_INTSRC;
+       mp_irq.irqtype = mp_INT;
+       mp_irq.irqflag = (trigger << 2) | polarity;
+       mp_irq.srcbus = MP_ISA_BUS;
+       mp_irq.srcbusirq = bus_irq;     /* IRQ */
+       mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
+       mp_irq.dstirq = pin;    /* INTIN# */
  
        save_mp_irq(&mp_irq);
  }
@@@ -1115,7 -1040,7 +1095,7 @@@ void __init mp_config_acpi_legacy_irqs(
        int i;
        int ioapic;
        unsigned int dstapic;
-       struct mp_config_intsrc mp_irq;
+       struct mpc_intsrc mp_irq;
  
  #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
        /*
        ioapic = mp_find_ioapic(0);
        if (ioapic < 0)
                return;
-       dstapic = mp_ioapics[ioapic].mp_apicid;
+       dstapic = mp_ioapics[ioapic].apicid;
  
        /*
         * Use the default configuration for the IRQs 0-15.  Unless
                int idx;
  
                for (idx = 0; idx < mp_irq_entries; idx++) {
-                       struct mp_config_intsrc *irq = mp_irqs + idx;
+                       struct mpc_intsrc *irq = mp_irqs + idx;
  
                        /* Do we already have a mapping for this ISA IRQ? */
-                       if (irq->mp_srcbus == MP_ISA_BUS
-                           && irq->mp_srcbusirq == i)
+                       if (irq->srcbus == MP_ISA_BUS && irq->srcbusirq == i)
                                break;
  
                        /* Do we already have a mapping for this IOAPIC pin */
-                       if (irq->mp_dstapic == dstapic &&
-                           irq->mp_dstirq == i)
+                       if (irq->dstapic == dstapic && irq->dstirq == i)
                                break;
                }
  
                        continue;       /* IRQ already used */
                }
  
-               mp_irq.mp_type = MP_INTSRC;
-               mp_irq.mp_irqflag = 0;  /* Conforming */
-               mp_irq.mp_srcbus = MP_ISA_BUS;
-               mp_irq.mp_dstapic = dstapic;
-               mp_irq.mp_irqtype = mp_INT;
-               mp_irq.mp_srcbusirq = i; /* Identity mapped */
-               mp_irq.mp_dstirq = i;
+               mp_irq.type = MP_INTSRC;
+               mp_irq.irqflag = 0;     /* Conforming */
+               mp_irq.srcbus = MP_ISA_BUS;
+               mp_irq.dstapic = dstapic;
+               mp_irq.irqtype = mp_INT;
+               mp_irq.srcbusirq = i; /* Identity mapped */
+               mp_irq.dstirq = i;
  
                save_mp_irq(&mp_irq);
        }
@@@ -1211,7 -1134,7 +1189,7 @@@ int mp_register_gsi(u32 gsi, int trigge
                return gsi;
        }
  
-       ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
+       ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
  
  #ifdef CONFIG_X86_32
        if (ioapic_renumber_irq)
@@@ -1285,22 -1208,22 +1263,22 @@@ int mp_config_acpi_gsi(unsigned char nu
                        u32 gsi, int triggering, int polarity)
  {
  #ifdef CONFIG_X86_MPPARSE
-       struct mp_config_intsrc mp_irq;
+       struct mpc_intsrc mp_irq;
        int ioapic;
  
        if (!acpi_ioapic)
                return 0;
  
        /* print the entry should happen on mptable identically */
-       mp_irq.mp_type = MP_INTSRC;
-       mp_irq.mp_irqtype = mp_INT;
-       mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
+       mp_irq.type = MP_INTSRC;
+       mp_irq.irqtype = mp_INT;
+       mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
                                (polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
-       mp_irq.mp_srcbus = number;
-       mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
+       mp_irq.srcbus = number;
+       mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
        ioapic = mp_find_ioapic(gsi);
-       mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id;
-       mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
+       mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
+       mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
  
        save_mp_irq(&mp_irq);
  #endif
@@@ -1427,7 -1350,7 +1405,7 @@@ static void __init acpi_process_madt(vo
                if (!error) {
                        acpi_lapic = 1;
  
- #ifdef CONFIG_X86_GENERICARCH
+ #ifdef CONFIG_X86_BIGSMP
                        generic_bigsmp_probe();
  #endif
                        /*
                                acpi_ioapic = 1;
  
                                smp_found_config = 1;
- #ifdef CONFIG_X86_32
-                               setup_apic_routing();
- #endif
+                               if (apic->setup_apic_routing)
+                                       apic->setup_apic_routing();
                        }
                }
                if (error == -EINVAL) {
@@@ -1548,7 -1470,7 +1525,7 @@@ static int __init dmi_ignore_irq0_timer
  
  /*
   * If your system is blacklisted here, but you find that acpi=force
 - * works for you, please contact acpi-devel@sourceforge.net
 + * works for you, please contact linux-acpi@vger.kernel.org
   */
  static struct dmi_system_id __initdata acpi_dmi_table[] = {
        /*
index 89c676d6caf7327fec9218384e56b2a85b0f0229,23da96e57b17ed610b7a2a940c9055e402590e11..022222c76e3b689f6e8937e77a3923b9008947f6
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
+  * acpi-cpufreq.c - ACPI Processor P-States Driver
   *
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  #include <linux/ftrace.h>
  
  #include <linux/acpi.h>
+ #include <linux/io.h>
+ #include <linux/delay.h>
+ #include <linux/uaccess.h>
  #include <acpi/processor.h>
  
- #include <asm/io.h>
  #include <asm/msr.h>
  #include <asm/processor.h>
  #include <asm/cpufeature.h>
- #include <asm/delay.h>
- #include <asm/uaccess.h>
  
- #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
+ #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+               "acpi-cpufreq", msg)
  
  MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
  MODULE_DESCRIPTION("ACPI Processor P-States Driver");
@@@ -95,7 -97,7 +97,7 @@@ static unsigned extract_io(u32 value, s
  
        perf = data->acpi_data;
  
-       for (i=0; i<perf->state_count; i++) {
+       for (i = 0; i < perf->state_count; i++) {
                if (value == perf->states[i].status)
                        return data->freq_table[i].frequency;
        }
@@@ -110,7 -112,7 +112,7 @@@ static unsigned extract_msr(u32 msr, st
        msr &= INTEL_MSR_RANGE;
        perf = data->acpi_data;
  
-       for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+       for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
                if (msr == perf->states[data->freq_table[i].index].status)
                        return data->freq_table[i].frequency;
        }
@@@ -138,15 -140,13 +140,13 @@@ struct io_addr 
        u8 bit_width;
  };
  
- typedef union {
-       struct msr_addr msr;
-       struct io_addr io;
- } drv_addr_union;
  struct drv_cmd {
        unsigned int type;
        const struct cpumask *mask;
-       drv_addr_union addr;
+       union {
+               struct msr_addr msr;
+               struct io_addr io;
+       } addr;
        u32 val;
  };
  
@@@ -369,7 -369,7 +369,7 @@@ static unsigned int check_freqs(const s
        unsigned int cur_freq;
        unsigned int i;
  
-       for (i=0; i<100; i++) {
+       for (i = 0; i < 100; i++) {
                cur_freq = extract_freq(get_cur_val(mask), data);
                if (cur_freq == freq)
                        return 1;
@@@ -494,7 -494,7 +494,7 @@@ acpi_cpufreq_guess_freq(struct acpi_cpu
                unsigned long freq;
                unsigned long freqn = perf->states[0].core_frequency * 1000;
  
-               for (i=0; i<(perf->state_count-1); i++) {
+               for (i = 0; i < (perf->state_count-1); i++) {
                        freq = freqn;
                        freqn = perf->states[i+1].core_frequency * 1000;
                        if ((2 * cpu_khz) > (freqn + freq)) {
@@@ -601,7 -601,7 +601,7 @@@ static int acpi_cpufreq_cpu_init(struc
        if (!data)
                return -ENOMEM;
  
-       data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
+       data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
        per_cpu(drv_data, cpu) = data;
  
        if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
  
        /* detect transition latency */
        policy->cpuinfo.transition_latency = 0;
-       for (i=0; i<perf->state_count; i++) {
+       for (i = 0; i < perf->state_count; i++) {
                if ((perf->states[i].transition_latency * 1000) >
                    policy->cpuinfo.transition_latency)
                        policy->cpuinfo.transition_latency =
                            perf->states[i].transition_latency * 1000;
        }
  
 +      /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
 +      if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
 +          policy->cpuinfo.transition_latency > 20 * 1000) {
 +              static int print_once;
 +              policy->cpuinfo.transition_latency = 20 * 1000;
 +              if (!print_once) {
 +                      print_once = 1;
 +                      printk(KERN_INFO "Capping off P-state tranision latency"
 +                              " at 20 uS\n");
 +              }
 +      }
 +
        data->max_freq = perf->states[0].core_frequency * 1000;
        /* table init */
-       for (i=0; i<perf->state_count; i++) {
-               if (i>0 && perf->states[i].core_frequency >=
+       for (i = 0; i < perf->state_count; i++) {
+               if (i > 0 && perf->states[i].core_frequency >=
                    data->freq_table[valid_states-1].frequency / 1000)
                        continue;
  
index 4e18d5119828767d88f2dddb5bda343b971aeb82,f1c51aea064df73fb28c3793da94c080703d4580..0bd48e65a0caa3a77335bd1e8d5a53bc8764fae3
  #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/delay.h>
+ #include <linux/timex.h>
+ #include <linux/io.h>
+ #include <linux/acpi.h>
+ #include <linux/kernel.h>
  
  #include <asm/msr.h>
- #include <asm/timex.h>
- #include <asm/io.h>
- #include <asm/acpi.h>
- #include <linux/acpi.h>
  #include <acpi/processor.h>
  
  #include "longhaul.h"
@@@ -58,7 -58,7 +58,7 @@@
  #define USE_NORTHBRIDGE               (1 << 2)
  
  static int cpu_model;
- static unsigned int numscales=16;
+ static unsigned int numscales = 16;
  static unsigned int fsb;
  
  static const struct mV_pos *vrm_mV_table;
@@@ -67,8 -67,8 +67,8 @@@ static const unsigned char *mV_vrm_tabl
  static unsigned int highest_speed, lowest_speed; /* kHz */
  static unsigned int minmult, maxmult;
  static int can_scale_voltage;
- static struct acpi_processor *pr = NULL;
- static struct acpi_processor_cx *cx = NULL;
+ static struct acpi_processor *pr;
+ static struct acpi_processor_cx *cx;
  static u32 acpi_regs_addr;
  static u8 longhaul_flags;
  static unsigned int longhaul_index;
@@@ -78,12 -78,13 +78,13 @@@ static int scale_voltage
  static int disable_acpi_c3;
  static int revid_errata;
  
- #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
+ #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+               "longhaul", msg)
  
  
  /* Clock ratios multiplied by 10 */
- static int clock_ratio[32];
- static int eblcr_table[32];
+ static int mults[32];
+ static int eblcr[32];
  static int longhaul_version;
  static struct cpufreq_frequency_table *longhaul_table;
  
@@@ -93,7 -94,7 +94,7 @@@ static char speedbuffer[8]
  static char *print_speed(int speed)
  {
        if (speed < 1000) {
-               snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed);
+               snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
                return speedbuffer;
        }
  
@@@ -122,27 -123,28 +123,28 @@@ static unsigned int calc_speed(int mult
  
  static int longhaul_get_cpu_mult(void)
  {
-       unsigned long invalue=0,lo, hi;
+       unsigned long invalue = 0, lo, hi;
  
-       rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
-       invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
-       if (longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) {
+       rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
+       invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
+       if (longhaul_version == TYPE_LONGHAUL_V2 ||
+           longhaul_version == TYPE_POWERSAVER) {
                if (lo & (1<<27))
-                       invalue+=16;
+                       invalue += 16;
        }
-       return eblcr_table[invalue];
+       return eblcr[invalue];
  }
  
  /* For processor with BCR2 MSR */
  
- static void do_longhaul1(unsigned int clock_ratio_index)
+ static void do_longhaul1(unsigned int mults_index)
  {
        union msr_bcr2 bcr2;
  
        rdmsrl(MSR_VIA_BCR2, bcr2.val);
        /* Enable software clock multiplier */
        bcr2.bits.ESOFTBF = 1;
-       bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff;
+       bcr2.bits.CLOCKMUL = mults_index & 0xff;
  
        /* Sync to timer tick */
        safe_halt();
  
  /* For processor with Longhaul MSR */
  
- static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
+ static void do_powersaver(int cx_address, unsigned int mults_index,
                          unsigned int dir)
  {
        union msr_longhaul longhaul;
                longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
        else
                longhaul.bits.RevisionKey = 0;
-       longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
-       longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
+       longhaul.bits.SoftBusRatio = mults_index & 0xf;
+       longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
        /* Setup new voltage */
        if (can_scale_voltage)
-               longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f;
+               longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
        /* Sync to timer tick */
        safe_halt();
        /* Raise voltage if necessary */
  
  /**
   * longhaul_set_cpu_frequency()
-  * @clock_ratio_index : bitpattern of the new multiplier.
+  * @mults_index : bitpattern of the new multiplier.
   *
   * Sets a new clock ratio.
   */
  
  static void longhaul_setstate(unsigned int table_index)
  {
-       unsigned int clock_ratio_index;
+       unsigned int mults_index;
        int speed, mult;
        struct cpufreq_freqs freqs;
        unsigned long flags;
        u32 bm_timeout = 1000;
        unsigned int dir = 0;
  
-       clock_ratio_index = longhaul_table[table_index].index;
+       mults_index = longhaul_table[table_index].index;
        /* Safety precautions */
-       mult = clock_ratio[clock_ratio_index & 0x1f];
+       mult = mults[mults_index & 0x1f];
        if (mult == -1)
                return;
        speed = calc_speed(mult);
  
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  
-       dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
+       dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
                        fsb, mult/10, mult%10, print_speed(speed/1000));
  retry_loop:
        preempt_disable();
  
        pic2_mask = inb(0xA1);
        pic1_mask = inb(0x21);  /* works on C3. save mask. */
-       outb(0xFF,0xA1);        /* Overkill */
-       outb(0xFE,0x21);        /* TMR0 only */
+       outb(0xFF, 0xA1);       /* Overkill */
+       outb(0xFE, 0x21);       /* TMR0 only */
  
        /* Wait while PCI bus is busy. */
        if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
                outb(3, 0x22);
        } else if ((pr != NULL) && pr->flags.bm_control) {
                /* Disable bus master arbitration */
 -              acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
 +              acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
        }
        switch (longhaul_version) {
  
         * Software controlled multipliers only.
         */
        case TYPE_LONGHAUL_V1:
-               do_longhaul1(clock_ratio_index);
+               do_longhaul1(mults_index);
                break;
  
        /*
        case TYPE_POWERSAVER:
                if (longhaul_flags & USE_ACPI_C3) {
                        /* Don't allow wakeup */
 -                      acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 +                      acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-                       do_powersaver(cx->address, clock_ratio_index, dir);
+                       do_powersaver(cx->address, mults_index, dir);
                } else {
-                       do_powersaver(0, clock_ratio_index, dir);
+                       do_powersaver(0, mults_index, dir);
                }
                break;
        }
                outb(0, 0x22);
        } else if ((pr != NULL) && pr->flags.bm_control) {
                /* Enable bus master arbitration */
 -              acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
 +              acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
        }
-       outb(pic2_mask,0xA1);   /* restore mask */
-       outb(pic1_mask,0x21);
+       outb(pic2_mask, 0xA1);  /* restore mask */
+       outb(pic1_mask, 0x21);
  
        local_irq_restore(flags);
        preempt_enable();
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  
        if (!bm_timeout)
-               printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n");
+               printk(KERN_INFO PFX "Warning: Timeout while waiting for "
+                               "idle PCI bus.\n");
  }
  
  /*
@@@ -458,31 -461,32 +461,32 @@@ static int __init longhaul_get_ranges(v
                break;
        }
  
-       dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
+       dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n",
                 minmult/10, minmult%10, maxmult/10, maxmult%10);
  
        highest_speed = calc_speed(maxmult);
        lowest_speed = calc_speed(minmult);
-       dprintk ("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
+       dprintk("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
                 print_speed(lowest_speed/1000),
                 print_speed(highest_speed/1000));
  
        if (lowest_speed == highest_speed) {
-               printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n");
+               printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
                return -EINVAL;
        }
        if (lowest_speed > highest_speed) {
-               printk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
+               printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
                        lowest_speed, highest_speed);
                return -EINVAL;
        }
  
-       longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
-       if(!longhaul_table)
+       longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
+                       GFP_KERNEL);
+       if (!longhaul_table)
                return -ENOMEM;
  
        for (j = 0; j < numscales; j++) {
-               ratio = clock_ratio[j];
+               ratio = mults[j];
                if (ratio == -1)
                        continue;
                if (ratio > maxmult || ratio < minmult)
                        }
                }
                if (min_i != j) {
-                       unsigned int temp;
-                       temp = longhaul_table[j].frequency;
-                       longhaul_table[j].frequency = longhaul_table[min_i].frequency;
-                       longhaul_table[min_i].frequency = temp;
-                       temp = longhaul_table[j].index;
-                       longhaul_table[j].index = longhaul_table[min_i].index;
-                       longhaul_table[min_i].index = temp;
+                       swap(longhaul_table[j].frequency,
+                            longhaul_table[min_i].frequency);
+                       swap(longhaul_table[j].index,
+                            longhaul_table[min_i].index);
                }
        }
  
  
        /* Find index we are running on */
        for (j = 0; j < k; j++) {
-               if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) {
+               if (mults[longhaul_table[j].index & 0x1f] == mult) {
                        longhaul_index = j;
                        break;
                }
@@@ -559,20 -560,22 +560,22 @@@ static void __init longhaul_setup_volta
        maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
  
        if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
-               printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
+               printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
                                        "Voltage scaling disabled.\n",
-                                       minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
+                                       minvid.mV/1000, minvid.mV%1000,
+                                       maxvid.mV/1000, maxvid.mV%1000);
                return;
        }
  
        if (minvid.mV == maxvid.mV) {
-               printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
-                               "both %d.%03d. Voltage scaling disabled\n",
+               printk(KERN_INFO PFX "Claims to support voltage scaling but "
+                               "min & max are both %d.%03d. "
+                               "Voltage scaling disabled\n",
                                maxvid.mV/1000, maxvid.mV%1000);
                return;
        }
  
-       /* How many voltage steps */
+       /* How many voltage steps*/
        numvscales = maxvid.pos - minvid.pos + 1;
        printk(KERN_INFO PFX
                "Max VID=%d.%03d  "
        j = longhaul.bits.MinMHzBR;
        if (longhaul.bits.MinMHzBR4)
                j += 16;
-       min_vid_speed = eblcr_table[j];
+       min_vid_speed = eblcr[j];
        if (min_vid_speed == -1)
                return;
        switch (longhaul.bits.MinMHzFSB) {
                        pos = minvid.pos;
                longhaul_table[j].index |= mV_vrm_table[pos] << 8;
                vid = vrm_mV_table[mV_vrm_table[pos]];
-               printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV);
+               printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
+                               speed, j, vid.mV);
                j++;
        }
  
@@@ -640,7 -644,8 +644,8 @@@ static int longhaul_target(struct cpufr
        unsigned int dir = 0;
        u8 vid, current_vid;
  
-       if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
+       if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
+                               relation, &table_index))
                return -EINVAL;
  
        /* Don't set same frequency again */
                 * this in hardware, C3 is old and we need to do this
                 * in software. */
                i = longhaul_index;
-               current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f;
+               current_vid = (longhaul_table[longhaul_index].index >> 8);
+               current_vid &= 0x1f;
                if (table_index > longhaul_index)
                        dir = 1;
                while (i != table_index) {
@@@ -691,9 -697,9 +697,9 @@@ static acpi_status longhaul_walk_callba
  {
        struct acpi_device *d;
  
-       if ( acpi_bus_get_device(obj_handle, &d) ) {
+       if (acpi_bus_get_device(obj_handle, &d))
                return 0;
-       }
        *return_value = acpi_driver_data(d);
        return 1;
  }
@@@ -750,7 -756,7 +756,7 @@@ static int longhaul_setup_southbridge(v
        /* Find VT8235 southbridge */
        dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
        if (dev == NULL)
-       /* Find VT8237 southbridge */
+               /* Find VT8237 southbridge */
                dev = pci_get_device(PCI_VENDOR_ID_VIA,
                                     PCI_DEVICE_ID_VIA_8237, NULL);
        if (dev != NULL) {
                if (pci_cmd & 1 << 7) {
                        pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
                        acpi_regs_addr &= 0xff00;
-                       printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr);
+                       printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
+                                       acpi_regs_addr);
                }
  
                pci_dev_put(dev);
  static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
  {
        struct cpuinfo_x86 *c = &cpu_data(0);
-       char *cpuname=NULL;
+       char *cpuname = NULL;
        int ret;
        u32 lo, hi;
  
                cpu_model = CPU_SAMUEL;
                cpuname = "C3 'Samuel' [C5A]";
                longhaul_version = TYPE_LONGHAUL_V1;
-               memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
-               memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr));
+               memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+               memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
                break;
  
        case 7:
                        cpuname = "C3 'Samuel 2' [C5B]";
                        /* Note, this is not a typo, early Samuel2's had
                         * Samuel1 ratios. */
-                       memcpy(clock_ratio, samuel1_clock_ratio,
-                               sizeof(samuel1_clock_ratio));
-                       memcpy(eblcr_table, samuel2_eblcr,
-                               sizeof(samuel2_eblcr));
+                       memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+                       memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
                        break;
                case 1 ... 15:
                        longhaul_version = TYPE_LONGHAUL_V1;
                                cpu_model = CPU_EZRA;
                                cpuname = "C3 'Ezra' [C5C]";
                        }
-                       memcpy(clock_ratio, ezra_clock_ratio,
-                               sizeof(ezra_clock_ratio));
-                       memcpy(eblcr_table, ezra_eblcr,
-                               sizeof(ezra_eblcr));
+                       memcpy(mults, ezra_mults, sizeof(ezra_mults));
+                       memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
                        break;
                }
                break;
                cpu_model = CPU_EZRA_T;
                cpuname = "C3 'Ezra-T' [C5M]";
                longhaul_version = TYPE_POWERSAVER;
-               numscales=32;
-               memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio));
-               memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr));
+               numscales = 32;
+               memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
+               memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
                break;
  
        case 9:
                longhaul_version = TYPE_POWERSAVER;
                numscales = 32;
-               memcpy(clock_ratio,
-                      nehemiah_clock_ratio,
-                      sizeof(nehemiah_clock_ratio));
-               memcpy(eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
+               memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
+               memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
                switch (c->x86_mask) {
                case 0 ... 1:
                        cpu_model = CPU_NEHEMIAH;
                        longhaul_version = TYPE_LONGHAUL_V1;
        }
  
-       printk (KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
+       printk(KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
        switch (longhaul_version) {
        case TYPE_LONGHAUL_V1:
        case TYPE_LONGHAUL_V2:
-               printk ("Longhaul v%d supported.\n", longhaul_version);
+               printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
                break;
        case TYPE_POWERSAVER:
-               printk ("Powersaver supported.\n");
+               printk(KERN_CONT "Powersaver supported.\n");
                break;
        };
  
@@@ -940,7 -941,7 +941,7 @@@ static int __devexit longhaul_cpu_exit(
        return 0;
  }
  
- static struct freq_attrlonghaul_attr[] = {
+ static struct freq_attr *longhaul_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        NULL,
  };
@@@ -966,13 -967,15 +967,15 @@@ static int __init longhaul_init(void
  
  #ifdef CONFIG_SMP
        if (num_online_cpus() > 1) {
-               printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n");
+               printk(KERN_ERR PFX "More than 1 CPU detected, "
+                               "longhaul disabled.\n");
                return -ENODEV;
        }
  #endif
  #ifdef CONFIG_X86_IO_APIC
        if (cpu_has_apic) {
-               printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n");
+               printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
+                               "broken in this configuration.\n");
                return -ENODEV;
        }
  #endif
@@@ -993,8 -996,8 +996,8 @@@ static void __exit longhaul_exit(void
  {
        int i;
  
-       for (i=0; i < numscales; i++) {
-               if (clock_ratio[i] == maxmult) {
+       for (i = 0; i < numscales; i++) {
+               if (mults[i] == maxmult) {
                        longhaul_setstate(i);
                        break;
                }
  /* Even if BIOS is exporting ACPI C3 state, and it is used
   * with success when CPU is idle, this state doesn't
   * trigger frequency transition in some cases. */
- module_param (disable_acpi_c3, int, 0644);
+ module_param(disable_acpi_c3, int, 0644);
  MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
  /* Change CPU voltage with frequency. Very usefull to save
   * power, but most VIA C3 processors aren't supporting it. */
- module_param (scale_voltage, int, 0644);
+ module_param(scale_voltage, int, 0644);
  MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
  /* Force revision key to 0 for processors which doesn't
   * support voltage scaling, but are introducing itself as
  module_param(revid_errata, int, 0644);
  MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
  
- MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
- MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
- MODULE_LICENSE ("GPL");
+ MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+ MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
+ MODULE_LICENSE("GPL");
  
  late_initcall(longhaul_init);
  module_exit(longhaul_exit);
diff --combined arch/x86/mm/srat_64.c
index 13d56f5b134925e7e2f68043c0ac9d8a6b4c4444,574c8bc95ef05c9253214fc71d34371818f1c78e..c7d272b8574cc1e55d9de9f10186dd1da5c75e85
@@@ -20,7 -20,8 +20,8 @@@
  #include <asm/proto.h>
  #include <asm/numa.h>
  #include <asm/e820.h>
- #include <asm/genapic.h>
+ #include <asm/apic.h>
+ #include <asm/uv/uv.h>
  
  int acpi_numa __initdata;
  
@@@ -115,36 -116,6 +116,36 @@@ void __init acpi_numa_slit_init(struct 
        reserve_early(phys, phys + length, "ACPI SLIT");
  }
  
 +/* Callback for Proximity Domain -> x2APIC mapping */
 +void __init
 +acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
 +{
 +      int pxm, node;
 +      int apic_id;
 +
 +      if (srat_disabled())
 +              return;
 +      if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
 +              bad_srat();
 +              return;
 +      }
 +      if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
 +              return;
 +      pxm = pa->proximity_domain;
 +      node = setup_node(pxm);
 +      if (node < 0) {
 +              printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
 +              bad_srat();
 +              return;
 +      }
 +
 +      apic_id = pa->apic_id;
 +      apicid_to_node[apic_id] = node;
 +      acpi_numa = 1;
 +      printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
 +             pxm, apic_id, node);
 +}
 +
  /* Callback for Proximity Domain -> LAPIC mapping */
  void __init
  acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
index dbca22651504b4dc15acec7b44a005ea36e7fed2,ab0aff3c7d6a3672bd7dd778853a77108e111528..a88f02bd6c94042e03ce24be89b2669a2182809b
@@@ -150,7 -150,8 +150,7 @@@ acpi_initialize_tables(struct acpi_tabl
         * Root Table Array. This array contains the information of the RSDT/XSDT
         * in a common, more useable format.
         */
 -      status =
 -          acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
 +      status = acpi_tb_parse_root_table(rsdp_address);
        return_ACPI_STATUS(status);
  }
  
@@@ -246,7 -247,7 +246,7 @@@ acpi_status acpi_load_table(struct acpi
  
  ACPI_EXPORT_SYMBOL(acpi_load_table)
  
 -/******************************************************************************
 +/*******************************************************************************
   *
   * FUNCTION:    acpi_get_table_header
   *
   * NOTE:        Caller is responsible in unmapping the header with
   *              acpi_os_unmap_memory
   *
 - *****************************************************************************/
 + ******************************************************************************/
  acpi_status
  acpi_get_table_header(char *signature,
                      u32 instance, struct acpi_table_header *out_table_header)
                return (AE_BAD_PARAMETER);
        }
  
 -      /*
 -       * Walk the root table list
 -       */
 +      /* Walk the root table list */
 +
        for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
                if (!ACPI_COMPARE_NAME
                    (&(acpi_gbl_root_table_list.tables[i].signature),
                }
  
                if (!acpi_gbl_root_table_list.tables[i].pointer) {
 -                      if ((acpi_gbl_root_table_list.tables[i].
 -                           flags & ACPI_TABLE_ORIGIN_MASK) ==
 +                      if ((acpi_gbl_root_table_list.tables[i].flags &
 +                           ACPI_TABLE_ORIGIN_MASK) ==
                            ACPI_TABLE_ORIGIN_MAPPED) {
                                header =
                                    acpi_os_map_memory(acpi_gbl_root_table_list.
  
  ACPI_EXPORT_SYMBOL(acpi_get_table_header)
  
 -/******************************************************************************
 +/*******************************************************************************
   *
   * FUNCTION:    acpi_unload_table_id
   *
@@@ -363,7 -365,7 +363,7 @@@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id
  
  /*******************************************************************************
   *
-  * FUNCTION:    acpi_get_table
+  * FUNCTION:    acpi_get_table_with_size
   *
   * PARAMETERS:  Signature           - ACPI signature of needed table
   *              Instance            - Which instance (for SSDTs)
   *
   * DESCRIPTION: Finds and verifies an ACPI table.
   *
 - *****************************************************************************/
 + ******************************************************************************/
  acpi_status
- acpi_get_table(char *signature,
-              u32 instance, struct acpi_table_header **out_table)
+ acpi_get_table_with_size(char *signature,
+              u32 instance, struct acpi_table_header **out_table,
+              acpi_size *tbl_size)
  {
         u32 i;
         u32 j;
                return (AE_BAD_PARAMETER);
        }
  
 -      /*
 -       * Walk the root table list
 -       */
 +      /* Walk the root table list */
 +
        for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
                if (!ACPI_COMPARE_NAME
                    (&(acpi_gbl_root_table_list.tables[i].signature),
                    acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
                if (ACPI_SUCCESS(status)) {
                        *out_table = acpi_gbl_root_table_list.tables[i].pointer;
+                       *tbl_size = acpi_gbl_root_table_list.tables[i].length;
                }
  
                if (!acpi_gbl_permanent_mmap) {
        return (AE_NOT_FOUND);
  }
  
+ acpi_status
+ acpi_get_table(char *signature,
+              u32 instance, struct acpi_table_header **out_table)
+ {
+       acpi_size tbl_size;
+       return acpi_get_table_with_size(signature,
+                      instance, out_table, &tbl_size);
+ }
  ACPI_EXPORT_SYMBOL(acpi_get_table)
  
  /*******************************************************************************
@@@ -488,6 -502,7 +499,6 @@@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_in
  static acpi_status acpi_tb_load_namespace(void)
  {
        acpi_status status;
 -      struct acpi_table_header *table;
        u32 i;
  
        ACPI_FUNCTION_TRACE(tb_load_namespace);
                goto unlock_and_exit;
        }
  
 -      /*
 -       * Find DSDT table
 -       */
 -      status =
 -          acpi_os_table_override(acpi_gbl_root_table_list.
 -                                 tables[ACPI_TABLE_INDEX_DSDT].pointer,
 -                                 &table);
 -      if (ACPI_SUCCESS(status) && table) {
 -              /*
 -               * DSDT table has been found
 -               */
 -              acpi_tb_delete_table(&acpi_gbl_root_table_list.
 -                                   tables[ACPI_TABLE_INDEX_DSDT]);
 -              acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
 -                  table;
 -              acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
 -                  table->length;
 -              acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
 -                  ACPI_TABLE_ORIGIN_UNKNOWN;
 -
 -              ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
 -              acpi_tb_print_table_header(0, table);
 -
 -              if (no_auto_ssdt == 0) {
 -                      printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
 -              }
 -      }
 +      /* A valid DSDT is required */
  
        status =
            acpi_tb_verify_table(&acpi_gbl_root_table_list.
                                 tables[ACPI_TABLE_INDEX_DSDT]);
        if (ACPI_FAILURE(status)) {
  
 -              /* A valid DSDT is required */
 -
                status = AE_NO_ACPI_TABLES;
                goto unlock_and_exit;
        }
  
        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  
 -      /*
 -       * Load and parse tables.
 -       */
 +      /* Load and parse tables */
 +
        status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
  
 -      /*
 -       * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
 -       */
 +      /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
 +
        (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
        for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
                if ((!ACPI_COMPARE_NAME
@@@ -585,8 -630,9 +596,8 @@@ acpi_status acpi_load_tables(void
  
        ACPI_FUNCTION_TRACE(acpi_load_tables);
  
 -      /*
 -       * Load the namespace from the tables
 -       */
 +      /* Load the namespace from the tables */
 +
        status = acpi_tb_load_namespace();
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status,
diff --combined drivers/acpi/battery.c
index 2abc03668627666ff9322618c750d84655a1177e,3bcb5bfc45d3366645bfdf6a417d6c140e30107d..b0de6312919a82a455f20f8d06dddd8f1b672d80
@@@ -30,7 -30,6 +30,7 @@@
  #include <linux/init.h>
  #include <linux/types.h>
  #include <linux/jiffies.h>
 +#include <linux/async.h>
  
  #ifdef CONFIG_ACPI_PROCFS_POWER
  #include <linux/proc_fs.h>
@@@ -93,7 -92,7 +93,7 @@@ struct acpi_battery 
  #endif
        struct acpi_device *device;
        unsigned long update_time;
 -      int current_now;
 +      int rate_now;
        int capacity_now;
        int voltage_now;
        int design_capacity;
@@@ -197,8 -196,7 +197,8 @@@ static int acpi_battery_get_property(st
                val->intval = battery->voltage_now * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
 -              val->intval = battery->current_now * 1000;
 +      case POWER_SUPPLY_PROP_POWER_NOW:
 +              val->intval = battery->rate_now * 1000;
                break;
        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
        case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@@ -249,7 -247,6 +249,7 @@@ static enum power_supply_property energ
        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_CURRENT_NOW,
 +      POWER_SUPPLY_PROP_POWER_NOW,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
        POWER_SUPPLY_PROP_ENERGY_NOW,
@@@ -276,7 -273,7 +276,7 @@@ struct acpi_offsets 
  
  static struct acpi_offsets state_offsets[] = {
        {offsetof(struct acpi_battery, state), 0},
 -      {offsetof(struct acpi_battery, current_now), 0},
 +      {offsetof(struct acpi_battery, rate_now), 0},
        {offsetof(struct acpi_battery, capacity_now), 0},
        {offsetof(struct acpi_battery, voltage_now), 0},
  };
@@@ -608,11 -605,11 +608,11 @@@ static int acpi_battery_print_state(str
        else
                seq_printf(seq, "charging state:          charged\n");
  
 -      if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
 +      if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "present rate:            unknown\n");
        else
                seq_printf(seq, "present rate:            %d %s\n",
 -                         battery->current_now, acpi_battery_units(battery));
 +                         battery->rate_now, acpi_battery_units(battery));
  
        if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "remaining capacity:      unknown\n");
@@@ -743,7 -740,7 +743,7 @@@ DECLARE_FILE_FUNCTIONS(alarm)
  static struct battery_file {
        struct file_operations ops;
        mode_t mode;
 -      char *name;
 +      const char *name;
  } acpi_battery_file[] = {
        FILE_DESCRIPTION_RO(info),
        FILE_DESCRIPTION_RO(state),
@@@ -763,7 -760,6 +763,6 @@@ static int acpi_battery_add_fs(struct a
                                                     acpi_battery_dir);
                if (!acpi_device_dir(device))
                        return -ENODEV;
-               acpi_device_dir(device)->owner = THIS_MODULE;
        }
  
        for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
@@@ -904,27 -900,21 +903,27 @@@ static struct acpi_driver acpi_battery_
                },
  };
  
 -static int __init acpi_battery_init(void)
 +static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
  {
        if (acpi_disabled)
 -              return -ENODEV;
 +              return;
  #ifdef CONFIG_ACPI_PROCFS_POWER
        acpi_battery_dir = acpi_lock_battery_dir();
        if (!acpi_battery_dir)
 -              return -ENODEV;
 +              return;
  #endif
        if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
  #ifdef CONFIG_ACPI_PROCFS_POWER
                acpi_unlock_battery_dir(acpi_battery_dir);
  #endif
 -              return -ENODEV;
 +              return;
        }
 +      return;
 +}
 +
 +static int __init acpi_battery_init(void)
 +{
 +      async_schedule(acpi_battery_init_async, NULL);
        return 0;
  }
  
diff --combined drivers/acpi/dock.c
index 8f62fa01a9c76f910d1c88d4245f18eeab995708,7af7db1ba8c452c05ef730ab432cabb8c7b59309..efb959d6c8a98c654e88e8de4ce6056ac26482aa
@@@ -977,7 -977,7 +977,7 @@@ static int dock_add(acpi_handle handle
                sizeof(struct dock_station *));
  
        /* we want the dock device to send uevents */
-       dock_device->dev.uevent_suppress = 0;
+       dev_set_uevent_suppress(&dock_device->dev, 0);
  
        if (is_dock(handle))
                dock_station->flags |= DOCK_IS_DOCK;
@@@ -1146,10 -1146,9 +1146,10 @@@ static int __init dock_init(void
  static void __exit dock_exit(void)
  {
        struct dock_station *dock_station;
 +      struct dock_station *tmp;
  
        unregister_acpi_bus_notifier(&dock_acpi_notifier);
 -      list_for_each_entry(dock_station, &dock_stations, sibiling)
 +      list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
                dock_remove(dock_station);
  }
  
diff --combined drivers/acpi/fan.c
index ae41cf3cf4e567e7497927d93779956af82164a4,8a02944bf92d687e4b1cf5c3e79b8efce59c9d6a..53698ea0837139996e6ae845168cc6e3b2337bdf
@@@ -68,35 -68,31 +68,35 @@@ static struct acpi_driver acpi_fan_driv
  };
  
  /* thermal cooling device callbacks */
 -static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
 +static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
 +                           *state)
  {
        /* ACPI fan device only support two states: ON/OFF */
 -      return sprintf(buf, "1\n");
 +      *state = 1;
 +      return 0;
  }
  
 -static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 +static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
 +                           *state)
  {
        struct acpi_device *device = cdev->devdata;
 -      int state;
        int result;
 +      int acpi_state;
  
        if (!device)
                return -EINVAL;
  
 -      result = acpi_bus_get_power(device->handle, &state);
 +      result = acpi_bus_get_power(device->handle, &acpi_state);
        if (result)
                return result;
  
 -      return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
 -                       (state == ACPI_STATE_D0 ? "1" : "unknown"));
 +      *state = (acpi_state == ACPI_STATE_D3 ? 0 :
 +               (acpi_state == ACPI_STATE_D0 ? 1 : -1));
 +      return 0;
  }
  
  static int
 -fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
 +fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  {
        struct acpi_device *device = cdev->devdata;
        int result;
@@@ -197,7 -193,6 +197,6 @@@ static int acpi_fan_add_fs(struct acpi_
                                                     acpi_fan_dir);
                if (!acpi_device_dir(device))
                        return -ENODEV;
-               acpi_device_dir(device)->owner = THIS_MODULE;
        }
  
        /* 'status' [R/W] */
@@@ -351,7 -346,6 +350,6 @@@ static int __init acpi_fan_init(void
        acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
        if (!acpi_fan_dir)
                return -ENODEV;
-       acpi_fan_dir->owner = THIS_MODULE;
  #endif
  
        result = acpi_bus_register_driver(&acpi_fan_driver);
diff --combined drivers/acpi/osl.c
index f50ca1ea80c32b79cb4b411df3c1465a582e7044,eb8980d67368e12b45667ddc87cba141bf4024de..d59f08ecaf1602d58cc908bee72966736caa7f0d
@@@ -272,14 -272,21 +272,21 @@@ acpi_os_map_memory(acpi_physical_addres
  }
  EXPORT_SYMBOL_GPL(acpi_os_map_memory);
  
- void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
+ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
  {
-       if (acpi_gbl_permanent_mmap) {
+       if (acpi_gbl_permanent_mmap)
                iounmap(virt);
-       }
+       else
+               __acpi_unmap_table(virt, size);
  }
  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
  
+ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+ {
+       if (!acpi_gbl_permanent_mmap)
+               __acpi_unmap_table(virt, size);
+ }
  #ifdef ACPI_FUTURE_USAGE
  acpi_status
  acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
@@@ -1063,9 -1070,9 +1070,9 @@@ __setup("acpi_wake_gpes_always_on", acp
   * in arbitrary AML code and can interfere with legacy drivers.
   * acpi_enforce_resources= can be set to:
   *
 - *   - strict           (2)
 + *   - strict (default) (2)
   *     -> further driver trying to access the resources will not load
 - *   - lax (default)    (1)
 + *   - lax              (1)
   *     -> further driver trying to access the resources will load, but you
   *     get a system message that something might go wrong...
   *
  #define ENFORCE_RESOURCES_LAX    1
  #define ENFORCE_RESOURCES_NO     0
  
 -static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
 +static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
  
  static int __init acpi_enforce_resources_setup(char *str)
  {
index 775324e34ffa04a202c5986098d1ecb8df520ec1,fa2f7422d23de1e2bec5ee3702fa15e2a5ca284c..8e683f8cc573c2129ec3869dcada94507d7e6829
@@@ -359,7 -359,6 +359,6 @@@ static int acpi_processor_add_fs(struc
                if (!acpi_device_dir(device))
                        return -ENODEV;
        }
-       acpi_device_dir(device)->owner = THIS_MODULE;
  
        /* 'info' [R] */
        entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
@@@ -427,29 -426,6 +426,29 @@@ static int map_lapic_id(struct acpi_sub
        return 0;
  }
  
 +static int map_x2apic_id(struct acpi_subtable_header *entry,
 +                       int device_declaration, u32 acpi_id, int *apic_id)
 +{
 +      struct acpi_madt_local_x2apic *apic =
 +              (struct acpi_madt_local_x2apic *)entry;
 +      u32 tmp = apic->local_apic_id;
 +
 +      /* Only check enabled APICs*/
 +      if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
 +              return 0;
 +
 +      /* Device statement declaration type */
 +      if (device_declaration) {
 +              if (apic->uid == acpi_id)
 +                      goto found;
 +      }
 +
 +      return 0;
 +found:
 +      *apic_id = tmp;
 +      return 1;
 +}
 +
  static int map_lsapic_id(struct acpi_subtable_header *entry,
                int device_declaration, u32 acpi_id, int *apic_id)
  {
@@@ -499,9 -475,6 +498,9 @@@ static int map_madt_entry(int type, u3
                if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
                        if (map_lapic_id(header, acpi_id, &apic_id))
                                break;
 +              } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
 +                      if (map_x2apic_id(header, type, acpi_id, &apic_id))
 +                              break;
                } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
                        if (map_lsapic_id(header, type, acpi_id, &apic_id))
                                break;
@@@ -1163,7 -1136,6 +1162,6 @@@ static int __init acpi_processor_init(v
        acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
        if (!acpi_processor_dir)
                return -ENOMEM;
-       acpi_processor_dir->owner = THIS_MODULE;
  
        /*
         * Check whether the system is DMI table. If yes, OSPM
index 215f1bf7d4c14b1aac0d40e5c0c36b95ee53aea1,68fd3d2927997efe09ced4d0df8120afa8adc7ce..cafb41000f6bd6b36eaaa4b4348faef59e5c0e49
@@@ -479,13 -479,6 +479,13 @@@ static int acpi_processor_get_psd(struc
                goto end;
        }
  
 +      if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
 +          pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
 +          pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
 +              printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
 +              result = -EFAULT;
 +              goto end;
 +      }
  end:
        kfree(buffer.pointer);
        return result;
@@@ -508,10 -501,9 +508,10 @@@ int acpi_processor_preregister_performa
  
        mutex_lock(&performance_mutex);
  
 -      retval = 0;
 -
 -      /* Call _PSD for all CPUs */
 +      /*
 +       * Check if another driver has already registered, and abort before
 +       * changing pr->performance if it has. Check input data as well.
 +       */
        for_each_possible_cpu(i) {
                pr = per_cpu(processors, i);
                if (!pr) {
  
                if (pr->performance) {
                        retval = -EBUSY;
 -                      continue;
 +                      goto err_out;
                }
  
-               if (!performance || !percpu_ptr(performance, i)) {
+               if (!performance || !per_cpu_ptr(performance, i)) {
                        retval = -EINVAL;
 -                      continue;
 +                      goto err_out;
                }
 +      }
 +
 +      /* Call _PSD for all CPUs */
 +      for_each_possible_cpu(i) {
 +              pr = per_cpu(processors, i);
 +              if (!pr)
 +                      continue;
  
-               pr->performance = percpu_ptr(performance, i);
+               pr->performance = per_cpu_ptr(performance, i);
                cpumask_set_cpu(i, pr->performance->shared_cpu_map);
                if (acpi_processor_get_psd(pr)) {
                        retval = -EINVAL;
         * Now that we have _PSD data from all CPUs, lets setup P-state 
         * domain info.
         */
 -      for_each_possible_cpu(i) {
 -              pr = per_cpu(processors, i);
 -              if (!pr)
 -                      continue;
 -
 -              /* Basic validity check for domain info */
 -              pdomain = &(pr->performance->domain_info);
 -              if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
 -                  (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
 -                      retval = -EINVAL;
 -                      goto err_ret;
 -              }
 -              if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
 -                  pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
 -                  pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
 -                      retval = -EINVAL;
 -                      goto err_ret;
 -              }
 -      }
 -
        cpumask_clear(covered_cpus);
        for_each_possible_cpu(i) {
                pr = per_cpu(processors, i);
@@@ -638,7 -643,6 +638,7 @@@ err_ret
                pr->performance = NULL; /* Will be set for real in register */
        }
  
 +err_out:
        mutex_unlock(&performance_mutex);
        free_cpumask_var(covered_cpus);
        return retval;
diff --combined drivers/acpi/sbs.c
index bb8fd1b6054bdf4da4d934064c21915048fabea2,59afd52ccc121aace5b3d47b56442d718901a090..4b214b74ebaa71c69fb1e3ed8193fdebd5c80d3d
@@@ -102,8 -102,8 +102,8 @@@ struct acpi_battery 
        u16 cycle_count;
        u16 temp_now;
        u16 voltage_now;
 -      s16 current_now;
 -      s16 current_avg;
 +      s16 rate_now;
 +      s16 rate_avg;
        u16 capacity_now;
        u16 state_of_charge;
        u16 state;
@@@ -202,9 -202,9 +202,9 @@@ static int acpi_sbs_battery_get_propert
                return -ENODEV;
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
 -              if (battery->current_now < 0)
 +              if (battery->rate_now < 0)
                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 -              else if (battery->current_now > 0)
 +              else if (battery->rate_now > 0)
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else
                        val->intval = POWER_SUPPLY_STATUS_FULL;
                                acpi_battery_vscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
 -              val->intval = abs(battery->current_now) *
 +      case POWER_SUPPLY_PROP_POWER_NOW:
 +              val->intval = abs(battery->rate_now) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CURRENT_AVG:
 -              val->intval = abs(battery->current_avg) *
 +      case POWER_SUPPLY_PROP_POWER_AVG:
 +              val->intval = abs(battery->rate_avg) *
                                acpi_battery_ipscale(battery) * 1000;
                break;
        case POWER_SUPPLY_PROP_CAPACITY:
@@@ -295,8 -293,6 +295,8 @@@ static enum power_supply_property sbs_e
        POWER_SUPPLY_PROP_VOLTAGE_NOW,
        POWER_SUPPLY_PROP_CURRENT_NOW,
        POWER_SUPPLY_PROP_CURRENT_AVG,
 +      POWER_SUPPLY_PROP_POWER_NOW,
 +      POWER_SUPPLY_PROP_POWER_AVG,
        POWER_SUPPLY_PROP_CAPACITY,
        POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
        POWER_SUPPLY_PROP_ENERGY_FULL,
        POWER_SUPPLY_PROP_MODEL_NAME,
        POWER_SUPPLY_PROP_MANUFACTURER,
  };
 +
  #endif
  
  /* --------------------------------------------------------------------------
@@@ -335,8 -330,8 +335,8 @@@ static struct acpi_battery_reader info_
  static struct acpi_battery_reader state_readers[] = {
        {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
        {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
 -      {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
 -      {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
 +      {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
 +      {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
        {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
        {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
        {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@@ -484,16 -479,15 +484,15 @@@ static in
  acpi_sbs_add_fs(struct proc_dir_entry **dir,
                struct proc_dir_entry *parent_dir,
                char *dir_name,
 -              struct file_operations *info_fops,
 -              struct file_operations *state_fops,
 -              struct file_operations *alarm_fops, void *data)
 +              const struct file_operations *info_fops,
 +              const struct file_operations *state_fops,
 +              const struct file_operations *alarm_fops, void *data)
  {
        if (!*dir) {
                *dir = proc_mkdir(dir_name, parent_dir);
                if (!*dir) {
                        return -ENODEV;
                }
-               (*dir)->owner = THIS_MODULE;
        }
  
        /* 'info' [R] */
@@@ -594,9 -588,9 +593,9 @@@ static int acpi_battery_read_state(stru
        seq_printf(seq, "capacity state:          %s\n",
                   (battery->state & 0x0010) ? "critical" : "ok");
        seq_printf(seq, "charging state:          %s\n",
 -                 (battery->current_now < 0) ? "discharging" :
 -                 ((battery->current_now > 0) ? "charging" : "charged"));
 -      rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
 +                 (battery->rate_now < 0) ? "discharging" :
 +                 ((battery->rate_now > 0) ? "charging" : "charged"));
 +      rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
        rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
                        acpi_battery_vscale(battery)/1000):1;
        seq_printf(seq, "present rate:            %d%s\n", rate,
@@@ -682,7 -676,7 +681,7 @@@ static int acpi_battery_alarm_open_fs(s
        return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
  }
  
 -static struct file_operations acpi_battery_info_fops = {
 +static const struct file_operations acpi_battery_info_fops = {
        .open = acpi_battery_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .owner = THIS_MODULE,
  };
  
 -static struct file_operations acpi_battery_state_fops = {
 +static const struct file_operations acpi_battery_state_fops = {
        .open = acpi_battery_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .owner = THIS_MODULE,
  };
  
 -static struct file_operations acpi_battery_alarm_fops = {
 +static const struct file_operations acpi_battery_alarm_fops = {
        .open = acpi_battery_alarm_open_fs,
        .read = seq_read,
        .write = acpi_battery_write_alarm,
@@@ -730,7 -724,7 +729,7 @@@ static int acpi_ac_state_open_fs(struc
        return single_open(file, acpi_ac_read_state, PDE(inode)->data);
  }
  
 -static struct file_operations acpi_ac_state_fops = {
 +static const struct file_operations acpi_ac_state_fops = {
        .open = acpi_ac_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
diff --combined drivers/acpi/tables.c
index 991c006a301ba211f1db5474b283aec0b29c3a42,fec1ae36d4310cadca89ff36c2e3174480c765dc..646d39c031caa4cc6de4a9884fea83fdf945e92a
@@@ -62,18 -62,6 +62,18 @@@ void acpi_table_print_madt_entry(struc
                }
                break;
  
 +      case ACPI_MADT_TYPE_LOCAL_X2APIC:
 +              {
 +                      struct acpi_madt_local_x2apic *p =
 +                          (struct acpi_madt_local_x2apic *)header;
 +                      printk(KERN_INFO PREFIX
 +                             "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
 +                             p->local_apic_id, p->uid,
 +                             (p->lapic_flags & ACPI_MADT_ENABLED) ?
 +                             "enabled" : "disabled");
 +              }
 +              break;
 +
        case ACPI_MADT_TYPE_IO_APIC:
                {
                        struct acpi_madt_io_apic *p =
                }
                break;
  
 +      case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
 +              {
 +                      u16 polarity, trigger;
 +                      struct acpi_madt_local_x2apic_nmi *p =
 +                          (struct acpi_madt_local_x2apic_nmi *)header;
 +
 +                      polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
 +                      trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
 +
 +                      printk(KERN_INFO PREFIX
 +                             "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
 +                             p->uid,
 +                             mps_inti_flags_polarity[polarity],
 +                             mps_inti_flags_trigger[trigger],
 +                             p->lint);
 +              }
 +              break;
 +
        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
                {
                        struct acpi_madt_local_apic_override *p =
@@@ -211,14 -181,15 +211,15 @@@ acpi_table_parse_entries(char *id
        struct acpi_subtable_header *entry;
        unsigned int count = 0;
        unsigned long table_end;
+       acpi_size tbl_size;
  
        if (!handler)
                return -EINVAL;
  
        if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-               acpi_get_table(id, acpi_apic_instance, &table_header);
+               acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
        else
-               acpi_get_table(id, 0, &table_header);
+               acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
  
        if (!table_header) {
                printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
               table_end) {
                if (entry->type == entry_id
                    && (!max_entries || count++ < max_entries))
-                       if (handler(entry, table_end))
+                       if (handler(entry, table_end)) {
+                               early_acpi_os_unmap_memory((char *)table_header, tbl_size);
                                return -EINVAL;
+                       }
  
                entry = (struct acpi_subtable_header *)
                    ((unsigned long)entry + entry->length);
                       "%i found\n", id, entry_id, count - max_entries, count);
        }
  
+       early_acpi_os_unmap_memory((char *)table_header, tbl_size);
        return count;
  }
  
@@@ -271,17 -245,19 +275,19 @@@ acpi_table_parse_madt(enum acpi_madt_ty
  int __init acpi_table_parse(char *id, acpi_table_handler handler)
  {
        struct acpi_table_header *table = NULL;
+       acpi_size tbl_size;
  
        if (!handler)
                return -EINVAL;
  
        if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-               acpi_get_table(id, acpi_apic_instance, &table);
+               acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size);
        else
-               acpi_get_table(id, 0, &table);
+               acpi_get_table_with_size(id, 0, &table, &tbl_size);
  
        if (table) {
                handler(table);
+               early_acpi_os_unmap_memory(table, tbl_size);
                return 0;
        } else
                return 1;
  static void __init check_multiple_madt(void)
  {
        struct acpi_table_header *table = NULL;
+       acpi_size tbl_size;
  
-       acpi_get_table(ACPI_SIG_MADT, 2, &table);
+       acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size);
        if (table) {
                printk(KERN_WARNING PREFIX
                       "BIOS bug: multiple APIC/MADT found,"
                       "If \"acpi_apic_instance=%d\" works better, "
                       "notify linux-acpi@vger.kernel.org\n",
                       acpi_apic_instance ? 0 : 2);
+               early_acpi_os_unmap_memory(table, tbl_size);
  
        } else
                acpi_apic_instance = 0;
diff --combined drivers/acpi/thermal.c
index 6b959976b7a42444c5c8c36ec859e9cd4343b81c,1ba9d61ea69a01289e9d25db201c387cf22fe55d..e8c143caf0fd6db6786944977c883af949ae84ca
  #include <linux/init.h>
  #include <linux/types.h>
  #include <linux/proc_fs.h>
 -#include <linux/timer.h>
  #include <linux/jiffies.h>
  #include <linux/kmod.h>
  #include <linux/seq_file.h>
  #include <linux/reboot.h>
 +#include <linux/device.h>
  #include <asm/uaccess.h>
  #include <linux/thermal.h>
  #include <acpi/acpi_bus.h>
@@@ -190,6 -190,7 +190,6 @@@ struct acpi_thermal 
        struct acpi_thermal_state state;
        struct acpi_thermal_trips trips;
        struct acpi_handle_list devices;
 -      struct timer_list timer;
        struct thermal_zone_device *thermal_zone;
        int tz_enabled;
        struct mutex lock;
@@@ -289,11 -290,6 +289,11 @@@ static int acpi_thermal_set_polling(str
  
        tz->polling_frequency = seconds * 10;   /* Convert value to deci-seconds */
  
 +      tz->thermal_zone->polling_delay = seconds * 1000;
 +
 +      if (tz->tz_enabled)
 +              thermal_zone_device_update(tz->thermal_zone);
 +
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "Polling frequency set to %lu seconds\n",
                          tz->polling_frequency/10));
@@@ -371,7 -367,7 +371,7 @@@ static int acpi_thermal_trips_update(st
                /*
                 * Treat freezing temperatures as invalid as well; some
                 * BIOSes return really low values and cause reboots at startup.
-                * Below zero (Celcius) values clearly aren't right for sure..
+                * Below zero (Celsius) values clearly aren't right for sure..
                 * ... so lets discard those as invalid.
                 */
                if (ACPI_FAILURE(status) ||
@@@ -573,18 -569,392 +573,18 @@@ static int acpi_thermal_get_trip_points
        return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
  }
  
 -static int acpi_thermal_critical(struct acpi_thermal *tz)
 -{
 -      if (!tz || !tz->trips.critical.flags.valid)
 -              return -EINVAL;
 -
 -      if (tz->temperature >= tz->trips.critical.temperature) {
 -              printk(KERN_WARNING PREFIX "Critical trip point\n");
 -              tz->trips.critical.flags.enabled = 1;
 -      } else if (tz->trips.critical.flags.enabled)
 -              tz->trips.critical.flags.enabled = 0;
 -
 -      acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
 -                              tz->trips.critical.flags.enabled);
 -      acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
 -                                        dev_name(&tz->device->dev),
 -                                        ACPI_THERMAL_NOTIFY_CRITICAL,
 -                                        tz->trips.critical.flags.enabled);
 -
 -      /* take no action if nocrt is set */
 -      if(!nocrt) {
 -              printk(KERN_EMERG
 -                      "Critical temperature reached (%ld C), shutting down.\n",
 -                      KELVIN_TO_CELSIUS(tz->temperature));
 -              orderly_poweroff(true);
 -      }
 -
 -      return 0;
 -}
 -
 -static int acpi_thermal_hot(struct acpi_thermal *tz)
 -{
 -      if (!tz || !tz->trips.hot.flags.valid)
 -              return -EINVAL;
 -
 -      if (tz->temperature >= tz->trips.hot.temperature) {
 -              printk(KERN_WARNING PREFIX "Hot trip point\n");
 -              tz->trips.hot.flags.enabled = 1;
 -      } else if (tz->trips.hot.flags.enabled)
 -              tz->trips.hot.flags.enabled = 0;
 -
 -      acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
 -                              tz->trips.hot.flags.enabled);
 -      acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
 -                                        dev_name(&tz->device->dev),
 -                                        ACPI_THERMAL_NOTIFY_HOT,
 -                                        tz->trips.hot.flags.enabled);
 -
 -      /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
 -
 -      return 0;
 -}
 -
 -static void acpi_thermal_passive(struct acpi_thermal *tz)
 -{
 -      int result = 1;
 -      struct acpi_thermal_passive *passive = NULL;
 -      int trend = 0;
 -      int i = 0;
 -
 -
 -      if (!tz || !tz->trips.passive.flags.valid)
 -              return;
 -
 -      passive = &(tz->trips.passive);
 -
 -      /*
 -       * Above Trip?
 -       * -----------
 -       * Calculate the thermal trend (using the passive cooling equation)
 -       * and modify the performance limit for all passive cooling devices
 -       * accordingly.  Note that we assume symmetry.
 -       */
 -      if (tz->temperature >= passive->temperature) {
 -              trend =
 -                  (passive->tc1 * (tz->temperature - tz->last_temperature)) +
 -                  (passive->tc2 * (tz->temperature - passive->temperature));
 -              ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 -                                "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
 -                                trend, passive->tc1, tz->temperature,
 -                                tz->last_temperature, passive->tc2,
 -                                tz->temperature, passive->temperature));
 -              passive->flags.enabled = 1;
 -              /* Heating up? */
 -              if (trend > 0)
 -                      for (i = 0; i < passive->devices.count; i++)
 -                              acpi_processor_set_thermal_limit(passive->
 -                                                               devices.
 -                                                               handles[i],
 -                                                               ACPI_PROCESSOR_LIMIT_INCREMENT);
 -              /* Cooling off? */
 -              else if (trend < 0) {
 -                      for (i = 0; i < passive->devices.count; i++)
 -                              /*
 -                               * assume that we are on highest
 -                               * freq/lowest thrott and can leave
 -                               * passive mode, even in error case
 -                               */
 -                              if (!acpi_processor_set_thermal_limit
 -                                  (passive->devices.handles[i],
 -                                   ACPI_PROCESSOR_LIMIT_DECREMENT))
 -                                      result = 0;
 -                      /*
 -                       * Leave cooling mode, even if the temp might
 -                       * higher than trip point This is because some
 -                       * machines might have long thermal polling
 -                       * frequencies (tsp) defined. We will fall back
 -                       * into passive mode in next cycle (probably quicker)
 -                       */
 -                      if (result) {
 -                              passive->flags.enabled = 0;
 -                              ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 -                                                "Disabling passive cooling, still above threshold,"
 -                                                " but we are cooling down\n"));
 -                      }
 -              }
 -              return;
 -      }
 -
 -      /*
 -       * Below Trip?
 -       * -----------
 -       * Implement passive cooling hysteresis to slowly increase performance
 -       * and avoid thrashing around the passive trip point.  Note that we
 -       * assume symmetry.
 -       */
 -      if (!passive->flags.enabled)
 -              return;
 -      for (i = 0; i < passive->devices.count; i++)
 -              if (!acpi_processor_set_thermal_limit
 -                  (passive->devices.handles[i],
 -                   ACPI_PROCESSOR_LIMIT_DECREMENT))
 -                      result = 0;
 -      if (result) {
 -              passive->flags.enabled = 0;
 -              ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 -                                "Disabling passive cooling (zone is cool)\n"));
 -      }
 -}
 -
 -static void acpi_thermal_active(struct acpi_thermal *tz)
 -{
 -      int result = 0;
 -      struct acpi_thermal_active *active = NULL;
 -      int i = 0;
 -      int j = 0;
 -      unsigned long maxtemp = 0;
 -
 -
 -      if (!tz)
 -              return;
 -
 -      for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
 -              active = &(tz->trips.active[i]);
 -              if (!active || !active->flags.valid)
 -                      break;
 -              if (tz->temperature >= active->temperature) {
 -                      /*
 -                       * Above Threshold?
 -                       * ----------------
 -                       * If not already enabled, turn ON all cooling devices
 -                       * associated with this active threshold.
 -                       */
 -                      if (active->temperature > maxtemp)
 -                              tz->state.active_index = i;
 -                      maxtemp = active->temperature;
 -                      if (active->flags.enabled)
 -                              continue;
 -                      for (j = 0; j < active->devices.count; j++) {
 -                              result =
 -                                  acpi_bus_set_power(active->devices.
 -                                                     handles[j],
 -                                                     ACPI_STATE_D0);
 -                              if (result) {
 -                                      printk(KERN_WARNING PREFIX
 -                                                    "Unable to turn cooling device [%p] 'on'\n",
 -                                                    active->devices.
 -                                                    handles[j]);
 -                                      continue;
 -                              }
 -                              active->flags.enabled = 1;
 -                              ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 -                                                "Cooling device [%p] now 'on'\n",
 -                                                active->devices.handles[j]));
 -                      }
 -                      continue;
 -              }
 -              if (!active->flags.enabled)
 -                      continue;
 -              /*
 -               * Below Threshold?
 -               * ----------------
 -               * Turn OFF all cooling devices associated with this
 -               * threshold.
 -               */
 -              for (j = 0; j < active->devices.count; j++) {
 -                      result = acpi_bus_set_power(active->devices.handles[j],
 -                                                  ACPI_STATE_D3);
 -                      if (result) {
 -                              printk(KERN_WARNING PREFIX
 -                                            "Unable to turn cooling device [%p] 'off'\n",
 -                                            active->devices.handles[j]);
 -                              continue;
 -                      }
 -                      active->flags.enabled = 0;
 -                      ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 -                                        "Cooling device [%p] now 'off'\n",
 -                                        active->devices.handles[j]));
 -              }
 -      }
 -}
 -
 -static void acpi_thermal_check(void *context);
 -
 -static void acpi_thermal_run(unsigned long data)
 -{
 -      struct acpi_thermal *tz = (struct acpi_thermal *)data;
 -      if (!tz->zombie)
 -              acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
 -}
 -
 -static void acpi_thermal_active_off(void *data)
 -{
 -      int result = 0;
 -      struct acpi_thermal *tz = data;
 -      int i = 0;
 -      int j = 0;
 -      struct acpi_thermal_active *active = NULL;
 -
 -      if (!tz) {
 -              printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
 -              return;
 -      }
 -
 -      result = acpi_thermal_get_temperature(tz);
 -      if (result)
 -              return;
 -
 -      for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
 -              active = &(tz->trips.active[i]);
 -              if (!active || !active->flags.valid)
 -                      break;
 -              if (tz->temperature >= active->temperature) {
 -                      /*
 -                       * If the thermal temperature is greater than the
 -                       * active threshod, unnecessary to turn off the
 -                       * the active cooling device.
 -                       */
 -                      continue;
 -              }
 -              /*
 -               * Below Threshold?
 -               * ----------------
 -               * Turn OFF all cooling devices associated with this
 -               * threshold.
 -               */
 -              for (j = 0; j < active->devices.count; j++)
 -                      result = acpi_bus_set_power(active->devices.handles[j],
 -                                                  ACPI_STATE_D3);
 -      }
 -}
 -
  static void acpi_thermal_check(void *data)
  {
 -      int result = 0;
        struct acpi_thermal *tz = data;
 -      unsigned long sleep_time = 0;
 -      unsigned long timeout_jiffies = 0;
 -      int i = 0;
 -      struct acpi_thermal_state state;
 -
 -
 -      if (!tz) {
 -              printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
 -              return;
 -      }
 -
 -      /* Check if someone else is already running */
 -      if (!mutex_trylock(&tz->lock))
 -              return;
 -
 -      state = tz->state;
 -
 -      result = acpi_thermal_get_temperature(tz);
 -      if (result)
 -              goto unlock;
 -
 -      if (!tz->tz_enabled)
 -              goto unlock;
 -
 -      memset(&tz->state, 0, sizeof(tz->state));
 -
 -      /*
 -       * Check Trip Points
 -       * -----------------
 -       * Compare the current temperature to the trip point values to see
 -       * if we've entered one of the thermal policy states.  Note that
 -       * this function determines when a state is entered, but the 
 -       * individual policy decides when it is exited (e.g. hysteresis).
 -       */
 -      if (tz->trips.critical.flags.valid)
 -              state.critical |=
 -                  (tz->temperature >= tz->trips.critical.temperature);
 -      if (tz->trips.hot.flags.valid)
 -              state.hot |= (tz->temperature >= tz->trips.hot.temperature);
 -      if (tz->trips.passive.flags.valid)
 -              state.passive |=
 -                  (tz->temperature >= tz->trips.passive.temperature);
 -      for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
 -              if (tz->trips.active[i].flags.valid)
 -                      state.active |=
 -                          (tz->temperature >=
 -                           tz->trips.active[i].temperature);
 -
 -      /*
 -       * Invoke Policy
 -       * -------------
 -       * Separated from the above check to allow individual policy to 
 -       * determine when to exit a given state.
 -       */
 -      if (state.critical)
 -              acpi_thermal_critical(tz);
 -      if (state.hot)
 -              acpi_thermal_hot(tz);
 -      if (state.passive)
 -              acpi_thermal_passive(tz);
 -      if (state.active)
 -              acpi_thermal_active(tz);
 -
 -      /*
 -       * Calculate State
 -       * ---------------
 -       * Again, separated from the above two to allow independent policy
 -       * decisions.
 -       */
 -      tz->state.critical = tz->trips.critical.flags.enabled;
 -      tz->state.hot = tz->trips.hot.flags.enabled;
 -      tz->state.passive = tz->trips.passive.flags.enabled;
 -      tz->state.active = 0;
 -      for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
 -              tz->state.active |= tz->trips.active[i].flags.enabled;
 -
 -      /*
 -       * Calculate Sleep Time
 -       * --------------------
 -       * If we're in the passive state, use _TSP's value.  Otherwise
 -       * use the default polling frequency (e.g. _TZP).  If no polling
 -       * frequency is specified then we'll wait forever (at least until
 -       * a thermal event occurs).  Note that _TSP and _TZD values are
 -       * given in 1/10th seconds (we must covert to milliseconds).
 -       */
 -      if (tz->state.passive) {
 -              sleep_time = tz->trips.passive.tsp * 100;
 -              timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
 -      } else if (tz->polling_frequency > 0) {
 -              sleep_time = tz->polling_frequency * 100;
 -              timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
 -      }
 -
 -      ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
 -                        tz->name, tz->temperature, sleep_time));
  
 -      /*
 -       * Schedule Next Poll
 -       * ------------------
 -       */
 -      if (!sleep_time) {
 -              if (timer_pending(&(tz->timer)))
 -                      del_timer(&(tz->timer));
 -      } else {
 -              if (timer_pending(&(tz->timer)))
 -                      mod_timer(&(tz->timer), timeout_jiffies);
 -              else {
 -                      tz->timer.data = (unsigned long)tz;
 -                      tz->timer.function = acpi_thermal_run;
 -                      tz->timer.expires = timeout_jiffies;
 -                      add_timer(&(tz->timer));
 -              }
 -      }
 -      unlock:
 -      mutex_unlock(&tz->lock);
 +      thermal_zone_device_update(tz->thermal_zone);
  }
  
  /* sys I/F for generic thermal sysfs support */
  #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
  
 -static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
 +static int thermal_get_temp(struct thermal_zone_device *thermal,
 +                          unsigned long *temp)
  {
        struct acpi_thermal *tz = thermal->devdata;
        int result;
        if (result)
                return result;
  
 -      return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
 +      *temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
 +      return 0;
  }
  
  static const char enabled[] = "kernel";
  static const char disabled[] = "user";
  static int thermal_get_mode(struct thermal_zone_device *thermal,
 -                              char *buf)
 +                              enum thermal_device_mode *mode)
  {
        struct acpi_thermal *tz = thermal->devdata;
  
        if (!tz)
                return -EINVAL;
  
 -      return sprintf(buf, "%s\n", tz->tz_enabled ?
 -                      enabled : disabled);
 +      *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
 +              THERMAL_DEVICE_DISABLED;
 +
 +      return 0;
  }
  
  static int thermal_set_mode(struct thermal_zone_device *thermal,
 -                              const char *buf)
 +                              enum thermal_device_mode mode)
  {
        struct acpi_thermal *tz = thermal->devdata;
        int enable;
        /*
         * enable/disable thermal management from ACPI thermal driver
         */
 -      if (!strncmp(buf, enabled, sizeof enabled - 1))
 +      if (mode == THERMAL_DEVICE_ENABLED)
                enable = 1;
 -      else if (!strncmp(buf, disabled, sizeof disabled - 1))
 +      else if (mode == THERMAL_DEVICE_DISABLED)
                enable = 0;
        else
                return -EINVAL;
  }
  
  static int thermal_get_trip_type(struct thermal_zone_device *thermal,
 -                               int trip, char *buf)
 +                               int trip, enum thermal_trip_type *type)
  {
        struct acpi_thermal *tz = thermal->devdata;
        int i;
                return -EINVAL;
  
        if (tz->trips.critical.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "critical\n");
 +              if (!trip) {
 +                      *type = THERMAL_TRIP_CRITICAL;
 +                      return 0;
 +              }
                trip--;
        }
  
        if (tz->trips.hot.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "hot\n");
 +              if (!trip) {
 +                      *type = THERMAL_TRIP_HOT;
 +                      return 0;
 +              }
                trip--;
        }
  
        if (tz->trips.passive.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "passive\n");
 +              if (!trip) {
 +                      *type = THERMAL_TRIP_PASSIVE;
 +                      return 0;
 +              }
                trip--;
        }
  
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
                tz->trips.active[i].flags.valid; i++) {
 -              if (!trip)
 -                      return sprintf(buf, "active%d\n", i);
 +              if (!trip) {
 +                      *type = THERMAL_TRIP_ACTIVE;
 +                      return 0;
 +              }
                trip--;
        }
  
  }
  
  static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
 -                               int trip, char *buf)
 +                               int trip, unsigned long *temp)
  {
        struct acpi_thermal *tz = thermal->devdata;
        int i;
                return -EINVAL;
  
        if (tz->trips.critical.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
 -                              tz->trips.critical.temperature));
 +              if (!trip) {
 +                      *temp = KELVIN_TO_MILLICELSIUS(
 +                              tz->trips.critical.temperature);
 +                      return 0;
 +              }
                trip--;
        }
  
        if (tz->trips.hot.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
 -                                      tz->trips.hot.temperature));
 +              if (!trip) {
 +                      *temp = KELVIN_TO_MILLICELSIUS(
 +                              tz->trips.hot.temperature);
 +                      return 0;
 +              }
                trip--;
        }
  
        if (tz->trips.passive.flags.valid) {
 -              if (!trip)
 -                      return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
 -                                      tz->trips.passive.temperature));
 +              if (!trip) {
 +                      *temp = KELVIN_TO_MILLICELSIUS(
 +                              tz->trips.passive.temperature);
 +                      return 0;
 +              }
                trip--;
        }
  
        for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
                tz->trips.active[i].flags.valid; i++) {
 -              if (!trip)
 -                      return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
 -                                      tz->trips.active[i].temperature));
 +              if (!trip) {
 +                      *temp = KELVIN_TO_MILLICELSIUS(
 +                              tz->trips.active[i].temperature);
 +                      return 0;
 +              }
                trip--;
        }
  
@@@ -751,29 -1102,6 +751,29 @@@ static int thermal_get_crit_temp(struc
                return -EINVAL;
  }
  
 +static int thermal_notify(struct thermal_zone_device *thermal, int trip,
 +                         enum thermal_trip_type trip_type)
 +{
 +      u8 type = 0;
 +      struct acpi_thermal *tz = thermal->devdata;
 +
 +      if (trip_type == THERMAL_TRIP_CRITICAL)
 +              type = ACPI_THERMAL_NOTIFY_CRITICAL;
 +      else if (trip_type == THERMAL_TRIP_HOT)
 +              type = ACPI_THERMAL_NOTIFY_HOT;
 +      else
 +              return 0;
 +
 +      acpi_bus_generate_proc_event(tz->device, type, 1);
 +      acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
 +                                      dev_name(&tz->device->dev), type, 1);
 +
 +      if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
 +              return 1;
 +
 +      return 0;
 +}
 +
  typedef int (*cb)(struct thermal_zone_device *, int,
                  struct thermal_cooling_device *);
  static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@@ -866,7 -1194,6 +866,7 @@@ static struct thermal_zone_device_ops a
        .get_trip_type = thermal_get_trip_type,
        .get_trip_temp = thermal_get_trip_temp,
        .get_crit_temp = thermal_get_crit_temp,
 +      .notify = thermal_notify,
  };
  
  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("acpitz",
 -                                      trips, tz, &acpi_thermal_zone_ops);
 +
 +      if (tz->trips.passive.flags.valid)
 +              tz->thermal_zone =
 +                      thermal_zone_device_register("acpitz", trips, tz,
 +                                                   &acpi_thermal_zone_ops,
 +                                                   tz->trips.passive.tc1,
 +                                                   tz->trips.passive.tc2,
 +                                                   tz->trips.passive.tsp*100,
 +                                                   tz->polling_frequency*100);
 +      else
 +              tz->thermal_zone =
 +                      thermal_zone_device_register("acpitz", trips, tz,
 +                                                   &acpi_thermal_zone_ops,
 +                                                   0, 0, 0,
 +                                                   tz->polling_frequency);
        if (IS_ERR(tz->thermal_zone))
                return -ENODEV;
  
@@@ -1133,13 -1447,13 +1133,13 @@@ static int acpi_thermal_polling_seq_sho
        if (!tz)
                goto end;
  
 -      if (!tz->polling_frequency) {
 +      if (!tz->thermal_zone->polling_delay) {
                seq_puts(seq, "<polling disabled>\n");
                goto end;
        }
  
 -      seq_printf(seq, "polling frequency:       %lu seconds\n",
 -                 (tz->polling_frequency / 10));
 +      seq_printf(seq, "polling frequency:       %d seconds\n",
 +                 (tz->thermal_zone->polling_delay / 1000));
  
        end:
        return 0;
@@@ -1192,7 -1506,6 +1192,6 @@@ static int acpi_thermal_add_fs(struct a
                                                     acpi_thermal_dir);
                if (!acpi_device_dir(device))
                        return -ENODEV;
-               acpi_device_dir(device)->owner = THIS_MODULE;
        }
  
        /* 'state' [R] */
@@@ -1369,6 -1682,12 +1368,6 @@@ static int acpi_thermal_add(struct acpi
        if (result)
                goto unregister_thermal_zone;
  
 -      init_timer(&tz->timer);
 -
 -      acpi_thermal_active_off(tz);
 -
 -      acpi_thermal_check(tz);
 -
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_DEVICE_NOTIFY,
                                             acpi_thermal_notify, tz);
@@@ -1397,15 -1716,36 +1396,15 @@@ static int acpi_thermal_remove(struct a
        acpi_status status = AE_OK;
        struct acpi_thermal *tz = NULL;
  
 -
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
  
        tz = acpi_driver_data(device);
  
 -      /* avoid timer adding new defer task */
 -      tz->zombie = 1;
 -      /* wait for running timer (on other CPUs) finish */
 -      del_timer_sync(&(tz->timer));
 -      /* synchronize deferred task */
 -      acpi_os_wait_events_complete(NULL);
 -      /* deferred task may reinsert timer */
 -      del_timer_sync(&(tz->timer));
 -
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_DEVICE_NOTIFY,
                                            acpi_thermal_notify);
  
 -      /* Terminate policy */
 -      if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
 -              tz->trips.passive.flags.enabled = 0;
 -              acpi_thermal_passive(tz);
 -      }
 -      if (tz->trips.active[0].flags.valid
 -          && tz->trips.active[0].flags.enabled) {
 -              tz->trips.active[0].flags.enabled = 0;
 -              acpi_thermal_active(tz);
 -      }
 -
        acpi_thermal_remove_fs(device);
        acpi_thermal_unregister_thermal_zone(tz);
        mutex_destroy(&tz->lock);
@@@ -1534,7 -1874,6 +1533,6 @@@ static int __init acpi_thermal_init(voi
        acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
        if (!acpi_thermal_dir)
                return -ENODEV;
-       acpi_thermal_dir->owner = THIS_MODULE;
  
        result = acpi_bus_register_driver(&acpi_thermal_driver);
        if (result < 0) {
diff --combined drivers/acpi/video.c
index d51d6f06c09b2a99f6a555e96e85821560ca4fc7,67cc36dc9b82fe94b7430628076191e3a6246894..ab06143672bc456ea9ed8c39349647caa8f8e888
@@@ -37,8 -37,6 +37,8 @@@
  #include <linux/thermal.h>
  #include <linux/video_output.h>
  #include <linux/sort.h>
 +#include <linux/pci.h>
 +#include <linux/pci_ids.h>
  #include <asm/uaccess.h>
  
  #include <acpi/acpi_bus.h>
@@@ -164,26 -162,16 +164,26 @@@ struct acpi_video_device_cap 
        u8 _BCL:1;              /*Query list of brightness control levels supported */
        u8 _BCM:1;              /*Set the brightness level */
        u8 _BQC:1;              /* Get current brightness level */
 +      u8 _BCQ:1;              /* Some buggy BIOS uses _BCQ instead of _BQC */
        u8 _DDC:1;              /*Return the EDID for this device */
        u8 _DCS:1;              /*Return status of output device */
        u8 _DGS:1;              /*Query graphics state */
        u8 _DSS:1;              /*Device state set */
  };
  
 +struct acpi_video_brightness_flags {
 +      u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
 +      u8 _BCL_reversed:1;             /* _BCL package is in a reversed order*/
 +      u8 _BCL_use_index:1;            /* levels in _BCL are index values */
 +      u8 _BCM_use_index:1;            /* input of _BCM is an index value */
 +      u8 _BQC_use_index:1;            /* _BQC returns an index value */
 +};
 +
  struct acpi_video_device_brightness {
        int curr;
        int count;
        int *levels;
 +      struct acpi_video_brightness_flags flags;
  };
  
  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 = {
 +static const struct file_operations acpi_video_bus_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_info_open_fs,
        .read = seq_read,
  };
  
  static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
 -static struct file_operations acpi_video_bus_ROM_fops = {
 +static const struct file_operations acpi_video_bus_ROM_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_ROM_open_fs,
        .read = seq_read,
  
  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 = {
 +static const struct file_operations acpi_video_bus_POST_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_info_open_fs,
        .read = seq_read,
  };
  
  static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
 -static struct file_operations acpi_video_bus_POST_fops = {
 +static ssize_t acpi_video_bus_write_POST(struct file *file,
 +      const char __user *buffer, size_t count, loff_t *data);
 +static const struct file_operations acpi_video_bus_POST_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_POST_open_fs,
        .read = seq_read,
 +      .write = acpi_video_bus_write_POST,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
 -static struct file_operations acpi_video_bus_DOS_fops = {
 +static ssize_t acpi_video_bus_write_DOS(struct file *file,
 +      const char __user *buffer, size_t count, loff_t *data);
 +static const struct file_operations acpi_video_bus_DOS_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_bus_DOS_open_fs,
        .read = seq_read,
 +      .write = acpi_video_bus_write_DOS,
        .llseek = seq_lseek,
        .release = single_release,
  };
  /* device */
  static int acpi_video_device_info_open_fs(struct inode *inode,
                                          struct file *file);
 -static struct file_operations acpi_video_device_info_fops = {
 +static const struct file_operations acpi_video_device_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_info_open_fs,
        .read = seq_read,
  
  static int acpi_video_device_state_open_fs(struct inode *inode,
                                           struct file *file);
 -static struct file_operations acpi_video_device_state_fops = {
 +static ssize_t acpi_video_device_write_state(struct file *file,
 +      const char __user *buffer, size_t count, loff_t *data);
 +static const struct file_operations acpi_video_device_state_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_state_open_fs,
        .read = seq_read,
 +      .write = acpi_video_device_write_state,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_device_brightness_open_fs(struct inode *inode,
                                                struct file *file);
 +static ssize_t acpi_video_device_write_brightness(struct file *file,
 +      const char __user *buffer, size_t count, loff_t *data);
  static struct file_operations acpi_video_device_brightness_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_brightness_open_fs,
        .read = seq_read,
 +      .write = acpi_video_device_write_brightness,
        .llseek = seq_lseek,
        .release = single_release,
  };
  
  static int acpi_video_device_EDID_open_fs(struct inode *inode,
                                          struct file *file);
 -static struct file_operations acpi_video_device_EDID_fops = {
 +static const struct file_operations acpi_video_device_EDID_fops = {
        .owner = THIS_MODULE,
        .open = acpi_video_device_EDID_open_fs,
        .read = seq_read,
        .release = single_release,
  };
  
 -static char device_decode[][30] = {
 +static const char device_decode[][30] = {
        "motherboard VGA device",
        "PCI VGA device",
        "AGP VGA device",
@@@ -318,7 -294,7 +318,7 @@@ static int acpi_video_device_lcd_get_le
                        unsigned long long *level);
  static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
 -static void acpi_video_switch_brightness(struct acpi_video_device *device,
 +static int acpi_video_switch_brightness(struct acpi_video_device *device,
                                         int event);
  static int acpi_video_device_get_state(struct acpi_video_device *device,
                            unsigned long long *state);
@@@ -332,9 -308,7 +332,9 @@@ static int acpi_video_get_brightness(st
        int i;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
 -      acpi_video_device_lcd_get_level_current(vd, &cur_level);
 +
 +      if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
 +              return -EINVAL;
        for (i = 2; i < vd->brightness->count; i++) {
                if (vd->brightness->levels[i] == cur_level)
                        /* The first two entries are special - see page 575
  
  static int acpi_video_set_brightness(struct backlight_device *bd)
  {
 -      int request_level = bd->props.brightness+2;
 +      int request_level = bd->props.brightness + 2;
        struct acpi_video_device *vd =
                (struct acpi_video_device *)bl_get_data(bd);
 -      acpi_video_device_lcd_set_level(vd,
 -                                      vd->brightness->levels[request_level]);
 -      return 0;
 +
 +      return acpi_video_device_lcd_set_level(vd,
 +                              vd->brightness->levels[request_level]);
  }
  
  static struct backlight_ops acpi_backlight_ops = {
@@@ -384,37 -358,32 +384,37 @@@ static struct output_properties acpi_ou
  
  
  /* thermal cooling device callbacks */
 -static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
 +static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
 +                             long *state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
  
 -      return sprintf(buf, "%d\n", video->brightness->count - 3);
 +      *state = video->brightness->count - 3;
 +      return 0;
  }
  
 -static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
 +static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
 +                             long *state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
        unsigned long long level;
 -      int state;
 +      int offset;
  
 -      acpi_video_device_lcd_get_level_current(video, &level);
 -      for (state = 2; state < video->brightness->count; state++)
 -              if (level == video->brightness->levels[state])
 -                      return sprintf(buf, "%d\n",
 -                                     video->brightness->count - state - 1);
 +      if (acpi_video_device_lcd_get_level_current(video, &level))
 +              return -EINVAL;
 +      for (offset = 2; offset < video->brightness->count; offset++)
 +              if (level == video->brightness->levels[offset]) {
 +                      *state = video->brightness->count - offset - 1;
 +                      return 0;
 +              }
  
        return -EINVAL;
  }
  
  static int
 -video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
 +video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  {
        struct acpi_device *device = cdev->devdata;
        struct acpi_video_device *video = acpi_driver_data(device);
@@@ -510,68 -479,34 +510,68 @@@ acpi_video_device_lcd_query_levels(stru
  static int
  acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
  {
 -      int status = AE_OK;
 +      int status;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
        int state;
  
 -
        arg0.integer.value = level;
  
 -      if (device->cap._BCM)
 -              status = acpi_evaluate_object(device->dev->handle, "_BCM",
 -                                            &args, NULL);
 +      status = acpi_evaluate_object(device->dev->handle, "_BCM",
 +                                    &args, NULL);
 +      if (ACPI_FAILURE(status)) {
 +              ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
 +              return -EIO;
 +      }
 +
        device->brightness->curr = level;
        for (state = 2; state < device->brightness->count; state++)
 -              if (level == device->brightness->levels[state])
 -                      device->backlight->props.brightness = state - 2;
 +              if (level == device->brightness->levels[state]) {
 +                      if (device->backlight)
 +                              device->backlight->props.brightness = state - 2;
 +                      return 0;
 +              }
  
 -      return status;
 +      ACPI_ERROR((AE_INFO, "Current brightness invalid"));
 +      return -EINVAL;
  }
  
  static int
  acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
                                        unsigned long long *level)
  {
 -      if (device->cap._BQC)
 -              return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
 -                                           level);
 +      acpi_status status = AE_OK;
 +
 +      if (device->cap._BQC || device->cap._BCQ) {
 +              char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
 +
 +              status = acpi_evaluate_integer(device->dev->handle, buf,
 +                                              NULL, level);
 +              if (ACPI_SUCCESS(status)) {
 +                      if (device->brightness->flags._BQC_use_index) {
 +                              if (device->brightness->flags._BCL_reversed)
 +                                      *level = device->brightness->count
 +                                                               - 3 - (*level);
 +                              *level = device->brightness->levels[*level + 2];
 +
 +                      }
 +                      device->brightness->curr = *level;
 +                      return 0;
 +              } else {
 +                      /* Fixme:
 +                       * should we return an error or ignore this failure?
 +                       * dev->brightness->curr is a cached value which stores
 +                       * the correct current backlight level in most cases.
 +                       * ACPI video backlight still works w/ buggy _BQC.
 +                       * http://bugzilla.kernel.org/show_bug.cgi?id=12233
 +                       */
 +                      ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
 +                      device->cap._BQC = device->cap._BCQ = 0;
 +              }
 +      }
 +
        *level = device->brightness->curr;
 -      return AE_OK;
 +      return 0;
  }
  
  static int
@@@ -720,11 -655,9 +720,11 @@@ static in
  acpi_video_init_brightness(struct acpi_video_device *device)
  {
        union acpi_object *obj = NULL;
 -      int i, max_level = 0, count = 0;
 +      int i, max_level = 0, count = 0, level_ac_battery = 0;
 +      unsigned long long level, level_old;
        union acpi_object *o;
        struct acpi_video_device_brightness *br = NULL;
 +      int result = -EINVAL;
  
        if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
        br = kzalloc(sizeof(*br), GFP_KERNEL);
        if (!br) {
                printk(KERN_ERR "can't allocate memory\n");
 +              result = -ENOMEM;
                goto out;
        }
  
 -      br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
 +      br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
                                GFP_KERNEL);
 -      if (!br->levels)
 +      if (!br->levels) {
 +              result = -ENOMEM;
                goto out_free;
 +      }
  
        for (i = 0; i < obj->package.count; i++) {
                o = (union acpi_object *)&obj->package.elements[i];
                count++;
        }
  
 -      /* don't sort the first two brightness levels */
 -      sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
 -              acpi_video_cmp_level, NULL);
 -
 -      if (count < 2)
 -              goto out_free_levels;
 +      /*
 +       * some buggy BIOS don't export the levels
 +       * when machine is on AC/Battery in _BCL package.
 +       * In this case, the first two elements in _BCL packages
 +       * are also supported brightness levels that OS should take care of.
 +       */
 +      for (i = 2; i < count; i++)
 +              if (br->levels[i] == br->levels[0] ||
 +                  br->levels[i] == br->levels[1])
 +                      level_ac_battery++;
 +
 +      if (level_ac_battery < 2) {
 +              level_ac_battery = 2 - level_ac_battery;
 +              br->flags._BCL_no_ac_battery_levels = 1;
 +              for (i = (count - 1 + level_ac_battery); i >= 2; i--)
 +                      br->levels[i] = br->levels[i - level_ac_battery];
 +              count += level_ac_battery;
 +      } else if (level_ac_battery > 2)
 +              ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
 +
 +      /* Check if the _BCL package is in a reversed order */
 +      if (max_level == br->levels[2]) {
 +              br->flags._BCL_reversed = 1;
 +              sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
 +                      acpi_video_cmp_level, NULL);
 +      } else if (max_level != br->levels[count - 1])
 +              ACPI_ERROR((AE_INFO,
 +                          "Found unordered _BCL package\n"));
  
        br->count = count;
        device->brightness = br;
 -      ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
 +
 +      /* Check the input/output of _BQC/_BCL/_BCM */
 +      if ((max_level < 100) && (max_level <= (count - 2)))
 +              br->flags._BCL_use_index = 1;
 +
 +      /*
 +       * _BCM is always consistent with _BCL,
 +       * at least for all the laptops we have ever seen.
 +       */
 +      br->flags._BCM_use_index = br->flags._BCL_use_index;
 +
 +      /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
 +      br->curr = max_level;
 +      result = acpi_video_device_lcd_get_level_current(device, &level_old);
 +      if (result)
 +              goto out_free_levels;
 +
 +      result = acpi_video_device_lcd_set_level(device, br->curr);
 +      if (result)
 +              goto out_free_levels;
 +
 +      result = acpi_video_device_lcd_get_level_current(device, &level);
 +      if (result)
 +              goto out_free_levels;
 +
 +      if ((level != level_old) && !br->flags._BCM_use_index) {
 +              /* Note:
 +               * This piece of code does not work correctly if the current
 +               * brightness levels is 0.
 +               * But I guess boxes that boot with such a dark screen are rare
 +               * and no more code is needed to cover this specifial case.
 +               */
 +
 +              if (level_ac_battery != 2) {
 +                      /*
 +                       * For now, we don't support the _BCL like this:
 +                       * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
 +                       * because we may mess up the index returned by _BQC.
 +                       * Plus: we have not got a box like this.
 +                       */
 +                      ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
 +              }
 +              br->flags._BQC_use_index = 1;
 +      }
 +
 +      ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 +                        "found %d brightness levels\n", count - 2));
        kfree(obj);
 -      return max_level;
 +      return result;
  
  out_free_levels:
        kfree(br->levels);
@@@ -850,7 -712,7 +850,7 @@@ out_free
  out:
        device->brightness = NULL;
        kfree(obj);
 -      return 0;
 +      return result;
  }
  
  /*
  static void acpi_video_device_find_cap(struct acpi_video_device *device)
  {
        acpi_handle h_dummy1;
 -      u32 max_level = 0;
  
  
        memset(&device->cap, 0, sizeof(device->cap));
        }
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
                device->cap._BQC = 1;
 +      else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
 +                              &h_dummy1))) {
 +              printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
 +              device->cap._BCQ = 1;
 +      }
 +
        if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
                device->cap._DDC = 1;
        }
                device->cap._DSS = 1;
        }
  
 -      if (acpi_video_backlight_support())
 -              max_level = acpi_video_init_brightness(device);
 -
 -      if (device->cap._BCL && device->cap._BCM && max_level > 0) {
 +      if (acpi_video_backlight_support()) {
                int result;
                static int count = 0;
                char *name;
 +
 +              result = acpi_video_init_brightness(device);
 +              if (result)
 +                      return;
                name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
                if (!name)
                        return;
                device->backlight = backlight_device_register(name,
                        NULL, device, &acpi_backlight_ops);
                device->backlight->props.max_brightness = device->brightness->count-3;
 -              /*
 -               * If there exists the _BQC object, the _BQC object will be
 -               * called to get the current backlight brightness. Otherwise
 -               * the brightness will be set to the maximum.
 -               */
 -              if (device->cap._BQC)
 -                      device->backlight->props.brightness =
 -                              acpi_video_get_brightness(device->backlight);
 -              else
 -                      device->backlight->props.brightness =
 -                              device->backlight->props.max_brightness;
 -              backlight_update_status(device->backlight);
                kfree(name);
  
                device->cdev = thermal_cooling_device_register("LCD",
@@@ -1193,12 -1061,13 +1193,12 @@@ acpi_video_device_write_brightness(stru
        /* validate through the list of available levels */
        for (i = 2; i < dev->brightness->count; i++)
                if (level == dev->brightness->levels[i]) {
 -                      if (ACPI_SUCCESS
 -                          (acpi_video_device_lcd_set_level(dev, level)))
 -                              dev->brightness->curr = level;
 +                      if (!acpi_video_device_lcd_set_level(dev, level))
 +                              return count;
                        break;
                }
  
 -      return count;
 +      return -EINVAL;
  }
  
  static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@@ -1256,8 -1125,6 +1256,6 @@@ static int acpi_video_device_add_fs(str
        if (!device_dir)
                return -ENOMEM;
  
-       device_dir->owner = THIS_MODULE;
        /* 'info' [R] */
        entry = proc_create_data("info", S_IRUGO, device_dir,
                        &acpi_video_device_info_fops, acpi_driver_data(device));
                goto err_remove_dir;
  
        /* 'state' [R/W] */
 -      acpi_video_device_state_fops.write = acpi_video_device_write_state;
        entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_device_state_fops,
                goto err_remove_info;
  
        /* 'brightness' [R/W] */
 -      acpi_video_device_brightness_fops.write =
 -              acpi_video_device_write_brightness;
        entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_device_brightness_fops,
@@@ -1531,8 -1401,6 +1529,6 @@@ static int acpi_video_bus_add_fs(struc
        if (!device_dir)
                return -ENOMEM;
  
-       device_dir->owner = THIS_MODULE;
        /* 'info' [R] */
        entry = proc_create_data("info", S_IRUGO, device_dir,
                                 &acpi_video_bus_info_fops,
                goto err_remove_rom;
  
        /* 'POST' [R/W] */
 -      acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
        entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_bus_POST_fops,
                goto err_remove_post_info;
  
        /* 'DOS' [R/W] */
 -      acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
        entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
                                 device_dir,
                                 &acpi_video_bus_DOS_fops,
@@@ -1875,29 -1745,15 +1871,29 @@@ acpi_video_get_next_level(struct acpi_v
        }
  }
  
 -static void
 +static int
  acpi_video_switch_brightness(struct acpi_video_device *device, int event)
  {
        unsigned long long level_current, level_next;
 +      int result = -EINVAL;
 +
        if (!device->brightness)
 -              return;
 -      acpi_video_device_lcd_get_level_current(device, &level_current);
 +              goto out;
 +
 +      result = acpi_video_device_lcd_get_level_current(device,
 +                                                       &level_current);
 +      if (result)
 +              goto out;
 +
        level_next = acpi_video_get_next_level(device, level_current, event);
 -      acpi_video_device_lcd_set_level(device, level_next);
 +
 +      result = acpi_video_device_lcd_set_level(device, level_next);
 +
 +out:
 +      if (result)
 +              printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
 +
 +      return result;
  }
  
  static int
@@@ -2264,34 -2120,13 +2260,33 @@@ static int acpi_video_bus_remove(struc
        return 0;
  }
  
 -static int __init acpi_video_init(void)
 +static int __init intel_opregion_present(void)
 +{
 +#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
 +      struct pci_dev *dev = NULL;
 +      u32 address;
 +
 +      for_each_pci_dev(dev) {
 +              if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
 +                      continue;
 +              if (dev->vendor != PCI_VENDOR_ID_INTEL)
 +                      continue;
 +              pci_read_config_dword(dev, 0xfc, &address);
 +              if (!address)
 +                      continue;
 +              return 1;
 +      }
 +#endif
 +      return 0;
 +}
 +
 +int acpi_video_register(void)
  {
        int result = 0;
  
        acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
        if (!acpi_video_dir)
                return -ENODEV;
-       acpi_video_dir->owner = THIS_MODULE;
  
        result = acpi_bus_register_driver(&acpi_video_bus);
        if (result < 0) {
  
        return 0;
  }
 +EXPORT_SYMBOL(acpi_video_register);
 +
 +/*
 + * This is kind of nasty. Hardware using Intel chipsets may require
 + * the video opregion code to be run first in order to initialise
 + * state before any ACPI video calls are made. To handle this we defer
 + * registration of the video class until the opregion code has run.
 + */
 +
 +static int __init acpi_video_init(void)
 +{
 +      if (intel_opregion_present())
 +              return 0;
 +
 +      return acpi_video_register();
 +}
  
  static void __exit acpi_video_exit(void)
  {
index 638686904e0628f5ffbe5d7f7388e251b4234718,c23b3a95b7cee3fcc7429e14cbe5d286b0b0d4ff..a000cf028826d635e42bf60d81bb0e36075252ad
@@@ -41,7 -41,6 +41,6 @@@
  int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
        drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
        u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
        u32 last_acthd = I915_READ(acthd_reg);
                if (ring->space >= n)
                        return 0;
  
-               if (master_priv->sarea_priv)
-                       master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+               if (dev->primary->master) {
+                       struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+                       if (master_priv->sarea_priv)
+                               master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+               }
  
                if (ring->head != last_head)
                        i = 0;
@@@ -356,7 -359,7 +359,7 @@@ static int validate_cmd(int cmd
        return ret;
  }
  
- static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
+ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
        int i;
        for (i = 0; i < dwords;) {
                int cmd, sz;
  
-               if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
-                       return -EINVAL;
+               cmd = buffer[i];
  
                if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
                        return -EINVAL;
                OUT_RING(cmd);
  
                while (++i, --sz) {
-                       if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
-                                                        sizeof(cmd))) {
-                               return -EINVAL;
-                       }
-                       OUT_RING(cmd);
+                       OUT_RING(buffer[i]);
                }
        }
  
  
  int
  i915_emit_box(struct drm_device *dev,
-             struct drm_clip_rect __user *boxes,
+             struct drm_clip_rect *boxes,
              int i, int DR1, int DR4)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_clip_rect box;
+       struct drm_clip_rect box = boxes[i];
        RING_LOCALS;
  
-       if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
-               return -EFAULT;
-       }
        if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
                DRM_ERROR("Bad box %d,%d..%d,%d\n",
                          box.x1, box.y1, box.x2, box.y2);
@@@ -460,7 -454,9 +454,9 @@@ static void i915_emit_breadcrumb(struc
  }
  
  static int i915_dispatch_cmdbuffer(struct drm_device * dev,
-                                  drm_i915_cmdbuffer_t * cmd)
+                                  drm_i915_cmdbuffer_t *cmd,
+                                  struct drm_clip_rect *cliprects,
+                                  void *cmdbuf)
  {
        int nbox = cmd->num_cliprects;
        int i = 0, count, ret;
  
        for (i = 0; i < count; i++) {
                if (i < nbox) {
-                       ret = i915_emit_box(dev, cmd->cliprects, i,
+                       ret = i915_emit_box(dev, cliprects, i,
                                            cmd->DR1, cmd->DR4);
                        if (ret)
                                return ret;
                }
  
-               ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
+               ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4);
                if (ret)
                        return ret;
        }
  }
  
  static int i915_dispatch_batchbuffer(struct drm_device * dev,
-                                    drm_i915_batchbuffer_t * batch)
+                                    drm_i915_batchbuffer_t * batch,
+                                    struct drm_clip_rect *cliprects)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_clip_rect __user *boxes = batch->cliprects;
        int nbox = batch->num_cliprects;
        int i = 0, count;
        RING_LOCALS;
  
        for (i = 0; i < count; i++) {
                if (i < nbox) {
-                       int ret = i915_emit_box(dev, boxes, i,
+                       int ret = i915_emit_box(dev, cliprects, i,
                                                batch->DR1, batch->DR4);
                        if (ret)
                                return ret;
@@@ -626,6 -622,7 +622,7 @@@ static int i915_batchbuffer(struct drm_
            master_priv->sarea_priv;
        drm_i915_batchbuffer_t *batch = data;
        int ret;
+       struct drm_clip_rect *cliprects = NULL;
  
        if (!dev_priv->allow_batchbuffer) {
                DRM_ERROR("Batchbuffer ioctl disabled\n");
  
        RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
  
-       if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
-                                                      batch->num_cliprects *
-                                                      sizeof(struct drm_clip_rect)))
-               return -EFAULT;
+       if (batch->num_cliprects < 0)
+               return -EINVAL;
+       if (batch->num_cliprects) {
+               cliprects = drm_calloc(batch->num_cliprects,
+                                      sizeof(struct drm_clip_rect),
+                                      DRM_MEM_DRIVER);
+               if (cliprects == NULL)
+                       return -ENOMEM;
+               ret = copy_from_user(cliprects, batch->cliprects,
+                                    batch->num_cliprects *
+                                    sizeof(struct drm_clip_rect));
+               if (ret != 0)
+                       goto fail_free;
+       }
  
        mutex_lock(&dev->struct_mutex);
-       ret = i915_dispatch_batchbuffer(dev, batch);
+       ret = i915_dispatch_batchbuffer(dev, batch, cliprects);
        mutex_unlock(&dev->struct_mutex);
  
        if (sarea_priv)
                sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ fail_free:
+       drm_free(cliprects,
+                batch->num_cliprects * sizeof(struct drm_clip_rect),
+                DRM_MEM_DRIVER);
        return ret;
  }
  
@@@ -659,6 -674,8 +674,8 @@@ static int i915_cmdbuffer(struct drm_de
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
            master_priv->sarea_priv;
        drm_i915_cmdbuffer_t *cmdbuf = data;
+       struct drm_clip_rect *cliprects = NULL;
+       void *batch_data;
        int ret;
  
        DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
  
        RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
  
-       if (cmdbuf->num_cliprects &&
-           DRM_VERIFYAREA_READ(cmdbuf->cliprects,
-                               cmdbuf->num_cliprects *
-                               sizeof(struct drm_clip_rect))) {
-               DRM_ERROR("Fault accessing cliprects\n");
-               return -EFAULT;
+       if (cmdbuf->num_cliprects < 0)
+               return -EINVAL;
+       batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER);
+       if (batch_data == NULL)
+               return -ENOMEM;
+       ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
+       if (ret != 0)
+               goto fail_batch_free;
+       if (cmdbuf->num_cliprects) {
+               cliprects = drm_calloc(cmdbuf->num_cliprects,
+                                      sizeof(struct drm_clip_rect),
+                                      DRM_MEM_DRIVER);
+               if (cliprects == NULL)
+                       goto fail_batch_free;
+               ret = copy_from_user(cliprects, cmdbuf->cliprects,
+                                    cmdbuf->num_cliprects *
+                                    sizeof(struct drm_clip_rect));
+               if (ret != 0)
+                       goto fail_clip_free;
        }
  
        mutex_lock(&dev->struct_mutex);
-       ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
+       ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data);
        mutex_unlock(&dev->struct_mutex);
        if (ret) {
                DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
-               return ret;
+               goto fail_batch_free;
        }
  
        if (sarea_priv)
                sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
-       return 0;
+ fail_batch_free:
+       drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
+ fail_clip_free:
+       drm_free(cliprects,
+                cmdbuf->num_cliprects * sizeof(struct drm_clip_rect),
+                DRM_MEM_DRIVER);
+       return ret;
  }
  
  static int i915_flip_bufs(struct drm_device *dev, void *data,
@@@ -880,7 -922,7 +922,7 @@@ static int i915_probe_agp(struct drm_de
         * Some of the preallocated space is taken by the GTT
         * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
         */
-       if (IS_G4X(dev))
+       if (IS_G4X(dev) || IS_IGD(dev))
                overhead = 4096;
        else
                overhead = (*aperture_size / 1024) + 4096;
@@@ -988,13 -1030,6 +1030,6 @@@ static int i915_load_modeset_init(struc
        if (ret)
                goto destroy_ringbuffer;
  
-       /* FIXME: re-add hotplug support */
- #if 0
-       ret = drm_hotplug_init(dev);
-       if (ret)
-               goto destroy_ringbuffer;
- #endif
        /* Always safe in the mode setting case. */
        /* FIXME: do pre/post-mode set stuff in core KMS code */
        dev->vblank_disable_allowed = 1;
  
        intel_modeset_init(dev);
  
-       drm_helper_initial_config(dev, false);
+       drm_helper_initial_config(dev);
  
        return 0;
  
@@@ -1057,7 -1092,7 +1092,7 @@@ void i915_master_destroy(struct drm_dev
  int i915_driver_load(struct drm_device *dev, unsigned long flags)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       unsigned long base, size;
+       resource_size_t base, size;
        int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
  
        /* i915 has 4 more counters */
        if (!IS_I945G(dev) && !IS_I945GM(dev))
                pci_enable_msi(dev->pdev);
  
 -      intel_opregion_init(dev);
 -
        spin_lock_init(&dev_priv->user_irq_lock);
        dev_priv->user_irq_refcount = 0;
  
                }
        }
  
 +      /* Must be done after probing outputs */
 +      intel_opregion_init(dev, 0);
 +
        return 0;
  
  out_iomapfree:
index 209592fdb7e77c0ea590f1a854a456cfde7fbea6,2c016769345020b58a9e49f525308a7af9ad3b04..6503e2210f657276f8598b5fba0ea72c720d4a19
@@@ -42,6 -42,8 +42,8 @@@ module_param_named(modeset, i915_modese
  unsigned int i915_fbpercrtc = 0;
  module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
  
+ static struct drm_driver driver;
  static struct pci_device_id pciidlist[] = {
        i915_PCI_IDS
  };
@@@ -99,7 -101,7 +101,7 @@@ static int i915_resume(struct drm_devic
  
        i915_restore_state(dev);
  
 -      intel_opregion_init(dev);
 +      intel_opregion_init(dev, 1);
  
        /* KMS EnterVT equivalent */
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
        return ret;
  }
  
+ static int __devinit
+ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+       return drm_get_dev(pdev, ent, &driver);
+ }
+ static void
+ i915_pci_remove(struct pci_dev *pdev)
+ {
+       struct drm_device *dev = pci_get_drvdata(pdev);
+       drm_put_dev(dev);
+ }
+ static int
+ i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+       struct drm_device *dev = pci_get_drvdata(pdev);
+       return i915_suspend(dev, state);
+ }
+ static int
+ i915_pci_resume(struct pci_dev *pdev)
+ {
+       struct drm_device *dev = pci_get_drvdata(pdev);
+       return i915_resume(dev);
+ }
  static struct vm_operations_struct i915_gem_vm_ops = {
        .fault = i915_gem_fault,
        .open = drm_gem_vm_open,
@@@ -150,8 -182,10 +182,10 @@@ static struct drm_driver driver = 
        .get_reg_ofs = drm_core_get_reg_ofs,
        .master_create = i915_master_create,
        .master_destroy = i915_master_destroy,
-       .proc_init = i915_gem_proc_init,
-       .proc_cleanup = i915_gem_proc_cleanup,
+ #if defined(CONFIG_DEBUG_FS)
+       .debugfs_init = i915_gem_debugfs_init,
+       .debugfs_cleanup = i915_gem_debugfs_cleanup,
+ #endif
        .gem_init_object = i915_gem_init_object,
        .gem_free_object = i915_gem_free_object,
        .gem_vm_ops = &i915_gem_vm_ops,
        .pci_driver = {
                 .name = DRIVER_NAME,
                 .id_table = pciidlist,
+                .probe = i915_pci_probe,
+                .remove = i915_pci_remove,
+ #ifdef CONFIG_PM
+                .resume = i915_pci_resume,
+                .suspend = i915_pci_suspend,
+ #endif
        },
  
        .name = DRIVER_NAME,
index b9a92c250b913d35b87b3d1bf2fcb71ade0daa63,317b1223e091c134bba16913fc7aa441710cd841..3750d80030482b73836cefc4216faf5db03998be
@@@ -159,6 -159,9 +159,9 @@@ typedef struct drm_i915_private 
        u32 irq_mask_reg;
        u32 pipestat[2];
  
+       u32 hotplug_supported_mask;
+       struct work_struct hotplug_work;
        int tex_lru_log_granularity;
        int allow_batchbuffer;
        struct mem_block *agp_heap;
                 *
                 * A reference is held on the buffer while on this list.
                 */
+               spinlock_t active_list_lock;
                struct list_head active_list;
  
                /**
@@@ -404,7 -408,8 +408,8 @@@ struct drm_i915_gem_object 
        /** AGP memory structure for our GTT binding. */
        DRM_AGP_MEM *agp_mem;
  
-       struct page **page_list;
+       struct page **pages;
+       int pages_refcount;
  
        /**
         * Current offset of the object in GTT space.
@@@ -519,7 -524,7 +524,7 @@@ extern int i915_driver_device_is_agp(st
  extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
  extern int i915_emit_box(struct drm_device *dev,
-                        struct drm_clip_rect __user *boxes,
+                        struct drm_clip_rect *boxes,
                         int i, int DR1, int DR4);
  
  /* i915_irq.c */
@@@ -604,8 -609,6 +609,6 @@@ int i915_gem_get_tiling(struct drm_devi
  int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
  void i915_gem_load(struct drm_device *dev);
- int i915_gem_proc_init(struct drm_minor *minor);
- void i915_gem_proc_cleanup(struct drm_minor *minor);
  int i915_gem_init_object(struct drm_gem_object *obj);
  void i915_gem_free_object(struct drm_gem_object *obj);
  int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
@@@ -649,6 -652,10 +652,10 @@@ void i915_gem_dump_object(struct drm_ge
                          const char *where, uint32_t mark);
  void i915_dump_lru(struct drm_device *dev, const char *where);
  
+ /* i915_debugfs.c */
+ int i915_gem_debugfs_init(struct drm_minor *minor);
+ void i915_gem_debugfs_cleanup(struct drm_minor *minor);
  /* i915_suspend.c */
  extern int i915_save_state(struct drm_device *dev);
  extern int i915_restore_state(struct drm_device *dev);
@@@ -659,12 -666,12 +666,12 @@@ extern int i915_restore_state(struct dr
  
  #ifdef CONFIG_ACPI
  /* i915_opregion.c */
 -extern int intel_opregion_init(struct drm_device *dev);
 +extern int intel_opregion_init(struct drm_device *dev, int resume);
  extern void intel_opregion_free(struct drm_device *dev);
  extern void opregion_asle_intr(struct drm_device *dev);
  extern void opregion_enable_asle(struct drm_device *dev);
  #else
 -static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
 +static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
  static inline void intel_opregion_free(struct drm_device *dev) { return; }
  static inline void opregion_asle_intr(struct drm_device *dev) { return; }
  static inline void opregion_enable_asle(struct drm_device *dev) { return; }
@@@ -784,15 -791,21 +791,21 @@@ extern int i915_wait_ring(struct drm_de
                     (dev)->pci_device == 0x2E22 || \
                     IS_GM45(dev))
  
+ #define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
+ #define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
+ #define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
  #define IS_G33(dev)    ((dev)->pci_device == 0x29C2 ||        \
                        (dev)->pci_device == 0x29B2 ||  \
-                       (dev)->pci_device == 0x29D2)
+                       (dev)->pci_device == 0x29D2 ||  \
+                       (IS_IGD(dev)))
  
  #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
                      IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
  
  #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
-                       IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
+                       IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
+                       IS_IGD(dev))
  
  #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
  /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
  #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
                                                      IS_I915GM(dev)))
  #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
+ #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
  
  #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
  
diff --combined drivers/pci/pci-acpi.c
index 368ca72dffbcfc230b2ba3a97a99b3c26106cbc5,fac5eddcefd2a2ee1100471de5c627654cd76814..ea15b05374570e03a6fd4068b5caa56185dff202
  #include <linux/pci-acpi.h>
  #include "pci.h"
  
- struct acpi_osc_data {
-       acpi_handle handle;
-       u32 support_set;
-       u32 control_set;
-       u32 control_query;
-       int is_queried;
-       struct list_head sibiling;
- };
- static LIST_HEAD(acpi_osc_data_list);
- struct acpi_osc_args {
-       u32 capbuf[3];
- };
- static DEFINE_MUTEX(pci_acpi_lock);
- static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
- {
-       struct acpi_osc_data *data;
-       list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
-               if (data->handle == handle)
-                       return data;
-       }
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return NULL;
-       INIT_LIST_HEAD(&data->sibiling);
-       data->handle = handle;
-       list_add_tail(&data->sibiling, &acpi_osc_data_list);
-       return data;
- }
- static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
-                         0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
- static acpi_status acpi_run_osc(acpi_handle handle,
-                               struct acpi_osc_args *osc_args, u32 *retval)
- {
-       acpi_status status;
-       struct acpi_object_list input;
-       union acpi_object in_params[4];
-       struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
-       union acpi_object *out_obj;
-       u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];
-       /* Setting up input parameters */
-       input.count = 4;
-       input.pointer = in_params;
-       in_params[0].type               = ACPI_TYPE_BUFFER;
-       in_params[0].buffer.length      = 16;
-       in_params[0].buffer.pointer     = OSC_UUID;
-       in_params[1].type               = ACPI_TYPE_INTEGER;
-       in_params[1].integer.value      = 1;
-       in_params[2].type               = ACPI_TYPE_INTEGER;
-       in_params[2].integer.value      = 3;
-       in_params[3].type               = ACPI_TYPE_BUFFER;
-       in_params[3].buffer.length      = 12;
-       in_params[3].buffer.pointer     = (u8 *)osc_args->capbuf;
-       status = acpi_evaluate_object(handle, "_OSC", &input, &output);
-       if (ACPI_FAILURE(status))
-               return status;
-       if (!output.length)
-               return AE_NULL_OBJECT;
-       out_obj = output.pointer;
-       if (out_obj->type != ACPI_TYPE_BUFFER) {
-               printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
-               status = AE_TYPE;
-               goto out_kfree;
-       }
-       /* Need to ignore the bit0 in result code */
-       errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
-       if (errors) {
-               if (errors & OSC_REQUEST_ERROR)
-                       printk(KERN_DEBUG "_OSC request fails\n"); 
-               if (errors & OSC_INVALID_UUID_ERROR)
-                       printk(KERN_DEBUG "_OSC invalid UUID\n"); 
-               if (errors & OSC_INVALID_REVISION_ERROR)
-                       printk(KERN_DEBUG "_OSC invalid revision\n"); 
-               if (errors & OSC_CAPABILITIES_MASK_ERROR) {
-                       if (flags & OSC_QUERY_ENABLE)
-                               goto out_success;
-                       printk(KERN_DEBUG "_OSC FW not grant req. control\n");
-                       status = AE_SUPPORT;
-                       goto out_kfree;
-               }
-               status = AE_ERROR;
-               goto out_kfree;
-       }
- out_success:
-       *retval = *((u32 *)(out_obj->buffer.pointer + 8));
-       status = AE_OK;
- out_kfree:
-       kfree(output.pointer);
-       return status;
- }
- static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
- {
-       acpi_status status;
-       u32 support_set, result;
-       struct acpi_osc_args osc_args;
-       /* do _OSC query for all possible controls */
-       support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
-       osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-       osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
-       osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
-       status = acpi_run_osc(osc_data->handle, &osc_args, &result);
-       if (ACPI_SUCCESS(status)) {
-               osc_data->support_set = support_set;
-               osc_data->control_query = result;
-               osc_data->is_queried = 1;
-       }
-       return status;
- }
- /*
-  * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
-  * @flags: Bitmask of flags to support
-  *
-  * See the ACPI spec for the definition of the flags
-  */
- int pci_acpi_osc_support(acpi_handle handle, u32 flags)
- {
-       acpi_status status;
-       acpi_handle tmp;
-       struct acpi_osc_data *osc_data;
-       int rc = 0;
-       status = acpi_get_handle(handle, "_OSC", &tmp);
-       if (ACPI_FAILURE(status))
-               return -ENOTTY;
-       mutex_lock(&pci_acpi_lock);
-       osc_data = acpi_get_osc_data(handle);
-       if (!osc_data) {
-               printk(KERN_ERR "acpi osc data array is full\n");
-               rc = -ENOMEM;
-               goto out;
-       }
-       __acpi_query_osc(flags, osc_data);
- out:
-       mutex_unlock(&pci_acpi_lock);
-       return rc;
- }
- /**
-  * pci_osc_control_set - commit requested control to Firmware
-  * @handle: acpi_handle for the target ACPI object
-  * @flags: driver's requested control bits
-  *
-  * Attempt to take control from Firmware on requested control bits.
-  **/
- acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
- {
-       acpi_status status;
-       u32 control_req, control_set, result;
-       acpi_handle tmp;
-       struct acpi_osc_data *osc_data;
-       struct acpi_osc_args osc_args;
-       status = acpi_get_handle(handle, "_OSC", &tmp);
-       if (ACPI_FAILURE(status))
-               return status;
-       mutex_lock(&pci_acpi_lock);
-       osc_data = acpi_get_osc_data(handle);
-       if (!osc_data) {
-               printk(KERN_ERR "acpi osc data array is full\n");
-               status = AE_ERROR;
-               goto out;
-       }
-       control_req = (flags & OSC_CONTROL_MASKS);
-       if (!control_req) {
-               status = AE_TYPE;
-               goto out;
-       }
-       /* No need to evaluate _OSC if the control was already granted. */
-       if ((osc_data->control_set & control_req) == control_req)
-               goto out;
-       if (!osc_data->is_queried) {
-               status = __acpi_query_osc(osc_data->support_set, osc_data);
-               if (ACPI_FAILURE(status))
-                       goto out;
-       }
-       if ((osc_data->control_query & control_req) != control_req) {
-               status = AE_SUPPORT;
-               goto out;
-       }
-       control_set = osc_data->control_set | control_req;
-       osc_args.capbuf[OSC_QUERY_TYPE] = 0;
-       osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
-       osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
-       status = acpi_run_osc(handle, &osc_args, &result);
-       if (ACPI_SUCCESS(status))
-               osc_data->control_set = result;
- out:
-       mutex_unlock(&pci_acpi_lock);
-       return status;
- }
- EXPORT_SYMBOL(pci_osc_control_set);
  /*
   * _SxD returns the D-state with the highest power
   * (lowest D-state number) supported in the S-state "x".
@@@ -386,12 -171,12 +171,12 @@@ static int __init acpi_pci_init(void
  {
        int ret;
  
 -      if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
 +      if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
                printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
                pci_no_msi();
        }
  
 -      if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
 +      if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
                printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
                pcie_no_aspm();
        }
index e02edf68a68ee6f49c02f33291c9500100452e40,bc8996c849acbd0ac163db6d48744370c7df5734..a90ec5cb2f20dcb547df43cb7a0f5f45c9abeab9
@@@ -2,7 -2,7 +2,7 @@@
   * ACPI Sony Notebook Control Driver (SNC and SPIC)
   *
   * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
 - * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
 + * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
   *
   * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
   * which are copyrighted by their respective authors.
@@@ -46,6 -46,7 +46,6 @@@
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/init.h>
 -#include <linux/smp_lock.h>
  #include <linux/types.h>
  #include <linux/backlight.h>
  #include <linux/platform_device.h>
@@@ -63,7 -64,6 +63,7 @@@
  #include <asm/uaccess.h>
  #include <linux/sonypi.h>
  #include <linux/sony-laptop.h>
 +#include <linux/rfkill.h>
  #ifdef CONFIG_SONYPI_COMPAT
  #include <linux/poll.h>
  #include <linux/miscdevice.h>
@@@ -123,18 -123,6 +123,18 @@@ MODULE_PARM_DESC(minor
                 "default is -1 (automatic)");
  #endif
  
 +enum sony_nc_rfkill {
 +      SONY_WIFI,
 +      SONY_BLUETOOTH,
 +      SONY_WWAN,
 +      SONY_WIMAX,
 +      SONY_RFKILL_MAX,
 +};
 +
 +static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
 +static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
 +static void sony_nc_rfkill_update(void);
 +
  /*********** Input Devices ***********/
  
  #define SONY_LAPTOP_BUF_SIZE  128
@@@ -146,7 -134,6 +146,7 @@@ struct sony_laptop_input_s 
        spinlock_t              fifo_lock;
        struct workqueue_struct *wq;
  };
 +
  static struct sony_laptop_input_s sony_laptop_input = {
        .users = ATOMIC_INIT(0),
  };
@@@ -224,14 -211,6 +224,14 @@@ static int sony_laptop_input_index[] = 
        48,     /* 61 SONYPI_EVENT_WIRELESS_OFF */
        49,     /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
        50,     /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
 +      51,     /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
 +      52,     /* 65 SONYPI_EVENT_MODEKEY_PRESSED */
 +      53,     /* 66 SONYPI_EVENT_PKEY_P4 */
 +      54,     /* 67 SONYPI_EVENT_PKEY_P5 */
 +      55,     /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
 +      56,     /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
 +      57,     /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
 +      -1,     /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
  };
  
  static int sony_laptop_input_keycode_map[] = {
        KEY_WLAN,       /* 47 SONYPI_EVENT_WIRELESS_ON */
        KEY_WLAN,       /* 48 SONYPI_EVENT_WIRELESS_OFF */
        KEY_ZOOMIN,     /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
 -      KEY_ZOOMOUT     /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
 +      KEY_ZOOMOUT,    /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
 +      KEY_EJECTCD,    /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
 +      KEY_F13,        /* 52 SONYPI_EVENT_MODEKEY_PRESSED */
 +      KEY_PROG4,      /* 53 SONYPI_EVENT_PKEY_P4 */
 +      KEY_F14,        /* 54 SONYPI_EVENT_PKEY_P5 */
 +      KEY_F15,        /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
 +      KEY_VOLUMEUP,   /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
 +      KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
  };
  
  /* release buttons after a short delay if pressed */
@@@ -397,7 -369,7 +397,7 @@@ static int sony_laptop_setup_input(stru
        sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
        if (!sony_laptop_input.wq) {
                printk(KERN_ERR DRV_PFX
 -                              "Unabe to create workqueue.\n");
 +                              "Unable to create workqueue.\n");
                error = -ENXIO;
                goto err_free_kfifo;
        }
@@@ -717,31 -689,6 +717,31 @@@ static int acpi_callsetfunc(acpi_handl
        return -1;
  }
  
 +static int sony_find_snc_handle(int handle)
 +{
 +      int i;
 +      int result;
 +
 +      for (i = 0x20; i < 0x30; i++) {
 +              acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
 +              if (result == handle)
 +                      return i-0x20;
 +      }
 +
 +      return -1;
 +}
 +
 +static int sony_call_snc_handle(int handle, int argument, int *result)
 +{
 +      int offset = sony_find_snc_handle(handle);
 +
 +      if (offset < 0)
 +              return -1;
 +
 +      return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
 +                              result);
 +}
 +
  /*
   * sony_nc_values input/output validate functions
   */
@@@ -862,53 -809,87 +862,53 @@@ struct sony_nc_event 
        u8      event;
  };
  
 -static struct sony_nc_event *sony_nc_events;
 -
 -/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
 - * for Fn keys
 - */
 -static int sony_nc_C_enable(const struct dmi_system_id *id)
 -{
 -      int result = 0;
 -
 -      printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
 -
 -      sony_nc_events = id->driver_data;
 -
 -      if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
 -                      || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
 -                      || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
 -                      || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
 -                      || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
 -                      || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
 -              printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
 -                              "functionalities may be missing\n");
 -              return 1;
 -      }
 -      return 0;
 -}
 -
 -static struct sony_nc_event sony_C_events[] = {
 +static struct sony_nc_event sony_100_events[] = {
 +      { 0x90, SONYPI_EVENT_PKEY_P1 },
 +      { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x91, SONYPI_EVENT_PKEY_P2 },
 +      { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
        { 0x81, SONYPI_EVENT_FNKEY_F1 },
        { 0x01, SONYPI_EVENT_FNKEY_RELEASED },
 +      { 0x82, SONYPI_EVENT_FNKEY_F2 },
 +      { 0x02, SONYPI_EVENT_FNKEY_RELEASED },
 +      { 0x83, SONYPI_EVENT_FNKEY_F3 },
 +      { 0x03, SONYPI_EVENT_FNKEY_RELEASED },
 +      { 0x84, SONYPI_EVENT_FNKEY_F4 },
 +      { 0x04, SONYPI_EVENT_FNKEY_RELEASED },
        { 0x85, SONYPI_EVENT_FNKEY_F5 },
        { 0x05, SONYPI_EVENT_FNKEY_RELEASED },
        { 0x86, SONYPI_EVENT_FNKEY_F6 },
        { 0x06, SONYPI_EVENT_FNKEY_RELEASED },
        { 0x87, SONYPI_EVENT_FNKEY_F7 },
        { 0x07, SONYPI_EVENT_FNKEY_RELEASED },
 +      { 0x89, SONYPI_EVENT_FNKEY_F9 },
 +      { 0x09, SONYPI_EVENT_FNKEY_RELEASED },
        { 0x8A, SONYPI_EVENT_FNKEY_F10 },
        { 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
        { 0x8C, SONYPI_EVENT_FNKEY_F12 },
        { 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
 +      { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
 +      { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
        { 0, 0 },
  };
  
 -/* SNC-only model map */
 -static const struct dmi_system_id sony_nc_ids[] = {
 -              {
 -                      .ident = "Sony Vaio FE Series",
 -                      .callback = sony_nc_C_enable,
 -                      .driver_data = sony_C_events,
 -                      .matches = {
 -                              DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 -                              DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
 -                      },
 -              },
 -              {
 -                      .ident = "Sony Vaio FZ Series",
 -                      .callback = sony_nc_C_enable,
 -                      .driver_data = sony_C_events,
 -                      .matches = {
 -                              DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 -                              DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
 -                      },
 -              },
 -              {
 -                      .ident = "Sony Vaio C Series",
 -                      .callback = sony_nc_C_enable,
 -                      .driver_data = sony_C_events,
 -                      .matches = {
 -                              DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 -                              DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
 -                      },
 -              },
 -              {
 -                      .ident = "Sony Vaio N Series",
 -                      .callback = sony_nc_C_enable,
 -                      .driver_data = sony_C_events,
 -                      .matches = {
 -                              DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 -                              DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
 -                      },
 -              },
 -              { }
 +static struct sony_nc_event sony_127_events[] = {
 +      { 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
 +      { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x82, SONYPI_EVENT_PKEY_P1 },
 +      { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x83, SONYPI_EVENT_PKEY_P2 },
 +      { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x84, SONYPI_EVENT_PKEY_P3 },
 +      { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x85, SONYPI_EVENT_PKEY_P4 },
 +      { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x86, SONYPI_EVENT_PKEY_P5 },
 +      { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
 +      { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
 +      { 0, 0 },
  };
  
  /*
   */
  static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
  {
 -      struct sony_nc_event *evmap;
        u32 ev = event;
 -      int result;
  
 -      if (ev == 0x92) {
 -              /* read the key pressed from EC.GECR
 -               * A call to SN07 with 0x0202 will do it as well respecting
 -               * the current protocol on different OSes
 -               *
 -               * Note: the path for GECR may be
 -               *   \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
 -               *   \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
 -               *
 -               * TODO: we may want to do the same for the older GHKE -need
 -               *       dmi list- so this snippet may become one more callback.
 -               */
 -              if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
 -                      dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
 -              else
 -                      ev = result & 0xFF;
 -      }
 +      if (ev >= 0x90) {
 +              /* New-style event */
 +              int result;
 +              int key_handle = 0;
 +              ev -= 0x90;
 +
 +              if (sony_find_snc_handle(0x100) == ev)
 +                      key_handle = 0x100;
 +              if (sony_find_snc_handle(0x127) == ev)
 +                      key_handle = 0x127;
 +
 +              if (key_handle) {
 +                      struct sony_nc_event *key_event;
 +
 +                      if (sony_call_snc_handle(key_handle, 0x200, &result)) {
 +                              dprintk("sony_acpi_notify, unable to decode"
 +                                      " event 0x%.2x 0x%.2x\n", key_handle,
 +                                      ev);
 +                              /* restore the original event */
 +                              ev = event;
 +                      } else {
 +                              ev = result & 0xFF;
 +
 +                              if (key_handle == 0x100)
 +                                      key_event = sony_100_events;
 +                              else
 +                                      key_event = sony_127_events;
 +
 +                              for (; key_event->data; key_event++) {
 +                                      if (key_event->data == ev) {
 +                                              ev = key_event->event;
 +                                              break;
 +                                      }
 +                              }
  
 -      if (sony_nc_events)
 -              for (evmap = sony_nc_events; evmap->event; evmap++) {
 -                      if (evmap->data == ev) {
 -                              ev = evmap->event;
 -                              break;
 +                              if (!key_event->data)
 +                                      printk(KERN_INFO DRV_PFX
 +                                                      "Unknown event: 0x%x 0x%x\n",
 +                                                      key_handle,
 +                                                      ev);
 +                              else
 +                                      sony_laptop_report_input_event(ev);
                        }
 +              } else if (sony_find_snc_handle(0x124) == ev) {
 +                      sony_nc_rfkill_update();
 +                      return;
                }
 +      } else
 +              sony_laptop_report_input_event(ev);
  
        dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
 -      sony_laptop_report_input_event(ev);
        acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
  }
  
@@@ -993,25 -953,9 +993,25 @@@ static acpi_status sony_walk_callback(a
  /*
   * ACPI device
   */
 +static int sony_nc_function_setup(struct acpi_device *device)
 +{
 +      int result;
 +
 +      /* Enable all events */
 +      acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
 +
 +      /* Setup hotkeys */
 +      sony_call_snc_handle(0x0100, 0, &result);
 +      sony_call_snc_handle(0x0101, 0, &result);
 +      sony_call_snc_handle(0x0102, 0x100, &result);
 +
 +      return 0;
 +}
 +
  static int sony_nc_resume(struct acpi_device *device)
  {
        struct sony_nc_value *item;
 +      acpi_handle handle;
  
        for (item = sony_nc_values; item->name; item++) {
                int ret;
                }
        }
  
 +      if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
 +                                       &handle))) {
 +              if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
 +                      dprintk("ECON Method failed\n");
 +      }
 +
 +      if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
 +                                       &handle))) {
 +              dprintk("Doing SNC setup\n");
 +              sony_nc_function_setup(device);
 +      }
 +
        /* set the last requested brightness level */
        if (sony_backlight_device &&
                        !sony_backlight_update_status(sony_backlight_device))
                printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
  
 -      /* re-initialize models with specific requirements */
 -      dmi_check_system(sony_nc_ids);
 +      return 0;
 +}
 +
 +static void sony_nc_rfkill_cleanup(void)
 +{
 +      int i;
 +
 +      for (i = 0; i < SONY_RFKILL_MAX; i++) {
 +              if (sony_rfkill_devices[i])
 +                      rfkill_unregister(sony_rfkill_devices[i]);
 +      }
 +}
 +
 +static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
 +{
 +      int result;
 +      int argument = sony_rfkill_address[(long) data];
 +
 +      sony_call_snc_handle(0x124, 0x200, &result);
 +      if (result & 0x1) {
 +              sony_call_snc_handle(0x124, argument, &result);
 +              if (result & 0xf)
 +                      *state = RFKILL_STATE_UNBLOCKED;
 +              else
 +                      *state = RFKILL_STATE_SOFT_BLOCKED;
 +      } else {
 +              *state = RFKILL_STATE_HARD_BLOCKED;
 +      }
 +
 +      return 0;
 +}
 +
 +static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
 +{
 +      int result;
 +      int argument = sony_rfkill_address[(long) data] + 0x100;
 +
 +      if (state == RFKILL_STATE_UNBLOCKED)
 +              argument |= 0xff0000;
 +
 +      return sony_call_snc_handle(0x124, argument, &result);
 +}
 +
 +static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
 +{
 +      int err = 0;
 +      struct rfkill *sony_wifi_rfkill;
 +
 +      sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
 +      if (!sony_wifi_rfkill)
 +              return -1;
 +      sony_wifi_rfkill->name = "sony-wifi";
 +      sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
 +      sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
 +      sony_wifi_rfkill->user_claim_unsupported = 1;
 +      sony_wifi_rfkill->data = (void *)SONY_WIFI;
 +      err = rfkill_register(sony_wifi_rfkill);
 +      if (err)
 +              rfkill_free(sony_wifi_rfkill);
 +      else
 +              sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
 +      return err;
 +}
 +
 +static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
 +{
 +      int err = 0;
 +      struct rfkill *sony_bluetooth_rfkill;
 +
 +      sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
 +                                              RFKILL_TYPE_BLUETOOTH);
 +      if (!sony_bluetooth_rfkill)
 +              return -1;
 +      sony_bluetooth_rfkill->name = "sony-bluetooth";
 +      sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
 +      sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
 +      sony_bluetooth_rfkill->user_claim_unsupported = 1;
 +      sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
 +      err = rfkill_register(sony_bluetooth_rfkill);
 +      if (err)
 +              rfkill_free(sony_bluetooth_rfkill);
 +      else
 +              sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
 +      return err;
 +}
 +
 +static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
 +{
 +      int err = 0;
 +      struct rfkill *sony_wwan_rfkill;
 +
 +      sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
 +      if (!sony_wwan_rfkill)
 +              return -1;
 +      sony_wwan_rfkill->name = "sony-wwan";
 +      sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
 +      sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
 +      sony_wwan_rfkill->user_claim_unsupported = 1;
 +      sony_wwan_rfkill->data = (void *)SONY_WWAN;
 +      err = rfkill_register(sony_wwan_rfkill);
 +      if (err)
 +              rfkill_free(sony_wwan_rfkill);
 +      else
 +              sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
 +      return err;
 +}
 +
 +static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
 +{
 +      int err = 0;
 +      struct rfkill *sony_wimax_rfkill;
 +
 +      sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
 +      if (!sony_wimax_rfkill)
 +              return -1;
 +      sony_wimax_rfkill->name = "sony-wimax";
 +      sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
 +      sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
 +      sony_wimax_rfkill->user_claim_unsupported = 1;
 +      sony_wimax_rfkill->data = (void *)SONY_WIMAX;
 +      err = rfkill_register(sony_wimax_rfkill);
 +      if (err)
 +              rfkill_free(sony_wimax_rfkill);
 +      else
 +              sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
 +      return err;
 +}
 +
 +static void sony_nc_rfkill_update()
 +{
 +      int i;
 +      enum rfkill_state state;
 +
 +      for (i = 0; i < SONY_RFKILL_MAX; i++) {
 +              if (sony_rfkill_devices[i]) {
 +                      sony_rfkill_devices[i]->
 +                              get_state(sony_rfkill_devices[i]->data,
 +                                        &state);
 +                      rfkill_force_state(sony_rfkill_devices[i], state);
 +              }
 +      }
 +}
 +
 +static int sony_nc_rfkill_setup(struct acpi_device *device)
 +{
 +      int result, ret;
 +
 +      if (sony_find_snc_handle(0x124) == -1)
 +              return -1;
 +
 +      ret = sony_call_snc_handle(0x124, 0xb00, &result);
 +      if (ret) {
 +              printk(KERN_INFO DRV_PFX
 +                     "Unable to enumerate rfkill devices: %x\n", ret);
 +              return ret;
 +      }
 +
 +      if (result & 0x1)
 +              sony_nc_setup_wifi_rfkill(device);
 +      if (result & 0x2)
 +              sony_nc_setup_bluetooth_rfkill(device);
 +      if (result & 0x1c)
 +              sony_nc_setup_wwan_rfkill(device);
 +      if (result & 0x20)
 +              sony_nc_setup_wimax_rfkill(device);
  
        return 0;
  }
@@@ -1255,24 -1024,11 +1255,24 @@@ static int sony_nc_add(struct acpi_devi
                        dprintk("_INI Method failed\n");
        }
  
 +      if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
 +                                       &handle))) {
 +              if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
 +                      dprintk("ECON Method failed\n");
 +      }
 +
 +      if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
 +                                       &handle))) {
 +              dprintk("Doing SNC setup\n");
 +              sony_nc_function_setup(device);
 +              sony_nc_rfkill_setup(device);
 +      }
 +
        /* setup input devices and helper fifo */
        result = sony_laptop_setup_input(device);
        if (result) {
                printk(KERN_ERR DRV_PFX
 -                              "Unabe to create input devices.\n");
 +                              "Unable to create input devices.\n");
                goto outwalk;
        }
  
  
        }
  
 -      /* initialize models with specific requirements */
 -      dmi_check_system(sony_nc_ids);
 -
        result = sony_pf_add();
        if (result)
                goto outbacklight;
        sony_laptop_remove_input();
  
        outwalk:
 +      sony_nc_rfkill_cleanup();
        return result;
  }
  
@@@ -1398,7 -1156,6 +1398,7 @@@ static int sony_nc_remove(struct acpi_d
  
        sony_pf_remove();
        sony_laptop_remove_input();
 +      sony_nc_rfkill_cleanup();
        dprintk(SONY_NC_DRIVER_NAME " removed.\n");
  
        return 0;
@@@ -1438,6 -1195,7 +1438,6 @@@ static struct acpi_driver sony_nc_drive
  #define SONYPI_TYPE1_OFFSET   0x04
  #define SONYPI_TYPE2_OFFSET   0x12
  #define SONYPI_TYPE3_OFFSET   0x12
 -#define SONYPI_TYPE4_OFFSET   0x12
  
  struct sony_pic_ioport {
        struct acpi_resource_io io1;
@@@ -1570,7 -1328,6 +1570,7 @@@ static struct sonypi_event sonypi_pkeye
        { 0x01, SONYPI_EVENT_PKEY_P1 },
        { 0x02, SONYPI_EVENT_PKEY_P2 },
        { 0x04, SONYPI_EVENT_PKEY_P3 },
 +      { 0x20, SONYPI_EVENT_PKEY_P1 },
        { 0, 0 }
  };
  
@@@ -1614,7 -1371,6 +1614,7 @@@ static struct sonypi_event sonypi_zoome
        { 0x39, SONYPI_EVENT_ZOOM_PRESSED },
        { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
        { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
 +      { 0x04, SONYPI_EVENT_ZOOM_PRESSED },
        { 0, 0 }
  };
  
@@@ -1645,19 -1401,6 +1645,19 @@@ static struct sonypi_event sonypi_batte
        { 0, 0 }
  };
  
 +/* The set of possible volume events */
 +static struct sonypi_event sonypi_volumeev[] = {
 +      { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
 +      { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
 +      { 0, 0 }
 +};
 +
 +/* The set of possible brightness events */
 +static struct sonypi_event sonypi_brightnessev[] = {
 +      { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
 +      { 0, 0 }
 +};
 +
  static struct sonypi_eventtypes type1_events[] = {
        { 0, 0xffffffff, sonypi_releaseev },
        { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@@ -1695,11 -1438,17 +1695,11 @@@ static struct sonypi_eventtypes type3_e
        { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
        { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
        { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
 -      { 0 },
 -};
 -static struct sonypi_eventtypes type4_events[] = {
 -      { 0, 0xffffffff, sonypi_releaseev },
 -      { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
 -      { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
 -      { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
 -      { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
        { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
        { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
        { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
 +      { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
 +      { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
        { 0 },
  };
  
@@@ -1762,11 -1511,11 +1762,11 @@@ static u8 sony_pic_call3(u8 dev, u8 fn
  /*
   * minidrivers for SPIC models
   */
 -static int type4_handle_irq(const u8 data_mask, const u8 ev)
 +static int type3_handle_irq(const u8 data_mask, const u8 ev)
  {
        /*
         * 0x31 could mean we have to take some extra action and wait for
 -       * the next irq for some Type4 models, it will generate a new
 +       * the next irq for some Type3 models, it will generate a new
         * irq and we can read new data from the device:
         *  - 0x5c and 0x5f requires 0xA0
         *  - 0x61 requires 0xB3
@@@ -1796,10 -1545,16 +1796,10 @@@ static struct device_ctrl spic_types[] 
        },
        {
                .model = SONYPI_DEVICE_TYPE3,
 -              .handle_irq = NULL,
 +              .handle_irq = type3_handle_irq,
                .evport_offset = SONYPI_TYPE3_OFFSET,
                .event_types = type3_events,
        },
 -      {
 -              .model = SONYPI_DEVICE_TYPE4,
 -              .handle_irq = type4_handle_irq,
 -              .evport_offset = SONYPI_TYPE4_OFFSET,
 -              .event_types = type4_events,
 -      },
  };
  
  static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
        if (pcidev) {
 -              dev->control = &spic_types[3];
 +              dev->control = &spic_types[2];
                goto out;
        }
  
        pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                        PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
        if (pcidev) {
 -              dev->control = &spic_types[3];
 +              dev->control = &spic_types[2];
 +              goto out;
 +      }
 +
 +      pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
 +                      PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
 +      if (pcidev) {
 +              dev->control = &spic_types[2];
                goto out;
        }
  
@@@ -1850,7 -1598,8 +1850,7 @@@ out
  
        printk(KERN_INFO DRV_PFX "detected Type%d model\n",
                        dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
 -                      dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
 -                      dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
 +                      dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
  }
  
  /* camera tests and poweron/poweroff */
@@@ -2005,14 -1754,17 +2005,14 @@@ int sony_pic_camera_command(int command
  EXPORT_SYMBOL(sony_pic_camera_command);
  
  /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
 -static void sony_pic_set_wwanpower(u8 state)
 +static void __sony_pic_set_wwanpower(u8 state)
  {
        state = !!state;
 -      mutex_lock(&spic_dev.lock);
 -      if (spic_dev.wwan_power == state) {
 -              mutex_unlock(&spic_dev.lock);
 +      if (spic_dev.wwan_power == state)
                return;
 -      }
        sony_pic_call2(0xB0, state);
 +      sony_pic_call1(0x82);
        spic_dev.wwan_power = state;
 -      mutex_unlock(&spic_dev.lock);
  }
  
  static ssize_t sony_pic_wwanpower_store(struct device *dev,
                return -EINVAL;
  
        value = simple_strtoul(buffer, NULL, 10);
 -      sony_pic_set_wwanpower(value);
 +      mutex_lock(&spic_dev.lock);
 +      __sony_pic_set_wwanpower(value);
 +      mutex_unlock(&spic_dev.lock);
  
        return count;
  }
@@@ -2167,12 -1917,7 +2167,7 @@@ static struct sonypi_compat_s sonypi_co
  
  static int sonypi_misc_fasync(int fd, struct file *filp, int on)
  {
-       int retval;
-       retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
-       if (retval < 0)
-               return retval;
-       return 0;
+       return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
  }
  
  static int sonypi_misc_release(struct inode *inode, struct file *file)
  static int sonypi_misc_open(struct inode *inode, struct file *file)
  {
        /* Flush input queue on first open */
 -      lock_kernel();
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
 +
        if (atomic_inc_return(&sonypi_compat.open_count) == 1)
 -              kfifo_reset(sonypi_compat.fifo);
 -      unlock_kernel();
 +              __kfifo_reset(sonypi_compat.fifo);
 +
 +      spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
 +
        return 0;
  }
  
@@@ -2245,8 -1985,8 +2240,8 @@@ static int ec_read16(u8 addr, u16 *valu
        return 0;
  }
  
 -static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
 -                           unsigned int cmd, unsigned long arg)
 +static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
 +                                                      unsigned long arg)
  {
        int ret = 0;
        void __user *argp = (void __user *)arg;
@@@ -2380,7 -2120,7 +2375,7 @@@ static const struct file_operations son
        .open           = sonypi_misc_open,
        .release        = sonypi_misc_release,
        .fasync         = sonypi_misc_fasync,
 -      .ioctl          = sonypi_misc_ioctl,
 +      .unlocked_ioctl = sonypi_misc_ioctl,
  };
  
  static struct miscdevice sonypi_misc_device = {
@@@ -2821,7 -2561,7 +2816,7 @@@ static int sony_pic_add(struct acpi_dev
        result = sony_pic_possible_resources(device);
        if (result) {
                printk(KERN_ERR DRV_PFX
 -                              "Unabe to read possible resources.\n");
 +                              "Unable to read possible resources.\n");
                goto err_free_resources;
        }
  
        result = sony_laptop_setup_input(device);
        if (result) {
                printk(KERN_ERR DRV_PFX
 -                              "Unabe to create input devices.\n");
 +                              "Unable to create input devices.\n");
                goto err_free_resources;
        }
  
index ba3682c5cde08575fbd0a3e4e3d2b503ab835380,d99f1cd435a281009f05839a8265a513890b63bd..a40b075743d9617dcfb4ed6de6c9131ad2c682c0
@@@ -3,7 -3,7 +3,7 @@@
   *
   *
   *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
 - *  Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
 + *  Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
   *
   *  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
@@@ -22,7 -22,7 +22,7 @@@
   */
  
  #define TPACPI_VERSION "0.22"
 -#define TPACPI_SYSFS_VERSION 0x020200
 +#define TPACPI_SYSFS_VERSION 0x020300
  
  /*
   *  Changelog:
@@@ -54,7 -54,6 +54,7 @@@
  #include <linux/string.h>
  #include <linux/list.h>
  #include <linux/mutex.h>
 +#include <linux/sched.h>
  #include <linux/kthread.h>
  #include <linux/freezer.h>
  #include <linux/delay.h>
@@@ -173,26 -172,29 +173,26 @@@ enum 
        TPACPI_RFK_UWB_SW_ID,
  };
  
 -/* Debugging */
 +/* printk headers */
  #define TPACPI_LOG TPACPI_FILE ": "
 -#define TPACPI_ALERT  KERN_ALERT  TPACPI_LOG
 -#define TPACPI_CRIT   KERN_CRIT   TPACPI_LOG
 -#define TPACPI_ERR    KERN_ERR    TPACPI_LOG
 -#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
 -#define TPACPI_INFO   KERN_INFO   TPACPI_LOG
 -#define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
 -
 +#define TPACPI_EMERG  KERN_EMERG      TPACPI_LOG
 +#define TPACPI_ALERT  KERN_ALERT      TPACPI_LOG
 +#define TPACPI_CRIT   KERN_CRIT       TPACPI_LOG
 +#define TPACPI_ERR    KERN_ERR        TPACPI_LOG
 +#define TPACPI_WARN   KERN_WARNING    TPACPI_LOG
 +#define TPACPI_NOTICE KERN_NOTICE     TPACPI_LOG
 +#define TPACPI_INFO   KERN_INFO       TPACPI_LOG
 +#define TPACPI_DEBUG  KERN_DEBUG      TPACPI_LOG
 +
 +/* Debugging printk groups */
  #define TPACPI_DBG_ALL                0xffff
 +#define TPACPI_DBG_DISCLOSETASK       0x8000
  #define TPACPI_DBG_INIT               0x0001
  #define TPACPI_DBG_EXIT               0x0002
 -#define dbg_printk(a_dbg_level, format, arg...) \
 -      do { if (dbg_level & a_dbg_level) \
 -              printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
 -      } while (0)
 -#ifdef CONFIG_THINKPAD_ACPI_DEBUG
 -#define vdbg_printk(a_dbg_level, format, arg...) \
 -      dbg_printk(a_dbg_level, format, ## arg)
 -static const char *str_supported(int is_supported);
 -#else
 -#define vdbg_printk(a_dbg_level, format, arg...)
 -#endif
 +#define TPACPI_DBG_RFKILL     0x0004
 +#define TPACPI_DBG_HKEY               0x0008
 +#define TPACPI_DBG_FAN                0x0010
 +#define TPACPI_DBG_BRGHT      0x0020
  
  #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
  #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@@ -275,6 -277,7 +275,6 @@@ static struct 
  
  static struct {
        u16 hotkey_mask_ff:1;
 -      u16 bright_cmos_ec_unsync:1;
  } tp_warned;
  
  struct thinkpad_id_data {
@@@ -323,39 -326,6 +323,39 @@@ static int tpacpi_uwb_emulstate
  #endif
  
  
 +/*************************************************************************
 + *  Debugging helpers
 + */
 +
 +#define dbg_printk(a_dbg_level, format, arg...) \
 +      do { if (dbg_level & (a_dbg_level)) \
 +              printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
 +      } while (0)
 +
 +#ifdef CONFIG_THINKPAD_ACPI_DEBUG
 +#define vdbg_printk dbg_printk
 +static const char *str_supported(int is_supported);
 +#else
 +#define vdbg_printk(a_dbg_level, format, arg...) \
 +      do { } while (0)
 +#endif
 +
 +static void tpacpi_log_usertask(const char * const what)
 +{
 +      printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
 +              what, task_tgid_vnr(current));
 +}
 +
 +#define tpacpi_disclose_usertask(what, format, arg...) \
 +      do { \
 +              if (unlikely( \
 +                  (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
 +                  (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
 +                      printk(TPACPI_DEBUG "%s: PID %d: " format, \
 +                              what, task_tgid_vnr(current), ## arg); \
 +              } \
 +      } while (0)
 +
  /****************************************************************************
   ****************************************************************************
   *
@@@ -1019,13 -989,10 +1019,13 @@@ static int __init tpacpi_new_rfkill(con
                /* try to set the initial state as the default for the rfkill
                 * type, since we ask the firmware to preserve it across S5 in
                 * NVRAM */
 -              rfkill_set_default(rfktype,
 +              if (rfkill_set_default(rfktype,
                                (initial_state == RFKILL_STATE_UNBLOCKED) ?
                                        RFKILL_STATE_UNBLOCKED :
 -                                      RFKILL_STATE_SOFT_BLOCKED);
 +                                      RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
 +                      vdbg_printk(TPACPI_DBG_RFKILL,
 +                                  "Default state for %s cannot be changed\n",
 +                                  name);
        }
  
        *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
        return 0;
  }
  
 +static void printk_deprecated_attribute(const char * const what,
 +                                      const char * const details)
 +{
 +      tpacpi_log_usertask("deprecated sysfs attribute");
 +      printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
 +              "will be removed. %s\n",
 +              what, details);
 +}
 +
 +static void printk_deprecated_rfkill_attribute(const char * const what)
 +{
 +      printk_deprecated_attribute(what,
 +                      "Please switch to generic rfkill before year 2010");
 +}
 +
  /*************************************************************************
   * thinkpad-acpi driver attributes
   */
@@@ -1430,6 -1382,7 +1430,6 @@@ static enum {   /* Reasons for waking up 
  
  static int hotkey_autosleep_ack;
  
 -static int hotkey_orig_status;
  static u32 hotkey_orig_mask;
  static u32 hotkey_all_mask;
  static u32 hotkey_reserved_mask;
@@@ -1576,9 -1529,9 +1576,9 @@@ static int hotkey_status_get(int *statu
        return 0;
  }
  
 -static int hotkey_status_set(int status)
 +static int hotkey_status_set(bool enable)
  {
 -      if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
 +      if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
                return -EIO;
  
        return 0;
@@@ -1894,9 -1847,6 +1894,9 @@@ static ssize_t hotkey_enable_show(struc
  {
        int res, status;
  
 +      printk_deprecated_attribute("hotkey_enable",
 +                      "Hotkey reporting is always enabled");
 +
        res = hotkey_status_get(&status);
        if (res)
                return res;
@@@ -1909,17 -1859,14 +1909,17 @@@ static ssize_t hotkey_enable_store(stru
                            const char *buf, size_t count)
  {
        unsigned long t;
 -      int res;
 +
 +      printk_deprecated_attribute("hotkey_enable",
 +                      "Hotkeys can be disabled through hotkey_mask");
  
        if (parse_strtoul(buf, 1, &t))
                return -EINVAL;
  
 -      res = hotkey_status_set(t);
 +      if (t == 0)
 +              return -EPERM;
  
 -      return (res) ? res : count;
 +      return count;
  }
  
  static struct device_attribute dev_attr_hotkey_enable =
@@@ -1963,8 -1910,6 +1963,8 @@@ static ssize_t hotkey_mask_store(struc
  
        mutex_unlock(&hotkey_mutex);
  
 +      tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
 +
        return (res) ? res : count;
  }
  
@@@ -1977,7 -1922,7 +1977,7 @@@ static ssize_t hotkey_bios_enabled_show
                           struct device_attribute *attr,
                           char *buf)
  {
 -      return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
 +      return sprintf(buf, "0\n");
  }
  
  static struct device_attribute dev_attr_hotkey_bios_enabled =
@@@ -2051,8 -1996,6 +2051,8 @@@ static ssize_t hotkey_source_mask_store
  
        mutex_unlock(&hotkey_mutex);
  
 +      tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
 +
        return count;
  }
  
@@@ -2085,8 -2028,6 +2085,8 @@@ static ssize_t hotkey_poll_freq_store(s
        hotkey_poll_setup(1);
        mutex_unlock(&hotkey_mutex);
  
 +      tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
 +
        return count;
  }
  
@@@ -2256,11 -2197,11 +2256,11 @@@ static void hotkey_exit(void
        kfree(hotkey_keycode_map);
  
        if (tp_features.hotkey) {
 -              dbg_printk(TPACPI_DBG_EXIT,
 +              dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
                           "restoring original hot key mask\n");
                /* no short-circuit boolean operator below! */
                if ((hotkey_mask_set(hotkey_orig_mask) |
 -                   hotkey_status_set(hotkey_orig_status)) != 0)
 +                   hotkey_status_set(false)) != 0)
                        printk(TPACPI_ERR
                               "failed to restore hot key mask "
                               "to BIOS defaults\n");
@@@ -2386,8 -2327,7 +2386,8 @@@ static int __init hotkey_init(struct ib
        int status;
        int hkeyv;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +                      "initializing hotkey subdriver\n");
  
        BUG_ON(!tpacpi_inputdev);
        BUG_ON(tpacpi_inputdev->open != NULL ||
        /* hotkey not supported on 570 */
        tp_features.hotkey = hkey_handle != NULL;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +              "hotkeys are %s\n",
                str_supported(tp_features.hotkey));
  
        if (!tp_features.hotkey)
                         * T4x, X31, and later
                         */
                        tp_features.hotkey_mask = 1;
 +                      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +                              "firmware HKEY interface version: 0x%x\n",
 +                              hkeyv);
                }
        }
  
 -      vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +              "hotkey masks are %s\n",
                str_supported(tp_features.hotkey_mask));
  
        if (tp_features.hotkey_mask) {
  
        /* hotkey_source_mask *must* be zero for
         * the first hotkey_mask_get */
 -      res = hotkey_status_get(&hotkey_orig_status);
 -      if (res)
 -              goto err_exit;
 -
        if (tp_features.hotkey_mask) {
                res = hotkey_mask_get();
                if (res)
                hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
        }
  
 -      vdbg_printk(TPACPI_DBG_INIT,
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
                    "hotkey source mask 0x%08x, polling freq %d\n",
                    hotkey_source_mask, hotkey_poll_freq);
  #endif
        }
  
        if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
                           "using Lenovo default hot key map\n");
                memcpy(hotkey_keycode_map, &lenovo_keycode_map,
                        TPACPI_HOTKEY_MAP_SIZE);
        } else {
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
                           "using IBM default hot key map\n");
                memcpy(hotkey_keycode_map, &ibm_keycode_map,
                        TPACPI_HOTKEY_MAP_SIZE);
                        | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
        }
  
 -      dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
 -      res = hotkey_status_set(1);
 +      dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +                      "enabling firmware HKEY event interface...\n");
 +      res = hotkey_status_set(true);
        if (res) {
                hotkey_exit();
                return res;
                return res;
        }
  
 -      dbg_printk(TPACPI_DBG_INIT,
 -                      "legacy hot key reporting over procfs %s\n",
 +      dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 +                      "legacy ibm/hotkey event reporting over procfs %s\n",
                        (hotkey_report_mode < 2) ?
                                "enabled" : "disabled");
  
@@@ -2946,17 -2884,9 +2946,17 @@@ static int hotkey_read(char *p
        return len;
  }
  
 +static void hotkey_enabledisable_warn(void)
 +{
 +      tpacpi_log_usertask("procfs hotkey enable/disable");
 +      WARN(1, TPACPI_WARN
 +           "hotkey enable/disable functionality has been "
 +           "removed from the driver. Hotkeys are always enabled.\n");
 +}
 +
  static int hotkey_write(char *buf)
  {
 -      int res, status;
 +      int res;
        u32 mask;
        char *cmd;
  
        if (mutex_lock_killable(&hotkey_mutex))
                return -ERESTARTSYS;
  
 -      status = -1;
        mask = hotkey_mask;
  
        res = 0;
        while ((cmd = next_cmd(&buf))) {
                if (strlencmp(cmd, "enable") == 0) {
 -                      status = 1;
 +                      hotkey_enabledisable_warn();
                } else if (strlencmp(cmd, "disable") == 0) {
 -                      status = 0;
 +                      hotkey_enabledisable_warn();
 +                      res = -EPERM;
                } else if (strlencmp(cmd, "reset") == 0) {
 -                      status = hotkey_orig_status;
                        mask = hotkey_orig_mask;
                } else if (sscanf(cmd, "0x%x", &mask) == 1) {
                        /* mask set */
                        goto errexit;
                }
        }
 -      if (status != -1)
 -              res = hotkey_status_set(status);
 +
 +      if (!res)
 +              tpacpi_disclose_usertask("procfs hotkey",
 +                      "set mask to 0x%08x\n", mask);
  
        if (!res && mask != hotkey_mask)
                res = hotkey_mask_set(mask);
@@@ -3042,17 -2971,13 +3042,17 @@@ enum 
        TP_ACPI_BLTH_SAVE_STATE         = 0x05, /* Save state for S4/S5 */
  };
  
 +#define TPACPI_RFK_BLUETOOTH_SW_NAME  "tpacpi_bluetooth_sw"
 +
  static struct rfkill *tpacpi_bluetooth_rfkill;
  
  static void bluetooth_suspend(pm_message_t state)
  {
        /* Try to make sure radio will resume powered off */
 -      acpi_evalf(NULL, NULL, "\\BLTH", "vd",
 -                 TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
 +      if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
 +                 TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
 +              vdbg_printk(TPACPI_DBG_RFKILL,
 +                      "bluetooth power down on resume request failed\n");
  }
  
  static int bluetooth_get_radiosw(void)
@@@ -3090,10 -3015,6 +3090,10 @@@ static void bluetooth_update_rfk(void
        if (status < 0)
                return;
        rfkill_force_state(tpacpi_bluetooth_rfkill, status);
 +
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +              "forced rfkill state to %d\n",
 +              status);
  }
  
  static int bluetooth_set_radiosw(int radio_on, int update_rfk)
            && radio_on)
                return -EPERM;
  
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +              "will %s bluetooth\n", radio_on ? "enable" : "disable");
 +
  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_bluetoothemul) {
                tpacpi_bluetooth_emulstate = !!radio_on;
@@@ -3142,8 -3060,6 +3142,8 @@@ static ssize_t bluetooth_enable_show(st
  {
        int status;
  
 +      printk_deprecated_rfkill_attribute("bluetooth_enable");
 +
        status = bluetooth_get_radiosw();
        if (status < 0)
                return status;
@@@ -3159,13 -3075,9 +3159,13 @@@ static ssize_t bluetooth_enable_store(s
        unsigned long t;
        int res;
  
 +      printk_deprecated_rfkill_attribute("bluetooth_enable");
 +
        if (parse_strtoul(buf, 1, &t))
                return -EINVAL;
  
 +      tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
 +
        res = bluetooth_set_radiosw(t, 1);
  
        return (res) ? res : count;
@@@ -3199,8 -3111,6 +3199,8 @@@ static int tpacpi_bluetooth_rfk_get(voi
  
  static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
  {
 +      dbg_printk(TPACPI_DBG_RFKILL,
 +                 "request to change radio state to %d\n", state);
        return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
  }
  
@@@ -3211,9 -3121,6 +3211,9 @@@ static void bluetooth_shutdown(void
                        TP_ACPI_BLTH_SAVE_STATE))
                printk(TPACPI_NOTICE
                        "failed to save bluetooth state to NVRAM\n");
 +      else
 +              vdbg_printk(TPACPI_DBG_RFKILL,
 +                      "bluestooth state saved to NVRAM\n");
  }
  
  static void bluetooth_exit(void)
@@@ -3232,8 -3139,7 +3232,8 @@@ static int __init bluetooth_init(struc
        int res;
        int status = 0;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +                      "initializing bluetooth subdriver\n");
  
        TPACPI_ACPIHANDLE_INIT(hkey);
  
        tp_features.bluetooth = hkey_handle &&
            acpi_evalf(hkey_handle, &status, "GBDC", "qd");
  
 -      vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +              "bluetooth is %s, status 0x%02x\n",
                str_supported(tp_features.bluetooth),
                status);
  
            !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
                /* no bluetooth hardware present in system */
                tp_features.bluetooth = 0;
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
                           "bluetooth hardware not installed\n");
        }
  
        res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
                                &tpacpi_bluetooth_rfkill,
                                RFKILL_TYPE_BLUETOOTH,
 -                              "tpacpi_bluetooth_sw",
 +                              TPACPI_RFK_BLUETOOTH_SW_NAME,
                                true,
                                tpacpi_bluetooth_rfk_set,
                                tpacpi_bluetooth_rfk_get);
@@@ -3306,27 -3211,19 +3306,27 @@@ static int bluetooth_read(char *p
  static int bluetooth_write(char *buf)
  {
        char *cmd;
 +      int state = -1;
  
        if (!tp_features.bluetooth)
                return -ENODEV;
  
        while ((cmd = next_cmd(&buf))) {
                if (strlencmp(cmd, "enable") == 0) {
 -                      bluetooth_set_radiosw(1, 1);
 +                      state = 1;
                } else if (strlencmp(cmd, "disable") == 0) {
 -                      bluetooth_set_radiosw(0, 1);
 +                      state = 0;
                } else
                        return -EINVAL;
        }
  
 +      if (state != -1) {
 +              tpacpi_disclose_usertask("procfs bluetooth",
 +                      "attempt to %s\n",
 +                      state ? "enable" : "disable");
 +              bluetooth_set_radiosw(state, 1);
 +      }
 +
        return 0;
  }
  
@@@ -3351,17 -3248,13 +3351,17 @@@ enum 
                                                   off / last state */
  };
  
 +#define TPACPI_RFK_WWAN_SW_NAME               "tpacpi_wwan_sw"
 +
  static struct rfkill *tpacpi_wan_rfkill;
  
  static void wan_suspend(pm_message_t state)
  {
        /* Try to make sure radio will resume powered off */
 -      acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
 -                 TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
 +      if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
 +                 TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
 +              vdbg_printk(TPACPI_DBG_RFKILL,
 +                      "WWAN power down on resume request failed\n");
  }
  
  static int wan_get_radiosw(void)
@@@ -3399,10 -3292,6 +3399,10 @@@ static void wan_update_rfk(void
        if (status < 0)
                return;
        rfkill_force_state(tpacpi_wan_rfkill, status);
 +
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +              "forced rfkill state to %d\n",
 +              status);
  }
  
  static int wan_set_radiosw(int radio_on, int update_rfk)
            && radio_on)
                return -EPERM;
  
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +              "will %s WWAN\n", radio_on ? "enable" : "disable");
 +
  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_wwanemul) {
                tpacpi_wwan_emulstate = !!radio_on;
@@@ -3451,8 -3337,6 +3451,8 @@@ static ssize_t wan_enable_show(struct d
  {
        int status;
  
 +      printk_deprecated_rfkill_attribute("wwan_enable");
 +
        status = wan_get_radiosw();
        if (status < 0)
                return status;
@@@ -3468,13 -3352,9 +3468,13 @@@ static ssize_t wan_enable_store(struct 
        unsigned long t;
        int res;
  
 +      printk_deprecated_rfkill_attribute("wwan_enable");
 +
        if (parse_strtoul(buf, 1, &t))
                return -EINVAL;
  
 +      tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
 +
        res = wan_set_radiosw(t, 1);
  
        return (res) ? res : count;
@@@ -3508,8 -3388,6 +3508,8 @@@ static int tpacpi_wan_rfk_get(void *dat
  
  static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
  {
 +      dbg_printk(TPACPI_DBG_RFKILL,
 +                 "request to change radio state to %d\n", state);
        return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
  }
  
@@@ -3520,9 -3398,6 +3520,9 @@@ static void wan_shutdown(void
                        TP_ACPI_WGSV_SAVE_STATE))
                printk(TPACPI_NOTICE
                        "failed to save WWAN state to NVRAM\n");
 +      else
 +              vdbg_printk(TPACPI_DBG_RFKILL,
 +                      "WWAN state saved to NVRAM\n");
  }
  
  static void wan_exit(void)
@@@ -3541,16 -3416,14 +3541,16 @@@ static int __init wan_init(struct ibm_i
        int res;
        int status = 0;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +                      "initializing wan subdriver\n");
  
        TPACPI_ACPIHANDLE_INIT(hkey);
  
        tp_features.wan = hkey_handle &&
            acpi_evalf(hkey_handle, &status, "GWAN", "qd");
  
 -      vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +              "wan is %s, status 0x%02x\n",
                str_supported(tp_features.wan),
                status);
  
            !(status & TP_ACPI_WANCARD_HWPRESENT)) {
                /* no wan hardware present in system */
                tp_features.wan = 0;
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
                           "wan hardware not installed\n");
        }
  
        res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
                                &tpacpi_wan_rfkill,
                                RFKILL_TYPE_WWAN,
 -                              "tpacpi_wwan_sw",
 +                              TPACPI_RFK_WWAN_SW_NAME,
                                true,
                                tpacpi_wan_rfk_set,
                                tpacpi_wan_rfk_get);
@@@ -3598,8 -3471,6 +3598,8 @@@ static int wan_read(char *p
        int len = 0;
        int status = wan_get_radiosw();
  
 +      tpacpi_disclose_usertask("procfs wan", "read");
 +
        if (!tp_features.wan)
                len += sprintf(p + len, "status:\t\tnot supported\n");
        else {
  static int wan_write(char *buf)
  {
        char *cmd;
 +      int state = -1;
  
        if (!tp_features.wan)
                return -ENODEV;
  
        while ((cmd = next_cmd(&buf))) {
                if (strlencmp(cmd, "enable") == 0) {
 -                      wan_set_radiosw(1, 1);
 +                      state = 1;
                } else if (strlencmp(cmd, "disable") == 0) {
 -                      wan_set_radiosw(0, 1);
 +                      state = 0;
                } else
                        return -EINVAL;
        }
  
 +      if (state != -1) {
 +              tpacpi_disclose_usertask("procfs wan",
 +                      "attempt to %s\n",
 +                      state ? "enable" : "disable");
 +              wan_set_radiosw(state, 1);
 +      }
 +
        return 0;
  }
  
@@@ -3658,8 -3521,6 +3658,8 @@@ enum 
        TP_ACPI_UWB_RADIOSSW    = 0x02, /* UWB radio enabled */
  };
  
 +#define TPACPI_RFK_UWB_SW_NAME        "tpacpi_uwb_sw"
 +
  static struct rfkill *tpacpi_uwb_rfkill;
  
  static int uwb_get_radiosw(void)
@@@ -3697,10 -3558,6 +3697,10 @@@ static void uwb_update_rfk(void
        if (status < 0)
                return;
        rfkill_force_state(tpacpi_uwb_rfkill, status);
 +
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +              "forced rfkill state to %d\n",
 +              status);
  }
  
  static int uwb_set_radiosw(int radio_on, int update_rfk)
            && radio_on)
                return -EPERM;
  
 +      vdbg_printk(TPACPI_DBG_RFKILL,
 +                      "will %s UWB\n", radio_on ? "enable" : "disable");
 +
  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_uwbemul) {
                tpacpi_uwb_emulstate = !!radio_on;
@@@ -3753,8 -3607,6 +3753,8 @@@ static int tpacpi_uwb_rfk_get(void *dat
  
  static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
  {
 +      dbg_printk(TPACPI_DBG_RFKILL,
 +                 "request to change radio state to %d\n", state);
        return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
  }
  
@@@ -3769,16 -3621,14 +3769,16 @@@ static int __init uwb_init(struct ibm_i
        int res;
        int status = 0;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +                      "initializing uwb subdriver\n");
  
        TPACPI_ACPIHANDLE_INIT(hkey);
  
        tp_features.uwb = hkey_handle &&
            acpi_evalf(hkey_handle, &status, "GUWB", "qd");
  
 -      vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 +              "uwb is %s, status 0x%02x\n",
                str_supported(tp_features.uwb),
                status);
  
        res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
                                &tpacpi_uwb_rfkill,
                                RFKILL_TYPE_UWB,
 -                              "tpacpi_uwb_sw",
 +                              TPACPI_RFK_UWB_SW_NAME,
                                false,
                                tpacpi_uwb_rfk_set,
                                tpacpi_uwb_rfk_get);
@@@ -4752,16 -4602,6 +4752,16 @@@ static const char * const tpacpi_led_na
        "tpacpi::unknown_led",
        "tpacpi::standby",
  };
 +#define TPACPI_SAFE_LEDS      0x0081U
 +
 +static inline bool tpacpi_is_led_restricted(const unsigned int led)
 +{
 +#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
 +      return false;
 +#else
 +      return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
 +#endif
 +}
  
  static int led_get_status(const unsigned int led)
  {
@@@ -4799,20 -4639,16 +4799,20 @@@ static int led_set_status(const unsigne
        switch (led_supported) {
        case TPACPI_LED_570:
                /* 570 */
 -              if (led > 7)
 +              if (unlikely(led > 7))
                        return -EINVAL;
 +              if (unlikely(tpacpi_is_led_restricted(led)))
 +                      return -EPERM;
                if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
                                (1 << led), led_sled_arg1[ledstatus]))
                        rc = -EIO;
                break;
        case TPACPI_LED_OLD:
                /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
 -              if (led > 7)
 +              if (unlikely(led > 7))
                        return -EINVAL;
 +              if (unlikely(tpacpi_is_led_restricted(led)))
 +                      return -EPERM;
                rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
                if (rc >= 0)
                        rc = ec_write(TPACPI_LED_EC_HLBL,
                break;
        case TPACPI_LED_NEW:
                /* all others */
 +              if (unlikely(led >= TPACPI_LED_NUMLEDS))
 +                      return -EINVAL;
 +              if (unlikely(tpacpi_is_led_restricted(led)))
 +                      return -EPERM;
                if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
                                led, led_led_arg1[ledstatus]))
                        rc = -EIO;
@@@ -4919,30 -4751,6 +4919,30 @@@ static void led_exit(void
        kfree(tpacpi_leds);
  }
  
 +static int __init tpacpi_init_led(unsigned int led)
 +{
 +      int rc;
 +
 +      tpacpi_leds[led].led = led;
 +
 +      tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
 +      tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
 +      if (led_supported == TPACPI_LED_570)
 +              tpacpi_leds[led].led_classdev.brightness_get =
 +                                              &led_sysfs_get;
 +
 +      tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
 +
 +      INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
 +
 +      rc = led_classdev_register(&tpacpi_pdev->dev,
 +                              &tpacpi_leds[led].led_classdev);
 +      if (rc < 0)
 +              tpacpi_leds[led].led_classdev.name = NULL;
 +
 +      return rc;
 +}
 +
  static int __init led_init(struct ibm_init_struct *iibm)
  {
        unsigned int i;
        }
  
        for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
 -              tpacpi_leds[i].led = i;
 -
 -              tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
 -              tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
 -              if (led_supported == TPACPI_LED_570)
 -                      tpacpi_leds[i].led_classdev.brightness_get =
 -                                                      &led_sysfs_get;
 -
 -              tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
 -
 -              INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
 -
 -              rc = led_classdev_register(&tpacpi_pdev->dev,
 -                                         &tpacpi_leds[i].led_classdev);
 -              if (rc < 0) {
 -                      tpacpi_leds[i].led_classdev.name = NULL;
 -                      led_exit();
 -                      return rc;
 +              if (!tpacpi_is_led_restricted(i)) {
 +                      rc = tpacpi_init_led(i);
 +                      if (rc < 0) {
 +                              led_exit();
 +                              return rc;
 +                      }
                }
        }
  
 +#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
 +      if (led_supported != TPACPI_LED_NONE)
 +              printk(TPACPI_NOTICE
 +                      "warning: userspace override of important "
 +                      "firmware LEDs is enabled\n");
 +#endif
        return (led_supported != TPACPI_LED_NONE)? 0 : 1;
  }
  
@@@ -5526,20 -5340,6 +5526,20 @@@ static struct ibm_struct ecdump_driver_
  
  #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
  
 +/*
 + * ThinkPads can read brightness from two places: EC HBRV (0x31), or
 + * CMOS NVRAM byte 0x5E, bits 0-3.
 + *
 + * EC HBRV (0x31) has the following layout
 + *   Bit 7: unknown function
 + *   Bit 6: unknown function
 + *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
 + *   Bit 4: must be set to zero to avoid problems
 + *   Bit 3-0: backlight brightness level
 + *
 + * brightness_get_raw returns status data in the HBRV layout
 + */
 +
  enum {
        TP_EC_BACKLIGHT = 0x31,
  
        TP_EC_BACKLIGHT_MAPSW = 0x20,
  };
  
 +enum tpacpi_brightness_access_mode {
 +      TPACPI_BRGHT_MODE_AUTO = 0,     /* Not implemented yet */
 +      TPACPI_BRGHT_MODE_EC,           /* EC control */
 +      TPACPI_BRGHT_MODE_UCMS_STEP,    /* UCMS step-based control */
 +      TPACPI_BRGHT_MODE_ECNVRAM,      /* EC control w/ NVRAM store */
 +      TPACPI_BRGHT_MODE_MAX
 +};
 +
  static struct backlight_device *ibm_backlight_device;
 -static int brightness_mode;
 +
 +static enum tpacpi_brightness_access_mode brightness_mode =
 +              TPACPI_BRGHT_MODE_MAX;
 +
  static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
  
  static struct mutex brightness_mutex;
  
 -/*
 - * ThinkPads can read brightness from two places: EC 0x31, or
 - * CMOS NVRAM byte 0x5E, bits 0-3.
 - *
 - * EC 0x31 has the following layout
 - *   Bit 7: unknown function
 - *   Bit 6: unknown function
 - *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
 - *   Bit 4: must be set to zero to avoid problems
 - *   Bit 3-0: backlight brightness level
 - *
 - * brightness_get_raw returns status data in the EC 0x31 layout
 - */
 -static int brightness_get_raw(int *status)
 +/* NVRAM brightness access,
 + * call with brightness_mutex held! */
 +static unsigned int tpacpi_brightness_nvram_get(void)
  {
 -      u8 lec = 0, lcmos = 0, level = 0;
 +      u8 lnvram;
  
 -      if (brightness_mode & 1) {
 -              if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
 -                      return -EIO;
 -              level = lec & TP_EC_BACKLIGHT_LVLMSK;
 -      };
 -      if (brightness_mode & 2) {
 -              lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
 -                       & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 -                      >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
 -              lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
 -              level = lcmos;
 -      }
 -
 -      if (brightness_mode == 3) {
 -              *status = lec;  /* Prefer EC, CMOS is just a backing store */
 -              lec &= TP_EC_BACKLIGHT_LVLMSK;
 -              if (lec == lcmos)
 -                      tp_warned.bright_cmos_ec_unsync = 0;
 -              else {
 -                      if (!tp_warned.bright_cmos_ec_unsync) {
 -                              printk(TPACPI_ERR
 -                                      "CMOS NVRAM (%u) and EC (%u) do not "
 -                                      "agree on display brightness level\n",
 -                                      (unsigned int) lcmos,
 -                                      (unsigned int) lec);
 -                              tp_warned.bright_cmos_ec_unsync = 1;
 -                      }
 +      lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
 +                & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 +                >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
 +      lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
 +
 +      return lnvram;
 +}
 +
 +static void tpacpi_brightness_checkpoint_nvram(void)
 +{
 +      u8 lec = 0;
 +      u8 b_nvram;
 +
 +      if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
 +              return;
 +
 +      vdbg_printk(TPACPI_DBG_BRGHT,
 +              "trying to checkpoint backlight level to NVRAM...\n");
 +
 +      if (mutex_lock_killable(&brightness_mutex) < 0)
 +              return;
 +
 +      if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
 +              goto unlock;
 +      lec &= TP_EC_BACKLIGHT_LVLMSK;
 +      b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
 +
 +      if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 +                           >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
 +              /* NVRAM needs update */
 +              b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
 +                              TP_NVRAM_POS_LEVEL_BRIGHTNESS);
 +              b_nvram |= lec;
 +              nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
 +              dbg_printk(TPACPI_DBG_BRGHT,
 +                         "updated NVRAM backlight level to %u (0x%02x)\n",
 +                         (unsigned int) lec, (unsigned int) b_nvram);
 +      } else
 +              vdbg_printk(TPACPI_DBG_BRGHT,
 +                         "NVRAM backlight level already is %u (0x%02x)\n",
 +                         (unsigned int) lec, (unsigned int) b_nvram);
 +
 +unlock:
 +      mutex_unlock(&brightness_mutex);
 +}
 +
 +
 +/* call with brightness_mutex held! */
 +static int tpacpi_brightness_get_raw(int *status)
 +{
 +      u8 lec = 0;
 +
 +      switch (brightness_mode) {
 +      case TPACPI_BRGHT_MODE_UCMS_STEP:
 +              *status = tpacpi_brightness_nvram_get();
 +              return 0;
 +      case TPACPI_BRGHT_MODE_EC:
 +      case TPACPI_BRGHT_MODE_ECNVRAM:
 +              if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
                        return -EIO;
 -              }
 -      } else {
 -              *status = level;
 +              *status = lec;
 +              return 0;
 +      default:
 +              return -ENXIO;
        }
 +}
 +
 +/* call with brightness_mutex held! */
 +/* do NOT call with illegal backlight level value */
 +static int tpacpi_brightness_set_ec(unsigned int value)
 +{
 +      u8 lec = 0;
 +
 +      if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
 +              return -EIO;
 +
 +      if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
 +                              (lec & TP_EC_BACKLIGHT_CMDMSK) |
 +                              (value & TP_EC_BACKLIGHT_LVLMSK))))
 +              return -EIO;
 +
 +      return 0;
 +}
 +
 +/* call with brightness_mutex held! */
 +static int tpacpi_brightness_set_ucmsstep(unsigned int value)
 +{
 +      int cmos_cmd, inc;
 +      unsigned int current_value, i;
 +
 +      current_value = tpacpi_brightness_nvram_get();
 +
 +      if (value == current_value)
 +              return 0;
 +
 +      cmos_cmd = (value > current_value) ?
 +                      TP_CMOS_BRIGHTNESS_UP :
 +                      TP_CMOS_BRIGHTNESS_DOWN;
 +      inc = (value > current_value) ? 1 : -1;
 +
 +      for (i = current_value; i != value; i += inc)
 +              if (issue_thinkpad_cmos_command(cmos_cmd))
 +                      return -EIO;
  
        return 0;
  }
  
  /* May return EINTR which can always be mapped to ERESTARTSYS */
 -static int brightness_set(int value)
 +static int brightness_set(unsigned int value)
  {
 -      int cmos_cmd, inc, i, res;
 -      int current_value;
 -      int command_bits;
 +      int res;
  
        if (value > ((tp_features.bright_16levels)? 15 : 7) ||
            value < 0)
                return -EINVAL;
  
 +      vdbg_printk(TPACPI_DBG_BRGHT,
 +                      "set backlight level to %d\n", value);
 +
        res = mutex_lock_killable(&brightness_mutex);
        if (res < 0)
                return res;
  
 -      res = brightness_get_raw(&current_value);
 -      if (res < 0)
 -              goto errout;
 -
 -      command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
 -      current_value &= TP_EC_BACKLIGHT_LVLMSK;
 -
 -      cmos_cmd = value > current_value ?
 -                      TP_CMOS_BRIGHTNESS_UP :
 -                      TP_CMOS_BRIGHTNESS_DOWN;
 -      inc = (value > current_value)? 1 : -1;
 -
 -      res = 0;
 -      for (i = current_value; i != value; i += inc) {
 -              if ((brightness_mode & 2) &&
 -                  issue_thinkpad_cmos_command(cmos_cmd)) {
 -                      res = -EIO;
 -                      goto errout;
 -              }
 -              if ((brightness_mode & 1) &&
 -                  !acpi_ec_write(TP_EC_BACKLIGHT,
 -                                 (i + inc) | command_bits)) {
 -                      res = -EIO;
 -                      goto errout;;
 -              }
 +      switch (brightness_mode) {
 +      case TPACPI_BRGHT_MODE_EC:
 +      case TPACPI_BRGHT_MODE_ECNVRAM:
 +              res = tpacpi_brightness_set_ec(value);
 +              break;
 +      case TPACPI_BRGHT_MODE_UCMS_STEP:
 +              res = tpacpi_brightness_set_ucmsstep(value);
 +              break;
 +      default:
 +              res = -ENXIO;
        }
  
 -errout:
        mutex_unlock(&brightness_mutex);
        return res;
  }
  
  static int brightness_update_status(struct backlight_device *bd)
  {
 -      /* it is the backlight class's job (caller) to handle
 -       * EINTR and other errors properly */
 -      return brightness_set(
 +      unsigned int level =
                (bd->props.fb_blank == FB_BLANK_UNBLANK &&
                 bd->props.power == FB_BLANK_UNBLANK) ?
 -                              bd->props.brightness : 0);
 +                              bd->props.brightness : 0;
 +
 +      dbg_printk(TPACPI_DBG_BRGHT,
 +                      "backlight: attempt to set level to %d\n",
 +                      level);
 +
 +      /* it is the backlight class's job (caller) to handle
 +       * EINTR and other errors properly */
 +      return brightness_set(level);
  }
  
  static int brightness_get(struct backlight_device *bd)
  {
        int status, res;
  
 -      res = brightness_get_raw(&status);
 +      res = mutex_lock_killable(&brightness_mutex);
        if (res < 0)
 -              return 0; /* FIXME: teach backlight about error handling */
 +              return 0;
 +
 +      res = tpacpi_brightness_get_raw(&status);
 +
 +      mutex_unlock(&brightness_mutex);
 +
 +      if (res < 0)
 +              return 0;
  
        return status & TP_EC_BACKLIGHT_LVLMSK;
  }
@@@ -5792,7 -5523,7 +5792,7 @@@ static int __init brightness_init(struc
        }
  
        if (!brightness_enable) {
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
                           "brightness support disabled by "
                           "module parameter\n");
                return 1;
        if (b == 16)
                tp_features.bright_16levels = 1;
  
 -      if (!brightness_mode) {
 -              if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
 -                      brightness_mode = 2;
 -              else
 -                      brightness_mode = 3;
 +      /*
 +       * Check for module parameter bogosity, note that we
 +       * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
 +       * able to detect "unspecified"
 +       */
 +      if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
 +              return -EINVAL;
  
 -              dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
 -                      brightness_mode);
 -      }
 +      /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
 +      if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
 +          brightness_mode == TPACPI_BRGHT_MODE_MAX) {
 +              if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
 +                      /*
 +                       * IBM models that define HBRV probably have
 +                       * EC-based backlight level control
 +                       */
 +                      if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
 +                              /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
 +                              brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
 +                      else
 +                              /* all other IBM ThinkPads */
 +                              brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
 +              } else
 +                      /* All Lenovo ThinkPads */
 +                      brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
  
 -      if (brightness_mode > 3)
 -              return -EINVAL;
 +              dbg_printk(TPACPI_DBG_BRGHT,
 +                         "selected brightness_mode=%d\n",
 +                         brightness_mode);
 +      }
  
 -      if (brightness_get_raw(&b) < 0)
 +      if (tpacpi_brightness_get_raw(&b) < 0)
                return 1;
  
        if (tp_features.bright_16levels)
                printk(TPACPI_ERR "Could not register backlight device\n");
                return PTR_ERR(ibm_backlight_device);
        }
 -      vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
 +                      "brightness is supported\n");
  
        ibm_backlight_device->props.max_brightness =
                                (tp_features.bright_16levels)? 15 : 7;
        return 0;
  }
  
 +static void brightness_suspend(pm_message_t state)
 +{
 +      tpacpi_brightness_checkpoint_nvram();
 +}
 +
 +static void brightness_shutdown(void)
 +{
 +      tpacpi_brightness_checkpoint_nvram();
 +}
 +
  static void brightness_exit(void)
  {
        if (ibm_backlight_device) {
 -              vdbg_printk(TPACPI_DBG_EXIT,
 +              vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
                            "calling backlight_device_unregister()\n");
                backlight_device_unregister(ibm_backlight_device);
        }
 +
 +      tpacpi_brightness_checkpoint_nvram();
  }
  
  static int brightness_read(char *p)
@@@ -5928,9 -5628,6 +5928,9 @@@ static int brightness_write(char *buf
                        return -EINVAL;
        }
  
 +      tpacpi_disclose_usertask("procfs brightness",
 +                      "set level to %d\n", level);
 +
        /*
         * Now we know what the final level should be, so we try to set it.
         * Doing it this way makes the syscall restartable in case of EINTR
@@@ -5944,8 -5641,6 +5944,8 @@@ static struct ibm_struct brightness_dri
        .read = brightness_read,
        .write = brightness_write,
        .exit = brightness_exit,
 +      .suspend = brightness_suspend,
 +      .shutdown = brightness_shutdown,
  };
  
  /*************************************************************************
@@@ -6116,7 -5811,7 +6116,7 @@@ static struct ibm_struct volume_driver_
   *    ThinkPads from this same time period (and earlier) probably lack the
   *    tachometer as well.
   *
-  *    Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+  *    Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
   *    was never fixed by IBM to report the EC firmware version string
   *    probably support the tachometer (like the early X models), so
   *    detecting it is quite hard.  We need more data to know for sure.
@@@ -6391,9 -6086,6 +6391,9 @@@ static int fan_set_level(int level
        default:
                return -ENXIO;
        }
 +
 +      vdbg_printk(TPACPI_DBG_FAN,
 +              "fan control: set fan control register to 0x%02x\n", level);
        return 0;
  }
  
@@@ -6471,11 -6163,6 +6471,11 @@@ static int fan_set_enable(void
        }
  
        mutex_unlock(&fan_mutex);
 +
 +      if (!rc)
 +              vdbg_printk(TPACPI_DBG_FAN,
 +                      "fan control: set fan control register to 0x%02x\n",
 +                      s);
        return rc;
  }
  
@@@ -6512,9 -6199,6 +6512,9 @@@ static int fan_set_disable(void
                rc = -ENXIO;
        }
  
 +      if (!rc)
 +              vdbg_printk(TPACPI_DBG_FAN,
 +                      "fan control: set fan control register to 0\n");
  
        mutex_unlock(&fan_mutex);
        return rc;
@@@ -6643,9 -6327,6 +6643,9 @@@ static ssize_t fan_pwm1_enable_store(st
        if (parse_strtoul(buf, 2, &t))
                return -EINVAL;
  
 +      tpacpi_disclose_usertask("hwmon pwm1_enable",
 +                      "set fan mode to %lu\n", t);
 +
        switch (t) {
        case 0:
                level = TP_EC_FAN_FULLSPEED;
@@@ -6711,9 -6392,6 +6711,9 @@@ static ssize_t fan_pwm1_store(struct de
        if (parse_strtoul(buf, 255, &s))
                return -EINVAL;
  
 +      tpacpi_disclose_usertask("hwmon pwm1",
 +                      "set fan speed to %lu\n", s);
 +
        /* scale down from 0-255 to 0-7 */
        newlevel = (s >> 5) & 0x07;
  
@@@ -6780,8 -6458,6 +6780,8 @@@ static ssize_t fan_fan_watchdog_store(s
        fan_watchdog_maxinterval = t;
        fan_watchdog_reset();
  
 +      tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
 +
        return count;
  }
  
@@@ -6803,8 -6479,7 +6803,8 @@@ static int __init fan_init(struct ibm_i
  {
        int rc;
  
 -      vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
 +                      "initializing fan subdriver\n");
  
        mutex_init(&fan_mutex);
        fan_status_access_mode = TPACPI_FAN_NONE;
                }
        }
  
 -      vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
 +      vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
 +              "fan is %s, modes %d, %d\n",
                str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
                  fan_control_access_mode != TPACPI_FAN_WR_NONE),
                fan_status_access_mode, fan_control_access_mode);
        if (!fan_control_allowed) {
                fan_control_access_mode = TPACPI_FAN_WR_NONE;
                fan_control_commands = 0;
 -              dbg_printk(TPACPI_DBG_INIT,
 +              dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
                           "fan control features disabled by parameter\n");
        }
  
  
  static void fan_exit(void)
  {
 -      vdbg_printk(TPACPI_DBG_EXIT,
 +      vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
                    "cancelling any pending fan watchdog tasks\n");
  
        /* FIXME: can we really do this unconditionally? */
@@@ -7083,9 -6757,6 +7083,9 @@@ static int fan_write_cmd_level(const ch
        if (*rc == -ENXIO)
                printk(TPACPI_ERR "level command accepted for unsupported "
                       "access mode %d", fan_control_access_mode);
 +      else if (!*rc)
 +              tpacpi_disclose_usertask("procfs fan",
 +                      "set level to %d\n", level);
  
        return 1;
  }
@@@ -7099,8 -6770,6 +7099,8 @@@ static int fan_write_cmd_enable(const c
        if (*rc == -ENXIO)
                printk(TPACPI_ERR "enable command accepted for unsupported "
                       "access mode %d", fan_control_access_mode);
 +      else if (!*rc)
 +              tpacpi_disclose_usertask("procfs fan", "enable\n");
  
        return 1;
  }
@@@ -7114,8 -6783,6 +7114,8 @@@ static int fan_write_cmd_disable(const 
        if (*rc == -ENXIO)
                printk(TPACPI_ERR "disable command accepted for unsupported "
                       "access mode %d", fan_control_access_mode);
 +      else if (!*rc)
 +              tpacpi_disclose_usertask("procfs fan", "disable\n");
  
        return 1;
  }
@@@ -7134,9 -6801,6 +7134,9 @@@ static int fan_write_cmd_speed(const ch
        if (*rc == -ENXIO)
                printk(TPACPI_ERR "speed command accepted for unsupported "
                       "access mode %d", fan_control_access_mode);
 +      else if (!*rc)
 +              tpacpi_disclose_usertask("procfs fan",
 +                      "set speed to %d\n", speed);
  
        return 1;
  }
@@@ -7150,12 -6814,8 +7150,12 @@@ static int fan_write_cmd_watchdog(cons
  
        if (interval < 0 || interval > 120)
                *rc = -EINVAL;
 -      else
 +      else {
                fan_watchdog_maxinterval = interval;
 +              tpacpi_disclose_usertask("procfs fan",
 +                      "set watchdog timer to %d\n",
 +                      interval);
 +      }
  
        return 1;
  }
@@@ -7332,7 -6992,6 +7332,6 @@@ static int __init ibm_init(struct ibm_i
                        ret = -ENODEV;
                        goto err_out;
                }
-               entry->owner = THIS_MODULE;
                entry->data = ibm;
                entry->read_proc = &dispatch_procfs_read;
                if (ibm->write)
@@@ -7584,10 -7243,10 +7583,10 @@@ module_param_named(fan_control, fan_con
  MODULE_PARM_DESC(fan_control,
                 "Enables setting fan parameters features when true");
  
 -module_param_named(brightness_mode, brightness_mode, int, 0);
 +module_param_named(brightness_mode, brightness_mode, uint, 0);
  MODULE_PARM_DESC(brightness_mode,
                 "Selects brightness control strategy: "
 -               "0=auto, 1=EC, 2=CMOS, 3=both");
 +               "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
  
  module_param(brightness_enable, uint, 0);
  MODULE_PARM_DESC(brightness_enable,
@@@ -7745,7 -7404,6 +7744,6 @@@ static int __init thinkpad_acpi_module_
                thinkpad_acpi_module_exit();
                return -ENODEV;
        }
-       proc_dir->owner = THIS_MODULE;
  
        ret = platform_driver_register(&tpacpi_pdriver);
        if (ret) {
        return 0;
  }
  
 -/* Please remove this in year 2009 */
 -MODULE_ALIAS("ibm_acpi");
 -
  MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
  
  /*
diff --combined include/acpi/acpiosxf.h
index 178adfb80237d0fb441630d52fadce0326fde0ba,ab0b85cf21f38df08b0eb3a3b752b42e2453d8fa..3e798593b17b0db94494bfeb6fc8b6c012300045
@@@ -144,6 -144,7 +144,7 @@@ void __iomem *acpi_os_map_memory(acpi_p
                                acpi_size length);
  
  void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
+ void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size);
  
  #ifdef ACPI_FUTURE_USAGE
  acpi_status
@@@ -241,6 -242,10 +242,6 @@@ acpi_os_derive_pci_id(acpi_handle rhand
  acpi_status acpi_os_validate_interface(char *interface);
  acpi_status acpi_osi_invalidate(char* interface);
  
 -acpi_status
 -acpi_os_validate_address(u8 space_id, acpi_physical_address address,
 -                       acpi_size length, char *name);
 -
  u64 acpi_os_get_timer(void);
  
  acpi_status acpi_os_signal(u32 function, void *info);
diff --combined include/acpi/acpixf.h
index 16826f15f01f003a3d633255dd857a396fee5991,cc40102fe2f3568f262a23862da91010eddde864..aeaf7cd41dc7bbdba97d79573a7febad13a259ee
@@@ -47,7 -47,7 +47,7 @@@
  
  /* Current ACPICA subsystem version in YYYYMMDD format */
  
 -#define ACPI_CA_VERSION                 0x20081204
 +#define ACPI_CA_VERSION                 0x20090320
  
  #include "actypes.h"
  #include "actbl.h"
@@@ -130,6 -130,10 +130,10 @@@ acpi_get_table_header(acpi_string signa
                      struct acpi_table_header *out_table_header);
  
  acpi_status
+ acpi_get_table_with_size(acpi_string signature,
+              u32 instance, struct acpi_table_header **out_table,
+              acpi_size *tbl_size);
+ acpi_status
  acpi_get_table(acpi_string signature,
               u32 instance, struct acpi_table_header **out_table);
  
@@@ -345,15 -349,17 +349,15 @@@ acpi_resource_to_address64(struct acpi_
   */
  acpi_status acpi_reset(void);
  
 -acpi_status acpi_get_register(u32 register_id, u32 * return_value);
 +acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value);
  
 -acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
 +acpi_status acpi_write_bit_register(u32 register_id, u32 value);
  
 -acpi_status acpi_set_register(u32 register_id, u32 value);
 +acpi_status acpi_set_firmware_waking_vector(u32 physical_address);
  
 -acpi_status
 -acpi_set_firmware_waking_vector(u32 physical_address);
 -
 -acpi_status
 -acpi_set_firmware_waking_vector64(u64 physical_address);
 +#if ACPI_MACHINE_WIDTH == 64
 +acpi_status acpi_set_firmware_waking_vector64(u64 physical_address);
 +#endif
  
  acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg);
  
diff --combined include/linux/acpi.h
index a6989e5175493b4d91922f0e49bfe63f1a1bdb86,d047f846c3ed6d434555f2734aee472627e9ef6b..6586cbd0d4af7251b75d4b246b7a268e9691e439
@@@ -79,6 -79,7 +79,7 @@@ typedef int (*acpi_table_handler) (stru
  typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
  
  char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
+ void __acpi_unmap_table(char *map, unsigned long size);
  int early_acpi_boot_init(void);
  int acpi_boot_init (void);
  int acpi_boot_table_init (void);
@@@ -96,7 -97,6 +97,7 @@@ void acpi_table_print_madt_entry (struc
  /* the following four functions are architecture-dependent */
  void acpi_numa_slit_init (struct acpi_table_slit *slit);
  void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
 +void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
  void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
  void acpi_numa_arch_fixup(void);
  
@@@ -257,6 -257,40 +258,40 @@@ void __init acpi_no_s4_hw_signature(voi
  void __init acpi_old_suspend_ordering(void);
  void __init acpi_s4_no_nvs(void);
  #endif /* CONFIG_PM_SLEEP */
+ #define OSC_QUERY_TYPE                        0
+ #define OSC_SUPPORT_TYPE              1
+ #define OSC_CONTROL_TYPE              2
+ #define OSC_SUPPORT_MASKS             0x1f
+ /* _OSC DW0 Definition */
+ #define OSC_QUERY_ENABLE              1
+ #define OSC_REQUEST_ERROR             2
+ #define OSC_INVALID_UUID_ERROR                4
+ #define OSC_INVALID_REVISION_ERROR    8
+ #define OSC_CAPABILITIES_MASK_ERROR   16
+ /* _OSC DW1 Definition (OS Support Fields) */
+ #define OSC_EXT_PCI_CONFIG_SUPPORT            1
+ #define OSC_ACTIVE_STATE_PWR_SUPPORT          2
+ #define OSC_CLOCK_PWR_CAPABILITY_SUPPORT      4
+ #define OSC_PCI_SEGMENT_GROUPS_SUPPORT                8
+ #define OSC_MSI_SUPPORT                               16
+ /* _OSC DW1 Definition (OS Control Fields) */
+ #define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL     1
+ #define OSC_SHPC_NATIVE_HP_CONTROL            2
+ #define OSC_PCI_EXPRESS_PME_CONTROL           4
+ #define OSC_PCI_EXPRESS_AER_CONTROL           8
+ #define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 16
+ #define OSC_CONTROL_MASKS     (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |    \
+                               OSC_SHPC_NATIVE_HP_CONTROL |            \
+                               OSC_PCI_EXPRESS_PME_CONTROL |           \
+                               OSC_PCI_EXPRESS_AER_CONTROL |           \
+                               OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
+ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags);
  #else /* CONFIG_ACPI */
  
  static inline int early_acpi_boot_init(void)