]> Git Repo - linux.git/commitdiff
Merge branch 'stable/for-x86-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel...
authorLen Brown <[email protected]>
Thu, 22 Mar 2012 05:31:09 +0000 (01:31 -0400)
committerLen Brown <[email protected]>
Thu, 22 Mar 2012 05:31:09 +0000 (01:31 -0400)
1  2 
drivers/acpi/acpica/hwsleep.c
drivers/acpi/osl.c
include/linux/acpi.h

index 3c4a922a9fc2810b607e47ffd3d799277ffcea5e,992359af7e2f315c9f7829206a2def3285ce4c13..af702a7a69d9a6c9af64d762b57853630f30c979
@@@ -6,7 -6,7 +6,7 @@@
   *****************************************************************************/
  
  /*
 - * Copyright (C) 2000 - 2011, Intel Corp.
 + * Copyright (C) 2000 - 2012, Intel Corp.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -43,9 -43,9 +43,9 @@@
   */
  
  #include <acpi/acpi.h>
+ #include <linux/acpi.h>
  #include "accommon.h"
  #include "actables.h"
- #include <linux/tboot.h>
  #include <linux/module.h>
  
  #define _COMPONENT          ACPI_HARDWARE
@@@ -344,8 -344,12 +344,12 @@@ acpi_status asmlinkage acpi_enter_sleep
  
        ACPI_FLUSH_CPU_CACHE();
  
-       tboot_sleep(sleep_state, pm1a_control, pm1b_control);
+       status = acpi_os_prepare_sleep(sleep_state, pm1a_control,
+                                      pm1b_control);
+       if (ACPI_SKIP(status))
+               return_ACPI_STATUS(AE_OK);
+       if (ACPI_FAILURE(status))
+               return_ACPI_STATUS(status);
        /* Write #2: Write both SLP_TYP + SLP_EN */
  
        status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
diff --combined drivers/acpi/osl.c
index 412a1e04a9226a84970654c433597455cb53f0ca,f3aae4ba507eb2aee7c02e45361b81ae86cb5d99..17516ad599372e4736cf8ffdf2d124d4854a3713
@@@ -31,7 -31,6 +31,7 @@@
  #include <linux/kernel.h>
  #include <linux/slab.h>
  #include <linux/mm.h>
 +#include <linux/highmem.h>
  #include <linux/pci.h>
  #include <linux/interrupt.h>
  #include <linux/kmod.h>
@@@ -77,6 -76,9 +77,9 @@@ EXPORT_SYMBOL(acpi_in_debugger)
  extern char line_buf[80];
  #endif                                /*ENABLE_DEBUGGER */
  
+ static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
+                                     u32 pm1b_ctrl);
  static acpi_osd_handler acpi_irq_handler;
  static void *acpi_irq_context;
  static struct workqueue_struct *kacpid_wq;
@@@ -84,6 -86,19 +87,6 @@@ static struct workqueue_struct *kacpi_n
  struct workqueue_struct *kacpi_hotplug_wq;
  EXPORT_SYMBOL(kacpi_hotplug_wq);
  
 -struct acpi_res_list {
 -      resource_size_t start;
 -      resource_size_t end;
 -      acpi_adr_space_type resource_type; /* IO port, System memory, ...*/
 -      char name[5];   /* only can have a length of 4 chars, make use of this
 -                         one instead of res->name, no need to kalloc then */
 -      struct list_head resource_list;
 -      int count;
 -};
 -
 -static LIST_HEAD(resource_list_head);
 -static DEFINE_SPINLOCK(acpi_res_lock);
 -
  /*
   * This list of permanent mappings is for memory that may be accessed from
   * interrupt context, where we can't do the ioremap().
@@@ -154,21 -169,17 +157,21 @@@ static u32 acpi_osi_handler(acpi_strin
        return supported;
  }
  
 -static void __init acpi_request_region (struct acpi_generic_address *addr,
 +static void __init acpi_request_region (struct acpi_generic_address *gas,
        unsigned int length, char *desc)
  {
 -      if (!addr->address || !length)
 +      u64 addr;
 +
 +      /* Handle possible alignment issues */
 +      memcpy(&addr, &gas->address, sizeof(addr));
 +      if (!addr || !length)
                return;
  
        /* Resources are never freed */
 -      if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
 -              request_region(addr->address, length, desc);
 -      else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 -              request_mem_region(addr->address, length, desc);
 +      if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
 +              request_region(addr, length, desc);
 +      else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 +              request_mem_region(addr, length, desc);
  }
  
  static int __init acpi_reserve_resources(void)
@@@ -322,37 -333,6 +325,37 @@@ acpi_map_lookup_virt(void __iomem *virt
        return NULL;
  }
  
 +#ifndef CONFIG_IA64
 +#define should_use_kmap(pfn)   page_is_ram(pfn)
 +#else
 +/* ioremap will take care of cache attributes */
 +#define should_use_kmap(pfn)   0
 +#endif
 +
 +static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
 +{
 +      unsigned long pfn;
 +
 +      pfn = pg_off >> PAGE_SHIFT;
 +      if (should_use_kmap(pfn)) {
 +              if (pg_sz > PAGE_SIZE)
 +                      return NULL;
 +              return (void __iomem __force *)kmap(pfn_to_page(pfn));
 +      } else
 +              return acpi_os_ioremap(pg_off, pg_sz);
 +}
 +
 +static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
 +{
 +      unsigned long pfn;
 +
 +      pfn = pg_off >> PAGE_SHIFT;
 +      if (page_is_ram(pfn))
 +              kunmap(pfn_to_page(pfn));
 +      else
 +              iounmap(vaddr);
 +}
 +
  void __iomem *__init_refok
  acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
  {
  
        pg_off = round_down(phys, PAGE_SIZE);
        pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
 -      virt = acpi_os_ioremap(pg_off, pg_sz);
 +      virt = acpi_map(pg_off, pg_sz);
        if (!virt) {
                mutex_unlock(&acpi_ioremap_lock);
                kfree(map);
@@@ -416,7 -396,7 +419,7 @@@ static void acpi_os_map_cleanup(struct 
  {
        if (!map->refcount) {
                synchronize_rcu();
 -              iounmap(map->virt);
 +              acpi_unmap(map->phys, map->virt);
                kfree(map);
        }
  }
@@@ -450,42 -430,35 +453,42 @@@ void __init early_acpi_os_unmap_memory(
                __acpi_unmap_table(virt, size);
  }
  
 -static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
 +int acpi_os_map_generic_address(struct acpi_generic_address *gas)
  {
 +      u64 addr;
        void __iomem *virt;
  
 -      if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
 +      if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
                return 0;
  
 -      if (!addr->address || !addr->bit_width)
 +      /* Handle possible alignment issues */
 +      memcpy(&addr, &gas->address, sizeof(addr));
 +      if (!addr || !gas->bit_width)
                return -EINVAL;
  
 -      virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
 +      virt = acpi_os_map_memory(addr, gas->bit_width / 8);
        if (!virt)
                return -EIO;
  
        return 0;
  }
 +EXPORT_SYMBOL(acpi_os_map_generic_address);
  
 -static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
 +void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
  {
 +      u64 addr;
        struct acpi_ioremap *map;
  
 -      if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
 +      if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
                return;
  
 -      if (!addr->address || !addr->bit_width)
 +      /* Handle possible alignment issues */
 +      memcpy(&addr, &gas->address, sizeof(addr));
 +      if (!addr || !gas->bit_width)
                return;
  
        mutex_lock(&acpi_ioremap_lock);
 -      map = acpi_map_lookup(addr->address, addr->bit_width / 8);
 +      map = acpi_map_lookup(addr, gas->bit_width / 8);
        if (!map) {
                mutex_unlock(&acpi_ioremap_lock);
                return;
  
        acpi_os_map_cleanup(map);
  }
 +EXPORT_SYMBOL(acpi_os_unmap_generic_address);
  
  #ifdef ACPI_FUTURE_USAGE
  acpi_status
@@@ -742,67 -714,6 +745,67 @@@ acpi_os_read_memory(acpi_physical_addre
        return AE_OK;
  }
  
 +#ifdef readq
 +static inline u64 read64(const volatile void __iomem *addr)
 +{
 +      return readq(addr);
 +}
 +#else
 +static inline u64 read64(const volatile void __iomem *addr)
 +{
 +      u64 l, h;
 +      l = readl(addr);
 +      h = readl(addr+4);
 +      return l | (h << 32);
 +}
 +#endif
 +
 +acpi_status
 +acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
 +{
 +      void __iomem *virt_addr;
 +      unsigned int size = width / 8;
 +      bool unmap = false;
 +      u64 dummy;
 +
 +      rcu_read_lock();
 +      virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
 +      if (!virt_addr) {
 +              rcu_read_unlock();
 +              virt_addr = acpi_os_ioremap(phys_addr, size);
 +              if (!virt_addr)
 +                      return AE_BAD_ADDRESS;
 +              unmap = true;
 +      }
 +
 +      if (!value)
 +              value = &dummy;
 +
 +      switch (width) {
 +      case 8:
 +              *(u8 *) value = readb(virt_addr);
 +              break;
 +      case 16:
 +              *(u16 *) value = readw(virt_addr);
 +              break;
 +      case 32:
 +              *(u32 *) value = readl(virt_addr);
 +              break;
 +      case 64:
 +              *(u64 *) value = read64(virt_addr);
 +              break;
 +      default:
 +              BUG();
 +      }
 +
 +      if (unmap)
 +              iounmap(virt_addr);
 +      else
 +              rcu_read_unlock();
 +
 +      return AE_OK;
 +}
 +
  acpi_status
  acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
  {
        return AE_OK;
  }
  
 +#ifdef writeq
 +static inline void write64(u64 val, volatile void __iomem *addr)
 +{
 +      writeq(val, addr);
 +}
 +#else
 +static inline void write64(u64 val, volatile void __iomem *addr)
 +{
 +      writel(val, addr);
 +      writel(val>>32, addr+4);
 +}
 +#endif
 +
 +acpi_status
 +acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width)
 +{
 +      void __iomem *virt_addr;
 +      unsigned int size = width / 8;
 +      bool unmap = false;
 +
 +      rcu_read_lock();
 +      virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
 +      if (!virt_addr) {
 +              rcu_read_unlock();
 +              virt_addr = acpi_os_ioremap(phys_addr, size);
 +              if (!virt_addr)
 +                      return AE_BAD_ADDRESS;
 +              unmap = true;
 +      }
 +
 +      switch (width) {
 +      case 8:
 +              writeb(value, virt_addr);
 +              break;
 +      case 16:
 +              writew(value, virt_addr);
 +              break;
 +      case 32:
 +              writel(value, virt_addr);
 +              break;
 +      case 64:
 +              write64(value, virt_addr);
 +              break;
 +      default:
 +              BUG();
 +      }
 +
 +      if (unmap)
 +              iounmap(virt_addr);
 +      else
 +              rcu_read_unlock();
 +
 +      return AE_OK;
 +}
 +
  acpi_status
  acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
                               u64 *value, u32 width)
@@@ -1425,28 -1281,44 +1428,28 @@@ __setup("acpi_enforce_resources=", acpi
   * drivers */
  int acpi_check_resource_conflict(const struct resource *res)
  {
 -      struct acpi_res_list *res_list_elem;
 -      int ioport = 0, clash = 0;
 +      acpi_adr_space_type space_id;
 +      acpi_size length;
 +      u8 warn = 0;
 +      int clash = 0;
  
        if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
                return 0;
        if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
                return 0;
  
 -      ioport = res->flags & IORESOURCE_IO;
 -
 -      spin_lock(&acpi_res_lock);
 -      list_for_each_entry(res_list_elem, &resource_list_head,
 -                          resource_list) {
 -              if (ioport && (res_list_elem->resource_type
 -                             != ACPI_ADR_SPACE_SYSTEM_IO))
 -                      continue;
 -              if (!ioport && (res_list_elem->resource_type
 -                              != ACPI_ADR_SPACE_SYSTEM_MEMORY))
 -                      continue;
 +      if (res->flags & IORESOURCE_IO)
 +              space_id = ACPI_ADR_SPACE_SYSTEM_IO;
 +      else
 +              space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
  
 -              if (res->end < res_list_elem->start
 -                  || res_list_elem->end < res->start)
 -                      continue;
 -              clash = 1;
 -              break;
 -      }
 -      spin_unlock(&acpi_res_lock);
 +      length = res->end - res->start + 1;
 +      if (acpi_enforce_resources != ENFORCE_RESOURCES_NO)
 +              warn = 1;
 +      clash = acpi_check_address_range(space_id, res->start, length, warn);
  
        if (clash) {
                if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
 -                      printk(KERN_WARNING "ACPI: resource %s %pR"
 -                             " conflicts with ACPI region %s "
 -                             "[%s 0x%zx-0x%zx]\n",
 -                             res->name, res, res_list_elem->name,
 -                             (res_list_elem->resource_type ==
 -                              ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem",
 -                             (size_t) res_list_elem->start,
 -                             (size_t) res_list_elem->end);
                        if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
                                printk(KERN_NOTICE "ACPI: This conflict may"
                                       " cause random problems and system"
@@@ -1598,6 -1470,155 +1601,6 @@@ acpi_status acpi_os_release_object(acpi
        kmem_cache_free(cache, object);
        return (AE_OK);
  }
 -
 -static inline int acpi_res_list_add(struct acpi_res_list *res)
 -{
 -      struct acpi_res_list *res_list_elem;
 -
 -      list_for_each_entry(res_list_elem, &resource_list_head,
 -                          resource_list) {
 -
 -              if (res->resource_type == res_list_elem->resource_type &&
 -                  res->start == res_list_elem->start &&
 -                  res->end == res_list_elem->end) {
 -
 -                      /*
 -                       * The Region(addr,len) already exist in the list,
 -                       * just increase the count
 -                       */
 -
 -                      res_list_elem->count++;
 -                      return 0;
 -              }
 -      }
 -
 -      res->count = 1;
 -      list_add(&res->resource_list, &resource_list_head);
 -      return 1;
 -}
 -
 -static inline void acpi_res_list_del(struct acpi_res_list *res)
 -{
 -      struct acpi_res_list *res_list_elem;
 -
 -      list_for_each_entry(res_list_elem, &resource_list_head,
 -                          resource_list) {
 -
 -              if (res->resource_type == res_list_elem->resource_type &&
 -                  res->start == res_list_elem->start &&
 -                  res->end == res_list_elem->end) {
 -
 -                      /*
 -                       * If the res count is decreased to 0,
 -                       * remove and free it
 -                       */
 -
 -                      if (--res_list_elem->count == 0) {
 -                              list_del(&res_list_elem->resource_list);
 -                              kfree(res_list_elem);
 -                      }
 -                      return;
 -              }
 -      }
 -}
 -
 -acpi_status
 -acpi_os_invalidate_address(
 -    u8                   space_id,
 -    acpi_physical_address   address,
 -    acpi_size               length)
 -{
 -      struct acpi_res_list res;
 -
 -      switch (space_id) {
 -      case ACPI_ADR_SPACE_SYSTEM_IO:
 -      case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 -              /* Only interference checks against SystemIO and SystemMemory
 -                 are needed */
 -              res.start = address;
 -              res.end = address + length - 1;
 -              res.resource_type = space_id;
 -              spin_lock(&acpi_res_lock);
 -              acpi_res_list_del(&res);
 -              spin_unlock(&acpi_res_lock);
 -              break;
 -      case ACPI_ADR_SPACE_PCI_CONFIG:
 -      case ACPI_ADR_SPACE_EC:
 -      case ACPI_ADR_SPACE_SMBUS:
 -      case ACPI_ADR_SPACE_CMOS:
 -      case ACPI_ADR_SPACE_PCI_BAR_TARGET:
 -      case ACPI_ADR_SPACE_DATA_TABLE:
 -      case ACPI_ADR_SPACE_FIXED_HARDWARE:
 -              break;
 -      }
 -      return AE_OK;
 -}
 -
 -/******************************************************************************
 - *
 - * FUNCTION:    acpi_os_validate_address
 - *
 - * PARAMETERS:  space_id             - ACPI space ID
 - *              address             - Physical address
 - *              length              - Address length
 - *
 - * RETURN:      AE_OK if address/length is valid for the space_id. Otherwise,
 - *              should return AE_AML_ILLEGAL_ADDRESS.
 - *
 - * DESCRIPTION: Validate a system address via the host OS. Used to validate
 - *              the addresses accessed by AML operation regions.
 - *
 - *****************************************************************************/
 -
 -acpi_status
 -acpi_os_validate_address (
 -    u8                   space_id,
 -    acpi_physical_address   address,
 -    acpi_size               length,
 -    char *name)
 -{
 -      struct acpi_res_list *res;
 -      int added;
 -      if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
 -              return AE_OK;
 -
 -      switch (space_id) {
 -      case ACPI_ADR_SPACE_SYSTEM_IO:
 -      case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 -              /* Only interference checks against SystemIO and SystemMemory
 -                 are needed */
 -              res = kzalloc(sizeof(struct acpi_res_list), GFP_KERNEL);
 -              if (!res)
 -                      return AE_OK;
 -              /* ACPI names are fixed to 4 bytes, still better use strlcpy */
 -              strlcpy(res->name, name, 5);
 -              res->start = address;
 -              res->end = address + length - 1;
 -              res->resource_type = space_id;
 -              spin_lock(&acpi_res_lock);
 -              added = acpi_res_list_add(res);
 -              spin_unlock(&acpi_res_lock);
 -              pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, "
 -                       "name: %s\n", added ? "Added" : "Already exist",
 -                       (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
 -                       ? "SystemIO" : "System Memory",
 -                       (unsigned long long)res->start,
 -                       (unsigned long long)res->end,
 -                       res->name);
 -              if (!added)
 -                      kfree(res);
 -              break;
 -      case ACPI_ADR_SPACE_PCI_CONFIG:
 -      case ACPI_ADR_SPACE_EC:
 -      case ACPI_ADR_SPACE_SMBUS:
 -      case ACPI_ADR_SPACE_CMOS:
 -      case ACPI_ADR_SPACE_PCI_BAR_TARGET:
 -      case ACPI_ADR_SPACE_DATA_TABLE:
 -      case ACPI_ADR_SPACE_FIXED_HARDWARE:
 -              break;
 -      }
 -      return AE_OK;
 -}
  #endif
  
  acpi_status __init acpi_os_initialize(void)
@@@ -1641,3 -1662,24 +1644,24 @@@ acpi_status acpi_os_terminate(void
  
        return AE_OK;
  }
+ acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
+                                 u32 pm1b_control)
+ {
+       int rc = 0;
+       if (__acpi_os_prepare_sleep)
+               rc = __acpi_os_prepare_sleep(sleep_state,
+                                            pm1a_control, pm1b_control);
+       if (rc < 0)
+               return AE_ERROR;
+       else if (rc > 0)
+               return AE_CTRL_SKIP;
+       return AE_OK;
+ }
+ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
+                              u32 pm1a_ctrl, u32 pm1b_ctrl))
+ {
+       __acpi_os_prepare_sleep = func;
+ }
diff --combined include/linux/acpi.h
index 3f968665899b9cadeef825dab03666d04eac3c64,fccd017b8b6e85ac1dbc4395d8f5a8eab8e57f67..104eda758e7f27dacb9446a33c7f26dde31c2493
@@@ -302,19 -302,10 +302,19 @@@ extern bool osc_sb_apei_support_acked
                                OSC_PCI_EXPRESS_PME_CONTROL |           \
                                OSC_PCI_EXPRESS_AER_CONTROL |           \
                                OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
 +
 +#define OSC_PCI_NATIVE_HOTPLUG        (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |    \
 +                              OSC_SHPC_NATIVE_HP_CONTROL)
 +
  extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
                                             u32 *mask, u32 req);
  extern void acpi_early_init(void);
  
 +extern int acpi_nvs_register(__u64 start, __u64 size);
 +
 +extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
 +                                  void *data);
 +
  #else /* !CONFIG_ACPI */
  
  #define acpi_disabled 1
@@@ -357,18 -348,25 +357,28 @@@ static inline int acpi_table_parse(cha
  {
        return -1;
  }
 -#endif        /* !CONFIG_ACPI */
  
 -#ifdef CONFIG_ACPI_SLEEP
 -int suspend_nvs_register(unsigned long start, unsigned long size);
 -#else
 -static inline int suspend_nvs_register(unsigned long a, unsigned long b)
 +static inline int acpi_nvs_register(__u64 start, __u64 size)
  {
        return 0;
  }
 -#endif
 +
 +static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
 +                                         void *data)
 +{
 +      return 0;
 +}
 +
 +#endif        /* !CONFIG_ACPI */
  
+ #ifdef CONFIG_ACPI
+ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
+                              u32 pm1a_ctrl,  u32 pm1b_ctrl));
+ acpi_status acpi_os_prepare_sleep(u8 sleep_state,
+                                 u32 pm1a_control, u32 pm1b_control);
+ #else
+ #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0)
+ #endif
  #endif        /*_LINUX_ACPI_H*/
This page took 0.0999 seconds and 4 git commands to generate.