From 04fbfca5a13279c88adc484271f0a040e9f48ad2 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 18 Dec 2012 14:05:12 +0100 Subject: ACPICA: Remove useless mini-C library. The mini-C library implementation is used by the embedded ACPICA users other than Linux. It was added to the kernel source to make it easier to incorporate future ACPICA changes, but as it turns our we can avoid carrying it thanks to some ACPICA release process tweaks, so remove drivers/acpi/acpica/utclib.c from the kernel source tree. [rjw: Modified the changelog slightly.] Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 2 +- drivers/acpi/acpica/utclib.c | 749 ------------------------------------------- 2 files changed, 1 insertion(+), 750 deletions(-) delete mode 100644 drivers/acpi/acpica/utclib.c diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index c8bc24bd1f7..bc7a03ded06 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -162,5 +162,5 @@ acpi-y += \ utxferror.o \ utxfmutex.o -acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o utclib.o +acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o diff --git a/drivers/acpi/acpica/utclib.c b/drivers/acpi/acpica/utclib.c deleted file mode 100644 index 19ea4755aa7..00000000000 --- a/drivers/acpi/acpica/utclib.c +++ /dev/null @@ -1,749 +0,0 @@ -/****************************************************************************** - * - * 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 -#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 */ -- cgit v1.2.3-70-g09d2 From 6780aa683d4d83ed887dd07b7987947d339d76f1 Mon Sep 17 00:00:00 2001 From: Adrian Huang Date: Sat, 15 Dec 2012 00:30:07 +0100 Subject: ACPI / APEI: Fix the returned value in erst_dbg_read If the persistent store is empty initially, the function 'erst_dbg_read' returns a nonzero value. The better way is to return a zero indicating the read operation reaches EOF. Tested on two different servers. Signed-off-by: Adrian Huang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/erst-dbg.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 903549df809..04ab5c9d3ce 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -111,8 +111,17 @@ retry_next: if (rc) goto out; /* 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; + } retry: rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); /* The record may be cleared by others, try read next record */ -- cgit v1.2.3-70-g09d2 From 8611ea5f5d708d60ab29ed3cdb33e67168404fc0 Mon Sep 17 00:00:00 2001 From: Liu Jinsong Date: Sun, 16 Dec 2012 14:08:41 +0100 Subject: ACPI / memhotplug: remove redundant logic of acpi memory hotadd When memory hotadd, acpi_memory_enable_device has already been done at drv->ops.add (acpi_memory_device_add), no need to do it again at notify callback. At acpi_memory_enable_device, acpi_memory_get_device_resources is also a redundant action, since it has been done at drv->ops.add. Signed-off-by: Liu Jinsong Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index eb30e5ab4ca..b679bf8478f 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -226,16 +226,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) struct acpi_memory_info *info; 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); /* * 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) 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; break; -- cgit v1.2.3-70-g09d2 From 5cc36c724eb60b5e5457807f3230e5bb5454e4d0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 16 Dec 2012 23:28:53 +0100 Subject: ACPI / PM: Do not apply ACPI_SUCCESS() to acpi_bus_get_device() result Since the return value of acpi_bus_get_device() is not of type acpi_status, ACPI_SUCCESS() should not be used for checking its return value. Fix that. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg --- drivers/acpi/device_pm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index f09dc987cf1..c6ff606c6d5 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -358,8 +358,7 @@ static struct acpi_device *acpi_dev_pm_get_node(struct device *dev) acpi_handle handle = DEVICE_ACPI_HANDLE(dev); struct acpi_device *adev; - return handle && ACPI_SUCCESS(acpi_bus_get_device(handle, &adev)) ? - adev : NULL; + return handle && !acpi_bus_get_device(handle, &adev) ? adev : NULL; } /** -- cgit v1.2.3-70-g09d2 From 23415eb5233eb3c1939c4cb7d6235af98a3a2955 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 18 Dec 2012 06:31:30 +0000 Subject: ACPI / glue: Update DBG macro to include KERN_DEBUG Currently these DBG statements are emitted at KERN_DEFAULT. Change the macro to emit at KERN_DEBUG. This can help avoid unexpected message interleaving. Signed-off-by: Joe Perches Signed-off-by: Rafael J. Wysocki --- drivers/acpi/glue.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 01551840d23..95af6f674a6 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -18,9 +18,14 @@ #define ACPI_GLUE_DEBUG 0 #if ACPI_GLUE_DEBUG -#define DBG(x...) printk(PREFIX x) +#define DBG(fmt, ...) \ + printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__) #else -#define DBG(x...) do { } while(0) +#define DBG(fmt, ...) \ +do { \ + if (0) \ + printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__); \ +} while (0) #endif static LIST_HEAD(bus_type_list); static DECLARE_RWSEM(bus_type_sem); -- cgit v1.2.3-70-g09d2 From 0271f4f1176d7205b2b73ef956b169db8f417932 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 26 Dec 2012 13:26:46 +0100 Subject: ACPI / power: Remove useless message from device registering routine After commit 71fbad6 (PCI/ACPI: Notify PCI devices when their power resource is turned on) made acpi_pci_bind() call acpi_power_resource_register_device(), the debug message at the end of the latter appears in the kernel log for every PCI device that doesn't happen to have power resources assigned (which is the vast majority of them). However, this message is totally useless, because it doesn't even say which device it is about. Moreover, it is misleading, because it only means that the given device has no power resources, which isn't exceptional at all. Remove that useless message altogether and simplify acpi_power_resource_register_device() slightly. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 7db61b8fa11..6e7b9d52381 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -445,11 +445,8 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) return -ENODEV; ret = acpi_bus_get_device(handle, &acpi_dev); - if (ret) - goto no_power_resource; - - if (!acpi_dev->power.flags.power_resources) - goto no_power_resource; + if (ret || !acpi_dev->power.flags.power_resources) + return -ENODEV; powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL); if (!powered_device) @@ -471,10 +468,6 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) } 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); -- cgit v1.2.3-70-g09d2 From c9377667e6cdf4ac910b0932868275eb0dbfcfeb Mon Sep 17 00:00:00 2001 From: Witold Szczeponik Date: Sat, 15 Dec 2012 01:00:14 +0100 Subject: PNP: Simplify setting of resources This patch factors out the setting of PNP resources into one function which is then reused for all PNP resource types. This makes the code more concise and avoids duplication. The parameters "type" and "flags" are not used at the moment but may be used by follow-up patches. Placeholders for these patches can be found in the comment lines that contain the "TBD" marker. As the code does not make any changes to the ABI, no regressions are expected. NB: While at it, support for bus type resources is added. Signed-off-by: Witold Szczeponik Reviewed-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- drivers/pnp/interface.c | 105 +++++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index cfaf5b73540..0c201317284 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -298,6 +298,39 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, 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, struct device_attribute *attr, const char *ubuf, size_t count) @@ -305,7 +338,6 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, struct pnp_dev *dev = to_pnp_dev(dmdev); char *buf = (void *)ubuf; int retval = 0; - resource_size_t start, end; if (dev->status & PNP_ATTACHED) { retval = -EBUSY; @@ -349,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, goto done; } if (!strnicmp(buf, "set", 3)) { + resource_size_t start; + resource_size_t end; + unsigned long flags; + if (dev->active) goto done; buf += 3; @@ -357,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, while (1) { buf = skip_spaces(buf); if (!strnicmp(buf, "io", 2)) { - buf = skip_spaces(buf + 2); - start = simple_strtoul(buf, &buf, 0); - buf = skip_spaces(buf); - if (*buf == '-') { - buf = skip_spaces(buf + 1); - end = simple_strtoul(buf, &buf, 0); - } else - end = start; - pnp_add_io_resource(dev, start, end, 0); - continue; - } - if (!strnicmp(buf, "mem", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - buf = skip_spaces(buf); - if (*buf == '-') { - buf = skip_spaces(buf + 1); - end = simple_strtoul(buf, &buf, 0); - } else - end = start; - pnp_add_mem_resource(dev, start, end, 0); - continue; - } - if (!strnicmp(buf, "irq", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - pnp_add_irq_resource(dev, start, 0); - continue; - } - if (!strnicmp(buf, "dma", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - pnp_add_dma_resource(dev, start, 0); - continue; - } - break; + buf = pnp_get_resource_value(buf + 2, + IORESOURCE_IO, + &start, &end, + &flags); + pnp_add_io_resource(dev, start, end, flags); + } else if (!strnicmp(buf, "mem", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_MEM, + &start, &end, + &flags); + pnp_add_mem_resource(dev, start, end, flags); + } else if (!strnicmp(buf, "irq", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_IRQ, + &start, NULL, + &flags); + pnp_add_irq_resource(dev, start, flags); + } else if (!strnicmp(buf, "dma", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_DMA, + &start, NULL, + &flags); + pnp_add_dma_resource(dev, start, flags); + } else if (!strnicmp(buf, "bus", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_BUS, + &start, &end, + NULL); + pnp_add_bus_resource(dev, start, end); + } else + break; } mutex_unlock(&pnp_res_mutex); goto done; -- cgit v1.2.3-70-g09d2 From 13cde3b2a617e2927c8ee6da7a8f8d103994430f Mon Sep 17 00:00:00 2001 From: Witold Szczeponik Date: Sat, 15 Dec 2012 01:02:08 +0100 Subject: PNP: Handle IORESOURCE_BITS in resource allocation The patch copies the flags masked by IORESOURCE_BITS from a resource's template. This is necessary because the resource settings require proper IORESOURCE_BITS which are not known during the definition of these resources using the "/sys/bus/pnp/*/*/resources" interface. (In fact, they should not be set by the user as the resource templates define the proper settings.) If the patch is not applied, the resource flags are not initialized properly and obscure messages in the kernel log have been seen ("invalid flags"). Signed-off-by: Witold Szczeponik Reviewed-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- drivers/pnp/manager.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index ed9ce507149..95cebf0185d 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -18,11 +18,27 @@ 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) { 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) { pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " "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) { 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) { pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " "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) res->start = 0; res->end = 0; + /* ??? rule->flags restricted to 8 bits, all tests bogus ??? */ if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) res->flags |= IORESOURCE_READONLY; 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) 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) { pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", 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) 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) { pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", idx, (int) res->start, res->flags); -- cgit v1.2.3-70-g09d2 From 0e5537b30d3029d784226ab51c2b923d1155b553 Mon Sep 17 00:00:00 2001 From: Sivaram Nair Date: Tue, 18 Dec 2012 13:52:50 +0100 Subject: cpuidle: Fix finding state with min power_usage Since cpuidle_state.power_usage is a signed value, use INT_MAX (instead of -1) to init the local copies so that functions that tries to find cpuidle states with minimum power usage works correctly even if they use non-negative values. Signed-off-by: Sivaram Nair Reviewed-by: Rik van Riel Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 2 +- drivers/cpuidle/governors/menu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 8df53dd8dbe..fb4a7dd57f9 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -70,7 +70,7 @@ int cpuidle_play_dead(void) struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int i, dead_state = -1; - int power_usage = -1; + int power_usage = INT_MAX; if (!drv) return -ENODEV; diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index bd40b943b6d..20ea33afdda 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -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); int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); - int power_usage = -1; + int power_usage = INT_MAX; int i; int multiplier; struct timespec t; -- cgit v1.2.3-70-g09d2 From 92638e2facc5330475c7d558acec77721c3214e4 Mon Sep 17 00:00:00 2001 From: Sivaram Nair Date: Tue, 18 Dec 2012 13:52:54 +0100 Subject: cpuidle / coupled: fix ready counter decrement The ready_waiting_counts atomic variable is compared against the wrong online cpu count. The latter is computed incorrectly using logical-OR instead of bit-OR. This patch fixes that. Signed-off-by: Sivaram Nair Acked-by: Santosh Shilimkar Acked-by: Colin Cross Cc: Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/coupled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 3265844839b..2a297f86dba 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c @@ -209,7 +209,7 @@ inline int cpuidle_coupled_set_not_ready(struct cpuidle_coupled *coupled) int all; 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, -MAX_WAITING_CPUS, all); -- cgit v1.2.3-70-g09d2 From 17915d582f9fe74efbd1c755f3ea5a5c2d9b3156 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Tue, 18 Dec 2012 13:54:22 +0100 Subject: intel_idle: pr_debug information need separated When debug kernel, the the below information is found: intel_idle: unaware of model 0x1a MWAIT 4 please contact lenb@kernel.orgACPI: Device input0 -> No ACPI support so this patch separates it. Signed-off-by: Youquan Song Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index c49c04d9c2b..4ba384f1ab5 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -506,7 +506,7 @@ static int intel_idle_cpuidle_driver_init(void) if (*cpuidle_state_table[cstate].name == '\0') pr_debug(PREFIX "unaware of model 0x%x" " MWAIT %d please" - " contact lenb@kernel.org", + " contact lenb@kernel.org\n", boot_cpu_data.x86_model, cstate); continue; } -- cgit v1.2.3-70-g09d2 From ac34d7c8c87c247db0270285950753da045acaad Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 3 Jan 2013 13:03:18 +0100 Subject: cpuidle: fix lock contention in the idle path Commit bf4d1b5 (cpuidle: support multiple drivers) introduced locking in cpuidle_get_cpu_driver(), which is used in the idle_call() function. This leads to a contention problem with a large number of CPUs, because they all try to run the idle routine at the same time. The lock can be safely removed because of how is used the cpuidle API. Namely, cpuidle_register_driver() is called first, but the cpuidle idle function is not entered before cpuidle_register_device() is called, because the cpuidle device is not enabled then. Moreover, cpuidle_unregister_driver(), which would reset the driver value to NULL, is not called before cpuidle_unregister_device(). All of the cpuidle drivers use the API in the same way. In general, a cleanup around the lock is necessary and a proper refcounting mechanism should be used to ensure the consistency in the API (for example, cpuidle_unregister_driver() should fail if the driver's refcount is not 0). However, these modifications will require some code reorganization and rewrite which will be too intrusive for a fix. For this reason, fix the contention problem introduced by commit bf4d1b5 by simply removing the locking from cpuidle_get_cpu_driver(), which restores the original behavior of that routine. [rjw: Changelog.] Reported-and-tested-by: Russ Anderson Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/driver.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 3af841fb397..c2b281afe0e 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -235,16 +235,10 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); */ struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev) { - struct cpuidle_driver *drv; - if (!dev) return NULL; - spin_lock(&cpuidle_driver_lock); - drv = __cpuidle_get_cpu_driver(dev->cpu); - spin_unlock(&cpuidle_driver_lock); - - return drv; + return __cpuidle_get_cpu_driver(dev->cpu); } EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver); -- cgit v1.2.3-70-g09d2 From 56836fb4dab8fe906b934b231b04c33c180f8da5 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Sat, 15 Dec 2012 00:22:02 +0100 Subject: cpufreq / stats: fix race between stats allocation and first usage This patch forces complete struct cpufreq_stats allocation for all cpus before registering CPUFREQ_TRANSITION_NOTIFIER notifier, otherwise in some conditions cpufreq_stat_notifier_trans() can be called in the middle of stats allocation, in this case cpufreq_stats_table already exists, but stat->freq_table is NULL. Signed-off-by: Konstantin Khlebnikov Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_stats.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index e40e5080964..9d7732b8104 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -364,18 +364,21 @@ static int __init cpufreq_stats_init(void) if (ret) return ret; + register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + for_each_online_cpu(cpu) + cpufreq_update_policy(cpu); + ret = cpufreq_register_notifier(¬ifier_trans_block, CPUFREQ_TRANSITION_NOTIFIER); if (ret) { cpufreq_unregister_notifier(¬ifier_policy_block, CPUFREQ_POLICY_NOTIFIER); + unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + for_each_online_cpu(cpu) + cpufreq_stats_free_table(cpu); return ret; } - register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); - for_each_online_cpu(cpu) { - cpufreq_update_policy(cpu); - } return 0; } static void __exit cpufreq_stats_exit(void) -- cgit v1.2.3-70-g09d2 From b5811bc469c0dbebb4f947800b9b234a9c0a68dc Mon Sep 17 00:00:00 2001 From: Rafał Bilski Date: Sat, 15 Dec 2012 00:45:02 +0100 Subject: cpufreq / Longhaul: Disable driver by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is only solution I can think of. User decides if he wants this driver on his machine. I don't have enough knowledge and time to find the reason why same code works on some machines and doesn't on others which use the same, or very similar, chipset and processor. Signed-off-by: Rafał Bilski Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/longhaul.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index f1fa500ac10..1180d536d1e 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -77,7 +77,7 @@ static unsigned int longhaul_index; static int scale_voltage; static int disable_acpi_c3; static int revid_errata; - +static int enable; /* Clock ratios multiplied by 10 */ static int mults[32]; @@ -965,6 +965,10 @@ static int __init longhaul_init(void) if (!x86_match_cpu(longhaul_id)) return -ENODEV; + if (!enable) { + printk(KERN_ERR PFX "Option \"enable\" not set. Aborting.\n"); + return -ENODEV; + } #ifdef CONFIG_SMP if (num_online_cpus() > 1) { printk(KERN_ERR PFX "More than 1 CPU detected, " @@ -1021,6 +1025,10 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor"); * such. */ module_param(revid_errata, int, 0644); 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 "); MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors."); -- cgit v1.2.3-70-g09d2 From 1e15f295408e21873dba5fdf17efcbd05fcb6729 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 29 Dec 2012 01:55:20 +0000 Subject: cpufreq / governor: Fix problem with cpufreq_ondemand or cpufreq_conservative Since commit 2aacdff entitled "cpufreq: Move common part from governors to separate file", whenever the drivers that depend on this new file (cpufreq_ondemand or cpufreq_conservative) are built as modules, a new module named cpufreq_governor is created because the Makefile includes cpufreq_governor.o twice. As drivers/cpufreq/cpufreq_governor.c contains no MODULE directives, the resulting module has no license specified, which results in logging of a "module license 'unspecified' taints kernel". In addition, a number of globals are exported GPL only, and are therefore not available. This fix establishes a new boolean configuration variable that forces cpufreq_governor.o to be linked into the kernel whenever either cpufreq_ondemand or cpufreq_conservative is selected. Signed-off-by: Larry Finger Reviewed-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig | 5 +++++ drivers/cpufreq/Makefile | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index ea512f47b78..e0a899f25e3 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -20,6 +20,9 @@ if CPU_FREQ config CPU_FREQ_TABLE tristate +config CPU_FREQ_GOV_COMMON + bool + config CPU_FREQ_STAT tristate "CPU frequency translation statistics" select CPU_FREQ_TABLE @@ -141,6 +144,7 @@ config CPU_FREQ_GOV_USERSPACE config CPU_FREQ_GOV_ONDEMAND tristate "'ondemand' cpufreq policy governor" select CPU_FREQ_TABLE + select CPU_FREQ_GOV_COMMON help 'ondemand' - This driver adds a dynamic cpufreq policy governor. The governor does a periodic polling and @@ -159,6 +163,7 @@ config CPU_FREQ_GOV_ONDEMAND config CPU_FREQ_GOV_CONSERVATIVE tristate "'conservative' cpufreq governor" depends on CPU_FREQ + select CPU_FREQ_GOV_COMMON help 'conservative' - this driver is rather similar to the 'ondemand' governor both in its source code and its purpose, the difference is diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 1f254ec087c..fadc4d496e2 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -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_POWERSAVE) += cpufreq_powersave.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_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o +obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o +obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o # CPUfreq cross-arch helpers obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o -- cgit v1.2.3-70-g09d2 From 4f5f64cf0cc916220aaa055992e31195470cfe37 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 4 Jan 2013 23:00:54 +0100 Subject: ACPI / scan: Do not use dummy HID for system bus ACPI nodes At one point acpi_device_set_id() checks if acpi_device_hid(device) returns NULL, but that never happens, so system bus devices with an empty list of PNP IDs are given the dummy HID ("device") instead of the "system bus HID" ("LNXSYBUS"). Fix the code to use the right check. Signed-off-by: Rafael J. Wysocki Cc: --- drivers/acpi/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 53502d1bbf2..c88be6c37c3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1346,7 +1346,7 @@ static void acpi_device_set_id(struct acpi_device *device) acpi_add_id(device, ACPI_DOCK_HID); else if (!acpi_ibm_smbus_match(device)) 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_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); -- cgit v1.2.3-70-g09d2 From 4ce4780270b69a0f4ce81887c2ef864c04cb7f9f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 18 Dec 2012 14:07:49 +0100 Subject: PM / QoS: Rename local variable in dev_pm_qos_add_ancestor_request() Local variable 'error' in dev_pm_qos_add_ancestor_request() need not contain error codes only, so rename it to 'ret'. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index ff46387f530..d21349544ce 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -542,19 +542,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, struct dev_pm_qos_request *req, s32 value) { struct device *ancestor = dev->parent; - int error = -ENODEV; + int ret = -ENODEV; while (ancestor && !ancestor->power.ignore_children) ancestor = ancestor->parent; if (ancestor) - error = dev_pm_qos_add_request(ancestor, req, - DEV_PM_QOS_LATENCY, value); + ret = dev_pm_qos_add_request(ancestor, req, + DEV_PM_QOS_LATENCY, value); - if (error < 0) + if (ret < 0) req->dev = NULL; - return error; + return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); -- cgit v1.2.3-70-g09d2 From 9f6d8f6ab26b42620a914d67f29822f9bba90233 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 22 Dec 2012 23:59:01 +0100 Subject: PM: Move disabling/enabling runtime PM to late suspend/early resume Currently, the PM core disables runtime PM for all devices right after executing subsystem/driver .suspend() callbacks for them and re-enables it right before executing subsystem/driver .resume() callbacks for them. This may lead to problems when there are two devices such that the .suspend() callback executed for one of them depends on runtime PM working for the other. In that case, if runtime PM has already been disabled for the second device, the first one's .suspend() won't work correctly (and analogously for resume). To make those issues go away, make the PM core disable runtime PM for devices right before executing subsystem/driver .suspend_late() callbacks for them and enable runtime PM for them right after executing subsystem/driver .resume_early() callbacks for them. This way the potential conflitcs between .suspend_late()/.resume_early() and their runtime PM counterparts are still prevented from happening, but the subtle ordering issues related to disabling/enabling runtime PM for devices during system suspend/resume are much easier to avoid. Reported-and-tested-by: Jan-Matthias Braun Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson Reviewed-by: Kevin Hilman Cc: 3.4+ --- Documentation/power/runtime_pm.txt | 9 +++++---- drivers/base/power/main.c | 9 ++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 4abe83e1045..03591a750f9 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -642,12 +642,13 @@ out the following operations: * During system suspend it calls pm_runtime_get_noresume() and pm_runtime_barrier() for every device right before executing the subsystem-level .suspend() callback for it. In addition to that it calls - pm_runtime_disable() for every device right after executing the - subsystem-level .suspend() callback for it. + __pm_runtime_disable() with 'false' as the second argument for every device + right before executing the subsystem-level .suspend_late() callback for it. * 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 - .resume() callback for it, respectively. + for every device right after executing the subsystem-level .resume_early() + callback and right after executing the subsystem-level .resume() callback + for it, respectively. 7. Generic subsystem callbacks diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index a3c1404c793..2b7f77d3fcb 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -513,6 +513,8 @@ static int device_resume_early(struct device *dev, pm_message_t state) Out: TRACE_RESUME(error); + + pm_runtime_enable(dev); return error; } @@ -589,8 +591,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) if (!dev->power.is_suspended) goto Unlock; - pm_runtime_enable(dev); - if (dev->pm_domain) { info = "power domain "; callback = pm_op(&dev->pm_domain->ops, state); @@ -930,6 +930,8 @@ static int device_suspend_late(struct device *dev, pm_message_t state) pm_callback_t callback = NULL; char *info = NULL; + __pm_runtime_disable(dev, false); + if (dev->power.syscore) return 0; @@ -1133,11 +1135,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) Complete: complete_all(&dev->power.completion); - if (error) async_error = error; - else if (dev->power.is_suspended) - __pm_runtime_disable(dev, false); return error; } -- cgit v1.2.3-70-g09d2