Commit 2a893f91 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pm+acpi-for-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management fixes from Rafael Wysocki:

 - Removal of some ACPICA code that the kernel will never use from Lv
   Zheng.

 - APEI fix from Adrian Huang.

 - Removal of unnecessary ACPI memory hotplug driver code from Liu
   Jinsong.

 - Minor ACPI power management fixes.

 - ACPI debug code fix from Joe Perches.

 - ACPI fix to make system bus device nodes get the right names.

 - PNP resources handling fixes from Witold Szczeponik.

 - cpuidle fix for a recent regression stalling boot on systems with
   great numbers of CPUs from Daniel Lezcano.

 - cpuidle fixes from Sivaram Nair.

 - intel_idle debug message fix from Youquan Song.

 - cpufreq build regression fix from Larry Finger.

 - cpufreq fix for an obscure initialization race related to statistics
   from Konstantin Khlebnikov.

 - cpufreq change disabling the Longhaul driver by default from Rafał
   Bilski.

 - PM core fix preventing device suspend errors from happening during
   system suspend due to obscure race conditions.

 - PM QoS local variable name cleanup.

* tag 'pm+acpi-for-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM: Move disabling/enabling runtime PM to late suspend/early resume
  PM / QoS: Rename local variable in dev_pm_qos_add_ancestor_request()
  ACPI / scan: Do not use dummy HID for system bus ACPI nodes
  cpufreq / governor: Fix problem with cpufreq_ondemand or cpufreq_conservative
  cpufreq / Longhaul: Disable driver by default
  cpufreq / stats: fix race between stats allocation and first usage
  cpuidle: fix lock contention in the idle path
  intel_idle: pr_debug information need separated
  cpuidle / coupled: fix ready counter decrement
  cpuidle: Fix finding state with min power_usage
  PNP: Handle IORESOURCE_BITS in resource allocation
  PNP: Simplify setting of resources
  ACPI / power: Remove useless message from device registering routine
  ACPI / glue: Update DBG macro to include KERN_DEBUG
  ACPI / PM: Do not apply ACPI_SUCCESS() to acpi_bus_get_device() result
  ACPI / memhotplug: remove redundant logic of acpi memory hotadd
  ACPI / APEI: Fix the returned value in erst_dbg_read
  ACPICA: Remove useless mini-C library.
parents 127aa930 f67ffa95
...@@ -642,12 +642,13 @@ out the following operations: ...@@ -642,12 +642,13 @@ out the following operations:
* During system suspend it calls pm_runtime_get_noresume() and * During system suspend it calls pm_runtime_get_noresume() and
pm_runtime_barrier() for every device right before executing the pm_runtime_barrier() for every device right before executing the
subsystem-level .suspend() callback for it. In addition to that it calls subsystem-level .suspend() callback for it. In addition to that it calls
pm_runtime_disable() for every device right after executing the __pm_runtime_disable() with 'false' as the second argument for every device
subsystem-level .suspend() callback for it. right before executing the subsystem-level .suspend_late() callback for it.
* During system resume it calls pm_runtime_enable() and pm_runtime_put_sync() * During system resume it calls pm_runtime_enable() and pm_runtime_put_sync()
for every device right before and right after executing the subsystem-level for every device right after executing the subsystem-level .resume_early()
.resume() callback for it, respectively. callback and right after executing the subsystem-level .resume() callback
for it, respectively.
7. Generic subsystem callbacks 7. Generic subsystem callbacks
......
...@@ -226,16 +226,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) ...@@ -226,16 +226,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
struct acpi_memory_info *info; struct acpi_memory_info *info;
int node; int node;
/* Get the range from the _CRS */
result = acpi_memory_get_device_resources(mem_device);
if (result) {
dev_err(&mem_device->device->dev,
"get_device_resources failed\n");
mem_device->state = MEMORY_INVALID_STATE;
return result;
}
node = acpi_get_node(mem_device->device->handle); node = acpi_get_node(mem_device->device->handle);
/* /*
* Tell the VM there is more memory here... * Tell the VM there is more memory here...
...@@ -342,14 +332,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -342,14 +332,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
break; break;
} }
if (acpi_memory_check_device(mem_device))
break;
if (acpi_memory_enable_device(mem_device)) {
acpi_handle_err(handle,"Cannot enable memory device\n");
break;
}
ost_code = ACPI_OST_SC_SUCCESS; ost_code = ACPI_OST_SC_SUCCESS;
break; break;
......
...@@ -162,5 +162,5 @@ acpi-y += \ ...@@ -162,5 +162,5 @@ acpi-y += \
utxferror.o \ utxferror.o \
utxfmutex.o utxfmutex.o
acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o utclib.o acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o
/******************************************************************************
*
* Module Name: cmclib - Local implementation of C library functions
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2012, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include "accommon.h"
/*
* These implementations of standard C Library routines can optionally be
* used if a C library is not available. In general, they are less efficient
* than an inline or assembly implementation
*/
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("cmclib")
#ifndef ACPI_USE_SYSTEM_CLIBRARY
#define NEGATIVE 1
#define POSITIVE 0
/*******************************************************************************
*
* FUNCTION: acpi_ut_memcmp (memcmp)
*
* PARAMETERS: buffer1 - First Buffer
* buffer2 - Second Buffer
* count - Maximum # of bytes to compare
*
* RETURN: Index where Buffers mismatched, or 0 if Buffers matched
*
* DESCRIPTION: Compare two Buffers, with a maximum length
*
******************************************************************************/
int acpi_ut_memcmp(const char *buffer1, const char *buffer2, acpi_size count)
{
return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*buffer1 -
(unsigned char)*buffer2));
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_memcpy (memcpy)
*
* PARAMETERS: dest - Target of the copy
* src - Source buffer to copy
* count - Number of bytes to copy
*
* RETURN: Dest
*
* DESCRIPTION: Copy arbitrary bytes of memory
*
******************************************************************************/
void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count)
{
char *new = (char *)dest;
char *old = (char *)src;
while (count) {
*new = *old;
new++;
old++;
count--;
}
return (dest);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_memset (memset)
*
* PARAMETERS: dest - Buffer to set
* value - Value to set each byte of memory
* count - Number of bytes to set
*
* RETURN: Dest
*
* DESCRIPTION: Initialize a buffer to a known value.
*
******************************************************************************/
void *acpi_ut_memset(void *dest, u8 value, acpi_size count)
{
char *new = (char *)dest;
while (count) {
*new = (char)value;
new++;
count--;
}
return (dest);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strlen (strlen)
*
* PARAMETERS: string - Null terminated string
*
* RETURN: Length
*
* DESCRIPTION: Returns the length of the input string
*
******************************************************************************/
acpi_size acpi_ut_strlen(const char *string)
{
u32 length = 0;
/* Count the string until a null is encountered */
while (*string) {
length++;
string++;
}
return (length);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strcpy (strcpy)
*
* PARAMETERS: dst_string - Target of the copy
* src_string - The source string to copy
*
* RETURN: dst_string
*
* DESCRIPTION: Copy a null terminated string
*
******************************************************************************/
char *acpi_ut_strcpy(char *dst_string, const char *src_string)
{
char *string = dst_string;
/* Move bytes brute force */
while (*src_string) {
*string = *src_string;
string++;
src_string++;
}
/* Null terminate */
*string = 0;
return (dst_string);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strncpy (strncpy)
*
* PARAMETERS: dst_string - Target of the copy
* src_string - The source string to copy
* count - Maximum # of bytes to copy
*
* RETURN: dst_string
*
* DESCRIPTION: Copy a null terminated string, with a maximum length
*
******************************************************************************/
char *acpi_ut_strncpy(char *dst_string, const char *src_string, acpi_size count)
{
char *string = dst_string;
/* Copy the string */
for (string = dst_string;
count && (count--, (*string++ = *src_string++));) {;
}
/* Pad with nulls if necessary */
while (count--) {
*string = 0;
string++;
}
/* Return original pointer */
return (dst_string);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strcmp (strcmp)
*
* PARAMETERS: string1 - First string
* string2 - Second string
*
* RETURN: Index where strings mismatched, or 0 if strings matched
*
* DESCRIPTION: Compare two null terminated strings
*
******************************************************************************/
int acpi_ut_strcmp(const char *string1, const char *string2)
{
for (; (*string1 == *string2); string2++) {
if (!*string1++) {
return (0);
}
}
return ((unsigned char)*string1 - (unsigned char)*string2);
}
#ifdef ACPI_FUTURE_IMPLEMENTATION
/* Not used at this time */
/*******************************************************************************
*
* FUNCTION: acpi_ut_strchr (strchr)
*
* PARAMETERS: string - Search string
* ch - character to search for
*
* RETURN: Ptr to char or NULL if not found
*
* DESCRIPTION: Search a string for a character
*
******************************************************************************/
char *acpi_ut_strchr(const char *string, int ch)
{
for (; (*string); string++) {
if ((*string) == (char)ch) {
return ((char *)string);
}
}
return (NULL);
}
#endif
/*******************************************************************************
*
* FUNCTION: acpi_ut_strncmp (strncmp)
*
* PARAMETERS: string1 - First string
* string2 - Second string
* count - Maximum # of bytes to compare
*
* RETURN: Index where strings mismatched, or 0 if strings matched
*
* DESCRIPTION: Compare two null terminated strings, with a maximum length
*
******************************************************************************/
int acpi_ut_strncmp(const char *string1, const char *string2, acpi_size count)
{
for (; count-- && (*string1 == *string2); string2++) {
if (!*string1++) {
return (0);
}
}
return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*string1 -
(unsigned char)*string2));
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strcat (Strcat)
*
* PARAMETERS: dst_string - Target of the copy
* src_string - The source string to copy
*
* RETURN: dst_string
*
* DESCRIPTION: Append a null terminated string to a null terminated string
*
******************************************************************************/
char *acpi_ut_strcat(char *dst_string, const char *src_string)
{
char *string;
/* Find end of the destination string */
for (string = dst_string; *string++;) {;
}
/* Concatenate the string */
for (--string; (*string++ = *src_string++);) {;
}
return (dst_string);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strncat (strncat)
*
* PARAMETERS: dst_string - Target of the copy
* src_string - The source string to copy
* count - Maximum # of bytes to copy
*
* RETURN: dst_string
*
* DESCRIPTION: Append a null terminated string to a null terminated string,
* with a maximum count.
*
******************************************************************************/
char *acpi_ut_strncat(char *dst_string, const char *src_string, acpi_size count)
{
char *string;
if (count) {
/* Find end of the destination string */
for (string = dst_string; *string++;) {;
}
/* Concatenate the string */
for (--string; (*string++ = *src_string++) && --count;) {;
}
/* Null terminate if necessary */
if (!count) {
*string = 0;
}
}
return (dst_string);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strstr (strstr)
*
* PARAMETERS: string1 - Target string
* string2 - Substring to search for
*
* RETURN: Where substring match starts, Null if no match found
*
* DESCRIPTION: Checks if String2 occurs in String1. This is not really a
* full implementation of strstr, only sufficient for command
* matching
*
******************************************************************************/
char *acpi_ut_strstr(char *string1, char *string2)
{
char *string;
if (acpi_ut_strlen(string2) > acpi_ut_strlen(string1)) {
return (NULL);
}
/* Walk entire string, comparing the letters */
for (string = string1; *string2;) {
if (*string2 != *string) {
return (NULL);
}
string2++;
string++;
}
return (string1);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_strtoul (strtoul)
*
* PARAMETERS: string - Null terminated string
* terminater - Where a pointer to the terminating byte is
* returned
* base - Radix of the string
*
* RETURN: Converted value
*
* DESCRIPTION: Convert a string into a 32-bit unsigned value.
* Note: use acpi_ut_strtoul64 for 64-bit integers.
*
******************************************************************************/
u32 acpi_ut_strtoul(const char *string, char **terminator, u32 base)
{
u32 converted = 0;
u32 index;
u32 sign;
const char *string_start;
u32 return_value = 0;
acpi_status status = AE_OK;
/*
* Save the value of the pointer to the buffer's first
* character, save the current errno value, and then
* skip over any white space in the buffer:
*/
string_start = string;
while (ACPI_IS_SPACE(*string) || *string == '\t') {
++string;
}
/*
* The buffer may contain an optional plus or minus sign.
* If it does, then skip over it but remember what is was:
*/
if (*string == '-') {
sign = NEGATIVE;
++string;
} else if (*string == '+') {
++string;
sign = POSITIVE;
} else {
sign = POSITIVE;
}
/*
* If the input parameter Base is zero, then we need to
* determine if it is octal, decimal, or hexadecimal:
*/
if (base == 0) {
if (*string == '0') {
if (acpi_ut_to_lower(*(++string)) == 'x') {
base = 16;
++string;
} else {
base = 8;
}
} else {
base = 10;
}
} else if (base < 2 || base > 36) {
/*
* The specified Base parameter is not in the domain of
* this function:
*/
goto done;
}
/*
* For octal and hexadecimal bases, skip over the leading
* 0 or 0x, if they are present.
*/
if (base == 8 && *string == '0') {
string++;
}
if (base == 16 &&
*string == '0' && acpi_ut_to_lower(*(++string)) == 'x') {
string++;
}
/*
* Main loop: convert the string to an unsigned long:
*/
while (*string) {
if (ACPI_IS_DIGIT(*string)) {
index = (u32)((u8)*string - '0');
} else {
index = (u32)acpi_ut_to_upper(*string);
if (ACPI_IS_UPPER(index)) {
index = index - 'A' + 10;
} else {
goto done;
}
}
if (index >= base) {
goto done;
}
/*
* Check to see if value is out of range:
*/
if (return_value > ((ACPI_UINT32_MAX - (u32)index) / (u32)base)) {
status = AE_ERROR;
return_value = 0; /* reset */
} else {
return_value *= base;
return_value += index;
converted = 1;
}
++string;
}
done:
/*
* If appropriate, update the caller's pointer to the next
* unconverted character in the buffer.
*/
if (terminator) {
if (converted == 0 && return_value == 0 && string != NULL) {
*terminator = (char *)string_start;
} else {
*terminator = (char *)string;
}
}
if (status == AE_ERROR) {
return_value = ACPI_UINT32_MAX;
}
/*
* If a minus sign was present, then "the conversion is negated":
*/
if (sign == NEGATIVE) {
return_value = (ACPI_UINT32_MAX - return_value) + 1;
}
return (return_value);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_to_upper (TOUPPER)
*
* PARAMETERS: c - Character to convert
*
* RETURN: Converted character as an int
*
* DESCRIPTION: Convert character to uppercase
*
******************************************************************************/
int acpi_ut_to_upper(int c)
{
return (ACPI_IS_LOWER(c) ? ((c) - 0x20) : (c));
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_to_lower (TOLOWER)
*
* PARAMETERS: c - Character to convert
*
* RETURN: Converted character as an int
*
* DESCRIPTION: Convert character to lowercase
*
******************************************************************************/
int acpi_ut_to_lower(int c)
{
return (ACPI_IS_UPPER(c) ? ((c) + 0x20) : (c));
}
/*******************************************************************************
*
* FUNCTION: is* functions
*
* DESCRIPTION: is* functions use the ctype table below
*
******************************************************************************/
const u8 _acpi_ctype[257] = {
_ACPI_CN, /* 0x00 0 NUL */
_ACPI_CN, /* 0x01 1 SOH */
_ACPI_CN, /* 0x02 2 STX */
_ACPI_CN, /* 0x03 3 ETX */
_ACPI_CN, /* 0x04 4 EOT */
_ACPI_CN, /* 0x05 5 ENQ */
_ACPI_CN, /* 0x06 6 ACK */
_ACPI_CN, /* 0x07 7 BEL */
_ACPI_CN, /* 0x08 8 BS */
_ACPI_CN | _ACPI_SP, /* 0x09 9 TAB */
_ACPI_CN | _ACPI_SP, /* 0x0A 10 LF */
_ACPI_CN | _ACPI_SP, /* 0x0B 11 VT */
_ACPI_CN | _ACPI_SP, /* 0x0C 12 FF */
_ACPI_CN | _ACPI_SP, /* 0x0D 13 CR */
_ACPI_CN, /* 0x0E 14 SO */
_ACPI_CN, /* 0x0F 15 SI */
_ACPI_CN, /* 0x10 16 DLE */
_ACPI_CN, /* 0x11 17 DC1 */
_ACPI_CN, /* 0x12 18 DC2 */
_ACPI_CN, /* 0x13 19 DC3 */
_ACPI_CN, /* 0x14 20 DC4 */
_ACPI_CN, /* 0x15 21 NAK */
_ACPI_CN, /* 0x16 22 SYN */
_ACPI_CN, /* 0x17 23 ETB */
_ACPI_CN, /* 0x18 24 CAN */
_ACPI_CN, /* 0x19 25 EM */
_ACPI_CN, /* 0x1A 26 SUB */
_ACPI_CN, /* 0x1B 27 ESC */
_ACPI_CN, /* 0x1C 28 FS */
_ACPI_CN, /* 0x1D 29 GS */
_ACPI_CN, /* 0x1E 30 RS */
_ACPI_CN, /* 0x1F 31 US */
_ACPI_XS | _ACPI_SP, /* 0x20 32 ' ' */
_ACPI_PU, /* 0x21 33 '!' */
_ACPI_PU, /* 0x22 34 '"' */
_ACPI_PU, /* 0x23 35 '#' */
_ACPI_PU, /* 0x24 36 '$' */
_ACPI_PU, /* 0x25 37 '%' */
_ACPI_PU, /* 0x26 38 '&' */
_ACPI_PU, /* 0x27 39 ''' */
_ACPI_PU, /* 0x28 40 '(' */
_ACPI_PU, /* 0x29 41 ')' */
_ACPI_PU, /* 0x2A 42 '*' */
_ACPI_PU, /* 0x2B 43 '+' */
_ACPI_PU, /* 0x2C 44 ',' */
_ACPI_PU, /* 0x2D 45 '-' */
_ACPI_PU, /* 0x2E 46 '.' */
_ACPI_PU, /* 0x2F 47 '/' */
_ACPI_XD | _ACPI_DI, /* 0x30 48 '0' */
_ACPI_XD | _ACPI_DI, /* 0x31 49 '1' */
_ACPI_XD | _ACPI_DI, /* 0x32 50 '2' */
_ACPI_XD | _ACPI_DI, /* 0x33 51 '3' */
_ACPI_XD | _ACPI_DI, /* 0x34 52 '4' */
_ACPI_XD | _ACPI_DI, /* 0x35 53 '5' */
_ACPI_XD | _ACPI_DI, /* 0x36 54 '6' */
_ACPI_XD | _ACPI_DI, /* 0x37 55 '7' */
_ACPI_XD | _ACPI_DI, /* 0x38 56 '8' */
_ACPI_XD | _ACPI_DI, /* 0x39 57 '9' */
_ACPI_PU, /* 0x3A 58 ':' */
_ACPI_PU, /* 0x3B 59 ';' */
_ACPI_PU, /* 0x3C 60 '<' */
_ACPI_PU, /* 0x3D 61 '=' */
_ACPI_PU, /* 0x3E 62 '>' */
_ACPI_PU, /* 0x3F 63 '?' */
_ACPI_PU, /* 0x40 64 '@' */
_ACPI_XD | _ACPI_UP, /* 0x41 65 'A' */
_ACPI_XD | _ACPI_UP, /* 0x42 66 'B' */
_ACPI_XD | _ACPI_UP, /* 0x43 67 'C' */
_ACPI_XD | _ACPI_UP, /* 0x44 68 'D' */
_ACPI_XD | _ACPI_UP, /* 0x45 69 'E' */
_ACPI_XD | _ACPI_UP, /* 0x46 70 'F' */
_ACPI_UP, /* 0x47 71 'G' */
_ACPI_UP, /* 0x48 72 'H' */
_ACPI_UP, /* 0x49 73 'I' */
_ACPI_UP, /* 0x4A 74 'J' */
_ACPI_UP, /* 0x4B 75 'K' */
_ACPI_UP, /* 0x4C 76 'L' */
_ACPI_UP, /* 0x4D 77 'M' */
_ACPI_UP, /* 0x4E 78 'N' */
_ACPI_UP, /* 0x4F 79 'O' */
_ACPI_UP, /* 0x50 80 'P' */
_ACPI_UP, /* 0x51 81 'Q' */
_ACPI_UP, /* 0x52 82 'R' */
_ACPI_UP, /* 0x53 83 'S' */
_ACPI_UP, /* 0x54 84 'T' */
_ACPI_UP, /* 0x55 85 'U' */
_ACPI_UP, /* 0x56 86 'V' */
_ACPI_UP, /* 0x57 87 'W' */
_ACPI_UP, /* 0x58 88 'X' */
_ACPI_UP, /* 0x59 89 'Y' */
_ACPI_UP, /* 0x5A 90 'Z' */
_ACPI_PU, /* 0x5B 91 '[' */
_ACPI_PU, /* 0x5C 92 '\' */
_ACPI_PU, /* 0x5D 93 ']' */
_ACPI_PU, /* 0x5E 94 '^' */
_ACPI_PU, /* 0x5F 95 '_' */
_ACPI_PU, /* 0x60 96 '`' */
_ACPI_XD | _ACPI_LO, /* 0x61 97 'a' */
_ACPI_XD | _ACPI_LO, /* 0x62 98 'b' */
_ACPI_XD | _ACPI_LO, /* 0x63 99 'c' */
_ACPI_XD | _ACPI_LO, /* 0x64 100 'd' */
_ACPI_XD | _ACPI_LO, /* 0x65 101 'e' */
_ACPI_XD | _ACPI_LO, /* 0x66 102 'f' */
_ACPI_LO, /* 0x67 103 'g' */
_ACPI_LO, /* 0x68 104 'h' */
_ACPI_LO, /* 0x69 105 'i' */
_ACPI_LO, /* 0x6A 106 'j' */
_ACPI_LO, /* 0x6B 107 'k' */
_ACPI_LO, /* 0x6C 108 'l' */
_ACPI_LO, /* 0x6D 109 'm' */
_ACPI_LO, /* 0x6E 110 'n' */
_ACPI_LO, /* 0x6F 111 'o' */
_ACPI_LO, /* 0x70 112 'p' */
_ACPI_LO, /* 0x71 113 'q' */
_ACPI_LO, /* 0x72 114 'r' */
_ACPI_LO, /* 0x73 115 's' */
_ACPI_LO, /* 0x74 116 't' */
_ACPI_LO, /* 0x75 117 'u' */
_ACPI_LO, /* 0x76 118 'v' */
_ACPI_LO, /* 0x77 119 'w' */
_ACPI_LO, /* 0x78 120 'x' */
_ACPI_LO, /* 0x79 121 'y' */
_ACPI_LO, /* 0x7A 122 'z' */
_ACPI_PU, /* 0x7B 123 '{' */
_ACPI_PU, /* 0x7C 124 '|' */
_ACPI_PU, /* 0x7D 125 '}' */
_ACPI_PU, /* 0x7E 126 '~' */
_ACPI_CN, /* 0x7F 127 DEL */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 to 0x8F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 to 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 to 0xAF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 to 0xBF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 to 0xCF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 to 0xDF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 to 0xEF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0 to 0xFF */
0 /* 0x100 */
};
#endif /* ACPI_USE_SYSTEM_CLIBRARY */
...@@ -111,8 +111,17 @@ static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, ...@@ -111,8 +111,17 @@ static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf,
if (rc) if (rc)
goto out; goto out;
/* no more record */ /* no more record */
if (id == APEI_ERST_INVALID_RECORD_ID) if (id == APEI_ERST_INVALID_RECORD_ID) {
/*
* If the persistent store is empty initially, the function
* 'erst_read' below will return "-ENOENT" value. This causes
* 'retry_next' label is entered again. The returned value
* should be zero indicating the read operation is EOF.
*/
len = 0;
goto out; goto out;
}
retry: retry:
rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len);
/* The record may be cleared by others, try read next record */ /* The record may be cleared by others, try read next record */
......
...@@ -358,8 +358,7 @@ static struct acpi_device *acpi_dev_pm_get_node(struct device *dev) ...@@ -358,8 +358,7 @@ static struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
acpi_handle handle = DEVICE_ACPI_HANDLE(dev); acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
struct acpi_device *adev; struct acpi_device *adev;
return handle && ACPI_SUCCESS(acpi_bus_get_device(handle, &adev)) ? return handle && !acpi_bus_get_device(handle, &adev) ? adev : NULL;
adev : NULL;
} }
/** /**
......
...@@ -18,9 +18,14 @@ ...@@ -18,9 +18,14 @@
#define ACPI_GLUE_DEBUG 0 #define ACPI_GLUE_DEBUG 0
#if ACPI_GLUE_DEBUG #if ACPI_GLUE_DEBUG
#define DBG(x...) printk(PREFIX x) #define DBG(fmt, ...) \
printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__)
#else #else
#define DBG(x...) do { } while(0) #define DBG(fmt, ...) \
do { \
if (0) \
printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__); \
} while (0)
#endif #endif
static LIST_HEAD(bus_type_list); static LIST_HEAD(bus_type_list);
static DECLARE_RWSEM(bus_type_sem); static DECLARE_RWSEM(bus_type_sem);
......
...@@ -445,11 +445,8 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) ...@@ -445,11 +445,8 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
return -ENODEV; return -ENODEV;
ret = acpi_bus_get_device(handle, &acpi_dev); ret = acpi_bus_get_device(handle, &acpi_dev);
if (ret) if (ret || !acpi_dev->power.flags.power_resources)
goto no_power_resource; return -ENODEV;
if (!acpi_dev->power.flags.power_resources)
goto no_power_resource;
powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL); powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL);
if (!powered_device) if (!powered_device)
...@@ -471,10 +468,6 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) ...@@ -471,10 +468,6 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
} }
return ret; return ret;
no_power_resource:
printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!\n");
return -ENODEV;
} }
EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
......
...@@ -1346,7 +1346,7 @@ static void acpi_device_set_id(struct acpi_device *device) ...@@ -1346,7 +1346,7 @@ static void acpi_device_set_id(struct acpi_device *device)
acpi_add_id(device, ACPI_DOCK_HID); acpi_add_id(device, ACPI_DOCK_HID);
else if (!acpi_ibm_smbus_match(device)) else if (!acpi_ibm_smbus_match(device))
acpi_add_id(device, ACPI_SMBUS_IBM_HID); acpi_add_id(device, ACPI_SMBUS_IBM_HID);
else if (!acpi_device_hid(device) && else if (list_empty(&device->pnp.ids) &&
ACPI_IS_ROOT_DEVICE(device->parent)) { ACPI_IS_ROOT_DEVICE(device->parent)) {
acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
......
...@@ -513,6 +513,8 @@ static int device_resume_early(struct device *dev, pm_message_t state) ...@@ -513,6 +513,8 @@ static int device_resume_early(struct device *dev, pm_message_t state)
Out: Out:
TRACE_RESUME(error); TRACE_RESUME(error);
pm_runtime_enable(dev);
return error; return error;
} }
...@@ -589,8 +591,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) ...@@ -589,8 +591,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
if (!dev->power.is_suspended) if (!dev->power.is_suspended)
goto Unlock; goto Unlock;
pm_runtime_enable(dev);
if (dev->pm_domain) { if (dev->pm_domain) {
info = "power domain "; info = "power domain ";
callback = pm_op(&dev->pm_domain->ops, state); callback = pm_op(&dev->pm_domain->ops, state);
...@@ -930,6 +930,8 @@ static int device_suspend_late(struct device *dev, pm_message_t state) ...@@ -930,6 +930,8 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL; pm_callback_t callback = NULL;
char *info = NULL; char *info = NULL;
__pm_runtime_disable(dev, false);
if (dev->power.syscore) if (dev->power.syscore)
return 0; return 0;
...@@ -1133,11 +1135,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) ...@@ -1133,11 +1135,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
Complete: Complete:
complete_all(&dev->power.completion); complete_all(&dev->power.completion);
if (error) if (error)
async_error = error; async_error = error;
else if (dev->power.is_suspended)
__pm_runtime_disable(dev, false);
return error; return error;
} }
......
...@@ -542,19 +542,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, ...@@ -542,19 +542,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
struct dev_pm_qos_request *req, s32 value) struct dev_pm_qos_request *req, s32 value)
{ {
struct device *ancestor = dev->parent; struct device *ancestor = dev->parent;
int error = -ENODEV; int ret = -ENODEV;
while (ancestor && !ancestor->power.ignore_children) while (ancestor && !ancestor->power.ignore_children)
ancestor = ancestor->parent; ancestor = ancestor->parent;
if (ancestor) if (ancestor)
error = dev_pm_qos_add_request(ancestor, req, ret = dev_pm_qos_add_request(ancestor, req,
DEV_PM_QOS_LATENCY, value); DEV_PM_QOS_LATENCY, value);
if (error < 0) if (ret < 0)
req->dev = NULL; req->dev = NULL;
return error; return ret;
} }
EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
......
...@@ -20,6 +20,9 @@ if CPU_FREQ ...@@ -20,6 +20,9 @@ if CPU_FREQ
config CPU_FREQ_TABLE config CPU_FREQ_TABLE
tristate tristate
config CPU_FREQ_GOV_COMMON
bool
config CPU_FREQ_STAT config CPU_FREQ_STAT
tristate "CPU frequency translation statistics" tristate "CPU frequency translation statistics"
select CPU_FREQ_TABLE select CPU_FREQ_TABLE
...@@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE ...@@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE
config CPU_FREQ_GOV_ONDEMAND config CPU_FREQ_GOV_ONDEMAND
tristate "'ondemand' cpufreq policy governor" tristate "'ondemand' cpufreq policy governor"
select CPU_FREQ_TABLE select CPU_FREQ_TABLE
select CPU_FREQ_GOV_COMMON
help help
'ondemand' - This driver adds a dynamic cpufreq policy governor. 'ondemand' - This driver adds a dynamic cpufreq policy governor.
The governor does a periodic polling and The governor does a periodic polling and
...@@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND ...@@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND
config CPU_FREQ_GOV_CONSERVATIVE config CPU_FREQ_GOV_CONSERVATIVE
tristate "'conservative' cpufreq governor" tristate "'conservative' cpufreq governor"
depends on CPU_FREQ depends on CPU_FREQ
select CPU_FREQ_GOV_COMMON
help help
'conservative' - this driver is rather similar to the 'ondemand' 'conservative' - this driver is rather similar to the 'ondemand'
governor both in its source code and its purpose, the difference is governor both in its source code and its purpose, the difference is
......
...@@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o ...@@ -7,8 +7,9 @@ obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o
obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o cpufreq_governor.o obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
# CPUfreq cross-arch helpers # CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
......
...@@ -364,18 +364,21 @@ static int __init cpufreq_stats_init(void) ...@@ -364,18 +364,21 @@ static int __init cpufreq_stats_init(void)
if (ret) if (ret)
return ret; return ret;
register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
for_each_online_cpu(cpu)
cpufreq_update_policy(cpu);
ret = cpufreq_register_notifier(&notifier_trans_block, ret = cpufreq_register_notifier(&notifier_trans_block,
CPUFREQ_TRANSITION_NOTIFIER); CPUFREQ_TRANSITION_NOTIFIER);
if (ret) { if (ret) {
cpufreq_unregister_notifier(&notifier_policy_block, cpufreq_unregister_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER); CPUFREQ_POLICY_NOTIFIER);
unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
for_each_online_cpu(cpu)
cpufreq_stats_free_table(cpu);
return ret; return ret;
} }
register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
for_each_online_cpu(cpu) {
cpufreq_update_policy(cpu);
}
return 0; return 0;
} }
static void __exit cpufreq_stats_exit(void) static void __exit cpufreq_stats_exit(void)
......
...@@ -77,7 +77,7 @@ static unsigned int longhaul_index; ...@@ -77,7 +77,7 @@ static unsigned int longhaul_index;
static int scale_voltage; static int scale_voltage;
static int disable_acpi_c3; static int disable_acpi_c3;
static int revid_errata; static int revid_errata;
static int enable;
/* Clock ratios multiplied by 10 */ /* Clock ratios multiplied by 10 */
static int mults[32]; static int mults[32];
...@@ -965,6 +965,10 @@ static int __init longhaul_init(void) ...@@ -965,6 +965,10 @@ static int __init longhaul_init(void)
if (!x86_match_cpu(longhaul_id)) if (!x86_match_cpu(longhaul_id))
return -ENODEV; return -ENODEV;
if (!enable) {
printk(KERN_ERR PFX "Option \"enable\" not set. Aborting.\n");
return -ENODEV;
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (num_online_cpus() > 1) { if (num_online_cpus() > 1) {
printk(KERN_ERR PFX "More than 1 CPU detected, " printk(KERN_ERR PFX "More than 1 CPU detected, "
...@@ -1021,6 +1025,10 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); ...@@ -1021,6 +1025,10 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
* such. */ * such. */
module_param(revid_errata, int, 0644); module_param(revid_errata, int, 0644);
MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID"); MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
/* By default driver is disabled to prevent incompatible
* system freeze. */
module_param(enable, int, 0644);
MODULE_PARM_DESC(enable, "Enable driver");
MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
......
...@@ -209,7 +209,7 @@ inline int cpuidle_coupled_set_not_ready(struct cpuidle_coupled *coupled) ...@@ -209,7 +209,7 @@ inline int cpuidle_coupled_set_not_ready(struct cpuidle_coupled *coupled)
int all; int all;
int ret; int ret;
all = coupled->online_count || (coupled->online_count << WAITING_BITS); all = coupled->online_count | (coupled->online_count << WAITING_BITS);
ret = atomic_add_unless(&coupled->ready_waiting_counts, ret = atomic_add_unless(&coupled->ready_waiting_counts,
-MAX_WAITING_CPUS, all); -MAX_WAITING_CPUS, all);
......
...@@ -70,7 +70,7 @@ int cpuidle_play_dead(void) ...@@ -70,7 +70,7 @@ int cpuidle_play_dead(void)
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int i, dead_state = -1; int i, dead_state = -1;
int power_usage = -1; int power_usage = INT_MAX;
if (!drv) if (!drv)
return -ENODEV; return -ENODEV;
......
...@@ -235,16 +235,10 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); ...@@ -235,16 +235,10 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver);
*/ */
struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev) struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
{ {
struct cpuidle_driver *drv;
if (!dev) if (!dev)
return NULL; return NULL;
spin_lock(&cpuidle_driver_lock); return __cpuidle_get_cpu_driver(dev->cpu);
drv = __cpuidle_get_cpu_driver(dev->cpu);
spin_unlock(&cpuidle_driver_lock);
return drv;
} }
EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver); EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
......
...@@ -312,7 +312,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) ...@@ -312,7 +312,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
{ {
struct menu_device *data = &__get_cpu_var(menu_devices); struct menu_device *data = &__get_cpu_var(menu_devices);
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
int power_usage = -1; int power_usage = INT_MAX;
int i; int i;
int multiplier; int multiplier;
struct timespec t; struct timespec t;
......
...@@ -506,7 +506,7 @@ static int intel_idle_cpuidle_driver_init(void) ...@@ -506,7 +506,7 @@ static int intel_idle_cpuidle_driver_init(void)
if (*cpuidle_state_table[cstate].name == '\0') if (*cpuidle_state_table[cstate].name == '\0')
pr_debug(PREFIX "unaware of model 0x%x" pr_debug(PREFIX "unaware of model 0x%x"
" MWAIT %d please" " MWAIT %d please"
" contact lenb@kernel.org", " contact lenb@kernel.org\n",
boot_cpu_data.x86_model, cstate); boot_cpu_data.x86_model, cstate);
continue; continue;
} }
......
...@@ -298,6 +298,39 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, ...@@ -298,6 +298,39 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
return ret; return ret;
} }
static char *pnp_get_resource_value(char *buf,
unsigned long type,
resource_size_t *start,
resource_size_t *end,
unsigned long *flags)
{
if (start)
*start = 0;
if (end)
*end = 0;
if (flags)
*flags = 0;
/* TBD: allow for disabled resources */
buf = skip_spaces(buf);
if (start) {
*start = simple_strtoull(buf, &buf, 0);
if (end) {
buf = skip_spaces(buf);
if (*buf == '-') {
buf = skip_spaces(buf + 1);
*end = simple_strtoull(buf, &buf, 0);
} else
*end = *start;
}
}
/* TBD: allow for additional flags, e.g., IORESOURCE_WINDOW */
return buf;
}
static ssize_t pnp_set_current_resources(struct device *dmdev, static ssize_t pnp_set_current_resources(struct device *dmdev,
struct device_attribute *attr, struct device_attribute *attr,
const char *ubuf, size_t count) const char *ubuf, size_t count)
...@@ -305,7 +338,6 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, ...@@ -305,7 +338,6 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
char *buf = (void *)ubuf; char *buf = (void *)ubuf;
int retval = 0; int retval = 0;
resource_size_t start, end;
if (dev->status & PNP_ATTACHED) { if (dev->status & PNP_ATTACHED) {
retval = -EBUSY; retval = -EBUSY;
...@@ -349,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, ...@@ -349,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,
goto done; goto done;
} }
if (!strnicmp(buf, "set", 3)) { if (!strnicmp(buf, "set", 3)) {
resource_size_t start;
resource_size_t end;
unsigned long flags;
if (dev->active) if (dev->active)
goto done; goto done;
buf += 3; buf += 3;
...@@ -357,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, ...@@ -357,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,
while (1) { while (1) {
buf = skip_spaces(buf); buf = skip_spaces(buf);
if (!strnicmp(buf, "io", 2)) { if (!strnicmp(buf, "io", 2)) {
buf = skip_spaces(buf + 2); buf = pnp_get_resource_value(buf + 2,
start = simple_strtoul(buf, &buf, 0); IORESOURCE_IO,
buf = skip_spaces(buf); &start, &end,
if (*buf == '-') { &flags);
buf = skip_spaces(buf + 1); pnp_add_io_resource(dev, start, end, flags);
end = simple_strtoul(buf, &buf, 0); } else if (!strnicmp(buf, "mem", 3)) {
} else buf = pnp_get_resource_value(buf + 3,
end = start; IORESOURCE_MEM,
pnp_add_io_resource(dev, start, end, 0); &start, &end,
continue; &flags);
} pnp_add_mem_resource(dev, start, end, flags);
if (!strnicmp(buf, "mem", 3)) { } else if (!strnicmp(buf, "irq", 3)) {
buf = skip_spaces(buf + 3); buf = pnp_get_resource_value(buf + 3,
start = simple_strtoul(buf, &buf, 0); IORESOURCE_IRQ,
buf = skip_spaces(buf); &start, NULL,
if (*buf == '-') { &flags);
buf = skip_spaces(buf + 1); pnp_add_irq_resource(dev, start, flags);
end = simple_strtoul(buf, &buf, 0); } else if (!strnicmp(buf, "dma", 3)) {
} else buf = pnp_get_resource_value(buf + 3,
end = start; IORESOURCE_DMA,
pnp_add_mem_resource(dev, start, end, 0); &start, NULL,
continue; &flags);
} pnp_add_dma_resource(dev, start, flags);
if (!strnicmp(buf, "irq", 3)) { } else if (!strnicmp(buf, "bus", 3)) {
buf = skip_spaces(buf + 3); buf = pnp_get_resource_value(buf + 3,
start = simple_strtoul(buf, &buf, 0); IORESOURCE_BUS,
pnp_add_irq_resource(dev, start, 0); &start, &end,
continue; NULL);
} pnp_add_bus_resource(dev, start, end);
if (!strnicmp(buf, "dma", 3)) { } else
buf = skip_spaces(buf + 3); break;
start = simple_strtoul(buf, &buf, 0);
pnp_add_dma_resource(dev, start, 0);
continue;
}
break;
} }
mutex_unlock(&pnp_res_mutex); mutex_unlock(&pnp_res_mutex);
goto done; goto done;
......
...@@ -18,11 +18,27 @@ ...@@ -18,11 +18,27 @@
DEFINE_MUTEX(pnp_res_mutex); DEFINE_MUTEX(pnp_res_mutex);
static struct resource *pnp_find_resource(struct pnp_dev *dev,
unsigned char rule,
unsigned long type,
unsigned int bar)
{
struct resource *res = pnp_get_resource(dev, type, bar);
/* when the resource already exists, set its resource bits from rule */
if (res) {
res->flags &= ~IORESOURCE_BITS;
res->flags |= rule & IORESOURCE_BITS;
}
return res;
}
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{ {
struct resource *res, local_res; struct resource *res, local_res;
res = pnp_get_resource(dev, IORESOURCE_IO, idx); res = pnp_find_resource(dev, rule->flags, IORESOURCE_IO, idx);
if (res) { if (res) {
pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start, "flags %#lx\n", idx, (unsigned long long) res->start,
...@@ -65,7 +81,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) ...@@ -65,7 +81,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
{ {
struct resource *res, local_res; struct resource *res, local_res;
res = pnp_get_resource(dev, IORESOURCE_MEM, idx); res = pnp_find_resource(dev, rule->flags, IORESOURCE_MEM, idx);
if (res) { if (res) {
pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start, "flags %#lx\n", idx, (unsigned long long) res->start,
...@@ -78,6 +94,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) ...@@ -78,6 +94,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
res->start = 0; res->start = 0;
res->end = 0; res->end = 0;
/* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
res->flags |= IORESOURCE_READONLY; res->flags |= IORESOURCE_READONLY;
if (rule->flags & IORESOURCE_MEM_CACHEABLE) if (rule->flags & IORESOURCE_MEM_CACHEABLE)
...@@ -123,7 +140,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) ...@@ -123,7 +140,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
}; };
res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx);
if (res) { if (res) {
pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags); idx, (int) res->start, res->flags);
...@@ -182,7 +199,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) ...@@ -182,7 +199,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
1, 3, 5, 6, 7, 0, 2, 4 1, 3, 5, 6, 7, 0, 2, 4
}; };
res = pnp_get_resource(dev, IORESOURCE_DMA, idx); res = pnp_find_resource(dev, rule->flags, IORESOURCE_DMA, idx);
if (res) { if (res) {
pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags); idx, (int) res->start, res->flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment