Merge branch 'x86-acpi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Dec 2012 18:03:23 +0000 (10:03 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Dec 2012 18:03:23 +0000 (10:03 -0800)
Pull x86 ACPI update from Peter Anvin:
 "This is a patchset which didn't make the last merge window.  It adds a
  debugging capability to feed ACPI tables via the initramfs.

  On a grander scope, it formalizes using the initramfs protocol for
  feeding arbitrary blobs which need to be accessed early to the kernel:
  they are fed first in the initramfs blob (lots of bootloaders can
  concatenate this at boot time, others can use a single file) in an
  uncompressed cpio archive using filenames starting with "kernel/".

  The ACPI maintainers requested that this patchset be fed via the x86
  tree rather than the ACPI tree as the footprint in the general x86
  code is much bigger than in the ACPI code proper."

* 'x86-acpi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  X86 ACPI: Use #ifdef not #if for CONFIG_X86 check
  ACPI: Fix build when disabled
  ACPI: Document ACPI table overriding via initrd
  ACPI: Create acpi_table_taint() function to avoid code duplication
  ACPI: Implement physical address table override
  ACPI: Store valid ACPI tables passed via early initrd in reserved memblock areas
  x86, acpi: Introduce x86 arch specific arch_reserve_mem_area() for e820 handling
  lib: Add early cpio decoder

1  2 
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/setup.c
drivers/acpi/Kconfig
drivers/acpi/osl.c
include/linux/acpi.h
lib/Makefile

@@@ -574,12 -574,6 +574,12 @@@ int acpi_register_gsi(struct device *de
  
        return irq;
  }
 +EXPORT_SYMBOL_GPL(acpi_register_gsi);
 +
 +void acpi_unregister_gsi(u32 gsi)
 +{
 +}
 +EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
  
  void __init acpi_set_irq_model_pic(void)
  {
@@@ -662,7 -656,7 +662,7 @@@ static int __cpuinit _acpi_map_lsapic(a
        acpi_register_lapic(physid, ACPI_MADT_ENABLED);
  
        /*
 -       * If mp_register_lapic successfully generates a new logical cpu
 +       * If acpi_register_lapic successfully generates a new logical cpu
         * number, then the following will get us exactly what was mapped
         */
        cpumask_andnot(new_map, cpu_present_mask, tmp_map);
@@@ -1706,3 -1700,9 +1706,9 @@@ int __acpi_release_global_lock(unsigne
        } while (unlikely (val != old));
        return old & 0x1;
  }
+ void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
+ {
+       e820_add_region(addr, size, E820_ACPI);
+       update_e820();
+ }
diff --combined arch/x86/kernel/setup.c
@@@ -68,7 -68,6 +68,7 @@@
  #include <linux/percpu.h>
  #include <linux/crash_dump.h>
  #include <linux/tboot.h>
 +#include <linux/jiffies.h>
  
  #include <video/edid.h>
  
@@@ -143,7 -142,11 +143,7 @@@ int default_check_phys_apicid_present(i
  }
  #endif
  
 -#ifndef CONFIG_DEBUG_BOOT_PARAMS
 -struct boot_params __initdata boot_params;
 -#else
  struct boot_params boot_params;
 -#endif
  
  /*
   * Machine setup..
@@@ -916,22 -919,8 +916,22 @@@ void __init setup_arch(char **cmdline_p
  
  #ifdef CONFIG_X86_64
        if (max_pfn > max_low_pfn) {
 -              max_pfn_mapped = init_memory_mapping(1UL<<32,
 -                                                   max_pfn<<PAGE_SHIFT);
 +              int i;
 +              unsigned long start, end;
 +              unsigned long start_pfn, end_pfn;
 +
 +              for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn,
 +                                                       NULL) {
 +
 +                      end = PFN_PHYS(end_pfn);
 +                      if (end <= (1UL<<32))
 +                              continue;
 +
 +                      start = PFN_PHYS(start_pfn);
 +                      max_pfn_mapped = init_memory_mapping(
 +                                              max((1UL<<32), start), end);
 +              }
 +
                /* can we preseve max_low_pfn ?*/
                max_low_pfn = max_pfn;
        }
  
        reserve_initrd();
  
+ #if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
+       acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
+ #endif
        reserve_crashkernel();
  
        vsmp_init();
        initmem_init();
        memblock_find_dma_reserve();
  
 -#ifdef CONFIG_KVM_CLOCK
 +#ifdef CONFIG_KVM_GUEST
        kvmclock_init();
  #endif
  
 -      x86_init.paging.pagetable_setup_start(swapper_pg_dir);
 -      paging_init();
 -      x86_init.paging.pagetable_setup_done(swapper_pg_dir);
 +      x86_init.paging.pagetable_init();
  
        if (boot_cpu_data.cpuid_level >= 0) {
                /* A CPU has %cr4 if and only if it has CPUID */
        mcheck_init();
  
        arch_init_ideal_nops();
 +
 +      register_refined_jiffies(CLOCK_TICK_RATE);
 +
 +#ifdef CONFIG_EFI
 +      /* Once setup is done above, disable efi_enabled on mismatched
 +       * firmware/kernel archtectures since there is no support for
 +       * runtime services.
 +       */
 +      if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) {
 +              pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
 +              efi_unmap_memmap();
 +              efi_enabled = 0;
 +      }
 +#endif
  }
  
  #ifdef CONFIG_X86_32
diff --combined drivers/acpi/Kconfig
@@@ -181,12 -181,6 +181,12 @@@ config ACPI_DOC
          This driver supports ACPI-controlled docking stations and removable
          drive bays such as the IBM Ultrabay and the Dell Module Bay.
  
 +config ACPI_I2C
 +      def_tristate I2C
 +      depends on I2C
 +      help
 +        ACPI I2C enumeration support.
 +
  config ACPI_PROCESSOR
        tristate "Processor"
        select THERMAL
@@@ -267,6 -261,15 +267,15 @@@ config ACPI_CUSTOM_DSD
        bool
        default ACPI_CUSTOM_DSDT_FILE != ""
  
+ config ACPI_INITRD_TABLE_OVERRIDE
+       bool "ACPI tables can be passed via uncompressed cpio in initrd"
+       default n
+       help
+         This option provides functionality to override arbitrary ACPI tables
+         via initrd. No functional change if no ACPI tables are passed via
+         initrd, therefore it's safe to say Y.
+         See Documentation/acpi/initrd_table_override.txt for details
  config ACPI_BLACKLIST_YEAR
        int "Disable ACPI for systems before Jan 1st this year" if X86_32
        default 0
@@@ -391,8 -394,8 +400,8 @@@ config ACPI_CUSTOM_METHO
          to override that restriction).
  
  config ACPI_BGRT
 -        tristate "Boottime Graphics Resource Table support"
 -        default n
 +      bool "Boottime Graphics Resource Table support"
 +      depends on EFI
          help
          This driver adds support for exposing the ACPI Boottime Graphics
          Resource Table, which allows the operating system to obtain
diff --combined drivers/acpi/osl.c
@@@ -534,6 -534,137 +534,137 @@@ acpi_os_predefined_override(const struc
        return AE_OK;
  }
  
+ #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
+ #include <linux/earlycpio.h>
+ #include <linux/memblock.h>
+ static u64 acpi_tables_addr;
+ static int all_tables_size;
+ /* Copied from acpica/tbutils.c:acpi_tb_checksum() */
+ u8 __init acpi_table_checksum(u8 *buffer, u32 length)
+ {
+       u8 sum = 0;
+       u8 *end = buffer + length;
+       while (buffer < end)
+               sum = (u8) (sum + *(buffer++));
+       return sum;
+ }
+ /* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */
+ static const char * const table_sigs[] = {
+       ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ,
+       ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT,
+       ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF,
+       ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET,
+       ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI,
+       ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
+       ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
+       ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
+       ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
+ /* Non-fatal errors: Affected tables/files are ignored */
+ #define INVALID_TABLE(x, path, name)                                  \
+       { pr_err("ACPI OVERRIDE: " x " [%s%s]\n", path, name); continue; }
+ #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
+ /* Must not increase 10 or needs code modification below */
+ #define ACPI_OVERRIDE_TABLES 10
+ void __init acpi_initrd_override(void *data, size_t size)
+ {
+       int sig, no, table_nr = 0, total_offset = 0;
+       long offset = 0;
+       struct acpi_table_header *table;
+       char cpio_path[32] = "kernel/firmware/acpi/";
+       struct cpio_data file;
+       struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
+       char *p;
+       if (data == NULL || size == 0)
+               return;
+       for (no = 0; no < ACPI_OVERRIDE_TABLES; no++) {
+               file = find_cpio_data(cpio_path, data, size, &offset);
+               if (!file.data)
+                       break;
+               data += offset;
+               size -= offset;
+               if (file.size < sizeof(struct acpi_table_header))
+                       INVALID_TABLE("Table smaller than ACPI header",
+                                     cpio_path, file.name);
+               table = file.data;
+               for (sig = 0; table_sigs[sig]; sig++)
+                       if (!memcmp(table->signature, table_sigs[sig], 4))
+                               break;
+               if (!table_sigs[sig])
+                       INVALID_TABLE("Unknown signature",
+                                     cpio_path, file.name);
+               if (file.size != table->length)
+                       INVALID_TABLE("File length does not match table length",
+                                     cpio_path, file.name);
+               if (acpi_table_checksum(file.data, table->length))
+                       INVALID_TABLE("Bad table checksum",
+                                     cpio_path, file.name);
+               pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
+                       table->signature, cpio_path, file.name, table->length);
+               all_tables_size += table->length;
+               early_initrd_files[table_nr].data = file.data;
+               early_initrd_files[table_nr].size = file.size;
+               table_nr++;
+       }
+       if (table_nr == 0)
+               return;
+       acpi_tables_addr =
+               memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT,
+                                      all_tables_size, PAGE_SIZE);
+       if (!acpi_tables_addr) {
+               WARN_ON(1);
+               return;
+       }
+       /*
+        * Only calling e820_add_reserve does not work and the
+        * tables are invalid (memory got used) later.
+        * memblock_reserve works as expected and the tables won't get modified.
+        * But it's not enough on X86 because ioremap will
+        * complain later (used by acpi_os_map_memory) that the pages
+        * that should get mapped are not marked "reserved".
+        * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
+        * works fine.
+        */
+       memblock_reserve(acpi_tables_addr, acpi_tables_addr + all_tables_size);
+       arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
+       p = early_ioremap(acpi_tables_addr, all_tables_size);
+       for (no = 0; no < table_nr; no++) {
+               memcpy(p + total_offset, early_initrd_files[no].data,
+                      early_initrd_files[no].size);
+               total_offset += early_initrd_files[no].size;
+       }
+       early_iounmap(p, all_tables_size);
+ }
+ #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
+ static void acpi_table_taint(struct acpi_table_header *table)
+ {
+       pr_warn(PREFIX
+               "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
+               table->signature, table->oem_table_id);
+       add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
+ }
  acpi_status
  acpi_os_table_override(struct acpi_table_header * existing_table,
                       struct acpi_table_header ** new_table)
        if (strncmp(existing_table->signature, "DSDT", 4) == 0)
                *new_table = (struct acpi_table_header *)AmlCode;
  #endif
-       if (*new_table != NULL) {
-               printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
-                          "this is unsafe: tainting kernel\n",
-                      existing_table->signature,
-                      existing_table->oem_table_id);
-               add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
-       }
+       if (*new_table != NULL)
+               acpi_table_taint(existing_table);
        return AE_OK;
  }
  
  acpi_status
  acpi_os_physical_table_override(struct acpi_table_header *existing_table,
-                               acpi_physical_address * new_address,
-                               u32 *new_table_length)
+                               acpi_physical_address *address,
+                               u32 *table_length)
  {
-       return AE_SUPPORT;
- }
+ #ifndef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
+       *table_length = 0;
+       *address = 0;
+       return AE_OK;
+ #else
+       int table_offset = 0;
+       struct acpi_table_header *table;
+       *table_length = 0;
+       *address = 0;
+       if (!acpi_tables_addr)
+               return AE_OK;
+       do {
+               if (table_offset + ACPI_HEADER_SIZE > all_tables_size) {
+                       WARN_ON(1);
+                       return AE_OK;
+               }
+               table = acpi_os_map_memory(acpi_tables_addr + table_offset,
+                                          ACPI_HEADER_SIZE);
  
+               if (table_offset + table->length > all_tables_size) {
+                       acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+                       WARN_ON(1);
+                       return AE_OK;
+               }
+               table_offset += table->length;
+               if (memcmp(existing_table->signature, table->signature, 4)) {
+                       acpi_os_unmap_memory(table,
+                                    ACPI_HEADER_SIZE);
+                       continue;
+               }
+               /* Only override tables with matching oem id */
+               if (memcmp(table->oem_table_id, existing_table->oem_table_id,
+                          ACPI_OEM_TABLE_ID_SIZE)) {
+                       acpi_os_unmap_memory(table,
+                                    ACPI_HEADER_SIZE);
+                       continue;
+               }
+               table_offset -= table->length;
+               *table_length = table->length;
+               acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
+               *address = acpi_tables_addr + table_offset;
+               break;
+       } while (table_offset + ACPI_HEADER_SIZE < all_tables_size);
+       if (*address != 0)
+               acpi_table_taint(existing_table);
+       return AE_OK;
+ #endif
+ }
  
  static irqreturn_t acpi_irq(int irq, void *dev_id)
  {
@@@ -932,7 -1112,7 +1112,7 @@@ static acpi_status __acpi_os_execute(ac
         * having a static work_struct.
         */
  
 -      dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
 +      dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
        if (!dpc)
                return AE_NO_MEMORY;
  
         * because the hotplug code may call driver .remove() functions,
         * which invoke flush_scheduled_work/acpi_os_wait_events_complete
         * to flush these workqueues.
 +       *
 +       * To prevent lockdep from complaining unnecessarily, make sure that
 +       * there is a different static lockdep key for each workqueue by using
 +       * INIT_WORK() for each of them separately.
         */
 -      queue = hp ? kacpi_hotplug_wq :
 -              (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
 -      dpc->wait = hp ? 1 : 0;
 -
 -      if (queue == kacpi_hotplug_wq)
 +      if (hp) {
 +              queue = kacpi_hotplug_wq;
 +              dpc->wait = 1;
                INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 -      else if (queue == kacpi_notify_wq)
 +      } else if (type == OSL_NOTIFY_HANDLER) {
 +              queue = kacpi_notify_wq;
                INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 -      else
 +      } else {
 +              queue = kacpid_wq;
                INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 +      }
  
        /*
         * On some machines, a software-initiated SMI causes corruption unless
@@@ -991,7 -1166,6 +1171,7 @@@ acpi_status acpi_os_hotplug_execute(acp
  {
        return __acpi_os_execute(0, function, context, 1);
  }
 +EXPORT_SYMBOL(acpi_os_hotplug_execute);
  
  void acpi_os_wait_events_complete(void)
  {
diff --combined include/linux/acpi.h
@@@ -25,9 -25,7 +25,9 @@@
  #ifndef _LINUX_ACPI_H
  #define _LINUX_ACPI_H
  
 +#include <linux/errno.h>
  #include <linux/ioport.h>     /* for struct resource */
 +#include <linux/device.h>
  
  #ifdef        CONFIG_ACPI
  
@@@ -78,6 -76,14 +78,14 @@@ typedef int (*acpi_table_handler) (stru
  
  typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
  
+ #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
+ void acpi_initrd_override(void *data, size_t size);
+ #else
+ static inline void acpi_initrd_override(void *data, size_t size)
+ {
+ }
+ #endif
  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);
@@@ -140,9 -146,9 +148,9 @@@ void acpi_penalize_isa_irq(int irq, in
  void acpi_pci_irq_disable (struct pci_dev *dev);
  
  struct acpi_pci_driver {
 -      struct acpi_pci_driver *next;
 -      int (*add)(acpi_handle handle);
 -      void (*remove)(acpi_handle handle);
 +      struct list_head node;
 +      int (*add)(struct acpi_pci_root *root);
 +      void (*remove)(struct acpi_pci_root *root);
  };
  
  int acpi_pci_register_driver(struct acpi_pci_driver *driver);
@@@ -252,26 -258,6 +260,26 @@@ extern int pnpacpi_disabled
  
  #define PXM_INVAL     (-1)
  
 +bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
 +bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
 +bool acpi_dev_resource_address_space(struct acpi_resource *ares,
 +                                   struct resource *res);
 +bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
 +                                       struct resource *res);
 +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
 +bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 +                               struct resource *res);
 +
 +struct resource_list_entry {
 +      struct list_head node;
 +      struct resource res;
 +};
 +
 +void acpi_dev_free_resource_list(struct list_head *list);
 +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 +                         int (*preproc)(struct acpi_resource *, void *),
 +                         void *preproc_data);
 +
  int acpi_check_resource_conflict(const struct resource *res);
  
  int acpi_check_region(resource_size_t start, resource_size_t n,
  
  int acpi_resources_are_enforced(void);
  
 -#ifdef CONFIG_PM_SLEEP
 +#ifdef CONFIG_HIBERNATION
  void __init acpi_no_s4_hw_signature(void);
 +#endif
 +
 +#ifdef CONFIG_PM_SLEEP
  void __init acpi_old_suspend_ordering(void);
  void __init acpi_nvs_nosave(void);
 +void __init acpi_nvs_nosave_s3(void);
  #endif /* CONFIG_PM_SLEEP */
  
  struct acpi_osc_context {
@@@ -390,17 -372,6 +398,17 @@@ extern int acpi_nvs_register(__u64 star
  extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
                                    void *data);
  
 +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 +                                             const struct device *dev);
 +
 +static inline bool acpi_driver_match_device(struct device *dev,
 +                                          const struct device_driver *drv)
 +{
 +      return !!acpi_match_device(drv->acpi_match_table, dev);
 +}
 +
 +#define ACPI_PTR(_ptr)        (_ptr)
 +
  #else /* !CONFIG_ACPI */
  
  #define acpi_disabled 1
@@@ -455,22 -426,6 +463,22 @@@ static inline int acpi_nvs_for_each_reg
        return 0;
  }
  
 +struct acpi_device_id;
 +
 +static inline const struct acpi_device_id *acpi_match_device(
 +      const struct acpi_device_id *ids, const struct device *dev)
 +{
 +      return NULL;
 +}
 +
 +static inline bool acpi_driver_match_device(struct device *dev,
 +                                          const struct device_driver *drv)
 +{
 +      return false;
 +}
 +
 +#define ACPI_PTR(_ptr)        (NULL)
 +
  #endif        /* !CONFIG_ACPI */
  
  #ifdef CONFIG_ACPI
@@@ -479,88 -434,16 +487,96 @@@ void acpi_os_set_prepare_sleep(int (*fu
  
  acpi_status acpi_os_prepare_sleep(u8 sleep_state,
                                  u32 pm1a_control, u32 pm1b_control);
+ #ifdef CONFIG_X86
+ void arch_reserve_mem_area(acpi_physical_address addr, size_t size);
+ #else
+ static inline void arch_reserve_mem_area(acpi_physical_address addr,
+                                         size_t size)
+ {
+ }
+ #endif /* CONFIG_X86 */
  #else
  #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
  #endif
  
 +#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME)
 +int acpi_dev_runtime_suspend(struct device *dev);
 +int acpi_dev_runtime_resume(struct device *dev);
 +int acpi_subsys_runtime_suspend(struct device *dev);
 +int acpi_subsys_runtime_resume(struct device *dev);
 +#else
 +static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; }
 +static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; }
 +static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
 +static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
 +#endif
 +
 +#ifdef CONFIG_ACPI_SLEEP
 +int acpi_dev_suspend_late(struct device *dev);
 +int acpi_dev_resume_early(struct device *dev);
 +int acpi_subsys_prepare(struct device *dev);
 +int acpi_subsys_suspend_late(struct device *dev);
 +int acpi_subsys_resume_early(struct device *dev);
 +#else
 +static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
 +static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
 +static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
 +static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; }
 +static inline int acpi_subsys_resume_early(struct device *dev) { return 0; }
 +#endif
 +
 +#if defined(CONFIG_ACPI) && defined(CONFIG_PM)
 +int acpi_dev_pm_attach(struct device *dev, bool power_on);
 +void acpi_dev_pm_detach(struct device *dev, bool power_off);
 +#else
 +static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 +{
 +      return -ENODEV;
 +}
 +static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {}
 +#endif
 +
 +#ifdef CONFIG_ACPI
 +__printf(3, 4)
 +void acpi_handle_printk(const char *level, acpi_handle handle,
 +                      const char *fmt, ...);
 +#else /* !CONFIG_ACPI */
 +static inline __printf(3, 4) void
 +acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {}
 +#endif        /* !CONFIG_ACPI */
 +
 +/*
 + * acpi_handle_<level>: Print message with ACPI prefix and object path
 + *
 + * These interfaces acquire the global namespace mutex to obtain an object
 + * path.  In interrupt context, it shows the object path as <n/a>.
 + */
 +#define acpi_handle_emerg(handle, fmt, ...)                           \
 +      acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_alert(handle, fmt, ...)                           \
 +      acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_crit(handle, fmt, ...)                            \
 +      acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_err(handle, fmt, ...)                             \
 +      acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_warn(handle, fmt, ...)                            \
 +      acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_notice(handle, fmt, ...)                          \
 +      acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
 +#define acpi_handle_info(handle, fmt, ...)                            \
 +      acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
 +
 +/* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */
 +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
 +#define acpi_handle_debug(handle, fmt, ...)                           \
 +      acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
 +#else
 +#define acpi_handle_debug(handle, fmt, ...)                           \
 +({                                                                    \
 +      if (0)                                                          \
 +              acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \
 +      0;                                                              \
 +})
 +#endif
 +
  #endif        /*_LINUX_ACPI_H*/
diff --combined lib/Makefile
@@@ -9,10 -9,10 +9,11 @@@ endi
  
  lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o timerqueue.o\
 -       idr.o int_sqrt.o extable.o prio_tree.o \
 +       idr.o int_sqrt.o extable.o \
         sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
         proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
-        is_single_threaded.o plist.o decompress.o kobject_uevent.o
 -       is_single_threaded.o plist.o decompress.o earlycpio.o
++       is_single_threaded.o plist.o decompress.o kobject_uevent.o \
++       earlycpio.o
  
  lib-$(CONFIG_MMU) += ioremap.o
  lib-$(CONFIG_SMP) += cpumask.o
@@@ -31,6 -31,7 +32,6 @@@ CFLAGS_kobject.o += -DDEBU
  CFLAGS_kobject_uevent.o += -DDEBUG
  endif
  
 -lib-$(CONFIG_HOTPLUG) += kobject_uevent.o
  obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
  obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o
  obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
@@@ -139,13 -140,6 +140,13 @@@ $(foreach file, $(libfdt_files), 
        $(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
  lib-$(CONFIG_LIBFDT) += $(libfdt_files)
  
 +obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
 +obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
 +
 +interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
 +
 +obj-$(CONFIG_ASN1) += asn1_decoder.o
 +
  hostprogs-y   := gen_crc32table
  clean-files   := crc32table.h
  
@@@ -156,19 -150,3 +157,19 @@@ quiet_cmd_crc32 = GEN     $
  
  $(obj)/crc32table.h: $(obj)/gen_crc32table
        $(call cmd,crc32)
 +
 +#
 +# Build a fast OID lookip registry from include/linux/oid_registry.h
 +#
 +obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
 +
 +$(obj)/oid_registry.o: $(obj)/oid_registry_data.c
 +
 +$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
 +                          $(src)/build_OID_registry
 +      $(call cmd,build_OID_registry)
 +
 +quiet_cmd_build_OID_registry = GEN     $@
 +      cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@
 +
 +clean-files   += oid_registry_data.c