diff options
234 files changed, 3111 insertions, 2503 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index 814b01354c41..b31e782bd985 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop | |||
| @@ -5,4 +5,15 @@ Contact: "Ike Panhc <ike.pan@canonical.com>" | |||
| 5 | Description: | 5 | Description: |
| 6 | Control the power of camera module. 1 means on, 0 means off. | 6 | Control the power of camera module. 1 means on, 0 means off. |
| 7 | 7 | ||
| 8 | What: /sys/devices/platform/ideapad/fan_mode | ||
| 9 | Date: June 2012 | ||
| 10 | KernelVersion: 3.6 | ||
| 11 | Contact: "Maxim Mikityanskiy <maxtram95@gmail.com>" | ||
| 12 | Description: | ||
| 13 | Change fan mode | ||
| 14 | There are four available modes: | ||
| 15 | * 0 -> Super Silent Mode | ||
| 16 | * 1 -> Standard Mode | ||
| 17 | * 2 -> Dust Cleaning | ||
| 18 | * 4 -> Efficient Thermal Dissipation Mode | ||
| 8 | 19 | ||
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt index d156e1b5db12..da80c2ae0915 100644 --- a/Documentation/devicetree/bindings/regulator/tps6586x.txt +++ b/Documentation/devicetree/bindings/regulator/tps6586x.txt | |||
| @@ -9,9 +9,9 @@ Required properties: | |||
| 9 | - regulators: list of regulators provided by this controller, must have | 9 | - regulators: list of regulators provided by this controller, must have |
| 10 | property "regulator-compatible" to match their hardware counterparts: | 10 | property "regulator-compatible" to match their hardware counterparts: |
| 11 | sm[0-2], ldo[0-9] and ldo_rtc | 11 | sm[0-2], ldo[0-9] and ldo_rtc |
| 12 | - sm0-supply: The input supply for the SM0. | 12 | - vin-sm0-supply: The input supply for the SM0. |
| 13 | - sm1-supply: The input supply for the SM1. | 13 | - vin-sm1-supply: The input supply for the SM1. |
| 14 | - sm2-supply: The input supply for the SM2. | 14 | - vin-sm2-supply: The input supply for the SM2. |
| 15 | - vinldo01-supply: The input supply for the LDO1 and LDO2 | 15 | - vinldo01-supply: The input supply for the LDO1 and LDO2 |
| 16 | - vinldo23-supply: The input supply for the LDO2 and LDO3 | 16 | - vinldo23-supply: The input supply for the LDO2 and LDO3 |
| 17 | - vinldo4-supply: The input supply for the LDO4 | 17 | - vinldo4-supply: The input supply for the LDO4 |
| @@ -30,9 +30,9 @@ Example: | |||
| 30 | #gpio-cells = <2>; | 30 | #gpio-cells = <2>; |
| 31 | gpio-controller; | 31 | gpio-controller; |
| 32 | 32 | ||
| 33 | sm0-supply = <&some_reg>; | 33 | vin-sm0-supply = <&some_reg>; |
| 34 | sm1-supply = <&some_reg>; | 34 | vin-sm1-supply = <&some_reg>; |
| 35 | sm2-supply = <&some_reg>; | 35 | vin-sm2-supply = <&some_reg>; |
| 36 | vinldo01-supply = <...>; | 36 | vinldo01-supply = <...>; |
| 37 | vinldo23-supply = <...>; | 37 | vinldo23-supply = <...>; |
| 38 | vinldo4-supply = <...>; | 38 | vinldo4-supply = <...>; |
diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm index 0403aaaba878..874a8ca93feb 100644 --- a/Documentation/w1/slaves/w1_therm +++ b/Documentation/w1/slaves/w1_therm | |||
| @@ -3,6 +3,7 @@ Kernel driver w1_therm | |||
| 3 | 3 | ||
| 4 | Supported chips: | 4 | Supported chips: |
| 5 | * Maxim ds18*20 based temperature sensors. | 5 | * Maxim ds18*20 based temperature sensors. |
| 6 | * Maxim ds1825 based temperature sensors. | ||
| 6 | 7 | ||
| 7 | Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 8 | Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
| 8 | 9 | ||
| @@ -15,6 +16,7 @@ supported family codes: | |||
| 15 | W1_THERM_DS18S20 0x10 | 16 | W1_THERM_DS18S20 0x10 |
| 16 | W1_THERM_DS1822 0x22 | 17 | W1_THERM_DS1822 0x22 |
| 17 | W1_THERM_DS18B20 0x28 | 18 | W1_THERM_DS18B20 0x28 |
| 19 | W1_THERM_DS1825 0x3B | ||
| 18 | 20 | ||
| 19 | Support is provided through the sysfs w1_slave file. Each open and | 21 | Support is provided through the sysfs w1_slave file. Each open and |
| 20 | read sequence will initiate a temperature conversion then provide two | 22 | read sequence will initiate a temperature conversion then provide two |
diff --git a/MAINTAINERS b/MAINTAINERS index 61ad79ea2b08..21372f36c158 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2217,7 +2217,7 @@ S: Maintained | |||
| 2217 | F: drivers/scsi/tmscsim.* | 2217 | F: drivers/scsi/tmscsim.* |
| 2218 | 2218 | ||
| 2219 | DC395x SCSI driver | 2219 | DC395x SCSI driver |
| 2220 | M: Oliver Neukum <oliver@neukum.name> | 2220 | M: Oliver Neukum <oliver@neukum.org> |
| 2221 | M: Ali Akcaagac <aliakc@web.de> | 2221 | M: Ali Akcaagac <aliakc@web.de> |
| 2222 | M: Jamie Lenehan <lenehan@twibble.org> | 2222 | M: Jamie Lenehan <lenehan@twibble.org> |
| 2223 | W: http://twibble.org/dist/dc395x/ | 2223 | W: http://twibble.org/dist/dc395x/ |
| @@ -4537,7 +4537,7 @@ S: Supported | |||
| 4537 | F: arch/microblaze/ | 4537 | F: arch/microblaze/ |
| 4538 | 4538 | ||
| 4539 | MICROTEK X6 SCANNER | 4539 | MICROTEK X6 SCANNER |
| 4540 | M: Oliver Neukum <oliver@neukum.name> | 4540 | M: Oliver Neukum <oliver@neukum.org> |
| 4541 | S: Maintained | 4541 | S: Maintained |
| 4542 | F: drivers/usb/image/microtek.* | 4542 | F: drivers/usb/image/microtek.* |
| 4543 | 4543 | ||
| @@ -7076,7 +7076,7 @@ F: include/linux/mtd/ubi.h | |||
| 7076 | F: include/mtd/ubi-user.h | 7076 | F: include/mtd/ubi-user.h |
| 7077 | 7077 | ||
| 7078 | USB ACM DRIVER | 7078 | USB ACM DRIVER |
| 7079 | M: Oliver Neukum <oliver@neukum.name> | 7079 | M: Oliver Neukum <oliver@neukum.org> |
| 7080 | L: linux-usb@vger.kernel.org | 7080 | L: linux-usb@vger.kernel.org |
| 7081 | S: Maintained | 7081 | S: Maintained |
| 7082 | F: Documentation/usb/acm.txt | 7082 | F: Documentation/usb/acm.txt |
| @@ -7097,7 +7097,7 @@ S: Supported | |||
| 7097 | F: drivers/block/ub.c | 7097 | F: drivers/block/ub.c |
| 7098 | 7098 | ||
| 7099 | USB CDC ETHERNET DRIVER | 7099 | USB CDC ETHERNET DRIVER |
| 7100 | M: Oliver Neukum <oliver@neukum.name> | 7100 | M: Oliver Neukum <oliver@neukum.org> |
| 7101 | L: linux-usb@vger.kernel.org | 7101 | L: linux-usb@vger.kernel.org |
| 7102 | S: Maintained | 7102 | S: Maintained |
| 7103 | F: drivers/net/usb/cdc_*.c | 7103 | F: drivers/net/usb/cdc_*.c |
| @@ -7170,7 +7170,7 @@ F: drivers/usb/host/isp116x* | |||
| 7170 | F: include/linux/usb/isp116x.h | 7170 | F: include/linux/usb/isp116x.h |
| 7171 | 7171 | ||
| 7172 | USB KAWASAKI LSI DRIVER | 7172 | USB KAWASAKI LSI DRIVER |
| 7173 | M: Oliver Neukum <oliver@neukum.name> | 7173 | M: Oliver Neukum <oliver@neukum.org> |
| 7174 | L: linux-usb@vger.kernel.org | 7174 | L: linux-usb@vger.kernel.org |
| 7175 | S: Maintained | 7175 | S: Maintained |
| 7176 | F: drivers/usb/serial/kl5kusb105.* | 7176 | F: drivers/usb/serial/kl5kusb105.* |
| @@ -7670,23 +7670,28 @@ S: Supported | |||
| 7670 | F: Documentation/hwmon/wm83?? | 7670 | F: Documentation/hwmon/wm83?? |
| 7671 | F: arch/arm/mach-s3c64xx/mach-crag6410* | 7671 | F: arch/arm/mach-s3c64xx/mach-crag6410* |
| 7672 | F: drivers/clk/clk-wm83*.c | 7672 | F: drivers/clk/clk-wm83*.c |
| 7673 | F: drivers/extcon/extcon-arizona.c | ||
| 7673 | F: drivers/leds/leds-wm83*.c | 7674 | F: drivers/leds/leds-wm83*.c |
| 7674 | F: drivers/gpio/gpio-*wm*.c | 7675 | F: drivers/gpio/gpio-*wm*.c |
| 7676 | F: drivers/gpio/gpio-arizona.c | ||
| 7675 | F: drivers/hwmon/wm83??-hwmon.c | 7677 | F: drivers/hwmon/wm83??-hwmon.c |
| 7676 | F: drivers/input/misc/wm831x-on.c | 7678 | F: drivers/input/misc/wm831x-on.c |
| 7677 | F: drivers/input/touchscreen/wm831x-ts.c | 7679 | F: drivers/input/touchscreen/wm831x-ts.c |
| 7678 | F: drivers/input/touchscreen/wm97*.c | 7680 | F: drivers/input/touchscreen/wm97*.c |
| 7679 | F: drivers/mfd/wm8*.c | 7681 | F: drivers/mfd/arizona* |
| 7682 | F: drivers/mfd/wm*.c | ||
| 7680 | F: drivers/power/wm83*.c | 7683 | F: drivers/power/wm83*.c |
| 7681 | F: drivers/rtc/rtc-wm83*.c | 7684 | F: drivers/rtc/rtc-wm83*.c |
| 7682 | F: drivers/regulator/wm8*.c | 7685 | F: drivers/regulator/wm8*.c |
| 7683 | F: drivers/video/backlight/wm83*_bl.c | 7686 | F: drivers/video/backlight/wm83*_bl.c |
| 7684 | F: drivers/watchdog/wm83*_wdt.c | 7687 | F: drivers/watchdog/wm83*_wdt.c |
| 7688 | F: include/linux/mfd/arizona/ | ||
| 7685 | F: include/linux/mfd/wm831x/ | 7689 | F: include/linux/mfd/wm831x/ |
| 7686 | F: include/linux/mfd/wm8350/ | 7690 | F: include/linux/mfd/wm8350/ |
| 7687 | F: include/linux/mfd/wm8400* | 7691 | F: include/linux/mfd/wm8400* |
| 7688 | F: include/linux/wm97xx.h | 7692 | F: include/linux/wm97xx.h |
| 7689 | F: include/sound/wm????.h | 7693 | F: include/sound/wm????.h |
| 7694 | F: sound/soc/codecs/arizona.? | ||
| 7690 | F: sound/soc/codecs/wm* | 7695 | F: sound/soc/codecs/wm* |
| 7691 | 7696 | ||
| 7692 | WORKQUEUE | 7697 | WORKQUEUE |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index d5b9b5e645cc..9944dedee5b1 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
| @@ -18,6 +18,8 @@ config ALPHA | |||
| 18 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 18 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 19 | select GENERIC_SMP_IDLE_THREAD | 19 | select GENERIC_SMP_IDLE_THREAD |
| 20 | select GENERIC_CMOS_UPDATE | 20 | select GENERIC_CMOS_UPDATE |
| 21 | select GENERIC_STRNCPY_FROM_USER | ||
| 22 | select GENERIC_STRNLEN_USER | ||
| 21 | help | 23 | help |
| 22 | The Alpha is a 64-bit general-purpose processor designed and | 24 | The Alpha is a 64-bit general-purpose processor designed and |
| 23 | marketed by the Digital Equipment Corporation of blessed memory, | 25 | marketed by the Digital Equipment Corporation of blessed memory, |
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index 3bb7ffeae3bc..c2cbe4fc391c 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) | 17 | #define ATOMIC_INIT(i) { (i) } |
| 18 | #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) | 18 | #define ATOMIC64_INIT(i) { (i) } |
| 19 | 19 | ||
| 20 | #define atomic_read(v) (*(volatile int *)&(v)->counter) | 20 | #define atomic_read(v) (*(volatile int *)&(v)->counter) |
| 21 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) | 21 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) |
diff --git a/arch/alpha/include/asm/fpu.h b/arch/alpha/include/asm/fpu.h index db00f7885faa..e477bcd5b94a 100644 --- a/arch/alpha/include/asm/fpu.h +++ b/arch/alpha/include/asm/fpu.h | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | #ifndef __ASM_ALPHA_FPU_H | 1 | #ifndef __ASM_ALPHA_FPU_H |
| 2 | #define __ASM_ALPHA_FPU_H | 2 | #define __ASM_ALPHA_FPU_H |
| 3 | 3 | ||
| 4 | #ifdef __KERNEL__ | ||
| 4 | #include <asm/special_insns.h> | 5 | #include <asm/special_insns.h> |
| 6 | #endif | ||
| 5 | 7 | ||
| 6 | /* | 8 | /* |
| 7 | * Alpha floating-point control register defines: | 9 | * Alpha floating-point control register defines: |
diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h index fd698a174f26..b87755a19554 100644 --- a/arch/alpha/include/asm/ptrace.h +++ b/arch/alpha/include/asm/ptrace.h | |||
| @@ -76,7 +76,10 @@ struct switch_stack { | |||
| 76 | #define task_pt_regs(task) \ | 76 | #define task_pt_regs(task) \ |
| 77 | ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) | 77 | ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) |
| 78 | 78 | ||
| 79 | #define force_successful_syscall_return() (task_pt_regs(current)->r0 = 0) | 79 | #define current_pt_regs() \ |
| 80 | ((struct pt_regs *) ((char *)current_thread_info() + 2*PAGE_SIZE) - 1) | ||
| 81 | |||
| 82 | #define force_successful_syscall_return() (current_pt_regs()->r0 = 0) | ||
| 80 | 83 | ||
| 81 | #endif | 84 | #endif |
| 82 | 85 | ||
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index dcb221a4b5be..7d2f75be932e 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
| @@ -76,9 +76,11 @@ | |||
| 76 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ | 76 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ |
| 77 | #define SO_NOFCS 43 | 77 | #define SO_NOFCS 43 |
| 78 | 78 | ||
| 79 | #ifdef __KERNEL__ | ||
| 79 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we | 80 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we |
| 80 | * have to define SOCK_NONBLOCK to a different value here. | 81 | * have to define SOCK_NONBLOCK to a different value here. |
| 81 | */ | 82 | */ |
| 82 | #define SOCK_NONBLOCK 0x40000000 | 83 | #define SOCK_NONBLOCK 0x40000000 |
| 84 | #endif /* __KERNEL__ */ | ||
| 83 | 85 | ||
| 84 | #endif /* _ASM_SOCKET_H */ | 86 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index b49ec2f8d6e3..766fdfde2b7a 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h | |||
| @@ -433,36 +433,12 @@ clear_user(void __user *to, long len) | |||
| 433 | #undef __module_address | 433 | #undef __module_address |
| 434 | #undef __module_call | 434 | #undef __module_call |
| 435 | 435 | ||
| 436 | /* Returns: -EFAULT if exception before terminator, N if the entire | 436 | #define user_addr_max() \ |
| 437 | buffer filled, else strlen. */ | 437 | (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) |
| 438 | 438 | ||
| 439 | extern long __strncpy_from_user(char *__to, const char __user *__from, long __to_len); | 439 | extern long strncpy_from_user(char *dest, const char __user *src, long count); |
| 440 | 440 | extern __must_check long strlen_user(const char __user *str); | |
| 441 | extern inline long | 441 | extern __must_check long strnlen_user(const char __user *str, long n); |
| 442 | strncpy_from_user(char *to, const char __user *from, long n) | ||
| 443 | { | ||
| 444 | long ret = -EFAULT; | ||
| 445 | if (__access_ok((unsigned long)from, 0, get_fs())) | ||
| 446 | ret = __strncpy_from_user(to, from, n); | ||
| 447 | return ret; | ||
| 448 | } | ||
| 449 | |||
| 450 | /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ | ||
| 451 | extern long __strlen_user(const char __user *); | ||
| 452 | |||
| 453 | extern inline long strlen_user(const char __user *str) | ||
| 454 | { | ||
| 455 | return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | /* Returns: 0 if exception before NUL or reaching the supplied limit (N), | ||
| 459 | * a value greater than N if the limit would be exceeded, else strlen. */ | ||
| 460 | extern long __strnlen_user(const char __user *, long); | ||
| 461 | |||
| 462 | extern inline long strnlen_user(const char __user *str, long n) | ||
| 463 | { | ||
| 464 | return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0; | ||
| 465 | } | ||
| 466 | 442 | ||
| 467 | /* | 443 | /* |
| 468 | * About the exception table: | 444 | * About the exception table: |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 633b23b0664a..a31a78eac9b9 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
| @@ -465,10 +465,12 @@ | |||
| 465 | #define __NR_setns 501 | 465 | #define __NR_setns 501 |
| 466 | #define __NR_accept4 502 | 466 | #define __NR_accept4 502 |
| 467 | #define __NR_sendmmsg 503 | 467 | #define __NR_sendmmsg 503 |
| 468 | #define __NR_process_vm_readv 504 | ||
| 469 | #define __NR_process_vm_writev 505 | ||
| 468 | 470 | ||
| 469 | #ifdef __KERNEL__ | 471 | #ifdef __KERNEL__ |
| 470 | 472 | ||
| 471 | #define NR_SYSCALLS 504 | 473 | #define NR_SYSCALLS 506 |
| 472 | 474 | ||
| 473 | #define __ARCH_WANT_OLD_READDIR | 475 | #define __ARCH_WANT_OLD_READDIR |
| 474 | #define __ARCH_WANT_STAT64 | 476 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/alpha/include/asm/word-at-a-time.h b/arch/alpha/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..6b340d0f1521 --- /dev/null +++ b/arch/alpha/include/asm/word-at-a-time.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #ifndef _ASM_WORD_AT_A_TIME_H | ||
| 2 | #define _ASM_WORD_AT_A_TIME_H | ||
| 3 | |||
| 4 | #include <asm/compiler.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * word-at-a-time interface for Alpha. | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * We do not use the word_at_a_time struct on Alpha, but it needs to be | ||
| 12 | * implemented to humour the generic code. | ||
| 13 | */ | ||
| 14 | struct word_at_a_time { | ||
| 15 | const unsigned long unused; | ||
| 16 | }; | ||
| 17 | |||
| 18 | #define WORD_AT_A_TIME_CONSTANTS { 0 } | ||
| 19 | |||
| 20 | /* Return nonzero if val has a zero */ | ||
| 21 | static inline unsigned long has_zero(unsigned long val, unsigned long *bits, const struct word_at_a_time *c) | ||
| 22 | { | ||
| 23 | unsigned long zero_locations = __kernel_cmpbge(0, val); | ||
| 24 | *bits = zero_locations; | ||
| 25 | return zero_locations; | ||
| 26 | } | ||
| 27 | |||
| 28 | static inline unsigned long prep_zero_mask(unsigned long val, unsigned long bits, const struct word_at_a_time *c) | ||
| 29 | { | ||
| 30 | return bits; | ||
| 31 | } | ||
| 32 | |||
| 33 | #define create_zero_mask(bits) (bits) | ||
| 34 | |||
| 35 | static inline unsigned long find_zero(unsigned long bits) | ||
| 36 | { | ||
| 37 | #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67) | ||
| 38 | /* Simple if have CIX instructions */ | ||
| 39 | return __kernel_cttz(bits); | ||
| 40 | #else | ||
| 41 | unsigned long t1, t2, t3; | ||
| 42 | /* Retain lowest set bit only */ | ||
| 43 | bits &= -bits; | ||
| 44 | /* Binary search for lowest set bit */ | ||
| 45 | t1 = bits & 0xf0; | ||
| 46 | t2 = bits & 0xcc; | ||
| 47 | t3 = bits & 0xaa; | ||
| 48 | if (t1) t1 = 4; | ||
| 49 | if (t2) t2 = 2; | ||
| 50 | if (t3) t3 = 1; | ||
| 51 | return t1 + t2 + t3; | ||
| 52 | #endif | ||
| 53 | } | ||
| 54 | |||
| 55 | #endif /* _ASM_WORD_AT_A_TIME_H */ | ||
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d96e742d4dc2..15fa821d09cd 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c | |||
| @@ -52,7 +52,6 @@ EXPORT_SYMBOL(alpha_write_fp_reg_s); | |||
| 52 | 52 | ||
| 53 | /* entry.S */ | 53 | /* entry.S */ |
| 54 | EXPORT_SYMBOL(kernel_thread); | 54 | EXPORT_SYMBOL(kernel_thread); |
| 55 | EXPORT_SYMBOL(kernel_execve); | ||
| 56 | 55 | ||
| 57 | /* Networking helper routines. */ | 56 | /* Networking helper routines. */ |
| 58 | EXPORT_SYMBOL(csum_tcpudp_magic); | 57 | EXPORT_SYMBOL(csum_tcpudp_magic); |
| @@ -74,8 +73,6 @@ EXPORT_SYMBOL(alpha_fp_emul); | |||
| 74 | */ | 73 | */ |
| 75 | EXPORT_SYMBOL(__copy_user); | 74 | EXPORT_SYMBOL(__copy_user); |
| 76 | EXPORT_SYMBOL(__do_clear_user); | 75 | EXPORT_SYMBOL(__do_clear_user); |
| 77 | EXPORT_SYMBOL(__strncpy_from_user); | ||
| 78 | EXPORT_SYMBOL(__strnlen_user); | ||
| 79 | 76 | ||
| 80 | /* | 77 | /* |
| 81 | * SMP-specific symbols. | 78 | * SMP-specific symbols. |
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 6d159cee5f2f..ec0da0567ab5 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
| @@ -663,58 +663,6 @@ kernel_thread: | |||
| 663 | br ret_to_kernel | 663 | br ret_to_kernel |
| 664 | .end kernel_thread | 664 | .end kernel_thread |
| 665 | 665 | ||
| 666 | /* | ||
| 667 | * kernel_execve(path, argv, envp) | ||
| 668 | */ | ||
| 669 | .align 4 | ||
| 670 | .globl kernel_execve | ||
| 671 | .ent kernel_execve | ||
| 672 | kernel_execve: | ||
| 673 | /* We can be called from a module. */ | ||
| 674 | ldgp $gp, 0($27) | ||
| 675 | lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) | ||
| 676 | .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0 | ||
| 677 | stq $26, 0($sp) | ||
| 678 | stq $16, 8($sp) | ||
| 679 | stq $17, 16($sp) | ||
| 680 | stq $18, 24($sp) | ||
| 681 | .prologue 1 | ||
| 682 | |||
| 683 | lda $16, 32($sp) | ||
| 684 | lda $17, 0 | ||
| 685 | lda $18, SIZEOF_PT_REGS | ||
| 686 | bsr $26, memset !samegp | ||
| 687 | |||
| 688 | /* Avoid the HAE being gratuitously wrong, which would cause us | ||
| 689 | to do the whole turn off interrupts thing and restore it. */ | ||
| 690 | ldq $2, alpha_mv+HAE_CACHE | ||
| 691 | stq $2, 152+32($sp) | ||
| 692 | |||
| 693 | ldq $16, 8($sp) | ||
| 694 | ldq $17, 16($sp) | ||
| 695 | ldq $18, 24($sp) | ||
| 696 | lda $19, 32($sp) | ||
| 697 | bsr $26, do_execve !samegp | ||
| 698 | |||
| 699 | ldq $26, 0($sp) | ||
| 700 | bne $0, 1f /* error! */ | ||
| 701 | |||
| 702 | /* Move the temporary pt_regs struct from its current location | ||
| 703 | to the top of the kernel stack frame. See copy_thread for | ||
| 704 | details for a normal process. */ | ||
| 705 | lda $16, 0x4000 - SIZEOF_PT_REGS($8) | ||
| 706 | lda $17, 32($sp) | ||
| 707 | lda $18, SIZEOF_PT_REGS | ||
| 708 | bsr $26, memmove !samegp | ||
| 709 | |||
| 710 | /* Take that over as our new stack frame and visit userland! */ | ||
| 711 | lda $sp, 0x4000 - SIZEOF_PT_REGS($8) | ||
| 712 | br $31, ret_from_sys_call | ||
| 713 | |||
| 714 | 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) | ||
| 715 | ret | ||
| 716 | .end kernel_execve | ||
| 717 | |||
| 718 | 666 | ||
| 719 | /* | 667 | /* |
| 720 | * Special system calls. Most of these are special in that they either | 668 | * Special system calls. Most of these are special in that they either |
| @@ -797,115 +745,6 @@ sys_rt_sigreturn: | |||
| 797 | .end sys_rt_sigreturn | 745 | .end sys_rt_sigreturn |
| 798 | 746 | ||
| 799 | .align 4 | 747 | .align 4 |
| 800 | .globl sys_sethae | ||
| 801 | .ent sys_sethae | ||
| 802 | sys_sethae: | ||
| 803 | .prologue 0 | ||
| 804 | stq $16, 152($sp) | ||
| 805 | ret | ||
| 806 | .end sys_sethae | ||
| 807 | |||
| 808 | .align 4 | ||
| 809 | .globl osf_getpriority | ||
| 810 | .ent osf_getpriority | ||
| 811 | osf_getpriority: | ||
| 812 | lda $sp, -16($sp) | ||
| 813 | stq $26, 0($sp) | ||
| 814 | .prologue 0 | ||
| 815 | |||
| 816 | jsr $26, sys_getpriority | ||
| 817 | |||
| 818 | ldq $26, 0($sp) | ||
| 819 | blt $0, 1f | ||
| 820 | |||
| 821 | /* Return value is the unbiased priority, i.e. 20 - prio. | ||
| 822 | This does result in negative return values, so signal | ||
| 823 | no error by writing into the R0 slot. */ | ||
| 824 | lda $1, 20 | ||
| 825 | stq $31, 16($sp) | ||
| 826 | subl $1, $0, $0 | ||
| 827 | unop | ||
| 828 | |||
| 829 | 1: lda $sp, 16($sp) | ||
| 830 | ret | ||
| 831 | .end osf_getpriority | ||
| 832 | |||
| 833 | .align 4 | ||
| 834 | .globl sys_getxuid | ||
| 835 | .ent sys_getxuid | ||
| 836 | sys_getxuid: | ||
| 837 | .prologue 0 | ||
| 838 | ldq $2, TI_TASK($8) | ||
| 839 | ldq $3, TASK_CRED($2) | ||
| 840 | ldl $0, CRED_UID($3) | ||
| 841 | ldl $1, CRED_EUID($3) | ||
| 842 | stq $1, 80($sp) | ||
| 843 | ret | ||
| 844 | .end sys_getxuid | ||
| 845 | |||
| 846 | .align 4 | ||
| 847 | .globl sys_getxgid | ||
| 848 | .ent sys_getxgid | ||
| 849 | sys_getxgid: | ||
| 850 | .prologue 0 | ||
| 851 | ldq $2, TI_TASK($8) | ||
| 852 | ldq $3, TASK_CRED($2) | ||
| 853 | ldl $0, CRED_GID($3) | ||
| 854 | ldl $1, CRED_EGID($3) | ||
| 855 | stq $1, 80($sp) | ||
| 856 | ret | ||
| 857 | .end sys_getxgid | ||
| 858 | |||
| 859 | .align 4 | ||
| 860 | .globl sys_getxpid | ||
| 861 | .ent sys_getxpid | ||
| 862 | sys_getxpid: | ||
| 863 | .prologue 0 | ||
| 864 | ldq $2, TI_TASK($8) | ||
| 865 | |||
| 866 | /* See linux/kernel/timer.c sys_getppid for discussion | ||
| 867 | about this loop. */ | ||
| 868 | ldq $3, TASK_GROUP_LEADER($2) | ||
| 869 | ldq $4, TASK_REAL_PARENT($3) | ||
| 870 | ldl $0, TASK_TGID($2) | ||
| 871 | 1: ldl $1, TASK_TGID($4) | ||
| 872 | #ifdef CONFIG_SMP | ||
| 873 | mov $4, $5 | ||
| 874 | mb | ||
| 875 | ldq $3, TASK_GROUP_LEADER($2) | ||
| 876 | ldq $4, TASK_REAL_PARENT($3) | ||
| 877 | cmpeq $4, $5, $5 | ||
| 878 | beq $5, 1b | ||
| 879 | #endif | ||
| 880 | stq $1, 80($sp) | ||
| 881 | ret | ||
| 882 | .end sys_getxpid | ||
| 883 | |||
| 884 | .align 4 | ||
| 885 | .globl sys_alpha_pipe | ||
| 886 | .ent sys_alpha_pipe | ||
| 887 | sys_alpha_pipe: | ||
| 888 | lda $sp, -16($sp) | ||
| 889 | stq $26, 0($sp) | ||
| 890 | .prologue 0 | ||
| 891 | |||
| 892 | mov $31, $17 | ||
| 893 | lda $16, 8($sp) | ||
| 894 | jsr $26, do_pipe_flags | ||
| 895 | |||
| 896 | ldq $26, 0($sp) | ||
| 897 | bne $0, 1f | ||
| 898 | |||
| 899 | /* The return values are in $0 and $20. */ | ||
| 900 | ldl $1, 12($sp) | ||
| 901 | ldl $0, 8($sp) | ||
| 902 | |||
| 903 | stq $1, 80+16($sp) | ||
| 904 | 1: lda $sp, 16($sp) | ||
| 905 | ret | ||
| 906 | .end sys_alpha_pipe | ||
| 907 | |||
| 908 | .align 4 | ||
| 909 | .globl sys_execve | 748 | .globl sys_execve |
| 910 | .ent sys_execve | 749 | .ent sys_execve |
| 911 | sys_execve: | 750 | sys_execve: |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 98a103621af6..bc1acdda7a5e 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
| @@ -1404,3 +1404,52 @@ SYSCALL_DEFINE3(osf_writev, unsigned long, fd, | |||
| 1404 | } | 1404 | } |
| 1405 | 1405 | ||
| 1406 | #endif | 1406 | #endif |
| 1407 | |||
| 1408 | SYSCALL_DEFINE2(osf_getpriority, int, which, int, who) | ||
| 1409 | { | ||
| 1410 | int prio = sys_getpriority(which, who); | ||
| 1411 | if (prio >= 0) { | ||
| 1412 | /* Return value is the unbiased priority, i.e. 20 - prio. | ||
| 1413 | This does result in negative return values, so signal | ||
| 1414 | no error */ | ||
| 1415 | force_successful_syscall_return(); | ||
| 1416 | prio = 20 - prio; | ||
| 1417 | } | ||
| 1418 | return prio; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | SYSCALL_DEFINE0(getxuid) | ||
| 1422 | { | ||
| 1423 | current_pt_regs()->r20 = sys_geteuid(); | ||
| 1424 | return sys_getuid(); | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | SYSCALL_DEFINE0(getxgid) | ||
| 1428 | { | ||
| 1429 | current_pt_regs()->r20 = sys_getegid(); | ||
| 1430 | return sys_getgid(); | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | SYSCALL_DEFINE0(getxpid) | ||
| 1434 | { | ||
| 1435 | current_pt_regs()->r20 = sys_getppid(); | ||
| 1436 | return sys_getpid(); | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | SYSCALL_DEFINE0(alpha_pipe) | ||
| 1440 | { | ||
| 1441 | int fd[2]; | ||
| 1442 | int res = do_pipe_flags(fd, 0); | ||
| 1443 | if (!res) { | ||
| 1444 | /* The return values are in $0 and $20. */ | ||
| 1445 | current_pt_regs()->r20 = fd[1]; | ||
| 1446 | res = fd[0]; | ||
| 1447 | } | ||
| 1448 | return res; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | SYSCALL_DEFINE1(sethae, unsigned long, val) | ||
| 1452 | { | ||
| 1453 | current_pt_regs()->hae = val; | ||
| 1454 | return 0; | ||
| 1455 | } | ||
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 153d3fce3e8e..d6fde98b74b3 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
| @@ -455,3 +455,22 @@ get_wchan(struct task_struct *p) | |||
| 455 | } | 455 | } |
| 456 | return pc; | 456 | return pc; |
| 457 | } | 457 | } |
| 458 | |||
| 459 | int kernel_execve(const char *path, const char *const argv[], const char *const envp[]) | ||
| 460 | { | ||
| 461 | /* Avoid the HAE being gratuitously wrong, which would cause us | ||
| 462 | to do the whole turn off interrupts thing and restore it. */ | ||
| 463 | struct pt_regs regs = {.hae = alpha_mv.hae_cache}; | ||
| 464 | int err = do_execve(path, argv, envp, ®s); | ||
| 465 | if (!err) { | ||
| 466 | struct pt_regs *p = current_pt_regs(); | ||
| 467 | /* copy regs to normal position and off to userland we go... */ | ||
| 468 | *p = regs; | ||
| 469 | __asm__ __volatile__ ( | ||
| 470 | "mov %0, $sp;" | ||
| 471 | "br $31, ret_from_sys_call" | ||
| 472 | : : "r"(p)); | ||
| 473 | } | ||
| 474 | return err; | ||
| 475 | } | ||
| 476 | EXPORT_SYMBOL(kernel_execve); | ||
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 87835235f114..2ac6b45c3e00 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
| @@ -111,7 +111,7 @@ sys_call_table: | |||
| 111 | .quad sys_socket | 111 | .quad sys_socket |
| 112 | .quad sys_connect | 112 | .quad sys_connect |
| 113 | .quad sys_accept | 113 | .quad sys_accept |
| 114 | .quad osf_getpriority /* 100 */ | 114 | .quad sys_osf_getpriority /* 100 */ |
| 115 | .quad sys_send | 115 | .quad sys_send |
| 116 | .quad sys_recv | 116 | .quad sys_recv |
| 117 | .quad sys_sigreturn | 117 | .quad sys_sigreturn |
| @@ -522,6 +522,8 @@ sys_call_table: | |||
| 522 | .quad sys_setns | 522 | .quad sys_setns |
| 523 | .quad sys_accept4 | 523 | .quad sys_accept4 |
| 524 | .quad sys_sendmmsg | 524 | .quad sys_sendmmsg |
| 525 | .quad sys_process_vm_readv | ||
| 526 | .quad sys_process_vm_writev /* 505 */ | ||
| 525 | 527 | ||
| 526 | .size sys_call_table, . - sys_call_table | 528 | .size sys_call_table, . - sys_call_table |
| 527 | .type sys_call_table, @object | 529 | .type sys_call_table, @object |
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index c0a83ab62b78..59660743237c 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile | |||
| @@ -31,8 +31,6 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ | |||
| 31 | $(ev6-y)memchr.o \ | 31 | $(ev6-y)memchr.o \ |
| 32 | $(ev6-y)copy_user.o \ | 32 | $(ev6-y)copy_user.o \ |
| 33 | $(ev6-y)clear_user.o \ | 33 | $(ev6-y)clear_user.o \ |
| 34 | $(ev6-y)strncpy_from_user.o \ | ||
| 35 | $(ev67-y)strlen_user.o \ | ||
| 36 | $(ev6-y)csum_ipv6_magic.o \ | 34 | $(ev6-y)csum_ipv6_magic.o \ |
| 37 | $(ev6-y)clear_page.o \ | 35 | $(ev6-y)clear_page.o \ |
| 38 | $(ev6-y)copy_page.o \ | 36 | $(ev6-y)copy_page.o \ |
diff --git a/arch/alpha/lib/ev6-strncpy_from_user.S b/arch/alpha/lib/ev6-strncpy_from_user.S deleted file mode 100644 index d2e28178cacc..000000000000 --- a/arch/alpha/lib/ev6-strncpy_from_user.S +++ /dev/null | |||
| @@ -1,424 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/alpha/lib/ev6-strncpy_from_user.S | ||
| 3 | * 21264 version contributed by Rick Gorton <rick.gorton@alpha-processor.com> | ||
| 4 | * | ||
| 5 | * Just like strncpy except in the return value: | ||
| 6 | * | ||
| 7 | * -EFAULT if an exception occurs before the terminator is copied. | ||
| 8 | * N if the buffer filled. | ||
| 9 | * | ||
| 10 | * Otherwise the length of the string is returned. | ||
| 11 | * | ||
| 12 | * Much of the information about 21264 scheduling/coding comes from: | ||
| 13 | * Compiler Writer's Guide for the Alpha 21264 | ||
| 14 | * abbreviated as 'CWG' in other comments here | ||
| 15 | * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html | ||
| 16 | * Scheduling notation: | ||
| 17 | * E - either cluster | ||
| 18 | * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1 | ||
| 19 | * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 | ||
| 20 | * A bunch of instructions got moved and temp registers were changed | ||
| 21 | * to aid in scheduling. Control flow was also re-arranged to eliminate | ||
| 22 | * branches, and to provide longer code sequences to enable better scheduling. | ||
| 23 | * A total rewrite (using byte load/stores for start & tail sequences) | ||
| 24 | * is desirable, but very difficult to do without a from-scratch rewrite. | ||
| 25 | * Save that for the future. | ||
| 26 | */ | ||
| 27 | |||
| 28 | |||
| 29 | #include <asm/errno.h> | ||
| 30 | #include <asm/regdef.h> | ||
| 31 | |||
| 32 | |||
| 33 | /* Allow an exception for an insn; exit if we get one. */ | ||
| 34 | #define EX(x,y...) \ | ||
| 35 | 99: x,##y; \ | ||
| 36 | .section __ex_table,"a"; \ | ||
| 37 | .long 99b - .; \ | ||
| 38 | lda $31, $exception-99b($0); \ | ||
| 39 | .previous | ||
| 40 | |||
| 41 | |||
| 42 | .set noat | ||
| 43 | .set noreorder | ||
| 44 | .text | ||
| 45 | |||
| 46 | .globl __strncpy_from_user | ||
| 47 | .ent __strncpy_from_user | ||
| 48 | .frame $30, 0, $26 | ||
| 49 | .prologue 0 | ||
| 50 | |||
| 51 | .align 4 | ||
| 52 | __strncpy_from_user: | ||
| 53 | and a0, 7, t3 # E : find dest misalignment | ||
| 54 | beq a2, $zerolength # U : | ||
| 55 | |||
| 56 | /* Are source and destination co-aligned? */ | ||
| 57 | mov a0, v0 # E : save the string start | ||
| 58 | xor a0, a1, t4 # E : | ||
| 59 | EX( ldq_u t1, 0(a1) ) # L : Latency=3 load first quadword | ||
| 60 | ldq_u t0, 0(a0) # L : load first (partial) aligned dest quadword | ||
| 61 | |||
| 62 | addq a2, t3, a2 # E : bias count by dest misalignment | ||
| 63 | subq a2, 1, a3 # E : | ||
| 64 | addq zero, 1, t10 # E : | ||
| 65 | and t4, 7, t4 # E : misalignment between the two | ||
| 66 | |||
| 67 | and a3, 7, t6 # E : number of tail bytes | ||
| 68 | sll t10, t6, t10 # E : t10 = bitmask of last count byte | ||
| 69 | bne t4, $unaligned # U : | ||
| 70 | lda t2, -1 # E : build a mask against false zero | ||
| 71 | |||
| 72 | /* | ||
| 73 | * We are co-aligned; take care of a partial first word. | ||
| 74 | * On entry to this basic block: | ||
| 75 | * t0 == the first destination word for masking back in | ||
| 76 | * t1 == the first source word. | ||
| 77 | */ | ||
| 78 | |||
| 79 | srl a3, 3, a2 # E : a2 = loop counter = (count - 1)/8 | ||
| 80 | addq a1, 8, a1 # E : | ||
| 81 | mskqh t2, a1, t2 # U : detection in the src word | ||
| 82 | nop | ||
| 83 | |||
| 84 | /* Create the 1st output word and detect 0's in the 1st input word. */ | ||
| 85 | mskqh t1, a1, t3 # U : | ||
| 86 | mskql t0, a1, t0 # U : assemble the first output word | ||
| 87 | ornot t1, t2, t2 # E : | ||
| 88 | nop | ||
| 89 | |||
| 90 | cmpbge zero, t2, t8 # E : bits set iff null found | ||
| 91 | or t0, t3, t0 # E : | ||
| 92 | beq a2, $a_eoc # U : | ||
| 93 | bne t8, $a_eos # U : 2nd branch in a quad. Bad. | ||
| 94 | |||
| 95 | /* On entry to this basic block: | ||
| 96 | * t0 == a source quad not containing a null. | ||
| 97 | * a0 - current aligned destination address | ||
| 98 | * a1 - current aligned source address | ||
| 99 | * a2 - count of quadwords to move. | ||
| 100 | * NOTE: Loop improvement - unrolling this is going to be | ||
| 101 | * a huge win, since we're going to stall otherwise. | ||
| 102 | * Fix this later. For _really_ large copies, look | ||
| 103 | * at using wh64 on a look-ahead basis. See the code | ||
| 104 | * in clear_user.S and copy_user.S. | ||
| 105 | * Presumably, since (a0) and (a1) do not overlap (by C definition) | ||
| 106 | * Lots of nops here: | ||
| 107 | * - Separate loads from stores | ||
| 108 | * - Keep it to 1 branch/quadpack so the branch predictor | ||
| 109 | * can train. | ||
| 110 | */ | ||
| 111 | $a_loop: | ||
| 112 | stq_u t0, 0(a0) # L : | ||
| 113 | addq a0, 8, a0 # E : | ||
| 114 | nop | ||
| 115 | subq a2, 1, a2 # E : | ||
| 116 | |||
| 117 | EX( ldq_u t0, 0(a1) ) # L : | ||
| 118 | addq a1, 8, a1 # E : | ||
| 119 | cmpbge zero, t0, t8 # E : Stall 2 cycles on t0 | ||
| 120 | beq a2, $a_eoc # U : | ||
| 121 | |||
| 122 | beq t8, $a_loop # U : | ||
| 123 | nop | ||
| 124 | nop | ||
| 125 | nop | ||
| 126 | |||
| 127 | /* Take care of the final (partial) word store. At this point | ||
| 128 | * the end-of-count bit is set in t8 iff it applies. | ||
| 129 | * | ||
| 130 | * On entry to this basic block we have: | ||
| 131 | * t0 == the source word containing the null | ||
| 132 | * t8 == the cmpbge mask that found it. | ||
| 133 | */ | ||
| 134 | $a_eos: | ||
| 135 | negq t8, t12 # E : find low bit set | ||
| 136 | and t8, t12, t12 # E : | ||
| 137 | |||
| 138 | /* We're doing a partial word store and so need to combine | ||
| 139 | our source and original destination words. */ | ||
| 140 | ldq_u t1, 0(a0) # L : | ||
| 141 | subq t12, 1, t6 # E : | ||
| 142 | |||
| 143 | or t12, t6, t8 # E : | ||
| 144 | zapnot t0, t8, t0 # U : clear src bytes > null | ||
| 145 | zap t1, t8, t1 # U : clear dst bytes <= null | ||
| 146 | or t0, t1, t0 # E : | ||
| 147 | |||
| 148 | stq_u t0, 0(a0) # L : | ||
| 149 | br $finish_up # L0 : | ||
| 150 | nop | ||
| 151 | nop | ||
| 152 | |||
| 153 | /* Add the end-of-count bit to the eos detection bitmask. */ | ||
| 154 | .align 4 | ||
| 155 | $a_eoc: | ||
| 156 | or t10, t8, t8 | ||
| 157 | br $a_eos | ||
| 158 | nop | ||
| 159 | nop | ||
| 160 | |||
| 161 | |||
| 162 | /* The source and destination are not co-aligned. Align the destination | ||
| 163 | and cope. We have to be very careful about not reading too much and | ||
| 164 | causing a SEGV. */ | ||
| 165 | |||
| 166 | .align 4 | ||
| 167 | $u_head: | ||
| 168 | /* We know just enough now to be able to assemble the first | ||
| 169 | full source word. We can still find a zero at the end of it | ||
| 170 | that prevents us from outputting the whole thing. | ||
| 171 | |||
| 172 | On entry to this basic block: | ||
| 173 | t0 == the first dest word, unmasked | ||
| 174 | t1 == the shifted low bits of the first source word | ||
| 175 | t6 == bytemask that is -1 in dest word bytes */ | ||
| 176 | |||
| 177 | EX( ldq_u t2, 8(a1) ) # L : load second src word | ||
| 178 | addq a1, 8, a1 # E : | ||
| 179 | mskql t0, a0, t0 # U : mask trailing garbage in dst | ||
| 180 | extqh t2, a1, t4 # U : | ||
| 181 | |||
| 182 | or t1, t4, t1 # E : first aligned src word complete | ||
| 183 | mskqh t1, a0, t1 # U : mask leading garbage in src | ||
| 184 | or t0, t1, t0 # E : first output word complete | ||
| 185 | or t0, t6, t6 # E : mask original data for zero test | ||
| 186 | |||
| 187 | cmpbge zero, t6, t8 # E : | ||
| 188 | beq a2, $u_eocfin # U : | ||
| 189 | bne t8, $u_final # U : bad news - 2nd branch in a quad | ||
| 190 | lda t6, -1 # E : mask out the bits we have | ||
| 191 | |||
| 192 | mskql t6, a1, t6 # U : already seen | ||
| 193 | stq_u t0, 0(a0) # L : store first output word | ||
| 194 | or t6, t2, t2 # E : | ||
| 195 | cmpbge zero, t2, t8 # E : find nulls in second partial | ||
| 196 | |||
| 197 | addq a0, 8, a0 # E : | ||
| 198 | subq a2, 1, a2 # E : | ||
| 199 | bne t8, $u_late_head_exit # U : | ||
| 200 | nop | ||
| 201 | |||
| 202 | /* Finally, we've got all the stupid leading edge cases taken care | ||
| 203 | of and we can set up to enter the main loop. */ | ||
| 204 | |||
| 205 | extql t2, a1, t1 # U : position hi-bits of lo word | ||
| 206 | EX( ldq_u t2, 8(a1) ) # L : read next high-order source word | ||
| 207 | addq a1, 8, a1 # E : | ||
| 208 | cmpbge zero, t2, t8 # E : | ||
| 209 | |||
| 210 | beq a2, $u_eoc # U : | ||
| 211 | bne t8, $u_eos # U : | ||
| 212 | nop | ||
| 213 | nop | ||
| 214 | |||
| 215 | /* Unaligned copy main loop. In order to avoid reading too much, | ||
| 216 | the loop is structured to detect zeros in aligned source words. | ||
| 217 | This has, unfortunately, effectively pulled half of a loop | ||
| 218 | iteration out into the head and half into the tail, but it does | ||
| 219 | prevent nastiness from accumulating in the very thing we want | ||
| 220 | to run as fast as possible. | ||
| 221 | |||
| 222 | On entry to this basic block: | ||
| 223 | t1 == the shifted high-order bits from the previous source word | ||
| 224 | t2 == the unshifted current source word | ||
| 225 | |||
| 226 | We further know that t2 does not contain a null terminator. */ | ||
| 227 | |||
| 228 | /* | ||
| 229 | * Extra nops here: | ||
| 230 | * separate load quads from store quads | ||
| 231 | * only one branch/quad to permit predictor training | ||
| 232 | */ | ||
| 233 | |||
| 234 | .align 4 | ||
| 235 | $u_loop: | ||
| 236 | extqh t2, a1, t0 # U : extract high bits for current word | ||
| 237 | addq a1, 8, a1 # E : | ||
| 238 | extql t2, a1, t3 # U : extract low bits for next time | ||
| 239 | addq a0, 8, a0 # E : | ||
| 240 | |||
| 241 | or t0, t1, t0 # E : current dst word now complete | ||
| 242 | EX( ldq_u t2, 0(a1) ) # L : load high word for next time | ||
| 243 | subq a2, 1, a2 # E : | ||
| 244 | nop | ||
| 245 | |||
| 246 | stq_u t0, -8(a0) # L : save the current word | ||
| 247 | mov t3, t1 # E : | ||
| 248 | cmpbge zero, t2, t8 # E : test new word for eos | ||
| 249 | beq a2, $u_eoc # U : | ||
| 250 | |||
| 251 | beq t8, $u_loop # U : | ||
| 252 | nop | ||
| 253 | nop | ||
| 254 | nop | ||
| 255 | |||
| 256 | /* We've found a zero somewhere in the source word we just read. | ||
| 257 | If it resides in the lower half, we have one (probably partial) | ||
| 258 | word to write out, and if it resides in the upper half, we | ||
| 259 | have one full and one partial word left to write out. | ||
| 260 | |||
| 261 | On entry to this basic block: | ||
| 262 | t1 == the shifted high-order bits from the previous source word | ||
| 263 | t2 == the unshifted current source word. */ | ||
| 264 | .align 4 | ||
| 265 | $u_eos: | ||
| 266 | extqh t2, a1, t0 # U : | ||
| 267 | or t0, t1, t0 # E : first (partial) source word complete | ||
| 268 | cmpbge zero, t0, t8 # E : is the null in this first bit? | ||
| 269 | nop | ||
| 270 | |||
| 271 | bne t8, $u_final # U : | ||
| 272 | stq_u t0, 0(a0) # L : the null was in the high-order bits | ||
| 273 | addq a0, 8, a0 # E : | ||
| 274 | subq a2, 1, a2 # E : | ||
| 275 | |||
| 276 | .align 4 | ||
| 277 | $u_late_head_exit: | ||
| 278 | extql t2, a1, t0 # U : | ||
| 279 | cmpbge zero, t0, t8 # E : | ||
| 280 | or t8, t10, t6 # E : | ||
| 281 | cmoveq a2, t6, t8 # E : | ||
| 282 | |||
| 283 | /* Take care of a final (probably partial) result word. | ||
| 284 | On entry to this basic block: | ||
| 285 | t0 == assembled source word | ||
| 286 | t8 == cmpbge mask that found the null. */ | ||
| 287 | .align 4 | ||
| 288 | $u_final: | ||
| 289 | negq t8, t6 # E : isolate low bit set | ||
| 290 | and t6, t8, t12 # E : | ||
| 291 | ldq_u t1, 0(a0) # L : | ||
| 292 | subq t12, 1, t6 # E : | ||
| 293 | |||
| 294 | or t6, t12, t8 # E : | ||
| 295 | zapnot t0, t8, t0 # U : kill source bytes > null | ||
| 296 | zap t1, t8, t1 # U : kill dest bytes <= null | ||
| 297 | or t0, t1, t0 # E : | ||
| 298 | |||
| 299 | stq_u t0, 0(a0) # E : | ||
| 300 | br $finish_up # U : | ||
| 301 | nop | ||
| 302 | nop | ||
| 303 | |||
| 304 | .align 4 | ||
| 305 | $u_eoc: # end-of-count | ||
| 306 | extqh t2, a1, t0 # U : | ||
| 307 | or t0, t1, t0 # E : | ||
| 308 | cmpbge zero, t0, t8 # E : | ||
| 309 | nop | ||
| 310 | |||
| 311 | .align 4 | ||
| 312 | $u_eocfin: # end-of-count, final word | ||
| 313 | or t10, t8, t8 # E : | ||
| 314 | br $u_final # U : | ||
| 315 | nop | ||
| 316 | nop | ||
| 317 | |||
| 318 | /* Unaligned copy entry point. */ | ||
| 319 | .align 4 | ||
| 320 | $unaligned: | ||
| 321 | |||
| 322 | srl a3, 3, a2 # U : a2 = loop counter = (count - 1)/8 | ||
| 323 | and a0, 7, t4 # E : find dest misalignment | ||
| 324 | and a1, 7, t5 # E : find src misalignment | ||
| 325 | mov zero, t0 # E : | ||
| 326 | |||
| 327 | /* Conditionally load the first destination word and a bytemask | ||
| 328 | with 0xff indicating that the destination byte is sacrosanct. */ | ||
| 329 | |||
| 330 | mov zero, t6 # E : | ||
| 331 | beq t4, 1f # U : | ||
| 332 | ldq_u t0, 0(a0) # L : | ||
| 333 | lda t6, -1 # E : | ||
| 334 | |||
| 335 | mskql t6, a0, t6 # E : | ||
| 336 | nop | ||
| 337 | nop | ||
| 338 | nop | ||
| 339 | |||
| 340 | .align 4 | ||
| 341 | 1: | ||
| 342 | subq a1, t4, a1 # E : sub dest misalignment from src addr | ||
| 343 | /* If source misalignment is larger than dest misalignment, we need | ||
| 344 | extra startup checks to avoid SEGV. */ | ||
| 345 | cmplt t4, t5, t12 # E : | ||
| 346 | extql t1, a1, t1 # U : shift src into place | ||
| 347 | lda t2, -1 # E : for creating masks later | ||
| 348 | |||
| 349 | beq t12, $u_head # U : | ||
| 350 | mskqh t2, t5, t2 # U : begin src byte validity mask | ||
| 351 | cmpbge zero, t1, t8 # E : is there a zero? | ||
| 352 | nop | ||
| 353 | |||
| 354 | extql t2, a1, t2 # U : | ||
| 355 | or t8, t10, t5 # E : test for end-of-count too | ||
| 356 | cmpbge zero, t2, t3 # E : | ||
| 357 | cmoveq a2, t5, t8 # E : Latency=2, extra map slot | ||
| 358 | |||
| 359 | nop # E : goes with cmov | ||
| 360 | andnot t8, t3, t8 # E : | ||
| 361 | beq t8, $u_head # U : | ||
| 362 | nop | ||
| 363 | |||
| 364 | /* At this point we've found a zero in the first partial word of | ||
| 365 | the source. We need to isolate the valid source data and mask | ||
| 366 | it into the original destination data. (Incidentally, we know | ||
| 367 | that we'll need at least one byte of that original dest word.) */ | ||
| 368 | |||
| 369 | ldq_u t0, 0(a0) # L : | ||
| 370 | negq t8, t6 # E : build bitmask of bytes <= zero | ||
| 371 | mskqh t1, t4, t1 # U : | ||
| 372 | and t6, t8, t12 # E : | ||
| 373 | |||
| 374 | subq t12, 1, t6 # E : | ||
| 375 | or t6, t12, t8 # E : | ||
| 376 | zapnot t2, t8, t2 # U : prepare source word; mirror changes | ||
| 377 | zapnot t1, t8, t1 # U : to source validity mask | ||
| 378 | |||
| 379 | andnot t0, t2, t0 # E : zero place for source to reside | ||
| 380 | or t0, t1, t0 # E : and put it there | ||
| 381 | stq_u t0, 0(a0) # L : | ||
| 382 | nop | ||
| 383 | |||
| 384 | .align 4 | ||
| 385 | $finish_up: | ||
| 386 | zapnot t0, t12, t4 # U : was last byte written null? | ||
| 387 | and t12, 0xf0, t3 # E : binary search for the address of the | ||
| 388 | cmovne t4, 1, t4 # E : Latency=2, extra map slot | ||
| 389 | nop # E : with cmovne | ||
| 390 | |||
| 391 | and t12, 0xcc, t2 # E : last byte written | ||
| 392 | and t12, 0xaa, t1 # E : | ||
| 393 | cmovne t3, 4, t3 # E : Latency=2, extra map slot | ||
| 394 | nop # E : with cmovne | ||
| 395 | |||
| 396 | bic a0, 7, t0 | ||
| 397 | cmovne t2, 2, t2 # E : Latency=2, extra map slot | ||
| 398 | nop # E : with cmovne | ||
| 399 | nop | ||
| 400 | |||
| 401 | cmovne t1, 1, t1 # E : Latency=2, extra map slot | ||
| 402 | nop # E : with cmovne | ||
| 403 | addq t0, t3, t0 # E : | ||
| 404 | addq t1, t2, t1 # E : | ||
| 405 | |||
| 406 | addq t0, t1, t0 # E : | ||
| 407 | addq t0, t4, t0 # add one if we filled the buffer | ||
| 408 | subq t0, v0, v0 # find string length | ||
| 409 | ret # L0 : | ||
| 410 | |||
| 411 | .align 4 | ||
| 412 | $zerolength: | ||
| 413 | nop | ||
| 414 | nop | ||
| 415 | nop | ||
| 416 | clr v0 | ||
| 417 | |||
| 418 | $exception: | ||
| 419 | nop | ||
| 420 | nop | ||
| 421 | nop | ||
| 422 | ret | ||
| 423 | |||
| 424 | .end __strncpy_from_user | ||
diff --git a/arch/alpha/lib/ev67-strlen_user.S b/arch/alpha/lib/ev67-strlen_user.S deleted file mode 100644 index 57e0d77b81a6..000000000000 --- a/arch/alpha/lib/ev67-strlen_user.S +++ /dev/null | |||
| @@ -1,107 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/alpha/lib/ev67-strlen_user.S | ||
| 3 | * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com> | ||
| 4 | * | ||
| 5 | * Return the length of the string including the NULL terminator | ||
| 6 | * (strlen+1) or zero if an error occurred. | ||
| 7 | * | ||
| 8 | * In places where it is critical to limit the processing time, | ||
| 9 | * and the data is not trusted, strnlen_user() should be used. | ||
| 10 | * It will return a value greater than its second argument if | ||
| 11 | * that limit would be exceeded. This implementation is allowed | ||
| 12 | * to access memory beyond the limit, but will not cross a page | ||
| 13 | * boundary when doing so. | ||
| 14 | * | ||
| 15 | * Much of the information about 21264 scheduling/coding comes from: | ||
| 16 | * Compiler Writer's Guide for the Alpha 21264 | ||
| 17 | * abbreviated as 'CWG' in other comments here | ||
| 18 | * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html | ||
| 19 | * Scheduling notation: | ||
| 20 | * E - either cluster | ||
| 21 | * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1 | ||
| 22 | * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 | ||
| 23 | * Try not to change the actual algorithm if possible for consistency. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <asm/regdef.h> | ||
| 27 | |||
| 28 | |||
| 29 | /* Allow an exception for an insn; exit if we get one. */ | ||
| 30 | #define EX(x,y...) \ | ||
| 31 | 99: x,##y; \ | ||
| 32 | .section __ex_table,"a"; \ | ||
| 33 | .long 99b - .; \ | ||
| 34 | lda v0, $exception-99b(zero); \ | ||
| 35 | .previous | ||
| 36 | |||
| 37 | |||
| 38 | .set noreorder | ||
| 39 | .set noat | ||
| 40 | .text | ||
| 41 | |||
| 42 | .globl __strlen_user | ||
| 43 | .ent __strlen_user | ||
| 44 | .frame sp, 0, ra | ||
| 45 | |||
| 46 | .align 4 | ||
| 47 | __strlen_user: | ||
| 48 | ldah a1, 32767(zero) # do not use plain strlen_user() for strings | ||
| 49 | # that might be almost 2 GB long; you should | ||
| 50 | # be using strnlen_user() instead | ||
| 51 | nop | ||
| 52 | nop | ||
| 53 | nop | ||
| 54 | |||
| 55 | .globl __strnlen_user | ||
| 56 | |||
| 57 | .align 4 | ||
| 58 | __strnlen_user: | ||
| 59 | .prologue 0 | ||
| 60 | EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned) | ||
| 61 | lda t1, -1(zero) # E : | ||
| 62 | |||
| 63 | insqh t1, a0, t1 # U : | ||
| 64 | andnot a0, 7, v0 # E : | ||
| 65 | or t1, t0, t0 # E : | ||
| 66 | subq a0, 1, a0 # E : get our +1 for the return | ||
| 67 | |||
| 68 | cmpbge zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0 | ||
| 69 | subq a1, 7, t2 # E : | ||
| 70 | subq a0, v0, t0 # E : | ||
| 71 | bne t1, $found # U : | ||
| 72 | |||
| 73 | addq t2, t0, t2 # E : | ||
| 74 | addq a1, 1, a1 # E : | ||
| 75 | nop # E : | ||
| 76 | nop # E : | ||
| 77 | |||
| 78 | .align 4 | ||
| 79 | $loop: ble t2, $limit # U : | ||
| 80 | EX( ldq t0, 8(v0) ) # L : | ||
| 81 | nop # E : | ||
| 82 | nop # E : | ||
| 83 | |||
| 84 | cmpbge zero, t0, t1 # E : | ||
| 85 | subq t2, 8, t2 # E : | ||
| 86 | addq v0, 8, v0 # E : addr += 8 | ||
| 87 | beq t1, $loop # U : | ||
| 88 | |||
| 89 | $found: cttz t1, t2 # U0 : | ||
| 90 | addq v0, t2, v0 # E : | ||
| 91 | subq v0, a0, v0 # E : | ||
| 92 | ret # L0 : | ||
| 93 | |||
| 94 | $exception: | ||
| 95 | nop | ||
| 96 | nop | ||
| 97 | nop | ||
| 98 | ret | ||
| 99 | |||
| 100 | .align 4 # currently redundant | ||
| 101 | $limit: | ||
| 102 | nop | ||
| 103 | nop | ||
| 104 | subq a1, t2, v0 | ||
| 105 | ret | ||
| 106 | |||
| 107 | .end __strlen_user | ||
diff --git a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S deleted file mode 100644 index 508a18e96479..000000000000 --- a/arch/alpha/lib/strlen_user.S +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/alpha/lib/strlen_user.S | ||
| 3 | * | ||
| 4 | * Return the length of the string including the NUL terminator | ||
| 5 | * (strlen+1) or zero if an error occurred. | ||
| 6 | * | ||
| 7 | * In places where it is critical to limit the processing time, | ||
| 8 | * and the data is not trusted, strnlen_user() should be used. | ||
| 9 | * It will return a value greater than its second argument if | ||
| 10 | * that limit would be exceeded. This implementation is allowed | ||
| 11 | * to access memory beyond the limit, but will not cross a page | ||
| 12 | * boundary when doing so. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <asm/regdef.h> | ||
| 16 | |||
| 17 | |||
| 18 | /* Allow an exception for an insn; exit if we get one. */ | ||
| 19 | #define EX(x,y...) \ | ||
| 20 | 99: x,##y; \ | ||
| 21 | .section __ex_table,"a"; \ | ||
| 22 | .long 99b - .; \ | ||
| 23 | lda v0, $exception-99b(zero); \ | ||
| 24 | .previous | ||
| 25 | |||
| 26 | |||
| 27 | .set noreorder | ||
| 28 | .set noat | ||
| 29 | .text | ||
| 30 | |||
| 31 | .globl __strlen_user | ||
| 32 | .ent __strlen_user | ||
| 33 | .frame sp, 0, ra | ||
| 34 | |||
| 35 | .align 3 | ||
| 36 | __strlen_user: | ||
| 37 | ldah a1, 32767(zero) # do not use plain strlen_user() for strings | ||
| 38 | # that might be almost 2 GB long; you should | ||
| 39 | # be using strnlen_user() instead | ||
| 40 | |||
| 41 | .globl __strnlen_user | ||
| 42 | |||
| 43 | .align 3 | ||
| 44 | __strnlen_user: | ||
| 45 | .prologue 0 | ||
| 46 | |||
| 47 | EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned) | ||
| 48 | lda t1, -1(zero) | ||
| 49 | insqh t1, a0, t1 | ||
| 50 | andnot a0, 7, v0 | ||
| 51 | or t1, t0, t0 | ||
| 52 | subq a0, 1, a0 # get our +1 for the return | ||
| 53 | cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0 | ||
| 54 | subq a1, 7, t2 | ||
| 55 | subq a0, v0, t0 | ||
| 56 | bne t1, $found | ||
| 57 | |||
| 58 | addq t2, t0, t2 | ||
| 59 | addq a1, 1, a1 | ||
| 60 | |||
| 61 | .align 3 | ||
| 62 | $loop: ble t2, $limit | ||
| 63 | EX( ldq t0, 8(v0) ) | ||
| 64 | subq t2, 8, t2 | ||
| 65 | addq v0, 8, v0 # addr += 8 | ||
| 66 | cmpbge zero, t0, t1 | ||
| 67 | beq t1, $loop | ||
| 68 | |||
| 69 | $found: negq t1, t2 # clear all but least set bit | ||
| 70 | and t1, t2, t1 | ||
| 71 | |||
| 72 | and t1, 0xf0, t2 # binary search for that set bit | ||
| 73 | and t1, 0xcc, t3 | ||
| 74 | and t1, 0xaa, t4 | ||
| 75 | cmovne t2, 4, t2 | ||
| 76 | cmovne t3, 2, t3 | ||
| 77 | cmovne t4, 1, t4 | ||
| 78 | addq t2, t3, t2 | ||
| 79 | addq v0, t4, v0 | ||
| 80 | addq v0, t2, v0 | ||
| 81 | nop # dual issue next two on ev4 and ev5 | ||
| 82 | subq v0, a0, v0 | ||
| 83 | $exception: | ||
| 84 | ret | ||
| 85 | |||
| 86 | .align 3 # currently redundant | ||
| 87 | $limit: | ||
| 88 | subq a1, t2, v0 | ||
| 89 | ret | ||
| 90 | |||
| 91 | .end __strlen_user | ||
diff --git a/arch/alpha/lib/strncpy_from_user.S b/arch/alpha/lib/strncpy_from_user.S deleted file mode 100644 index 73ee21160ff7..000000000000 --- a/arch/alpha/lib/strncpy_from_user.S +++ /dev/null | |||
| @@ -1,339 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/alpha/lib/strncpy_from_user.S | ||
| 3 | * Contributed by Richard Henderson (rth@tamu.edu) | ||
| 4 | * | ||
| 5 | * Just like strncpy except in the return value: | ||
| 6 | * | ||
| 7 | * -EFAULT if an exception occurs before the terminator is copied. | ||
| 8 | * N if the buffer filled. | ||
| 9 | * | ||
| 10 | * Otherwise the length of the string is returned. | ||
| 11 | */ | ||
| 12 | |||
| 13 | |||
| 14 | #include <asm/errno.h> | ||
| 15 | #include <asm/regdef.h> | ||
| 16 | |||
| 17 | |||
| 18 | /* Allow an exception for an insn; exit if we get one. */ | ||
| 19 | #define EX(x,y...) \ | ||
| 20 | 99: x,##y; \ | ||
| 21 | .section __ex_table,"a"; \ | ||
| 22 | .long 99b - .; \ | ||
| 23 | lda $31, $exception-99b($0); \ | ||
| 24 | .previous | ||
| 25 | |||
| 26 | |||
| 27 | .set noat | ||
| 28 | .set noreorder | ||
| 29 | .text | ||
| 30 | |||
| 31 | .globl __strncpy_from_user | ||
| 32 | .ent __strncpy_from_user | ||
| 33 | .frame $30, 0, $26 | ||
| 34 | .prologue 0 | ||
| 35 | |||
| 36 | .align 3 | ||
| 37 | $aligned: | ||
| 38 | /* On entry to this basic block: | ||
| 39 | t0 == the first destination word for masking back in | ||
| 40 | t1 == the first source word. */ | ||
| 41 | |||
| 42 | /* Create the 1st output word and detect 0's in the 1st input word. */ | ||
| 43 | lda t2, -1 # e1 : build a mask against false zero | ||
| 44 | mskqh t2, a1, t2 # e0 : detection in the src word | ||
| 45 | mskqh t1, a1, t3 # e0 : | ||
| 46 | ornot t1, t2, t2 # .. e1 : | ||
| 47 | mskql t0, a1, t0 # e0 : assemble the first output word | ||
| 48 | cmpbge zero, t2, t8 # .. e1 : bits set iff null found | ||
| 49 | or t0, t3, t0 # e0 : | ||
| 50 | beq a2, $a_eoc # .. e1 : | ||
| 51 | bne t8, $a_eos # .. e1 : | ||
| 52 | |||
| 53 | /* On entry to this basic block: | ||
| 54 | t0 == a source word not containing a null. */ | ||
| 55 | |||
| 56 | $a_loop: | ||
| 57 | stq_u t0, 0(a0) # e0 : | ||
| 58 | addq a0, 8, a0 # .. e1 : | ||
| 59 | EX( ldq_u t0, 0(a1) ) # e0 : | ||
| 60 | addq a1, 8, a1 # .. e1 : | ||
| 61 | subq a2, 1, a2 # e0 : | ||
| 62 | cmpbge zero, t0, t8 # .. e1 (stall) | ||
| 63 | beq a2, $a_eoc # e1 : | ||
| 64 | beq t8, $a_loop # e1 : | ||
| 65 | |||
| 66 | /* Take care of the final (partial) word store. At this point | ||
| 67 | the end-of-count bit is set in t8 iff it applies. | ||
| 68 | |||
| 69 | On entry to this basic block we have: | ||
| 70 | t0 == the source word containing the null | ||
| 71 | t8 == the cmpbge mask that found it. */ | ||
| 72 | |||
| 73 | $a_eos: | ||
| 74 | negq t8, t12 # e0 : find low bit set | ||
| 75 | and t8, t12, t12 # e1 (stall) | ||
| 76 | |||
| 77 | /* For the sake of the cache, don't read a destination word | ||
| 78 | if we're not going to need it. */ | ||
| 79 | and t12, 0x80, t6 # e0 : | ||
| 80 | bne t6, 1f # .. e1 (zdb) | ||
| 81 | |||
| 82 | /* We're doing a partial word store and so need to combine | ||
| 83 | our source and original destination words. */ | ||
| 84 | ldq_u t1, 0(a0) # e0 : | ||
| 85 | subq t12, 1, t6 # .. e1 : | ||
| 86 | or t12, t6, t8 # e0 : | ||
| 87 | unop # | ||
| 88 | zapnot t0, t8, t0 # e0 : clear src bytes > null | ||
| 89 | zap t1, t8, t1 # .. e1 : clear dst bytes <= null | ||
| 90 | or t0, t1, t0 # e1 : | ||
| 91 | |||
| 92 | 1: stq_u t0, 0(a0) | ||
| 93 | br $finish_up | ||
| 94 | |||
| 95 | /* Add the end-of-count bit to the eos detection bitmask. */ | ||
| 96 | $a_eoc: | ||
| 97 | or t10, t8, t8 | ||
| 98 | br $a_eos | ||
| 99 | |||
| 100 | /*** The Function Entry Point ***/ | ||
| 101 | .align 3 | ||
| 102 | __strncpy_from_user: | ||
| 103 | mov a0, v0 # save the string start | ||
| 104 | beq a2, $zerolength | ||
| 105 | |||
| 106 | /* Are source and destination co-aligned? */ | ||
| 107 | xor a0, a1, t1 # e0 : | ||
| 108 | and a0, 7, t0 # .. e1 : find dest misalignment | ||
| 109 | and t1, 7, t1 # e0 : | ||
| 110 | addq a2, t0, a2 # .. e1 : bias count by dest misalignment | ||
| 111 | subq a2, 1, a2 # e0 : | ||
| 112 | and a2, 7, t2 # e1 : | ||
| 113 | srl a2, 3, a2 # e0 : a2 = loop counter = (count - 1)/8 | ||
| 114 | addq zero, 1, t10 # .. e1 : | ||
| 115 | sll t10, t2, t10 # e0 : t10 = bitmask of last count byte | ||
| 116 | bne t1, $unaligned # .. e1 : | ||
| 117 | |||
| 118 | /* We are co-aligned; take care of a partial first word. */ | ||
| 119 | |||
| 120 | EX( ldq_u t1, 0(a1) ) # e0 : load first src word | ||
| 121 | addq a1, 8, a1 # .. e1 : | ||
| 122 | |||
| 123 | beq t0, $aligned # avoid loading dest word if not needed | ||
| 124 | ldq_u t0, 0(a0) # e0 : | ||
| 125 | br $aligned # .. e1 : | ||
| 126 | |||
| 127 | |||
| 128 | /* The source and destination are not co-aligned. Align the destination | ||
| 129 | and cope. We have to be very careful about not reading too much and | ||
| 130 | causing a SEGV. */ | ||
| 131 | |||
| 132 | .align 3 | ||
| 133 | $u_head: | ||
| 134 | /* We know just enough now to be able to assemble the first | ||
| 135 | full source word. We can still find a zero at the end of it | ||
| 136 | that prevents us from outputting the whole thing. | ||
| 137 | |||
| 138 | On entry to this basic block: | ||
| 139 | t0 == the first dest word, unmasked | ||
| 140 | t1 == the shifted low bits of the first source word | ||
| 141 | t6 == bytemask that is -1 in dest word bytes */ | ||
| 142 | |||
| 143 | EX( ldq_u t2, 8(a1) ) # e0 : load second src word | ||
| 144 | addq a1, 8, a1 # .. e1 : | ||
| 145 | mskql t0, a0, t0 # e0 : mask trailing garbage in dst | ||
| 146 | extqh t2, a1, t4 # e0 : | ||
| 147 | or t1, t4, t1 # e1 : first aligned src word complete | ||
| 148 | mskqh t1, a0, t1 # e0 : mask leading garbage in src | ||
| 149 | or t0, t1, t0 # e0 : first output word complete | ||
| 150 | or t0, t6, t6 # e1 : mask original data for zero test | ||
| 151 | cmpbge zero, t6, t8 # e0 : | ||
| 152 | beq a2, $u_eocfin # .. e1 : | ||
| 153 | bne t8, $u_final # e1 : | ||
| 154 | |||
| 155 | lda t6, -1 # e1 : mask out the bits we have | ||
| 156 | mskql t6, a1, t6 # e0 : already seen | ||
| 157 | stq_u t0, 0(a0) # e0 : store first output word | ||
| 158 | or t6, t2, t2 # .. e1 : | ||
| 159 | cmpbge zero, t2, t8 # e0 : find nulls in second partial | ||
| 160 | addq a0, 8, a0 # .. e1 : | ||
| 161 | subq a2, 1, a2 # e0 : | ||
| 162 | bne t8, $u_late_head_exit # .. e1 : | ||
| 163 | |||
| 164 | /* Finally, we've got all the stupid leading edge cases taken care | ||
| 165 | of and we can set up to enter the main loop. */ | ||
| 166 | |||
| 167 | extql t2, a1, t1 # e0 : position hi-bits of lo word | ||
| 168 | EX( ldq_u t2, 8(a1) ) # .. e1 : read next high-order source word | ||
| 169 | addq a1, 8, a1 # e0 : | ||
| 170 | cmpbge zero, t2, t8 # e1 (stall) | ||
| 171 | beq a2, $u_eoc # e1 : | ||
| 172 | bne t8, $u_eos # e1 : | ||
| 173 | |||
| 174 | /* Unaligned copy main loop. In order to avoid reading too much, | ||
| 175 | the loop is structured to detect zeros in aligned source words. | ||
| 176 | This has, unfortunately, effectively pulled half of a loop | ||
| 177 | iteration out into the head and half into the tail, but it does | ||
| 178 | prevent nastiness from accumulating in the very thing we want | ||
| 179 | to run as fast as possible. | ||
| 180 | |||
| 181 | On entry to this basic block: | ||
| 182 | t1 == the shifted high-order bits from the previous source word | ||
| 183 | t2 == the unshifted current source word | ||
| 184 | |||
| 185 | We further know that t2 does not contain a null terminator. */ | ||
| 186 | |||
| 187 | .align 3 | ||
| 188 | $u_loop: | ||
| 189 | extqh t2, a1, t0 # e0 : extract high bits for current word | ||
| 190 | addq a1, 8, a1 # .. e1 : | ||
| 191 | extql t2, a1, t3 # e0 : extract low bits for next time | ||
| 192 | addq a0, 8, a0 # .. e1 : | ||
| 193 | or t0, t1, t0 # e0 : current dst word now complete | ||
| 194 | EX( ldq_u t2, 0(a1) ) # .. e1 : load high word for next time | ||
| 195 | stq_u t0, -8(a0) # e0 : save the current word | ||
| 196 | mov t3, t1 # .. e1 : | ||
| 197 | subq a2, 1, a2 # e0 : | ||
| 198 | cmpbge zero, t2, t8 # .. e1 : test new word for eos | ||
| 199 | beq a2, $u_eoc # e1 : | ||
| 200 | beq t8, $u_loop # e1 : | ||
| 201 | |||
| 202 | /* We've found a zero somewhere in the source word we just read. | ||
| 203 | If it resides in the lower half, we have one (probably partial) | ||
| 204 | word to write out, and if it resides in the upper half, we | ||
| 205 | have one full and one partial word left to write out. | ||
| 206 | |||
| 207 | On entry to this basic block: | ||
| 208 | t1 == the shifted high-order bits from the previous source word | ||
| 209 | t2 == the unshifted current source word. */ | ||
| 210 | $u_eos: | ||
| 211 | extqh t2, a1, t0 # e0 : | ||
| 212 | or t0, t1, t0 # e1 : first (partial) source word complete | ||
| 213 | |||
| 214 | cmpbge zero, t0, t8 # e0 : is the null in this first bit? | ||
| 215 | bne t8, $u_final # .. e1 (zdb) | ||
| 216 | |||
| 217 | stq_u t0, 0(a0) # e0 : the null was in the high-order bits | ||
| 218 | addq a0, 8, a0 # .. e1 : | ||
| 219 | subq a2, 1, a2 # e1 : | ||
| 220 | |||
| 221 | $u_late_head_exit: | ||
| 222 | extql t2, a1, t0 # .. e0 : | ||
| 223 | cmpbge zero, t0, t8 # e0 : | ||
| 224 | or t8, t10, t6 # e1 : | ||
| 225 | cmoveq a2, t6, t8 # e0 : | ||
| 226 | nop # .. e1 : | ||
| 227 | |||
| 228 | /* Take care of a final (probably partial) result word. | ||
| 229 | On entry to this basic block: | ||
| 230 | t0 == assembled source word | ||
| 231 | t8 == cmpbge mask that found the null. */ | ||
| 232 | $u_final: | ||
| 233 | negq t8, t6 # e0 : isolate low bit set | ||
| 234 | and t6, t8, t12 # e1 : | ||
| 235 | |||
| 236 | and t12, 0x80, t6 # e0 : avoid dest word load if we can | ||
| 237 | bne t6, 1f # .. e1 (zdb) | ||
| 238 | |||
| 239 | ldq_u t1, 0(a0) # e0 : | ||
| 240 | subq t12, 1, t6 # .. e1 : | ||
| 241 | or t6, t12, t8 # e0 : | ||
| 242 | zapnot t0, t8, t0 # .. e1 : kill source bytes > null | ||
| 243 | zap t1, t8, t1 # e0 : kill dest bytes <= null | ||
| 244 | or t0, t1, t0 # e1 : | ||
| 245 | |||
| 246 | 1: stq_u t0, 0(a0) # e0 : | ||
| 247 | br $finish_up | ||
| 248 | |||
| 249 | $u_eoc: # end-of-count | ||
| 250 | extqh t2, a1, t0 | ||
| 251 | or t0, t1, t0 | ||
| 252 | cmpbge zero, t0, t8 | ||
| 253 | |||
| 254 | $u_eocfin: # end-of-count, final word | ||
| 255 | or t10, t8, t8 | ||
| 256 | br $u_final | ||
| 257 | |||
| 258 | /* Unaligned copy entry point. */ | ||
| 259 | .align 3 | ||
| 260 | $unaligned: | ||
| 261 | |||
| 262 | EX( ldq_u t1, 0(a1) ) # e0 : load first source word | ||
| 263 | |||
| 264 | and a0, 7, t4 # .. e1 : find dest misalignment | ||
| 265 | and a1, 7, t5 # e0 : find src misalignment | ||
| 266 | |||
| 267 | /* Conditionally load the first destination word and a bytemask | ||
| 268 | with 0xff indicating that the destination byte is sacrosanct. */ | ||
| 269 | |||
| 270 | mov zero, t0 # .. e1 : | ||
| 271 | mov zero, t6 # e0 : | ||
| 272 | beq t4, 1f # .. e1 : | ||
| 273 | ldq_u t0, 0(a0) # e0 : | ||
| 274 | lda t6, -1 # .. e1 : | ||
| 275 | mskql t6, a0, t6 # e0 : | ||
| 276 | 1: | ||
| 277 | subq a1, t4, a1 # .. e1 : sub dest misalignment from src addr | ||
| 278 | |||
| 279 | /* If source misalignment is larger than dest misalignment, we need | ||
| 280 | extra startup checks to avoid SEGV. */ | ||
| 281 | |||
| 282 | cmplt t4, t5, t12 # e1 : | ||
| 283 | extql t1, a1, t1 # .. e0 : shift src into place | ||
| 284 | lda t2, -1 # e0 : for creating masks later | ||
| 285 | beq t12, $u_head # e1 : | ||
| 286 | |||
| 287 | mskqh t2, t5, t2 # e0 : begin src byte validity mask | ||
| 288 | cmpbge zero, t1, t8 # .. e1 : is there a zero? | ||
| 289 | extql t2, a1, t2 # e0 : | ||
| 290 | or t8, t10, t5 # .. e1 : test for end-of-count too | ||
| 291 | cmpbge zero, t2, t3 # e0 : | ||
| 292 | cmoveq a2, t5, t8 # .. e1 : | ||
| 293 | andnot t8, t3, t8 # e0 : | ||
| 294 | beq t8, $u_head # .. e1 (zdb) | ||
| 295 | |||
| 296 | /* At this point we've found a zero in the first partial word of | ||
| 297 | the source. We need to isolate the valid source data and mask | ||
| 298 | it into the original destination data. (Incidentally, we know | ||
| 299 | that we'll need at least one byte of that original dest word.) */ | ||
| 300 | |||
| 301 | ldq_u t0, 0(a0) # e0 : | ||
| 302 | negq t8, t6 # .. e1 : build bitmask of bytes <= zero | ||
| 303 | mskqh t1, t4, t1 # e0 : | ||
| 304 | and t6, t8, t12 # .. e1 : | ||
| 305 | subq t12, 1, t6 # e0 : | ||
| 306 | or t6, t12, t8 # e1 : | ||
| 307 | |||
| 308 | zapnot t2, t8, t2 # e0 : prepare source word; mirror changes | ||
| 309 | zapnot t1, t8, t1 # .. e1 : to source validity mask | ||
| 310 | |||
| 311 | andnot t0, t2, t0 # e0 : zero place for source to reside | ||
| 312 | or t0, t1, t0 # e1 : and put it there | ||
| 313 | stq_u t0, 0(a0) # e0 : | ||
| 314 | |||
| 315 | $finish_up: | ||
| 316 | zapnot t0, t12, t4 # was last byte written null? | ||
| 317 | cmovne t4, 1, t4 | ||
| 318 | |||
| 319 | and t12, 0xf0, t3 # binary search for the address of the | ||
| 320 | and t12, 0xcc, t2 # last byte written | ||
| 321 | and t12, 0xaa, t1 | ||
| 322 | bic a0, 7, t0 | ||
| 323 | cmovne t3, 4, t3 | ||
| 324 | cmovne t2, 2, t2 | ||
| 325 | cmovne t1, 1, t1 | ||
| 326 | addq t0, t3, t0 | ||
| 327 | addq t1, t2, t1 | ||
| 328 | addq t0, t1, t0 | ||
| 329 | addq t0, t4, t0 # add one if we filled the buffer | ||
| 330 | |||
| 331 | subq t0, v0, v0 # find string length | ||
| 332 | ret | ||
| 333 | |||
| 334 | $zerolength: | ||
| 335 | clr v0 | ||
| 336 | $exception: | ||
| 337 | ret | ||
| 338 | |||
| 339 | .end __strncpy_from_user | ||
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index 5eecab1a84ef..0c4132dd3507 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c | |||
| @@ -89,6 +89,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
| 89 | const struct exception_table_entry *fixup; | 89 | const struct exception_table_entry *fixup; |
| 90 | int fault, si_code = SEGV_MAPERR; | 90 | int fault, si_code = SEGV_MAPERR; |
| 91 | siginfo_t info; | 91 | siginfo_t info; |
| 92 | unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | ||
| 93 | (cause > 0 ? FAULT_FLAG_WRITE : 0)); | ||
| 92 | 94 | ||
| 93 | /* As of EV6, a load into $31/$f31 is a prefetch, and never faults | 95 | /* As of EV6, a load into $31/$f31 is a prefetch, and never faults |
| 94 | (or is suppressed by the PALcode). Support that for older CPUs | 96 | (or is suppressed by the PALcode). Support that for older CPUs |
| @@ -114,6 +116,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
| 114 | goto vmalloc_fault; | 116 | goto vmalloc_fault; |
| 115 | #endif | 117 | #endif |
| 116 | 118 | ||
| 119 | retry: | ||
| 117 | down_read(&mm->mmap_sem); | 120 | down_read(&mm->mmap_sem); |
| 118 | vma = find_vma(mm, address); | 121 | vma = find_vma(mm, address); |
| 119 | if (!vma) | 122 | if (!vma) |
| @@ -144,8 +147,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
| 144 | /* If for any reason at all we couldn't handle the fault, | 147 | /* If for any reason at all we couldn't handle the fault, |
| 145 | make sure we exit gracefully rather than endlessly redo | 148 | make sure we exit gracefully rather than endlessly redo |
| 146 | the fault. */ | 149 | the fault. */ |
| 147 | fault = handle_mm_fault(mm, vma, address, cause > 0 ? FAULT_FLAG_WRITE : 0); | 150 | fault = handle_mm_fault(mm, vma, address, flags); |
| 148 | up_read(&mm->mmap_sem); | 151 | |
| 152 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
| 153 | return; | ||
| 154 | |||
| 149 | if (unlikely(fault & VM_FAULT_ERROR)) { | 155 | if (unlikely(fault & VM_FAULT_ERROR)) { |
| 150 | if (fault & VM_FAULT_OOM) | 156 | if (fault & VM_FAULT_OOM) |
| 151 | goto out_of_memory; | 157 | goto out_of_memory; |
| @@ -153,10 +159,26 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
| 153 | goto do_sigbus; | 159 | goto do_sigbus; |
| 154 | BUG(); | 160 | BUG(); |
| 155 | } | 161 | } |
| 156 | if (fault & VM_FAULT_MAJOR) | 162 | |
| 157 | current->maj_flt++; | 163 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
| 158 | else | 164 | if (fault & VM_FAULT_MAJOR) |
| 159 | current->min_flt++; | 165 | current->maj_flt++; |
| 166 | else | ||
| 167 | current->min_flt++; | ||
| 168 | if (fault & VM_FAULT_RETRY) { | ||
| 169 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
| 170 | |||
| 171 | /* No need to up_read(&mm->mmap_sem) as we would | ||
| 172 | * have already released it in __lock_page_or_retry | ||
| 173 | * in mm/filemap.c. | ||
| 174 | */ | ||
| 175 | |||
| 176 | goto retry; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | up_read(&mm->mmap_sem); | ||
| 181 | |||
| 160 | return; | 182 | return; |
| 161 | 183 | ||
| 162 | /* Something tried to access memory that isn't in our memory map. | 184 | /* Something tried to access memory that isn't in our memory map. |
| @@ -186,12 +208,14 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
| 186 | /* We ran out of memory, or some other thing happened to us that | 208 | /* We ran out of memory, or some other thing happened to us that |
| 187 | made us unable to handle the page fault gracefully. */ | 209 | made us unable to handle the page fault gracefully. */ |
| 188 | out_of_memory: | 210 | out_of_memory: |
| 211 | up_read(&mm->mmap_sem); | ||
| 189 | if (!user_mode(regs)) | 212 | if (!user_mode(regs)) |
| 190 | goto no_context; | 213 | goto no_context; |
| 191 | pagefault_out_of_memory(); | 214 | pagefault_out_of_memory(); |
| 192 | return; | 215 | return; |
| 193 | 216 | ||
| 194 | do_sigbus: | 217 | do_sigbus: |
| 218 | up_read(&mm->mmap_sem); | ||
| 195 | /* Send a sigbus, regardless of whether we were in kernel | 219 | /* Send a sigbus, regardless of whether we were in kernel |
| 196 | or user mode. */ | 220 | or user mode. */ |
| 197 | info.si_signo = SIGBUS; | 221 | info.si_signo = SIGBUS; |
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index a0a5d27aa215..b8ce18f485d3 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <asm/ptrace.h> | 14 | #include <asm/ptrace.h> |
| 15 | #include <asm/special_insns.h> | ||
| 15 | 16 | ||
| 16 | #include "op_impl.h" | 17 | #include "op_impl.h" |
| 17 | 18 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e91c7cdc6fe5..6d6e18fee9fe 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -38,7 +38,6 @@ config ARM | |||
| 38 | select HARDIRQS_SW_RESEND | 38 | select HARDIRQS_SW_RESEND |
| 39 | select GENERIC_IRQ_PROBE | 39 | select GENERIC_IRQ_PROBE |
| 40 | select GENERIC_IRQ_SHOW | 40 | select GENERIC_IRQ_SHOW |
| 41 | select GENERIC_IRQ_PROBE | ||
| 42 | select ARCH_WANT_IPC_PARSE_VERSION | 41 | select ARCH_WANT_IPC_PARSE_VERSION |
| 43 | select HARDIRQS_SW_RESEND | 42 | select HARDIRQS_SW_RESEND |
| 44 | select CPU_PM if (SUSPEND || CPU_IDLE) | 43 | select CPU_PM if (SUSPEND || CPU_IDLE) |
| @@ -126,11 +125,6 @@ config TRACE_IRQFLAGS_SUPPORT | |||
| 126 | bool | 125 | bool |
| 127 | default y | 126 | default y |
| 128 | 127 | ||
| 129 | config GENERIC_LOCKBREAK | ||
| 130 | bool | ||
| 131 | default y | ||
| 132 | depends on SMP && PREEMPT | ||
| 133 | |||
| 134 | config RWSEM_GENERIC_SPINLOCK | 128 | config RWSEM_GENERIC_SPINLOCK |
| 135 | bool | 129 | bool |
| 136 | default y | 130 | default y |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index f66626d71e7d..41dc31f834c3 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
| @@ -195,6 +195,18 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
| 195 | 195 | ||
| 196 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) | 196 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) |
| 197 | 197 | ||
| 198 | #define pte_none(pte) (!pte_val(pte)) | ||
| 199 | #define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) | ||
| 200 | #define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) | ||
| 201 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) | ||
| 202 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | ||
| 203 | #define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) | ||
| 204 | #define pte_special(pte) (0) | ||
| 205 | |||
| 206 | #define pte_present_user(pte) \ | ||
| 207 | ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ | ||
| 208 | (L_PTE_PRESENT | L_PTE_USER)) | ||
| 209 | |||
| 198 | #if __LINUX_ARM_ARCH__ < 6 | 210 | #if __LINUX_ARM_ARCH__ < 6 |
| 199 | static inline void __sync_icache_dcache(pte_t pteval) | 211 | static inline void __sync_icache_dcache(pte_t pteval) |
| 200 | { | 212 | { |
| @@ -206,25 +218,15 @@ extern void __sync_icache_dcache(pte_t pteval); | |||
| 206 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 218 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
| 207 | pte_t *ptep, pte_t pteval) | 219 | pte_t *ptep, pte_t pteval) |
| 208 | { | 220 | { |
| 209 | if (addr >= TASK_SIZE) | 221 | unsigned long ext = 0; |
| 210 | set_pte_ext(ptep, pteval, 0); | 222 | |
| 211 | else { | 223 | if (addr < TASK_SIZE && pte_present_user(pteval)) { |
| 212 | __sync_icache_dcache(pteval); | 224 | __sync_icache_dcache(pteval); |
| 213 | set_pte_ext(ptep, pteval, PTE_EXT_NG); | 225 | ext |= PTE_EXT_NG; |
| 214 | } | 226 | } |
| 215 | } | ||
| 216 | 227 | ||
| 217 | #define pte_none(pte) (!pte_val(pte)) | 228 | set_pte_ext(ptep, pteval, ext); |
| 218 | #define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) | 229 | } |
| 219 | #define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) | ||
| 220 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) | ||
| 221 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | ||
| 222 | #define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) | ||
| 223 | #define pte_special(pte) (0) | ||
| 224 | |||
| 225 | #define pte_present_user(pte) \ | ||
| 226 | ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ | ||
| 227 | (L_PTE_PRESENT | L_PTE_USER)) | ||
| 228 | 230 | ||
| 229 | #define PTE_BIT_FUNC(fn,op) \ | 231 | #define PTE_BIT_FUNC(fn,op) \ |
| 230 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } | 232 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } |
| @@ -251,13 +253,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
| 251 | * | 253 | * |
| 252 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | 254 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 |
| 253 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 255 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
| 254 | * <--------------- offset --------------------> <- type --> 0 0 0 | 256 | * <--------------- offset ----------------------> < type -> 0 0 0 |
| 255 | * | 257 | * |
| 256 | * This gives us up to 63 swap files and 32GB per swap file. Note that | 258 | * This gives us up to 31 swap files and 64GB per swap file. Note that |
| 257 | * the offset field is always non-zero. | 259 | * the offset field is always non-zero. |
| 258 | */ | 260 | */ |
| 259 | #define __SWP_TYPE_SHIFT 3 | 261 | #define __SWP_TYPE_SHIFT 3 |
| 260 | #define __SWP_TYPE_BITS 6 | 262 | #define __SWP_TYPE_BITS 5 |
| 261 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) | 263 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) |
| 262 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) | 264 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) |
| 263 | 265 | ||
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h index e3f757263438..05b8e82ec9f5 100644 --- a/arch/arm/include/asm/sched_clock.h +++ b/arch/arm/include/asm/sched_clock.h | |||
| @@ -10,5 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | extern void sched_clock_postinit(void); | 11 | extern void sched_clock_postinit(void); |
| 12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); | 12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); |
| 13 | extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | ||
| 14 | unsigned long rate); | ||
| 13 | 15 | ||
| 14 | #endif | 16 | #endif |
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 27d186abbc06..f4515393248d 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c | |||
| @@ -21,6 +21,8 @@ struct clock_data { | |||
| 21 | u32 epoch_cyc_copy; | 21 | u32 epoch_cyc_copy; |
| 22 | u32 mult; | 22 | u32 mult; |
| 23 | u32 shift; | 23 | u32 shift; |
| 24 | bool suspended; | ||
| 25 | bool needs_suspend; | ||
| 24 | }; | 26 | }; |
| 25 | 27 | ||
| 26 | static void sched_clock_poll(unsigned long wrap_ticks); | 28 | static void sched_clock_poll(unsigned long wrap_ticks); |
| @@ -49,6 +51,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) | |||
| 49 | u64 epoch_ns; | 51 | u64 epoch_ns; |
| 50 | u32 epoch_cyc; | 52 | u32 epoch_cyc; |
| 51 | 53 | ||
| 54 | if (cd.suspended) | ||
| 55 | return cd.epoch_ns; | ||
| 56 | |||
| 52 | /* | 57 | /* |
| 53 | * Load the epoch_cyc and epoch_ns atomically. We do this by | 58 | * Load the epoch_cyc and epoch_ns atomically. We do this by |
| 54 | * ensuring that we always write epoch_cyc, epoch_ns and | 59 | * ensuring that we always write epoch_cyc, epoch_ns and |
| @@ -98,6 +103,13 @@ static void sched_clock_poll(unsigned long wrap_ticks) | |||
| 98 | update_sched_clock(); | 103 | update_sched_clock(); |
| 99 | } | 104 | } |
| 100 | 105 | ||
| 106 | void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | ||
| 107 | unsigned long rate) | ||
| 108 | { | ||
| 109 | setup_sched_clock(read, bits, rate); | ||
| 110 | cd.needs_suspend = true; | ||
| 111 | } | ||
| 112 | |||
| 101 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) | 113 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) |
| 102 | { | 114 | { |
| 103 | unsigned long r, w; | 115 | unsigned long r, w; |
| @@ -169,11 +181,23 @@ void __init sched_clock_postinit(void) | |||
| 169 | static int sched_clock_suspend(void) | 181 | static int sched_clock_suspend(void) |
| 170 | { | 182 | { |
| 171 | sched_clock_poll(sched_clock_timer.data); | 183 | sched_clock_poll(sched_clock_timer.data); |
| 184 | if (cd.needs_suspend) | ||
| 185 | cd.suspended = true; | ||
| 172 | return 0; | 186 | return 0; |
| 173 | } | 187 | } |
| 174 | 188 | ||
| 189 | static void sched_clock_resume(void) | ||
| 190 | { | ||
| 191 | if (cd.needs_suspend) { | ||
| 192 | cd.epoch_cyc = read_sched_clock(); | ||
| 193 | cd.epoch_cyc_copy = cd.epoch_cyc; | ||
| 194 | cd.suspended = false; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 175 | static struct syscore_ops sched_clock_ops = { | 198 | static struct syscore_ops sched_clock_ops = { |
| 176 | .suspend = sched_clock_suspend, | 199 | .suspend = sched_clock_suspend, |
| 200 | .resume = sched_clock_resume, | ||
| 177 | }; | 201 | }; |
| 178 | 202 | ||
| 179 | static int __init sched_clock_syscore_init(void) | 203 | static int __init sched_clock_syscore_init(void) |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 198b08456e90..26c12c6440fc 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
| @@ -321,7 +321,7 @@ void store_cpu_topology(unsigned int cpuid) | |||
| 321 | * init_cpu_topology is called at boot when only one cpu is running | 321 | * init_cpu_topology is called at boot when only one cpu is running |
| 322 | * which prevent simultaneous write access to cpu_topology array | 322 | * which prevent simultaneous write access to cpu_topology array |
| 323 | */ | 323 | */ |
| 324 | void init_cpu_topology(void) | 324 | void __init init_cpu_topology(void) |
| 325 | { | 325 | { |
| 326 | unsigned int cpu; | 326 | unsigned int cpu; |
| 327 | 327 | ||
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 2473fd1fd51c..af72969820b4 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
| @@ -16,13 +16,30 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ | |||
| 16 | call_with_stack.o | 16 | call_with_stack.o |
| 17 | 17 | ||
| 18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o | 18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o |
| 19 | mmu-y += copy_from_user.o copy_to_user.o | 19 | |
| 20 | # the code in uaccess.S is not preemption safe and | ||
| 21 | # probably faster on ARMv3 only | ||
| 22 | ifeq ($(CONFIG_PREEMPT),y) | ||
| 23 | mmu-y += copy_from_user.o copy_to_user.o | ||
| 24 | else | ||
| 25 | ifneq ($(CONFIG_CPU_32v3),y) | ||
| 26 | mmu-y += copy_from_user.o copy_to_user.o | ||
| 27 | else | ||
| 28 | mmu-y += uaccess.o | ||
| 29 | endif | ||
| 30 | endif | ||
| 20 | 31 | ||
| 21 | # using lib_ here won't override already available weak symbols | 32 | # using lib_ here won't override already available weak symbols |
| 22 | obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o | 33 | obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o |
| 23 | 34 | ||
| 24 | lib-$(CONFIG_MMU) += $(mmu-y) | 35 | lib-$(CONFIG_MMU) += $(mmu-y) |
| 25 | lib-y += io-readsw-armv4.o io-writesw-armv4.o | 36 | |
| 37 | ifeq ($(CONFIG_CPU_32v3),y) | ||
| 38 | lib-y += io-readsw-armv3.o io-writesw-armv3.o | ||
| 39 | else | ||
| 40 | lib-y += io-readsw-armv4.o io-writesw-armv4.o | ||
| 41 | endif | ||
| 42 | |||
| 26 | lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o | 43 | lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o |
| 27 | lib-$(CONFIG_ARCH_SHARK) += io-shark.o | 44 | lib-$(CONFIG_ARCH_SHARK) += io-shark.o |
| 28 | 45 | ||
diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S new file mode 100644 index 000000000000..88487c8c4f23 --- /dev/null +++ b/arch/arm/lib/io-readsw-armv3.S | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/io-readsw-armv3.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995-2000 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #include <linux/linkage.h> | ||
| 11 | #include <asm/assembler.h> | ||
| 12 | |||
| 13 | .Linsw_bad_alignment: | ||
| 14 | adr r0, .Linsw_bad_align_msg | ||
| 15 | mov r2, lr | ||
| 16 | b panic | ||
| 17 | .Linsw_bad_align_msg: | ||
| 18 | .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n" | ||
| 19 | .align | ||
| 20 | |||
| 21 | .Linsw_align: tst r1, #1 | ||
| 22 | bne .Linsw_bad_alignment | ||
| 23 | |||
| 24 | ldr r3, [r0] | ||
| 25 | strb r3, [r1], #1 | ||
| 26 | mov r3, r3, lsr #8 | ||
| 27 | strb r3, [r1], #1 | ||
| 28 | |||
| 29 | subs r2, r2, #1 | ||
| 30 | moveq pc, lr | ||
| 31 | |||
| 32 | ENTRY(__raw_readsw) | ||
| 33 | teq r2, #0 @ do we have to check for the zero len? | ||
| 34 | moveq pc, lr | ||
| 35 | tst r1, #3 | ||
| 36 | bne .Linsw_align | ||
| 37 | |||
| 38 | .Linsw_aligned: mov ip, #0xff | ||
| 39 | orr ip, ip, ip, lsl #8 | ||
| 40 | stmfd sp!, {r4, r5, r6, lr} | ||
| 41 | |||
| 42 | subs r2, r2, #8 | ||
| 43 | bmi .Lno_insw_8 | ||
| 44 | |||
| 45 | .Linsw_8_lp: ldr r3, [r0] | ||
| 46 | and r3, r3, ip | ||
| 47 | ldr r4, [r0] | ||
| 48 | orr r3, r3, r4, lsl #16 | ||
| 49 | |||
| 50 | ldr r4, [r0] | ||
| 51 | and r4, r4, ip | ||
| 52 | ldr r5, [r0] | ||
| 53 | orr r4, r4, r5, lsl #16 | ||
| 54 | |||
| 55 | ldr r5, [r0] | ||
| 56 | and r5, r5, ip | ||
| 57 | ldr r6, [r0] | ||
| 58 | orr r5, r5, r6, lsl #16 | ||
| 59 | |||
| 60 | ldr r6, [r0] | ||
| 61 | and r6, r6, ip | ||
| 62 | ldr lr, [r0] | ||
| 63 | orr r6, r6, lr, lsl #16 | ||
| 64 | |||
| 65 | stmia r1!, {r3 - r6} | ||
| 66 | |||
| 67 | subs r2, r2, #8 | ||
| 68 | bpl .Linsw_8_lp | ||
| 69 | |||
| 70 | tst r2, #7 | ||
| 71 | ldmeqfd sp!, {r4, r5, r6, pc} | ||
| 72 | |||
| 73 | .Lno_insw_8: tst r2, #4 | ||
| 74 | beq .Lno_insw_4 | ||
| 75 | |||
| 76 | ldr r3, [r0] | ||
| 77 | and r3, r3, ip | ||
| 78 | ldr r4, [r0] | ||
| 79 | orr r3, r3, r4, lsl #16 | ||
| 80 | |||
| 81 | ldr r4, [r0] | ||
| 82 | and r4, r4, ip | ||
| 83 | ldr r5, [r0] | ||
| 84 | orr r4, r4, r5, lsl #16 | ||
| 85 | |||
| 86 | stmia r1!, {r3, r4} | ||
| 87 | |||
| 88 | .Lno_insw_4: tst r2, #2 | ||
| 89 | beq .Lno_insw_2 | ||
| 90 | |||
| 91 | ldr r3, [r0] | ||
| 92 | and r3, r3, ip | ||
| 93 | ldr r4, [r0] | ||
| 94 | orr r3, r3, r4, lsl #16 | ||
| 95 | |||
| 96 | str r3, [r1], #4 | ||
| 97 | |||
| 98 | .Lno_insw_2: tst r2, #1 | ||
| 99 | ldrne r3, [r0] | ||
| 100 | strneb r3, [r1], #1 | ||
| 101 | movne r3, r3, lsr #8 | ||
| 102 | strneb r3, [r1] | ||
| 103 | |||
| 104 | ldmfd sp!, {r4, r5, r6, pc} | ||
| 105 | |||
| 106 | |||
diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S new file mode 100644 index 000000000000..49b800419e32 --- /dev/null +++ b/arch/arm/lib/io-writesw-armv3.S | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/io-writesw-armv3.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995-2000 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | #include <linux/linkage.h> | ||
| 11 | #include <asm/assembler.h> | ||
| 12 | |||
| 13 | .Loutsw_bad_alignment: | ||
| 14 | adr r0, .Loutsw_bad_align_msg | ||
| 15 | mov r2, lr | ||
| 16 | b panic | ||
| 17 | .Loutsw_bad_align_msg: | ||
| 18 | .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n" | ||
| 19 | .align | ||
| 20 | |||
| 21 | .Loutsw_align: tst r1, #1 | ||
| 22 | bne .Loutsw_bad_alignment | ||
| 23 | |||
| 24 | add r1, r1, #2 | ||
| 25 | |||
| 26 | ldr r3, [r1, #-4] | ||
| 27 | mov r3, r3, lsr #16 | ||
| 28 | orr r3, r3, r3, lsl #16 | ||
| 29 | str r3, [r0] | ||
| 30 | subs r2, r2, #1 | ||
| 31 | moveq pc, lr | ||
| 32 | |||
| 33 | ENTRY(__raw_writesw) | ||
| 34 | teq r2, #0 @ do we have to check for the zero len? | ||
| 35 | moveq pc, lr | ||
| 36 | tst r1, #3 | ||
| 37 | bne .Loutsw_align | ||
| 38 | |||
| 39 | stmfd sp!, {r4, r5, r6, lr} | ||
| 40 | |||
| 41 | subs r2, r2, #8 | ||
| 42 | bmi .Lno_outsw_8 | ||
| 43 | |||
| 44 | .Loutsw_8_lp: ldmia r1!, {r3, r4, r5, r6} | ||
| 45 | |||
| 46 | mov ip, r3, lsl #16 | ||
| 47 | orr ip, ip, ip, lsr #16 | ||
| 48 | str ip, [r0] | ||
| 49 | |||
| 50 | mov ip, r3, lsr #16 | ||
| 51 | orr ip, ip, ip, lsl #16 | ||
| 52 | str ip, [r0] | ||
| 53 | |||
| 54 | mov ip, r4, lsl #16 | ||
| 55 | orr ip, ip, ip, lsr #16 | ||
| 56 | str ip, [r0] | ||
| 57 | |||
| 58 | mov ip, r4, lsr #16 | ||
| 59 | orr ip, ip, ip, lsl #16 | ||
| 60 | str ip, [r0] | ||
| 61 | |||
| 62 | mov ip, r5, lsl #16 | ||
| 63 | orr ip, ip, ip, lsr #16 | ||
| 64 | str ip, [r0] | ||
| 65 | |||
| 66 | mov ip, r5, lsr #16 | ||
| 67 | orr ip, ip, ip, lsl #16 | ||
| 68 | str ip, [r0] | ||
| 69 | |||
| 70 | mov ip, r6, lsl #16 | ||
| 71 | orr ip, ip, ip, lsr #16 | ||
| 72 | str ip, [r0] | ||
| 73 | |||
| 74 | mov ip, r6, lsr #16 | ||
| 75 | orr ip, ip, ip, lsl #16 | ||
| 76 | str ip, [r0] | ||
| 77 | |||
| 78 | subs r2, r2, #8 | ||
| 79 | bpl .Loutsw_8_lp | ||
| 80 | |||
| 81 | tst r2, #7 | ||
| 82 | ldmeqfd sp!, {r4, r5, r6, pc} | ||
| 83 | |||
| 84 | .Lno_outsw_8: tst r2, #4 | ||
| 85 | beq .Lno_outsw_4 | ||
| 86 | |||
| 87 | ldmia r1!, {r3, r4} | ||
| 88 | |||
| 89 | mov ip, r3, lsl #16 | ||
| 90 | orr ip, ip, ip, lsr #16 | ||
| 91 | str ip, [r0] | ||
| 92 | |||
| 93 | mov ip, r3, lsr #16 | ||
| 94 | orr ip, ip, ip, lsl #16 | ||
| 95 | str ip, [r0] | ||
| 96 | |||
| 97 | mov ip, r4, lsl #16 | ||
| 98 | orr ip, ip, ip, lsr #16 | ||
| 99 | str ip, [r0] | ||
| 100 | |||
| 101 | mov ip, r4, lsr #16 | ||
| 102 | orr ip, ip, ip, lsl #16 | ||
| 103 | str ip, [r0] | ||
| 104 | |||
| 105 | .Lno_outsw_4: tst r2, #2 | ||
| 106 | beq .Lno_outsw_2 | ||
| 107 | |||
| 108 | ldr r3, [r1], #4 | ||
| 109 | |||
| 110 | mov ip, r3, lsl #16 | ||
| 111 | orr ip, ip, ip, lsr #16 | ||
| 112 | str ip, [r0] | ||
| 113 | |||
| 114 | mov ip, r3, lsr #16 | ||
| 115 | orr ip, ip, ip, lsl #16 | ||
| 116 | str ip, [r0] | ||
| 117 | |||
| 118 | .Lno_outsw_2: tst r2, #1 | ||
| 119 | |||
| 120 | ldrne r3, [r1] | ||
| 121 | |||
| 122 | movne ip, r3, lsl #16 | ||
| 123 | orrne ip, ip, ip, lsr #16 | ||
| 124 | strne ip, [r0] | ||
| 125 | |||
| 126 | ldmfd sp!, {r4, r5, r6, pc} | ||
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S new file mode 100644 index 000000000000..5c908b1cb8ed --- /dev/null +++ b/arch/arm/lib/uaccess.S | |||
| @@ -0,0 +1,564 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/lib/uaccess.S | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995, 1996,1997,1998 Russell King | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * Routines to block copy data to/from user memory | ||
| 11 | * These are highly optimised both for the 4k page size | ||
| 12 | * and for various alignments. | ||
| 13 | */ | ||
| 14 | #include <linux/linkage.h> | ||
| 15 | #include <asm/assembler.h> | ||
| 16 | #include <asm/errno.h> | ||
| 17 | #include <asm/domain.h> | ||
| 18 | |||
| 19 | .text | ||
| 20 | |||
| 21 | #define PAGE_SHIFT 12 | ||
| 22 | |||
| 23 | /* Prototype: int __copy_to_user(void *to, const char *from, size_t n) | ||
| 24 | * Purpose : copy a block to user memory from kernel memory | ||
| 25 | * Params : to - user memory | ||
| 26 | * : from - kernel memory | ||
| 27 | * : n - number of bytes to copy | ||
| 28 | * Returns : Number of bytes NOT copied. | ||
| 29 | */ | ||
| 30 | |||
| 31 | .Lc2u_dest_not_aligned: | ||
| 32 | rsb ip, ip, #4 | ||
| 33 | cmp ip, #2 | ||
| 34 | ldrb r3, [r1], #1 | ||
| 35 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
| 36 | ldrgeb r3, [r1], #1 | ||
| 37 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
| 38 | ldrgtb r3, [r1], #1 | ||
| 39 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
| 40 | sub r2, r2, ip | ||
| 41 | b .Lc2u_dest_aligned | ||
| 42 | |||
| 43 | ENTRY(__copy_to_user) | ||
| 44 | stmfd sp!, {r2, r4 - r7, lr} | ||
| 45 | cmp r2, #4 | ||
| 46 | blt .Lc2u_not_enough | ||
| 47 | ands ip, r0, #3 | ||
| 48 | bne .Lc2u_dest_not_aligned | ||
| 49 | .Lc2u_dest_aligned: | ||
| 50 | |||
| 51 | ands ip, r1, #3 | ||
| 52 | bne .Lc2u_src_not_aligned | ||
| 53 | /* | ||
| 54 | * Seeing as there has to be at least 8 bytes to copy, we can | ||
| 55 | * copy one word, and force a user-mode page fault... | ||
| 56 | */ | ||
| 57 | |||
| 58 | .Lc2u_0fupi: subs r2, r2, #4 | ||
| 59 | addmi ip, r2, #4 | ||
| 60 | bmi .Lc2u_0nowords | ||
| 61 | ldr r3, [r1], #4 | ||
| 62 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
| 63 | mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | ||
| 64 | rsb ip, ip, #0 | ||
| 65 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 66 | beq .Lc2u_0fupi | ||
| 67 | /* | ||
| 68 | * ip = max no. of bytes to copy before needing another "strt" insn | ||
| 69 | */ | ||
| 70 | cmp r2, ip | ||
| 71 | movlt ip, r2 | ||
| 72 | sub r2, r2, ip | ||
| 73 | subs ip, ip, #32 | ||
| 74 | blt .Lc2u_0rem8lp | ||
| 75 | |||
| 76 | .Lc2u_0cpy8lp: ldmia r1!, {r3 - r6} | ||
| 77 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
| 78 | ldmia r1!, {r3 - r6} | ||
| 79 | subs ip, ip, #32 | ||
| 80 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
| 81 | bpl .Lc2u_0cpy8lp | ||
| 82 | |||
| 83 | .Lc2u_0rem8lp: cmn ip, #16 | ||
| 84 | ldmgeia r1!, {r3 - r6} | ||
| 85 | stmgeia r0!, {r3 - r6} @ Shouldnt fault | ||
| 86 | tst ip, #8 | ||
| 87 | ldmneia r1!, {r3 - r4} | ||
| 88 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
| 89 | tst ip, #4 | ||
| 90 | ldrne r3, [r1], #4 | ||
| 91 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
| 92 | ands ip, ip, #3 | ||
| 93 | beq .Lc2u_0fupi | ||
| 94 | .Lc2u_0nowords: teq ip, #0 | ||
| 95 | beq .Lc2u_finished | ||
| 96 | .Lc2u_nowords: cmp ip, #2 | ||
| 97 | ldrb r3, [r1], #1 | ||
| 98 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
| 99 | ldrgeb r3, [r1], #1 | ||
| 100 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
| 101 | ldrgtb r3, [r1], #1 | ||
| 102 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
| 103 | b .Lc2u_finished | ||
| 104 | |||
| 105 | .Lc2u_not_enough: | ||
| 106 | movs ip, r2 | ||
| 107 | bne .Lc2u_nowords | ||
| 108 | .Lc2u_finished: mov r0, #0 | ||
| 109 | ldmfd sp!, {r2, r4 - r7, pc} | ||
| 110 | |||
| 111 | .Lc2u_src_not_aligned: | ||
| 112 | bic r1, r1, #3 | ||
| 113 | ldr r7, [r1], #4 | ||
| 114 | cmp ip, #2 | ||
| 115 | bgt .Lc2u_3fupi | ||
| 116 | beq .Lc2u_2fupi | ||
| 117 | .Lc2u_1fupi: subs r2, r2, #4 | ||
| 118 | addmi ip, r2, #4 | ||
| 119 | bmi .Lc2u_1nowords | ||
| 120 | mov r3, r7, pull #8 | ||
| 121 | ldr r7, [r1], #4 | ||
| 122 | orr r3, r3, r7, push #24 | ||
| 123 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
| 124 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
| 125 | rsb ip, ip, #0 | ||
| 126 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 127 | beq .Lc2u_1fupi | ||
| 128 | cmp r2, ip | ||
| 129 | movlt ip, r2 | ||
| 130 | sub r2, r2, ip | ||
| 131 | subs ip, ip, #16 | ||
| 132 | blt .Lc2u_1rem8lp | ||
| 133 | |||
| 134 | .Lc2u_1cpy8lp: mov r3, r7, pull #8 | ||
| 135 | ldmia r1!, {r4 - r7} | ||
| 136 | subs ip, ip, #16 | ||
| 137 | orr r3, r3, r4, push #24 | ||
| 138 | mov r4, r4, pull #8 | ||
| 139 | orr r4, r4, r5, push #24 | ||
| 140 | mov r5, r5, pull #8 | ||
| 141 | orr r5, r5, r6, push #24 | ||
| 142 | mov r6, r6, pull #8 | ||
| 143 | orr r6, r6, r7, push #24 | ||
| 144 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
| 145 | bpl .Lc2u_1cpy8lp | ||
| 146 | |||
| 147 | .Lc2u_1rem8lp: tst ip, #8 | ||
| 148 | movne r3, r7, pull #8 | ||
| 149 | ldmneia r1!, {r4, r7} | ||
| 150 | orrne r3, r3, r4, push #24 | ||
| 151 | movne r4, r4, pull #8 | ||
| 152 | orrne r4, r4, r7, push #24 | ||
| 153 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
| 154 | tst ip, #4 | ||
| 155 | movne r3, r7, pull #8 | ||
| 156 | ldrne r7, [r1], #4 | ||
| 157 | orrne r3, r3, r7, push #24 | ||
| 158 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
| 159 | ands ip, ip, #3 | ||
| 160 | beq .Lc2u_1fupi | ||
| 161 | .Lc2u_1nowords: mov r3, r7, get_byte_1 | ||
| 162 | teq ip, #0 | ||
| 163 | beq .Lc2u_finished | ||
| 164 | cmp ip, #2 | ||
| 165 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
| 166 | movge r3, r7, get_byte_2 | ||
| 167 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
| 168 | movgt r3, r7, get_byte_3 | ||
| 169 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
| 170 | b .Lc2u_finished | ||
| 171 | |||
| 172 | .Lc2u_2fupi: subs r2, r2, #4 | ||
| 173 | addmi ip, r2, #4 | ||
| 174 | bmi .Lc2u_2nowords | ||
| 175 | mov r3, r7, pull #16 | ||
| 176 | ldr r7, [r1], #4 | ||
| 177 | orr r3, r3, r7, push #16 | ||
| 178 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
| 179 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
| 180 | rsb ip, ip, #0 | ||
| 181 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 182 | beq .Lc2u_2fupi | ||
| 183 | cmp r2, ip | ||
| 184 | movlt ip, r2 | ||
| 185 | sub r2, r2, ip | ||
| 186 | subs ip, ip, #16 | ||
| 187 | blt .Lc2u_2rem8lp | ||
| 188 | |||
| 189 | .Lc2u_2cpy8lp: mov r3, r7, pull #16 | ||
| 190 | ldmia r1!, {r4 - r7} | ||
| 191 | subs ip, ip, #16 | ||
| 192 | orr r3, r3, r4, push #16 | ||
| 193 | mov r4, r4, pull #16 | ||
| 194 | orr r4, r4, r5, push #16 | ||
| 195 | mov r5, r5, pull #16 | ||
| 196 | orr r5, r5, r6, push #16 | ||
| 197 | mov r6, r6, pull #16 | ||
| 198 | orr r6, r6, r7, push #16 | ||
| 199 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
| 200 | bpl .Lc2u_2cpy8lp | ||
| 201 | |||
| 202 | .Lc2u_2rem8lp: tst ip, #8 | ||
| 203 | movne r3, r7, pull #16 | ||
| 204 | ldmneia r1!, {r4, r7} | ||
| 205 | orrne r3, r3, r4, push #16 | ||
| 206 | movne r4, r4, pull #16 | ||
| 207 | orrne r4, r4, r7, push #16 | ||
| 208 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
| 209 | tst ip, #4 | ||
| 210 | movne r3, r7, pull #16 | ||
| 211 | ldrne r7, [r1], #4 | ||
| 212 | orrne r3, r3, r7, push #16 | ||
| 213 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
| 214 | ands ip, ip, #3 | ||
| 215 | beq .Lc2u_2fupi | ||
| 216 | .Lc2u_2nowords: mov r3, r7, get_byte_2 | ||
| 217 | teq ip, #0 | ||
| 218 | beq .Lc2u_finished | ||
| 219 | cmp ip, #2 | ||
| 220 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
| 221 | movge r3, r7, get_byte_3 | ||
| 222 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
| 223 | ldrgtb r3, [r1], #0 | ||
| 224 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
| 225 | b .Lc2u_finished | ||
| 226 | |||
| 227 | .Lc2u_3fupi: subs r2, r2, #4 | ||
| 228 | addmi ip, r2, #4 | ||
| 229 | bmi .Lc2u_3nowords | ||
| 230 | mov r3, r7, pull #24 | ||
| 231 | ldr r7, [r1], #4 | ||
| 232 | orr r3, r3, r7, push #8 | ||
| 233 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
| 234 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
| 235 | rsb ip, ip, #0 | ||
| 236 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 237 | beq .Lc2u_3fupi | ||
| 238 | cmp r2, ip | ||
| 239 | movlt ip, r2 | ||
| 240 | sub r2, r2, ip | ||
| 241 | subs ip, ip, #16 | ||
| 242 | blt .Lc2u_3rem8lp | ||
| 243 | |||
| 244 | .Lc2u_3cpy8lp: mov r3, r7, pull #24 | ||
| 245 | ldmia r1!, {r4 - r7} | ||
| 246 | subs ip, ip, #16 | ||
| 247 | orr r3, r3, r4, push #8 | ||
| 248 | mov r4, r4, pull #24 | ||
| 249 | orr r4, r4, r5, push #8 | ||
| 250 | mov r5, r5, pull #24 | ||
| 251 | orr r5, r5, r6, push #8 | ||
| 252 | mov r6, r6, pull #24 | ||
| 253 | orr r6, r6, r7, push #8 | ||
| 254 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
| 255 | bpl .Lc2u_3cpy8lp | ||
| 256 | |||
| 257 | .Lc2u_3rem8lp: tst ip, #8 | ||
| 258 | movne r3, r7, pull #24 | ||
| 259 | ldmneia r1!, {r4, r7} | ||
| 260 | orrne r3, r3, r4, push #8 | ||
| 261 | movne r4, r4, pull #24 | ||
| 262 | orrne r4, r4, r7, push #8 | ||
| 263 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
| 264 | tst ip, #4 | ||
| 265 | movne r3, r7, pull #24 | ||
| 266 | ldrne r7, [r1], #4 | ||
| 267 | orrne r3, r3, r7, push #8 | ||
| 268 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
| 269 | ands ip, ip, #3 | ||
| 270 | beq .Lc2u_3fupi | ||
| 271 | .Lc2u_3nowords: mov r3, r7, get_byte_3 | ||
| 272 | teq ip, #0 | ||
| 273 | beq .Lc2u_finished | ||
| 274 | cmp ip, #2 | ||
| 275 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
| 276 | ldrgeb r3, [r1], #1 | ||
| 277 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
| 278 | ldrgtb r3, [r1], #0 | ||
| 279 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
| 280 | b .Lc2u_finished | ||
| 281 | ENDPROC(__copy_to_user) | ||
| 282 | |||
| 283 | .pushsection .fixup,"ax" | ||
| 284 | .align 0 | ||
| 285 | 9001: ldmfd sp!, {r0, r4 - r7, pc} | ||
| 286 | .popsection | ||
| 287 | |||
| 288 | /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); | ||
| 289 | * Purpose : copy a block from user memory to kernel memory | ||
| 290 | * Params : to - kernel memory | ||
| 291 | * : from - user memory | ||
| 292 | * : n - number of bytes to copy | ||
| 293 | * Returns : Number of bytes NOT copied. | ||
| 294 | */ | ||
| 295 | .Lcfu_dest_not_aligned: | ||
| 296 | rsb ip, ip, #4 | ||
| 297 | cmp ip, #2 | ||
| 298 | USER( TUSER( ldrb) r3, [r1], #1) @ May fault | ||
| 299 | strb r3, [r0], #1 | ||
| 300 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
| 301 | strgeb r3, [r0], #1 | ||
| 302 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
| 303 | strgtb r3, [r0], #1 | ||
| 304 | sub r2, r2, ip | ||
| 305 | b .Lcfu_dest_aligned | ||
| 306 | |||
| 307 | ENTRY(__copy_from_user) | ||
| 308 | stmfd sp!, {r0, r2, r4 - r7, lr} | ||
| 309 | cmp r2, #4 | ||
| 310 | blt .Lcfu_not_enough | ||
| 311 | ands ip, r0, #3 | ||
| 312 | bne .Lcfu_dest_not_aligned | ||
| 313 | .Lcfu_dest_aligned: | ||
| 314 | ands ip, r1, #3 | ||
| 315 | bne .Lcfu_src_not_aligned | ||
| 316 | |||
| 317 | /* | ||
| 318 | * Seeing as there has to be at least 8 bytes to copy, we can | ||
| 319 | * copy one word, and force a user-mode page fault... | ||
| 320 | */ | ||
| 321 | |||
| 322 | .Lcfu_0fupi: subs r2, r2, #4 | ||
| 323 | addmi ip, r2, #4 | ||
| 324 | bmi .Lcfu_0nowords | ||
| 325 | USER( TUSER( ldr) r3, [r1], #4) | ||
| 326 | str r3, [r0], #4 | ||
| 327 | mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | ||
| 328 | rsb ip, ip, #0 | ||
| 329 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 330 | beq .Lcfu_0fupi | ||
| 331 | /* | ||
| 332 | * ip = max no. of bytes to copy before needing another "strt" insn | ||
| 333 | */ | ||
| 334 | cmp r2, ip | ||
| 335 | movlt ip, r2 | ||
| 336 | sub r2, r2, ip | ||
| 337 | subs ip, ip, #32 | ||
| 338 | blt .Lcfu_0rem8lp | ||
| 339 | |||
| 340 | .Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault | ||
| 341 | stmia r0!, {r3 - r6} | ||
| 342 | ldmia r1!, {r3 - r6} @ Shouldnt fault | ||
| 343 | subs ip, ip, #32 | ||
| 344 | stmia r0!, {r3 - r6} | ||
| 345 | bpl .Lcfu_0cpy8lp | ||
| 346 | |||
| 347 | .Lcfu_0rem8lp: cmn ip, #16 | ||
| 348 | ldmgeia r1!, {r3 - r6} @ Shouldnt fault | ||
| 349 | stmgeia r0!, {r3 - r6} | ||
| 350 | tst ip, #8 | ||
| 351 | ldmneia r1!, {r3 - r4} @ Shouldnt fault | ||
| 352 | stmneia r0!, {r3 - r4} | ||
| 353 | tst ip, #4 | ||
| 354 | TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault | ||
| 355 | strne r3, [r0], #4 | ||
| 356 | ands ip, ip, #3 | ||
| 357 | beq .Lcfu_0fupi | ||
| 358 | .Lcfu_0nowords: teq ip, #0 | ||
| 359 | beq .Lcfu_finished | ||
| 360 | .Lcfu_nowords: cmp ip, #2 | ||
| 361 | USER( TUSER( ldrb) r3, [r1], #1) @ May fault | ||
| 362 | strb r3, [r0], #1 | ||
| 363 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
| 364 | strgeb r3, [r0], #1 | ||
| 365 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
| 366 | strgtb r3, [r0], #1 | ||
| 367 | b .Lcfu_finished | ||
| 368 | |||
| 369 | .Lcfu_not_enough: | ||
| 370 | movs ip, r2 | ||
| 371 | bne .Lcfu_nowords | ||
| 372 | .Lcfu_finished: mov r0, #0 | ||
| 373 | add sp, sp, #8 | ||
| 374 | ldmfd sp!, {r4 - r7, pc} | ||
| 375 | |||
| 376 | .Lcfu_src_not_aligned: | ||
| 377 | bic r1, r1, #3 | ||
| 378 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
| 379 | cmp ip, #2 | ||
| 380 | bgt .Lcfu_3fupi | ||
| 381 | beq .Lcfu_2fupi | ||
| 382 | .Lcfu_1fupi: subs r2, r2, #4 | ||
| 383 | addmi ip, r2, #4 | ||
| 384 | bmi .Lcfu_1nowords | ||
| 385 | mov r3, r7, pull #8 | ||
| 386 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
| 387 | orr r3, r3, r7, push #24 | ||
| 388 | str r3, [r0], #4 | ||
| 389 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
| 390 | rsb ip, ip, #0 | ||
| 391 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 392 | beq .Lcfu_1fupi | ||
| 393 | cmp r2, ip | ||
| 394 | movlt ip, r2 | ||
| 395 | sub r2, r2, ip | ||
| 396 | subs ip, ip, #16 | ||
| 397 | blt .Lcfu_1rem8lp | ||
| 398 | |||
| 399 | .Lcfu_1cpy8lp: mov r3, r7, pull #8 | ||
| 400 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
| 401 | subs ip, ip, #16 | ||
| 402 | orr r3, r3, r4, push #24 | ||
| 403 | mov r4, r4, pull #8 | ||
| 404 | orr r4, r4, r5, push #24 | ||
| 405 | mov r5, r5, pull #8 | ||
| 406 | orr r5, r5, r6, push #24 | ||
| 407 | mov r6, r6, pull #8 | ||
| 408 | orr r6, r6, r7, push #24 | ||
| 409 | stmia r0!, {r3 - r6} | ||
| 410 | bpl .Lcfu_1cpy8lp | ||
| 411 | |||
| 412 | .Lcfu_1rem8lp: tst ip, #8 | ||
| 413 | movne r3, r7, pull #8 | ||
| 414 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
| 415 | orrne r3, r3, r4, push #24 | ||
| 416 | movne r4, r4, pull #8 | ||
| 417 | orrne r4, r4, r7, push #24 | ||
| 418 | stmneia r0!, {r3 - r4} | ||
| 419 | tst ip, #4 | ||
| 420 | movne r3, r7, pull #8 | ||
| 421 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
| 422 | orrne r3, r3, r7, push #24 | ||
| 423 | strne r3, [r0], #4 | ||
| 424 | ands ip, ip, #3 | ||
| 425 | beq .Lcfu_1fupi | ||
| 426 | .Lcfu_1nowords: mov r3, r7, get_byte_1 | ||
| 427 | teq ip, #0 | ||
| 428 | beq .Lcfu_finished | ||
| 429 | cmp ip, #2 | ||
| 430 | strb r3, [r0], #1 | ||
| 431 | movge r3, r7, get_byte_2 | ||
| 432 | strgeb r3, [r0], #1 | ||
| 433 | movgt r3, r7, get_byte_3 | ||
| 434 | strgtb r3, [r0], #1 | ||
| 435 | b .Lcfu_finished | ||
| 436 | |||
| 437 | .Lcfu_2fupi: subs r2, r2, #4 | ||
| 438 | addmi ip, r2, #4 | ||
| 439 | bmi .Lcfu_2nowords | ||
| 440 | mov r3, r7, pull #16 | ||
| 441 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
| 442 | orr r3, r3, r7, push #16 | ||
| 443 | str r3, [r0], #4 | ||
| 444 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
| 445 | rsb ip, ip, #0 | ||
| 446 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 447 | beq .Lcfu_2fupi | ||
| 448 | cmp r2, ip | ||
| 449 | movlt ip, r2 | ||
| 450 | sub r2, r2, ip | ||
| 451 | subs ip, ip, #16 | ||
| 452 | blt .Lcfu_2rem8lp | ||
| 453 | |||
| 454 | |||
| 455 | .Lcfu_2cpy8lp: mov r3, r7, pull #16 | ||
| 456 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
| 457 | subs ip, ip, #16 | ||
| 458 | orr r3, r3, r4, push #16 | ||
| 459 | mov r4, r4, pull #16 | ||
| 460 | orr r4, r4, r5, push #16 | ||
| 461 | mov r5, r5, pull #16 | ||
| 462 | orr r5, r5, r6, push #16 | ||
| 463 | mov r6, r6, pull #16 | ||
| 464 | orr r6, r6, r7, push #16 | ||
| 465 | stmia r0!, {r3 - r6} | ||
| 466 | bpl .Lcfu_2cpy8lp | ||
| 467 | |||
| 468 | .Lcfu_2rem8lp: tst ip, #8 | ||
| 469 | movne r3, r7, pull #16 | ||
| 470 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
| 471 | orrne r3, r3, r4, push #16 | ||
| 472 | movne r4, r4, pull #16 | ||
| 473 | orrne r4, r4, r7, push #16 | ||
| 474 | stmneia r0!, {r3 - r4} | ||
| 475 | tst ip, #4 | ||
| 476 | movne r3, r7, pull #16 | ||
| 477 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
| 478 | orrne r3, r3, r7, push #16 | ||
| 479 | strne r3, [r0], #4 | ||
| 480 | ands ip, ip, #3 | ||
| 481 | beq .Lcfu_2fupi | ||
| 482 | .Lcfu_2nowords: mov r3, r7, get_byte_2 | ||
| 483 | teq ip, #0 | ||
| 484 | beq .Lcfu_finished | ||
| 485 | cmp ip, #2 | ||
| 486 | strb r3, [r0], #1 | ||
| 487 | movge r3, r7, get_byte_3 | ||
| 488 | strgeb r3, [r0], #1 | ||
| 489 | USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault | ||
| 490 | strgtb r3, [r0], #1 | ||
| 491 | b .Lcfu_finished | ||
| 492 | |||
| 493 | .Lcfu_3fupi: subs r2, r2, #4 | ||
| 494 | addmi ip, r2, #4 | ||
| 495 | bmi .Lcfu_3nowords | ||
| 496 | mov r3, r7, pull #24 | ||
| 497 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
| 498 | orr r3, r3, r7, push #8 | ||
| 499 | str r3, [r0], #4 | ||
| 500 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
| 501 | rsb ip, ip, #0 | ||
| 502 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
| 503 | beq .Lcfu_3fupi | ||
| 504 | cmp r2, ip | ||
| 505 | movlt ip, r2 | ||
| 506 | sub r2, r2, ip | ||
| 507 | subs ip, ip, #16 | ||
| 508 | blt .Lcfu_3rem8lp | ||
| 509 | |||
| 510 | .Lcfu_3cpy8lp: mov r3, r7, pull #24 | ||
| 511 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
| 512 | orr r3, r3, r4, push #8 | ||
| 513 | mov r4, r4, pull #24 | ||
| 514 | orr r4, r4, r5, push #8 | ||
| 515 | mov r5, r5, pull #24 | ||
| 516 | orr r5, r5, r6, push #8 | ||
| 517 | mov r6, r6, pull #24 | ||
| 518 | orr r6, r6, r7, push #8 | ||
| 519 | stmia r0!, {r3 - r6} | ||
| 520 | subs ip, ip, #16 | ||
| 521 | bpl .Lcfu_3cpy8lp | ||
| 522 | |||
| 523 | .Lcfu_3rem8lp: tst ip, #8 | ||
| 524 | movne r3, r7, pull #24 | ||
| 525 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
| 526 | orrne r3, r3, r4, push #8 | ||
| 527 | movne r4, r4, pull #24 | ||
| 528 | orrne r4, r4, r7, push #8 | ||
| 529 | stmneia r0!, {r3 - r4} | ||
| 530 | tst ip, #4 | ||
| 531 | movne r3, r7, pull #24 | ||
| 532 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
| 533 | orrne r3, r3, r7, push #8 | ||
| 534 | strne r3, [r0], #4 | ||
| 535 | ands ip, ip, #3 | ||
| 536 | beq .Lcfu_3fupi | ||
| 537 | .Lcfu_3nowords: mov r3, r7, get_byte_3 | ||
| 538 | teq ip, #0 | ||
| 539 | beq .Lcfu_finished | ||
| 540 | cmp ip, #2 | ||
| 541 | strb r3, [r0], #1 | ||
| 542 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
| 543 | strgeb r3, [r0], #1 | ||
| 544 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
| 545 | strgtb r3, [r0], #1 | ||
| 546 | b .Lcfu_finished | ||
| 547 | ENDPROC(__copy_from_user) | ||
| 548 | |||
| 549 | .pushsection .fixup,"ax" | ||
| 550 | .align 0 | ||
| 551 | /* | ||
| 552 | * We took an exception. r0 contains a pointer to | ||
| 553 | * the byte not copied. | ||
| 554 | */ | ||
| 555 | 9001: ldr r2, [sp], #4 @ void *to | ||
| 556 | sub r2, r0, r2 @ bytes copied | ||
| 557 | ldr r1, [sp], #4 @ unsigned long count | ||
| 558 | subs r4, r1, r2 @ bytes left to copy | ||
| 559 | movne r1, r4 | ||
| 560 | blne __memzero | ||
| 561 | mov r0, r4 | ||
| 562 | ldmfd sp!, {r4 - r7, pc} | ||
| 563 | .popsection | ||
| 564 | |||
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 77458548e031..40ca11ed6e5f 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
| @@ -231,8 +231,6 @@ void __sync_icache_dcache(pte_t pteval) | |||
| 231 | struct page *page; | 231 | struct page *page; |
| 232 | struct address_space *mapping; | 232 | struct address_space *mapping; |
| 233 | 233 | ||
| 234 | if (!pte_present_user(pteval)) | ||
| 235 | return; | ||
| 236 | if (cache_is_vipt_nonaliasing() && !pte_exec(pteval)) | 234 | if (cache_is_vipt_nonaliasing() && !pte_exec(pteval)) |
| 237 | /* only flush non-aliasing VIPT caches for exec mappings */ | 235 | /* only flush non-aliasing VIPT caches for exec mappings */ |
| 238 | return; | 236 | return; |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index c2021139cb56..ea94765acf9a 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
| @@ -38,10 +38,10 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
| 38 | dsb | 38 | dsb |
| 39 | mov r0, r0, lsr #PAGE_SHIFT @ align address | 39 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
| 40 | mov r1, r1, lsr #PAGE_SHIFT | 40 | mov r1, r1, lsr #PAGE_SHIFT |
| 41 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
| 42 | mov r3, #0 | ||
| 43 | #else | ||
| 44 | asid r3, r3 @ mask ASID | 41 | asid r3, r3 @ mask ASID |
| 42 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
| 43 | ALT_SMP(W(mov) r3, #0 ) | ||
| 44 | ALT_UP(W(nop) ) | ||
| 45 | #endif | 45 | #endif |
| 46 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | 46 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
| 47 | mov r1, r1, lsl #PAGE_SHIFT | 47 | mov r1, r1, lsl #PAGE_SHIFT |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index fb849d044bde..c834b32af275 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
| @@ -719,8 +719,10 @@ static int __init vfp_init(void) | |||
| 719 | if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) | 719 | if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) |
| 720 | elf_hwcap |= HWCAP_NEON; | 720 | elf_hwcap |= HWCAP_NEON; |
| 721 | #endif | 721 | #endif |
| 722 | #ifdef CONFIG_VFPv3 | ||
| 722 | if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) | 723 | if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) |
| 723 | elf_hwcap |= HWCAP_VFPv4; | 724 | elf_hwcap |= HWCAP_VFPv4; |
| 725 | #endif | ||
| 724 | } | 726 | } |
| 725 | } | 727 | } |
| 726 | return 0; | 728 | return 0; |
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 052f81a76239..983c859e40b7 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | config C6X | 6 | config C6X |
| 7 | def_bool y | 7 | def_bool y |
| 8 | select CLKDEV_LOOKUP | 8 | select CLKDEV_LOOKUP |
| 9 | select GENERIC_ATOMIC64 | ||
| 9 | select GENERIC_IRQ_SHOW | 10 | select GENERIC_IRQ_SHOW |
| 10 | select HAVE_ARCH_TRACEHOOK | 11 | select HAVE_ARCH_TRACEHOOK |
| 11 | select HAVE_DMA_API_DEBUG | 12 | select HAVE_DMA_API_DEBUG |
diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h index 6d521d96d941..09c5a0f5f4d1 100644 --- a/arch/c6x/include/asm/cache.h +++ b/arch/c6x/include/asm/cache.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Port on Texas Instruments TMS320C6x architecture | 2 | * Port on Texas Instruments TMS320C6x architecture |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated | 4 | * Copyright (C) 2005, 2006, 2009, 2010, 2012 Texas Instruments Incorporated |
| 5 | * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) | 5 | * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -16,9 +16,14 @@ | |||
| 16 | /* | 16 | /* |
| 17 | * Cache line size | 17 | * Cache line size |
| 18 | */ | 18 | */ |
| 19 | #define L1D_CACHE_BYTES 64 | 19 | #define L1D_CACHE_SHIFT 6 |
| 20 | #define L1P_CACHE_BYTES 32 | 20 | #define L1D_CACHE_BYTES (1 << L1D_CACHE_SHIFT) |
| 21 | #define L2_CACHE_BYTES 128 | 21 | |
| 22 | #define L1P_CACHE_SHIFT 5 | ||
| 23 | #define L1P_CACHE_BYTES (1 << L1P_CACHE_SHIFT) | ||
| 24 | |||
| 25 | #define L2_CACHE_SHIFT 7 | ||
| 26 | #define L2_CACHE_BYTES (1 << L2_CACHE_SHIFT) | ||
| 22 | 27 | ||
| 23 | /* | 28 | /* |
| 24 | * L2 used as cache | 29 | * L2 used as cache |
| @@ -29,7 +34,8 @@ | |||
| 29 | * For practical reasons the L1_CACHE_BYTES defines should not be smaller than | 34 | * For practical reasons the L1_CACHE_BYTES defines should not be smaller than |
| 30 | * the L2 line size | 35 | * the L2 line size |
| 31 | */ | 36 | */ |
| 32 | #define L1_CACHE_BYTES L2_CACHE_BYTES | 37 | #define L1_CACHE_SHIFT L2_CACHE_SHIFT |
| 38 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
| 33 | 39 | ||
| 34 | #define L2_CACHE_ALIGN_LOW(x) \ | 40 | #define L2_CACHE_ALIGN_LOW(x) \ |
| 35 | (((x) & ~(L2_CACHE_BYTES - 1))) | 41 | (((x) & ~(L2_CACHE_BYTES - 1))) |
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 954d81e2e837..7913695b2fcb 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig | |||
| @@ -234,5 +234,4 @@ CONFIG_CRYPTO_PCBC=m | |||
| 234 | CONFIG_CRYPTO_MD5=y | 234 | CONFIG_CRYPTO_MD5=y |
| 235 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 235 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 236 | CONFIG_CRC_T10DIF=y | 236 | CONFIG_CRC_T10DIF=y |
| 237 | CONFIG_MISC_DEVICES=y | ||
| 238 | CONFIG_INTEL_IOMMU=y | 237 | CONFIG_INTEL_IOMMU=y |
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 91c41ecfa6d9..f8e913365423 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig | |||
| @@ -209,4 +209,3 @@ CONFIG_MAGIC_SYSRQ=y | |||
| 209 | CONFIG_DEBUG_KERNEL=y | 209 | CONFIG_DEBUG_KERNEL=y |
| 210 | CONFIG_DEBUG_MUTEXES=y | 210 | CONFIG_DEBUG_MUTEXES=y |
| 211 | CONFIG_CRYPTO_MD5=y | 211 | CONFIG_CRYPTO_MD5=y |
| 212 | CONFIG_MISC_DEVICES=y | ||
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b0c5276861ec..682e9c210baa 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
| @@ -27,6 +27,10 @@ ifeq ($(CONFIG_X86_32),y) | |||
| 27 | 27 | ||
| 28 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return | 28 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return |
| 29 | 29 | ||
| 30 | # Never want PIC in a 32-bit kernel, prevent breakage with GCC built | ||
| 31 | # with nonstandard options | ||
| 32 | KBUILD_CFLAGS += -fno-pic | ||
| 33 | |||
| 30 | # prevent gcc from keeping the stack 16 byte aligned | 34 | # prevent gcc from keeping the stack 16 byte aligned |
| 31 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) | 35 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) |
| 32 | 36 | ||
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 5a747dd884db..f7535bedc33f 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile | |||
| @@ -57,7 +57,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ | |||
| 57 | -Wall -Wstrict-prototypes \ | 57 | -Wall -Wstrict-prototypes \ |
| 58 | -march=i386 -mregparm=3 \ | 58 | -march=i386 -mregparm=3 \ |
| 59 | -include $(srctree)/$(src)/code16gcc.h \ | 59 | -include $(srctree)/$(src)/code16gcc.h \ |
| 60 | -fno-strict-aliasing -fomit-frame-pointer \ | 60 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
| 61 | $(call cc-option, -ffreestanding) \ | 61 | $(call cc-option, -ffreestanding) \ |
| 62 | $(call cc-option, -fno-toplevel-reorder,\ | 62 | $(call cc-option, -fno-toplevel-reorder,\ |
| 63 | $(call cc-option, -fno-unit-at-a-time)) \ | 63 | $(call cc-option, -fno-unit-at-a-time)) \ |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a6c64aaddf9a..c265593ec2cd 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1356,6 +1356,16 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
| 1356 | if (!IO_APIC_IRQ(irq)) | 1356 | if (!IO_APIC_IRQ(irq)) |
| 1357 | return; | 1357 | return; |
| 1358 | 1358 | ||
| 1359 | /* | ||
| 1360 | * For legacy irqs, cfg->domain starts with cpu 0. Now that IO-APIC | ||
| 1361 | * can handle this irq and the apic driver is finialized at this point, | ||
| 1362 | * update the cfg->domain. | ||
| 1363 | */ | ||
| 1364 | if (irq < legacy_pic->nr_legacy_irqs && | ||
| 1365 | cpumask_equal(cfg->domain, cpumask_of(0))) | ||
| 1366 | apic->vector_allocation_domain(0, cfg->domain, | ||
| 1367 | apic->target_cpus()); | ||
| 1368 | |||
| 1359 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) | 1369 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) |
| 1360 | return; | 1370 | return; |
| 1361 | 1371 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 46d8786d655e..a5fbc3c5fccc 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -144,6 +144,8 @@ static int __init x86_xsave_setup(char *s) | |||
| 144 | { | 144 | { |
| 145 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); | 145 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
| 146 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); | 146 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); |
| 147 | setup_clear_cpu_cap(X86_FEATURE_AVX); | ||
| 148 | setup_clear_cpu_cap(X86_FEATURE_AVX2); | ||
| 147 | return 1; | 149 | return 1; |
| 148 | } | 150 | } |
| 149 | __setup("noxsave", x86_xsave_setup); | 151 | __setup("noxsave", x86_xsave_setup); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 382366977d4c..7f2739e03e79 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -1522,8 +1522,16 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr) | |||
| 1522 | arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; | 1522 | arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; |
| 1523 | arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; | 1523 | arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; |
| 1524 | arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask; | 1524 | arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask; |
| 1525 | /* | ||
| 1526 | * If PMU counter has PEBS enabled it is not enough to disable counter | ||
| 1527 | * on a guest entry since PEBS memory write can overshoot guest entry | ||
| 1528 | * and corrupt guest memory. Disabling PEBS solves the problem. | ||
| 1529 | */ | ||
| 1530 | arr[1].msr = MSR_IA32_PEBS_ENABLE; | ||
| 1531 | arr[1].host = cpuc->pebs_enabled; | ||
| 1532 | arr[1].guest = 0; | ||
| 1525 | 1533 | ||
| 1526 | *nr = 1; | 1534 | *nr = 2; |
| 1527 | return arr; | 1535 | return arr; |
| 1528 | } | 1536 | } |
| 1529 | 1537 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 7563fda9f033..0a5571080e74 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
| @@ -796,7 +796,6 @@ static struct intel_uncore_type *nhm_msr_uncores[] = { | |||
| 796 | 796 | ||
| 797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); | 797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); |
| 798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); | 798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); |
| 799 | DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63"); | ||
| 800 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); | 799 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); |
| 801 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); | 800 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); |
| 802 | 801 | ||
| @@ -902,16 +901,21 @@ static struct attribute_group nhmex_uncore_cbox_format_group = { | |||
| 902 | .attrs = nhmex_uncore_cbox_formats_attr, | 901 | .attrs = nhmex_uncore_cbox_formats_attr, |
| 903 | }; | 902 | }; |
| 904 | 903 | ||
| 904 | /* msr offset for each instance of cbox */ | ||
| 905 | static unsigned nhmex_cbox_msr_offsets[] = { | ||
| 906 | 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0, | ||
| 907 | }; | ||
| 908 | |||
| 905 | static struct intel_uncore_type nhmex_uncore_cbox = { | 909 | static struct intel_uncore_type nhmex_uncore_cbox = { |
| 906 | .name = "cbox", | 910 | .name = "cbox", |
| 907 | .num_counters = 6, | 911 | .num_counters = 6, |
| 908 | .num_boxes = 8, | 912 | .num_boxes = 10, |
| 909 | .perf_ctr_bits = 48, | 913 | .perf_ctr_bits = 48, |
| 910 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, | 914 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, |
| 911 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, | 915 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, |
| 912 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | 916 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, |
| 913 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, | 917 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, |
| 914 | .msr_offset = NHMEX_C_MSR_OFFSET, | 918 | .msr_offsets = nhmex_cbox_msr_offsets, |
| 915 | .pair_ctr_ctl = 1, | 919 | .pair_ctr_ctl = 1, |
| 916 | .ops = &nhmex_uncore_ops, | 920 | .ops = &nhmex_uncore_ops, |
| 917 | .format_group = &nhmex_uncore_cbox_format_group | 921 | .format_group = &nhmex_uncore_cbox_format_group |
| @@ -1032,24 +1036,22 @@ static struct intel_uncore_type nhmex_uncore_bbox = { | |||
| 1032 | 1036 | ||
| 1033 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | 1037 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) |
| 1034 | { | 1038 | { |
| 1035 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | 1039 | struct hw_perf_event *hwc = &event->hw; |
| 1036 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | 1040 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| 1041 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
| 1037 | 1042 | ||
| 1038 | if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) { | 1043 | /* only TO_R_PROG_EV event uses the match/mask register */ |
| 1039 | reg1->config = event->attr.config1; | 1044 | if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) != |
| 1040 | reg2->config = event->attr.config2; | 1045 | NHMEX_S_EVENT_TO_R_PROG_EV) |
| 1041 | } else { | 1046 | return 0; |
| 1042 | reg1->config = ~0ULL; | ||
| 1043 | reg2->config = ~0ULL; | ||
| 1044 | } | ||
| 1045 | 1047 | ||
| 1046 | if (box->pmu->pmu_idx == 0) | 1048 | if (box->pmu->pmu_idx == 0) |
| 1047 | reg1->reg = NHMEX_S0_MSR_MM_CFG; | 1049 | reg1->reg = NHMEX_S0_MSR_MM_CFG; |
| 1048 | else | 1050 | else |
| 1049 | reg1->reg = NHMEX_S1_MSR_MM_CFG; | 1051 | reg1->reg = NHMEX_S1_MSR_MM_CFG; |
| 1050 | |||
| 1051 | reg1->idx = 0; | 1052 | reg1->idx = 0; |
| 1052 | 1053 | reg1->config = event->attr.config1; | |
| 1054 | reg2->config = event->attr.config2; | ||
| 1053 | return 0; | 1055 | return 0; |
| 1054 | } | 1056 | } |
| 1055 | 1057 | ||
| @@ -1059,8 +1061,8 @@ static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
| 1059 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1061 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| 1060 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | 1062 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; |
| 1061 | 1063 | ||
| 1062 | wrmsrl(reg1->reg, 0); | 1064 | if (reg1->idx != EXTRA_REG_NONE) { |
| 1063 | if (reg1->config != ~0ULL || reg2->config != ~0ULL) { | 1065 | wrmsrl(reg1->reg, 0); |
| 1064 | wrmsrl(reg1->reg + 1, reg1->config); | 1066 | wrmsrl(reg1->reg + 1, reg1->config); |
| 1065 | wrmsrl(reg1->reg + 2, reg2->config); | 1067 | wrmsrl(reg1->reg + 2, reg2->config); |
| 1066 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); | 1068 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); |
| @@ -1074,7 +1076,6 @@ static struct attribute *nhmex_uncore_sbox_formats_attr[] = { | |||
| 1074 | &format_attr_edge.attr, | 1076 | &format_attr_edge.attr, |
| 1075 | &format_attr_inv.attr, | 1077 | &format_attr_inv.attr, |
| 1076 | &format_attr_thresh8.attr, | 1078 | &format_attr_thresh8.attr, |
| 1077 | &format_attr_mm_cfg.attr, | ||
| 1078 | &format_attr_match.attr, | 1079 | &format_attr_match.attr, |
| 1079 | &format_attr_mask.attr, | 1080 | &format_attr_mask.attr, |
| 1080 | NULL, | 1081 | NULL, |
| @@ -1142,6 +1143,9 @@ static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { | |||
| 1142 | EVENT_EXTRA_END | 1143 | EVENT_EXTRA_END |
| 1143 | }; | 1144 | }; |
| 1144 | 1145 | ||
| 1146 | /* Nehalem-EX or Westmere-EX ? */ | ||
| 1147 | bool uncore_nhmex; | ||
| 1148 | |||
| 1145 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) | 1149 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) |
| 1146 | { | 1150 | { |
| 1147 | struct intel_uncore_extra_reg *er; | 1151 | struct intel_uncore_extra_reg *er; |
| @@ -1171,18 +1175,29 @@ static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 | |||
| 1171 | return false; | 1175 | return false; |
| 1172 | 1176 | ||
| 1173 | /* mask of the shared fields */ | 1177 | /* mask of the shared fields */ |
| 1174 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | 1178 | if (uncore_nhmex) |
| 1179 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
| 1180 | else | ||
| 1181 | mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
| 1175 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | 1182 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; |
| 1176 | 1183 | ||
| 1177 | raw_spin_lock_irqsave(&er->lock, flags); | 1184 | raw_spin_lock_irqsave(&er->lock, flags); |
| 1178 | /* add mask of the non-shared field if it's in use */ | 1185 | /* add mask of the non-shared field if it's in use */ |
| 1179 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) | 1186 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) { |
| 1180 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1187 | if (uncore_nhmex) |
| 1188 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1189 | else | ||
| 1190 | mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1191 | } | ||
| 1181 | 1192 | ||
| 1182 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { | 1193 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { |
| 1183 | atomic_add(1 << (idx * 8), &er->ref); | 1194 | atomic_add(1 << (idx * 8), &er->ref); |
| 1184 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | | 1195 | if (uncore_nhmex) |
| 1185 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1196 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | |
| 1197 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1198 | else | ||
| 1199 | mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK | | ||
| 1200 | WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1186 | er->config &= ~mask; | 1201 | er->config &= ~mask; |
| 1187 | er->config |= (config & mask); | 1202 | er->config |= (config & mask); |
| 1188 | ret = true; | 1203 | ret = true; |
| @@ -1216,7 +1231,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | |||
| 1216 | 1231 | ||
| 1217 | /* get the non-shared control bits and shift them */ | 1232 | /* get the non-shared control bits and shift them */ |
| 1218 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | 1233 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; |
| 1219 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1234 | if (uncore_nhmex) |
| 1235 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1236 | else | ||
| 1237 | config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
| 1220 | if (new_idx > orig_idx) { | 1238 | if (new_idx > orig_idx) { |
| 1221 | idx = new_idx - orig_idx; | 1239 | idx = new_idx - orig_idx; |
| 1222 | config <<= 3 * idx; | 1240 | config <<= 3 * idx; |
| @@ -1226,6 +1244,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | |||
| 1226 | } | 1244 | } |
| 1227 | 1245 | ||
| 1228 | /* add the shared control bits back */ | 1246 | /* add the shared control bits back */ |
| 1247 | if (uncore_nhmex) | ||
| 1248 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
| 1249 | else | ||
| 1250 | config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
| 1229 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | 1251 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; |
| 1230 | if (modify) { | 1252 | if (modify) { |
| 1231 | /* adjust the main event selector */ | 1253 | /* adjust the main event selector */ |
| @@ -1264,7 +1286,8 @@ again: | |||
| 1264 | } | 1286 | } |
| 1265 | 1287 | ||
| 1266 | /* for the match/mask registers */ | 1288 | /* for the match/mask registers */ |
| 1267 | if ((uncore_box_is_fake(box) || !reg2->alloc) && | 1289 | if (reg2->idx != EXTRA_REG_NONE && |
| 1290 | (uncore_box_is_fake(box) || !reg2->alloc) && | ||
| 1268 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) | 1291 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) |
| 1269 | goto fail; | 1292 | goto fail; |
| 1270 | 1293 | ||
| @@ -1278,7 +1301,8 @@ again: | |||
| 1278 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) | 1301 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) |
| 1279 | nhmex_mbox_alter_er(event, idx[0], true); | 1302 | nhmex_mbox_alter_er(event, idx[0], true); |
| 1280 | reg1->alloc |= alloc; | 1303 | reg1->alloc |= alloc; |
| 1281 | reg2->alloc = 1; | 1304 | if (reg2->idx != EXTRA_REG_NONE) |
| 1305 | reg2->alloc = 1; | ||
| 1282 | } | 1306 | } |
| 1283 | return NULL; | 1307 | return NULL; |
| 1284 | fail: | 1308 | fail: |
| @@ -1342,9 +1366,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1342 | struct extra_reg *er; | 1366 | struct extra_reg *er; |
| 1343 | unsigned msr; | 1367 | unsigned msr; |
| 1344 | int reg_idx = 0; | 1368 | int reg_idx = 0; |
| 1345 | |||
| 1346 | if (WARN_ON_ONCE(reg1->idx != -1)) | ||
| 1347 | return -EINVAL; | ||
| 1348 | /* | 1369 | /* |
| 1349 | * The mbox events may require 2 extra MSRs at the most. But only | 1370 | * The mbox events may require 2 extra MSRs at the most. But only |
| 1350 | * the lower 32 bits in these MSRs are significant, so we can use | 1371 | * the lower 32 bits in these MSRs are significant, so we can use |
| @@ -1355,11 +1376,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1355 | continue; | 1376 | continue; |
| 1356 | if (event->attr.config1 & ~er->valid_mask) | 1377 | if (event->attr.config1 & ~er->valid_mask) |
| 1357 | return -EINVAL; | 1378 | return -EINVAL; |
| 1358 | if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) || | ||
| 1359 | er->idx == __BITS_VALUE(reg1->idx, 1, 8)) | ||
| 1360 | continue; | ||
| 1361 | if (WARN_ON_ONCE(reg_idx >= 2)) | ||
| 1362 | return -EINVAL; | ||
| 1363 | 1379 | ||
| 1364 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; | 1380 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; |
| 1365 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) | 1381 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) |
| @@ -1368,6 +1384,8 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1368 | /* always use the 32~63 bits to pass the PLD config */ | 1384 | /* always use the 32~63 bits to pass the PLD config */ |
| 1369 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) | 1385 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) |
| 1370 | reg_idx = 1; | 1386 | reg_idx = 1; |
| 1387 | else if (WARN_ON_ONCE(reg_idx > 0)) | ||
| 1388 | return -EINVAL; | ||
| 1371 | 1389 | ||
| 1372 | reg1->idx &= ~(0xff << (reg_idx * 8)); | 1390 | reg1->idx &= ~(0xff << (reg_idx * 8)); |
| 1373 | reg1->reg &= ~(0xffff << (reg_idx * 16)); | 1391 | reg1->reg &= ~(0xffff << (reg_idx * 16)); |
| @@ -1376,17 +1394,21 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1376 | reg1->config = event->attr.config1; | 1394 | reg1->config = event->attr.config1; |
| 1377 | reg_idx++; | 1395 | reg_idx++; |
| 1378 | } | 1396 | } |
| 1379 | /* use config2 to pass the filter config */ | 1397 | /* |
| 1380 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; | 1398 | * The mbox only provides ability to perform address matching |
| 1381 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) | 1399 | * for the PLD events. |
| 1382 | reg2->config = event->attr.config2; | 1400 | */ |
| 1383 | else | 1401 | if (reg_idx == 2) { |
| 1384 | reg2->config = ~0ULL; | 1402 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; |
| 1385 | if (box->pmu->pmu_idx == 0) | 1403 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) |
| 1386 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | 1404 | reg2->config = event->attr.config2; |
| 1387 | else | 1405 | else |
| 1388 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | 1406 | reg2->config = ~0ULL; |
| 1389 | 1407 | if (box->pmu->pmu_idx == 0) | |
| 1408 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | ||
| 1409 | else | ||
| 1410 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | ||
| 1411 | } | ||
| 1390 | return 0; | 1412 | return 0; |
| 1391 | } | 1413 | } |
| 1392 | 1414 | ||
| @@ -1422,34 +1444,36 @@ static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
| 1422 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), | 1444 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), |
| 1423 | nhmex_mbox_shared_reg_config(box, idx)); | 1445 | nhmex_mbox_shared_reg_config(box, idx)); |
| 1424 | 1446 | ||
| 1425 | wrmsrl(reg2->reg, 0); | 1447 | if (reg2->idx != EXTRA_REG_NONE) { |
| 1426 | if (reg2->config != ~0ULL) { | 1448 | wrmsrl(reg2->reg, 0); |
| 1427 | wrmsrl(reg2->reg + 1, | 1449 | if (reg2->config != ~0ULL) { |
| 1428 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); | 1450 | wrmsrl(reg2->reg + 1, |
| 1429 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & | 1451 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); |
| 1430 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); | 1452 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & |
| 1431 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | 1453 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); |
| 1454 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | ||
| 1455 | } | ||
| 1432 | } | 1456 | } |
| 1433 | 1457 | ||
| 1434 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | 1458 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); |
| 1435 | } | 1459 | } |
| 1436 | 1460 | ||
| 1437 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); | 1461 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); |
| 1438 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); | 1462 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); |
| 1439 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); | 1463 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); |
| 1440 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); | 1464 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); |
| 1441 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); | 1465 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); |
| 1442 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); | 1466 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); |
| 1443 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg, filter_cfg, "config2:63"); | 1467 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63"); |
| 1444 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); | 1468 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); |
| 1445 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); | 1469 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); |
| 1446 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); | 1470 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); |
| 1447 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); | 1471 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); |
| 1448 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); | 1472 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); |
| 1449 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); | 1473 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); |
| 1450 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); | 1474 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); |
| 1451 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); | 1475 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); |
| 1452 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); | 1476 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); |
| 1453 | 1477 | ||
| 1454 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | 1478 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { |
| 1455 | &format_attr_count_mode.attr, | 1479 | &format_attr_count_mode.attr, |
| @@ -1458,7 +1482,7 @@ static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | |||
| 1458 | &format_attr_flag_mode.attr, | 1482 | &format_attr_flag_mode.attr, |
| 1459 | &format_attr_inc_sel.attr, | 1483 | &format_attr_inc_sel.attr, |
| 1460 | &format_attr_set_flag_sel.attr, | 1484 | &format_attr_set_flag_sel.attr, |
| 1461 | &format_attr_filter_cfg.attr, | 1485 | &format_attr_filter_cfg_en.attr, |
| 1462 | &format_attr_filter_match.attr, | 1486 | &format_attr_filter_match.attr, |
| 1463 | &format_attr_filter_mask.attr, | 1487 | &format_attr_filter_mask.attr, |
| 1464 | &format_attr_dsp.attr, | 1488 | &format_attr_dsp.attr, |
| @@ -1482,6 +1506,12 @@ static struct uncore_event_desc nhmex_uncore_mbox_events[] = { | |||
| 1482 | { /* end: all zeroes */ }, | 1506 | { /* end: all zeroes */ }, |
| 1483 | }; | 1507 | }; |
| 1484 | 1508 | ||
| 1509 | static struct uncore_event_desc wsmex_uncore_mbox_events[] = { | ||
| 1510 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"), | ||
| 1511 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"), | ||
| 1512 | { /* end: all zeroes */ }, | ||
| 1513 | }; | ||
| 1514 | |||
| 1485 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { | 1515 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { |
| 1486 | NHMEX_UNCORE_OPS_COMMON_INIT(), | 1516 | NHMEX_UNCORE_OPS_COMMON_INIT(), |
| 1487 | .enable_event = nhmex_mbox_msr_enable_event, | 1517 | .enable_event = nhmex_mbox_msr_enable_event, |
| @@ -1513,7 +1543,7 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
| 1513 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1543 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| 1514 | int port; | 1544 | int port; |
| 1515 | 1545 | ||
| 1516 | /* adjust the main event selector */ | 1546 | /* adjust the main event selector and extra register index */ |
| 1517 | if (reg1->idx % 2) { | 1547 | if (reg1->idx % 2) { |
| 1518 | reg1->idx--; | 1548 | reg1->idx--; |
| 1519 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1549 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
| @@ -1522,29 +1552,17 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
| 1522 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1552 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
| 1523 | } | 1553 | } |
| 1524 | 1554 | ||
| 1525 | /* adjust address or config of extra register */ | 1555 | /* adjust extra register config */ |
| 1526 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | 1556 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; |
| 1527 | switch (reg1->idx % 6) { | 1557 | switch (reg1->idx % 6) { |
| 1528 | case 0: | ||
| 1529 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
| 1530 | break; | ||
| 1531 | case 1: | ||
| 1532 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
| 1533 | break; | ||
| 1534 | case 2: | 1558 | case 2: |
| 1535 | /* the 8~15 bits to the 0~7 bits */ | 1559 | /* shift the 8~15 bits to the 0~7 bits */ |
| 1536 | reg1->config >>= 8; | 1560 | reg1->config >>= 8; |
| 1537 | break; | 1561 | break; |
| 1538 | case 3: | 1562 | case 3: |
| 1539 | /* the 0~7 bits to the 8~15 bits */ | 1563 | /* shift the 0~7 bits to the 8~15 bits */ |
| 1540 | reg1->config <<= 8; | 1564 | reg1->config <<= 8; |
| 1541 | break; | 1565 | break; |
| 1542 | case 4: | ||
| 1543 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
| 1544 | break; | ||
| 1545 | case 5: | ||
| 1546 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
| 1547 | break; | ||
| 1548 | }; | 1566 | }; |
| 1549 | } | 1567 | } |
| 1550 | 1568 | ||
| @@ -1671,7 +1689,7 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1671 | struct hw_perf_event *hwc = &event->hw; | 1689 | struct hw_perf_event *hwc = &event->hw; |
| 1672 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | 1690 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; |
| 1673 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | 1691 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; |
| 1674 | int port, idx; | 1692 | int idx; |
| 1675 | 1693 | ||
| 1676 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> | 1694 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> |
| 1677 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1695 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
| @@ -1681,27 +1699,11 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
| 1681 | reg1->idx = idx; | 1699 | reg1->idx = idx; |
| 1682 | reg1->config = event->attr.config1; | 1700 | reg1->config = event->attr.config1; |
| 1683 | 1701 | ||
| 1684 | port = idx / 6 + box->pmu->pmu_idx * 4; | 1702 | switch (idx % 6) { |
| 1685 | idx %= 6; | ||
| 1686 | switch (idx) { | ||
| 1687 | case 0: | ||
| 1688 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
| 1689 | break; | ||
| 1690 | case 1: | ||
| 1691 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
| 1692 | break; | ||
| 1693 | case 2: | ||
| 1694 | case 3: | ||
| 1695 | reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port); | ||
| 1696 | break; | ||
| 1697 | case 4: | 1703 | case 4: |
| 1698 | case 5: | 1704 | case 5: |
| 1699 | if (idx == 4) | ||
| 1700 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
| 1701 | else | ||
| 1702 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
| 1703 | reg2->config = event->attr.config2; | ||
| 1704 | hwc->config |= event->attr.config & (~0ULL << 32); | 1705 | hwc->config |= event->attr.config & (~0ULL << 32); |
| 1706 | reg2->config = event->attr.config2; | ||
| 1705 | break; | 1707 | break; |
| 1706 | }; | 1708 | }; |
| 1707 | return 0; | 1709 | return 0; |
| @@ -1727,28 +1729,34 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
| 1727 | struct hw_perf_event *hwc = &event->hw; | 1729 | struct hw_perf_event *hwc = &event->hw; |
| 1728 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1730 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| 1729 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | 1731 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; |
| 1730 | int idx, er_idx; | 1732 | int idx, port; |
| 1731 | 1733 | ||
| 1732 | idx = reg1->idx % 6; | 1734 | idx = reg1->idx; |
| 1733 | er_idx = idx; | 1735 | port = idx / 6 + box->pmu->pmu_idx * 4; |
| 1734 | if (er_idx > 2) | ||
| 1735 | er_idx--; | ||
| 1736 | er_idx += (reg1->idx / 6) * 5; | ||
| 1737 | 1736 | ||
| 1738 | switch (idx) { | 1737 | switch (idx % 6) { |
| 1739 | case 0: | 1738 | case 0: |
| 1739 | wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config); | ||
| 1740 | break; | ||
| 1740 | case 1: | 1741 | case 1: |
| 1741 | wrmsrl(reg1->reg, reg1->config); | 1742 | wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config); |
| 1742 | break; | 1743 | break; |
| 1743 | case 2: | 1744 | case 2: |
| 1744 | case 3: | 1745 | case 3: |
| 1745 | wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx)); | 1746 | wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), |
| 1747 | nhmex_rbox_shared_reg_config(box, 2 + (idx / 6) * 5)); | ||
| 1746 | break; | 1748 | break; |
| 1747 | case 4: | 1749 | case 4: |
| 1750 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), | ||
| 1751 | hwc->config >> 32); | ||
| 1752 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config); | ||
| 1753 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config); | ||
| 1754 | break; | ||
| 1748 | case 5: | 1755 | case 5: |
| 1749 | wrmsrl(reg1->reg, reg1->config); | 1756 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port), |
| 1750 | wrmsrl(reg1->reg + 1, hwc->config >> 32); | 1757 | hwc->config >> 32); |
| 1751 | wrmsrl(reg1->reg + 2, reg2->config); | 1758 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config); |
| 1759 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config); | ||
| 1752 | break; | 1760 | break; |
| 1753 | }; | 1761 | }; |
| 1754 | 1762 | ||
| @@ -1756,8 +1764,8 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
| 1756 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); | 1764 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); |
| 1757 | } | 1765 | } |
| 1758 | 1766 | ||
| 1759 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63"); | 1767 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63"); |
| 1760 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63"); | 1768 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63"); |
| 1761 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); | 1769 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); |
| 1762 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); | 1770 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); |
| 1763 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); | 1771 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); |
| @@ -2303,6 +2311,7 @@ int uncore_pmu_event_init(struct perf_event *event) | |||
| 2303 | event->hw.idx = -1; | 2311 | event->hw.idx = -1; |
| 2304 | event->hw.last_tag = ~0ULL; | 2312 | event->hw.last_tag = ~0ULL; |
| 2305 | event->hw.extra_reg.idx = EXTRA_REG_NONE; | 2313 | event->hw.extra_reg.idx = EXTRA_REG_NONE; |
| 2314 | event->hw.branch_reg.idx = EXTRA_REG_NONE; | ||
| 2306 | 2315 | ||
| 2307 | if (event->attr.config == UNCORE_FIXED_EVENT) { | 2316 | if (event->attr.config == UNCORE_FIXED_EVENT) { |
| 2308 | /* no fixed counter */ | 2317 | /* no fixed counter */ |
| @@ -2373,7 +2382,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type) | |||
| 2373 | type->attr_groups[1] = NULL; | 2382 | type->attr_groups[1] = NULL; |
| 2374 | } | 2383 | } |
| 2375 | 2384 | ||
| 2376 | static void uncore_types_exit(struct intel_uncore_type **types) | 2385 | static void __init uncore_types_exit(struct intel_uncore_type **types) |
| 2377 | { | 2386 | { |
| 2378 | int i; | 2387 | int i; |
| 2379 | for (i = 0; types[i]; i++) | 2388 | for (i = 0; types[i]; i++) |
| @@ -2814,7 +2823,13 @@ static int __init uncore_cpu_init(void) | |||
| 2814 | snbep_uncore_cbox.num_boxes = max_cores; | 2823 | snbep_uncore_cbox.num_boxes = max_cores; |
| 2815 | msr_uncores = snbep_msr_uncores; | 2824 | msr_uncores = snbep_msr_uncores; |
| 2816 | break; | 2825 | break; |
| 2817 | case 46: | 2826 | case 46: /* Nehalem-EX */ |
| 2827 | uncore_nhmex = true; | ||
| 2828 | case 47: /* Westmere-EX aka. Xeon E7 */ | ||
| 2829 | if (!uncore_nhmex) | ||
| 2830 | nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events; | ||
| 2831 | if (nhmex_uncore_cbox.num_boxes > max_cores) | ||
| 2832 | nhmex_uncore_cbox.num_boxes = max_cores; | ||
| 2818 | msr_uncores = nhmex_msr_uncores; | 2833 | msr_uncores = nhmex_msr_uncores; |
| 2819 | break; | 2834 | break; |
| 2820 | default: | 2835 | default: |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index c9e5dc56630a..5b81c1856aac 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
| @@ -230,6 +230,7 @@ | |||
| 230 | #define NHMEX_S1_MSR_MASK 0xe5a | 230 | #define NHMEX_S1_MSR_MASK 0xe5a |
| 231 | 231 | ||
| 232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) | 232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) |
| 233 | #define NHMEX_S_EVENT_TO_R_PROG_EV 0 | ||
| 233 | 234 | ||
| 234 | /* NHM-EX Mbox */ | 235 | /* NHM-EX Mbox */ |
| 235 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 | 236 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 |
| @@ -275,18 +276,12 @@ | |||
| 275 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | 276 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ |
| 276 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) | 277 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) |
| 277 | 278 | ||
| 278 | 279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23)) | |
| 279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f | ||
| 280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5) | ||
| 281 | #define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8) | ||
| 282 | #define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23) | ||
| 283 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \ | ||
| 284 | (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \ | ||
| 285 | NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \ | ||
| 286 | NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \ | ||
| 287 | NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR) | ||
| 288 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) | 280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) |
| 289 | 281 | ||
| 282 | #define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24)) | ||
| 283 | #define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (12 + 3 * (n))) | ||
| 284 | |||
| 290 | /* | 285 | /* |
| 291 | * use the 9~13 bits to select event If the 7th bit is not set, | 286 | * use the 9~13 bits to select event If the 7th bit is not set, |
| 292 | * otherwise use the 19~21 bits to select event. | 287 | * otherwise use the 19~21 bits to select event. |
| @@ -368,6 +363,7 @@ struct intel_uncore_type { | |||
| 368 | unsigned num_shared_regs:8; | 363 | unsigned num_shared_regs:8; |
| 369 | unsigned single_fixed:1; | 364 | unsigned single_fixed:1; |
| 370 | unsigned pair_ctr_ctl:1; | 365 | unsigned pair_ctr_ctl:1; |
| 366 | unsigned *msr_offsets; | ||
| 371 | struct event_constraint unconstrainted; | 367 | struct event_constraint unconstrainted; |
| 372 | struct event_constraint *constraints; | 368 | struct event_constraint *constraints; |
| 373 | struct intel_uncore_pmu *pmus; | 369 | struct intel_uncore_pmu *pmus; |
| @@ -485,29 +481,31 @@ unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) | |||
| 485 | return idx * 8 + box->pmu->type->perf_ctr; | 481 | return idx * 8 + box->pmu->type->perf_ctr; |
| 486 | } | 482 | } |
| 487 | 483 | ||
| 488 | static inline | 484 | static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box) |
| 489 | unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) | 485 | { |
| 486 | struct intel_uncore_pmu *pmu = box->pmu; | ||
| 487 | return pmu->type->msr_offsets ? | ||
| 488 | pmu->type->msr_offsets[pmu->pmu_idx] : | ||
| 489 | pmu->type->msr_offset * pmu->pmu_idx; | ||
| 490 | } | ||
| 491 | |||
| 492 | static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) | ||
| 490 | { | 493 | { |
| 491 | if (!box->pmu->type->box_ctl) | 494 | if (!box->pmu->type->box_ctl) |
| 492 | return 0; | 495 | return 0; |
| 493 | return box->pmu->type->box_ctl + | 496 | return box->pmu->type->box_ctl + uncore_msr_box_offset(box); |
| 494 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
| 495 | } | 497 | } |
| 496 | 498 | ||
| 497 | static inline | 499 | static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) |
| 498 | unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) | ||
| 499 | { | 500 | { |
| 500 | if (!box->pmu->type->fixed_ctl) | 501 | if (!box->pmu->type->fixed_ctl) |
| 501 | return 0; | 502 | return 0; |
| 502 | return box->pmu->type->fixed_ctl + | 503 | return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box); |
| 503 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | static inline | 506 | static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) |
| 507 | unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) | ||
| 508 | { | 507 | { |
| 509 | return box->pmu->type->fixed_ctr + | 508 | return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box); |
| 510 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
| 511 | } | 509 | } |
| 512 | 510 | ||
| 513 | static inline | 511 | static inline |
| @@ -515,7 +513,7 @@ unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | |||
| 515 | { | 513 | { |
| 516 | return box->pmu->type->event_ctl + | 514 | return box->pmu->type->event_ctl + |
| 517 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 515 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
| 518 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 516 | uncore_msr_box_offset(box); |
| 519 | } | 517 | } |
| 520 | 518 | ||
| 521 | static inline | 519 | static inline |
| @@ -523,7 +521,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | |||
| 523 | { | 521 | { |
| 524 | return box->pmu->type->perf_ctr + | 522 | return box->pmu->type->perf_ctr + |
| 525 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 523 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
| 526 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 524 | uncore_msr_box_offset(box); |
| 527 | } | 525 | } |
| 528 | 526 | ||
| 529 | static inline | 527 | static inline |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 931930a96160..a718e0d23503 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -919,13 +919,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
| 919 | 919 | ||
| 920 | /* | 920 | /* |
| 921 | * On success we use clflush, when the CPU supports it to | 921 | * On success we use clflush, when the CPU supports it to |
| 922 | * avoid the wbindv. If the CPU does not support it, in the | 922 | * avoid the wbindv. If the CPU does not support it and in the |
| 923 | * error case, and during early boot (for EFI) we fall back | 923 | * error case we fall back to cpa_flush_all (which uses |
| 924 | * to cpa_flush_all (which uses wbinvd): | 924 | * wbindv): |
| 925 | */ | 925 | */ |
| 926 | if (early_boot_irqs_disabled) | 926 | if (!ret && cpu_has_clflush) { |
| 927 | __cpa_flush_all((void *)(long)cache); | ||
| 928 | else if (!ret && cpu_has_clflush) { | ||
| 929 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { | 927 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { |
| 930 | cpa_flush_array(addr, numpages, cache, | 928 | cpa_flush_array(addr, numpages, cache, |
| 931 | cpa.flags, pages); | 929 | cpa.flags, pages); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 2dc29f51e75a..92660edaa1e7 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
| @@ -234,7 +234,22 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
| 234 | return status; | 234 | return status; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static int efi_set_rtc_mmss(unsigned long nowtime) | 237 | static efi_status_t __init phys_efi_get_time(efi_time_t *tm, |
| 238 | efi_time_cap_t *tc) | ||
| 239 | { | ||
| 240 | unsigned long flags; | ||
| 241 | efi_status_t status; | ||
| 242 | |||
| 243 | spin_lock_irqsave(&rtc_lock, flags); | ||
| 244 | efi_call_phys_prelog(); | ||
| 245 | status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), | ||
| 246 | virt_to_phys(tc)); | ||
| 247 | efi_call_phys_epilog(); | ||
| 248 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
| 249 | return status; | ||
| 250 | } | ||
| 251 | |||
| 252 | int efi_set_rtc_mmss(unsigned long nowtime) | ||
| 238 | { | 253 | { |
| 239 | int real_seconds, real_minutes; | 254 | int real_seconds, real_minutes; |
| 240 | efi_status_t status; | 255 | efi_status_t status; |
| @@ -263,7 +278,7 @@ static int efi_set_rtc_mmss(unsigned long nowtime) | |||
| 263 | return 0; | 278 | return 0; |
| 264 | } | 279 | } |
| 265 | 280 | ||
| 266 | static unsigned long efi_get_time(void) | 281 | unsigned long efi_get_time(void) |
| 267 | { | 282 | { |
| 268 | efi_status_t status; | 283 | efi_status_t status; |
| 269 | efi_time_t eft; | 284 | efi_time_t eft; |
| @@ -606,13 +621,18 @@ static int __init efi_runtime_init(void) | |||
| 606 | } | 621 | } |
| 607 | /* | 622 | /* |
| 608 | * We will only need *early* access to the following | 623 | * We will only need *early* access to the following |
| 609 | * EFI runtime service before set_virtual_address_map | 624 | * two EFI runtime services before set_virtual_address_map |
| 610 | * is invoked. | 625 | * is invoked. |
| 611 | */ | 626 | */ |
| 627 | efi_phys.get_time = (efi_get_time_t *)runtime->get_time; | ||
| 612 | efi_phys.set_virtual_address_map = | 628 | efi_phys.set_virtual_address_map = |
| 613 | (efi_set_virtual_address_map_t *) | 629 | (efi_set_virtual_address_map_t *) |
| 614 | runtime->set_virtual_address_map; | 630 | runtime->set_virtual_address_map; |
| 615 | 631 | /* | |
| 632 | * Make efi_get_time can be called before entering | ||
| 633 | * virtual mode. | ||
| 634 | */ | ||
| 635 | efi.get_time = phys_efi_get_time; | ||
| 616 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); | 636 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); |
| 617 | 637 | ||
| 618 | return 0; | 638 | return 0; |
| @@ -700,10 +720,12 @@ void __init efi_init(void) | |||
| 700 | efi_enabled = 0; | 720 | efi_enabled = 0; |
| 701 | return; | 721 | return; |
| 702 | } | 722 | } |
| 723 | #ifdef CONFIG_X86_32 | ||
| 703 | if (efi_native) { | 724 | if (efi_native) { |
| 704 | x86_platform.get_wallclock = efi_get_time; | 725 | x86_platform.get_wallclock = efi_get_time; |
| 705 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 726 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
| 706 | } | 727 | } |
| 728 | #endif | ||
| 707 | 729 | ||
| 708 | #if EFI_DEBUG | 730 | #if EFI_DEBUG |
| 709 | print_efi_memmap(); | 731 | print_efi_memmap(); |
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index b2d534cab25f..88692871823f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
| @@ -72,7 +72,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \ | |||
| 72 | -Wall -Wstrict-prototypes \ | 72 | -Wall -Wstrict-prototypes \ |
| 73 | -march=i386 -mregparm=3 \ | 73 | -march=i386 -mregparm=3 \ |
| 74 | -include $(srctree)/$(src)/../../boot/code16gcc.h \ | 74 | -include $(srctree)/$(src)/../../boot/code16gcc.h \ |
| 75 | -fno-strict-aliasing -fomit-frame-pointer \ | 75 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
| 76 | $(call cc-option, -ffreestanding) \ | 76 | $(call cc-option, -ffreestanding) \ |
| 77 | $(call cc-option, -fno-toplevel-reorder,\ | 77 | $(call cc-option, -fno-toplevel-reorder,\ |
| 78 | $(call cc-option, -fno-unit-at-a-time)) \ | 78 | $(call cc-option, -fno-unit-at-a-time)) \ |
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index 29aed7ac2c02..a582bfed95bb 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl | |||
| @@ -60,8 +60,8 @@ | |||
| 60 | 51 common getsockname sys_getsockname | 60 | 51 common getsockname sys_getsockname |
| 61 | 52 common getpeername sys_getpeername | 61 | 52 common getpeername sys_getpeername |
| 62 | 53 common socketpair sys_socketpair | 62 | 53 common socketpair sys_socketpair |
| 63 | 54 common setsockopt sys_setsockopt | 63 | 54 64 setsockopt sys_setsockopt |
| 64 | 55 common getsockopt sys_getsockopt | 64 | 55 64 getsockopt sys_getsockopt |
| 65 | 56 common clone stub_clone | 65 | 56 common clone stub_clone |
| 66 | 57 common fork stub_fork | 66 | 57 common fork stub_fork |
| 67 | 58 common vfork stub_vfork | 67 | 58 common vfork stub_vfork |
| @@ -353,3 +353,5 @@ | |||
| 353 | 538 x32 sendmmsg compat_sys_sendmmsg | 353 | 538 x32 sendmmsg compat_sys_sendmmsg |
| 354 | 539 x32 process_vm_readv compat_sys_process_vm_readv | 354 | 539 x32 process_vm_readv compat_sys_process_vm_readv |
| 355 | 540 x32 process_vm_writev compat_sys_process_vm_writev | 355 | 540 x32 process_vm_writev compat_sys_process_vm_writev |
| 356 | 541 x32 setsockopt compat_sys_setsockopt | ||
| 357 | 542 x32 getsockopt compat_sys_getsockopt | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index f338037a4f3d..5e6e00bc1652 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
| @@ -1865,6 +1865,7 @@ int __dev_printk(const char *level, const struct device *dev, | |||
| 1865 | struct va_format *vaf) | 1865 | struct va_format *vaf) |
| 1866 | { | 1866 | { |
| 1867 | char dict[128]; | 1867 | char dict[128]; |
| 1868 | const char *level_extra = ""; | ||
| 1868 | size_t dictlen = 0; | 1869 | size_t dictlen = 0; |
| 1869 | const char *subsys; | 1870 | const char *subsys; |
| 1870 | 1871 | ||
| @@ -1911,10 +1912,14 @@ int __dev_printk(const char *level, const struct device *dev, | |||
| 1911 | "DEVICE=+%s:%s", subsys, dev_name(dev)); | 1912 | "DEVICE=+%s:%s", subsys, dev_name(dev)); |
| 1912 | } | 1913 | } |
| 1913 | skip: | 1914 | skip: |
| 1915 | if (level[2]) | ||
| 1916 | level_extra = &level[2]; /* skip past KERN_SOH "L" */ | ||
| 1917 | |||
| 1914 | return printk_emit(0, level[1] - '0', | 1918 | return printk_emit(0, level[1] - '0', |
| 1915 | dictlen ? dict : NULL, dictlen, | 1919 | dictlen ? dict : NULL, dictlen, |
| 1916 | "%s %s: %pV", | 1920 | "%s %s: %s%pV", |
| 1917 | dev_driver_string(dev), dev_name(dev), vaf); | 1921 | dev_driver_string(dev), dev_name(dev), |
| 1922 | level_extra, vaf); | ||
| 1918 | } | 1923 | } |
| 1919 | EXPORT_SYMBOL(__dev_printk); | 1924 | EXPORT_SYMBOL(__dev_printk); |
| 1920 | 1925 | ||
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 59894873a3b3..7d9c1cb1c39a 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
| @@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
| 147 | || (dev->power.request_pending | 147 | || (dev->power.request_pending |
| 148 | && dev->power.request == RPM_REQ_RESUME)) | 148 | && dev->power.request == RPM_REQ_RESUME)) |
| 149 | retval = -EAGAIN; | 149 | retval = -EAGAIN; |
| 150 | else if (__dev_pm_qos_read_value(dev) < 0) | ||
| 151 | retval = -EPERM; | ||
| 150 | else if (dev->power.runtime_status == RPM_SUSPENDED) | 152 | else if (dev->power.runtime_status == RPM_SUSPENDED) |
| 151 | retval = 1; | 153 | retval = 1; |
| 152 | 154 | ||
| @@ -388,7 +390,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
| 388 | goto repeat; | 390 | goto repeat; |
| 389 | } | 391 | } |
| 390 | 392 | ||
| 391 | dev->power.deferred_resume = false; | ||
| 392 | if (dev->power.no_callbacks) | 393 | if (dev->power.no_callbacks) |
| 393 | goto no_callback; /* Assume success. */ | 394 | goto no_callback; /* Assume success. */ |
| 394 | 395 | ||
| @@ -403,12 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
| 403 | goto out; | 404 | goto out; |
| 404 | } | 405 | } |
| 405 | 406 | ||
| 406 | if (__dev_pm_qos_read_value(dev) < 0) { | ||
| 407 | /* Negative PM QoS constraint means "never suspend". */ | ||
| 408 | retval = -EPERM; | ||
| 409 | goto out; | ||
| 410 | } | ||
| 411 | |||
| 412 | __update_runtime_status(dev, RPM_SUSPENDING); | 407 | __update_runtime_status(dev, RPM_SUSPENDING); |
| 413 | 408 | ||
| 414 | if (dev->pm_domain) | 409 | if (dev->pm_domain) |
| @@ -440,6 +435,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
| 440 | wake_up_all(&dev->power.wait_queue); | 435 | wake_up_all(&dev->power.wait_queue); |
| 441 | 436 | ||
| 442 | if (dev->power.deferred_resume) { | 437 | if (dev->power.deferred_resume) { |
| 438 | dev->power.deferred_resume = false; | ||
| 443 | rpm_resume(dev, 0); | 439 | rpm_resume(dev, 0); |
| 444 | retval = -EAGAIN; | 440 | retval = -EAGAIN; |
| 445 | goto out; | 441 | goto out; |
| @@ -584,6 +580,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
| 584 | || dev->parent->power.runtime_status == RPM_ACTIVE) { | 580 | || dev->parent->power.runtime_status == RPM_ACTIVE) { |
| 585 | atomic_inc(&dev->parent->power.child_count); | 581 | atomic_inc(&dev->parent->power.child_count); |
| 586 | spin_unlock(&dev->parent->power.lock); | 582 | spin_unlock(&dev->parent->power.lock); |
| 583 | retval = 1; | ||
| 587 | goto no_callback; /* Assume success. */ | 584 | goto no_callback; /* Assume success. */ |
| 588 | } | 585 | } |
| 589 | spin_unlock(&dev->parent->power.lock); | 586 | spin_unlock(&dev->parent->power.lock); |
| @@ -664,7 +661,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
| 664 | } | 661 | } |
| 665 | wake_up_all(&dev->power.wait_queue); | 662 | wake_up_all(&dev->power.wait_queue); |
| 666 | 663 | ||
| 667 | if (!retval) | 664 | if (retval >= 0) |
| 668 | rpm_idle(dev, RPM_ASYNC); | 665 | rpm_idle(dev, RPM_ASYNC); |
| 669 | 666 | ||
| 670 | out: | 667 | out: |
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 2c9bf2692232..3265844839bf 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c | |||
| @@ -678,10 +678,22 @@ static int cpuidle_coupled_cpu_notify(struct notifier_block *nb, | |||
| 678 | int cpu = (unsigned long)hcpu; | 678 | int cpu = (unsigned long)hcpu; |
| 679 | struct cpuidle_device *dev; | 679 | struct cpuidle_device *dev; |
| 680 | 680 | ||
| 681 | switch (action & ~CPU_TASKS_FROZEN) { | ||
| 682 | case CPU_UP_PREPARE: | ||
| 683 | case CPU_DOWN_PREPARE: | ||
| 684 | case CPU_ONLINE: | ||
| 685 | case CPU_DEAD: | ||
| 686 | case CPU_UP_CANCELED: | ||
| 687 | case CPU_DOWN_FAILED: | ||
| 688 | break; | ||
| 689 | default: | ||
| 690 | return NOTIFY_OK; | ||
| 691 | } | ||
| 692 | |||
| 681 | mutex_lock(&cpuidle_lock); | 693 | mutex_lock(&cpuidle_lock); |
| 682 | 694 | ||
| 683 | dev = per_cpu(cpuidle_devices, cpu); | 695 | dev = per_cpu(cpuidle_devices, cpu); |
| 684 | if (!dev->coupled) | 696 | if (!dev || !dev->coupled) |
| 685 | goto out; | 697 | goto out; |
| 686 | 698 | ||
| 687 | switch (action & ~CPU_TASKS_FROZEN) { | 699 | switch (action & ~CPU_TASKS_FROZEN) { |
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe3db45fa83c..3cc152e690b0 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c | |||
| @@ -107,7 +107,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) | |||
| 107 | if (ret < 0) | 107 | if (ret < 0) |
| 108 | return ret; | 108 | return ret; |
| 109 | 109 | ||
| 110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); | 110 | ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, |
| 111 | pdev->name); | ||
| 111 | if (ret < 0) | 112 | if (ret < 0) |
| 112 | goto err; | 113 | goto err; |
| 113 | 114 | ||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 23120c00a881..90e28081712d 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
| @@ -22,6 +22,7 @@ menuconfig DRM | |||
| 22 | config DRM_USB | 22 | config DRM_USB |
| 23 | tristate | 23 | tristate |
| 24 | depends on DRM | 24 | depends on DRM |
| 25 | depends on USB_ARCH_HAS_HCD | ||
| 25 | select USB | 26 | select USB |
| 26 | 27 | ||
| 27 | config DRM_KMS_HELPER | 28 | config DRM_KMS_HELPER |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fc841e87b343..26ebffebe710 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
| @@ -211,11 +211,6 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, | |||
| 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static int nouveau_dsm_init(void) | ||
| 215 | { | ||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | 214 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) |
| 220 | { | 215 | { |
| 221 | /* easy option one - intel vendor ID means Integrated */ | 216 | /* easy option one - intel vendor ID means Integrated */ |
| @@ -232,7 +227,6 @@ static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | |||
| 232 | static struct vga_switcheroo_handler nouveau_dsm_handler = { | 227 | static struct vga_switcheroo_handler nouveau_dsm_handler = { |
| 233 | .switchto = nouveau_dsm_switchto, | 228 | .switchto = nouveau_dsm_switchto, |
| 234 | .power_state = nouveau_dsm_power_state, | 229 | .power_state = nouveau_dsm_power_state, |
| 235 | .init = nouveau_dsm_init, | ||
| 236 | .get_client_id = nouveau_dsm_get_client_id, | 230 | .get_client_id = nouveau_dsm_get_client_id, |
| 237 | }; | 231 | }; |
| 238 | 232 | ||
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index 0b5e096d39a6..56e0bf31d425 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config DRM_UDL | 1 | config DRM_UDL |
| 2 | tristate "DisplayLink" | 2 | tristate "DisplayLink" |
| 3 | depends on DRM && EXPERIMENTAL | 3 | depends on DRM && EXPERIMENTAL |
| 4 | depends on USB_ARCH_HAS_HCD | ||
| 4 | select DRM_USB | 5 | select DRM_USB |
| 5 | select FB_SYS_FILLRECT | 6 | select FB_SYS_FILLRECT |
| 6 | select FB_SYS_COPYAREA | 7 | select FB_SYS_COPYAREA |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc9..e25cf31faab2 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
| @@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = { | |||
| 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), | 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | 73 | static bool vga_switcheroo_ready(void) |
| 74 | { | ||
| 75 | mutex_lock(&vgasr_mutex); | ||
| 76 | if (vgasr_priv.handler) { | ||
| 77 | mutex_unlock(&vgasr_mutex); | ||
| 78 | return -EINVAL; | ||
| 79 | } | ||
| 80 | |||
| 81 | vgasr_priv.handler = handler; | ||
| 82 | mutex_unlock(&vgasr_mutex); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
| 86 | |||
| 87 | void vga_switcheroo_unregister_handler(void) | ||
| 88 | { | 74 | { |
| 89 | mutex_lock(&vgasr_mutex); | 75 | /* we're ready if we get two clients + handler */ |
| 90 | vgasr_priv.handler = NULL; | 76 | return !vgasr_priv.active && |
| 91 | mutex_unlock(&vgasr_mutex); | 77 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler; |
| 92 | } | 78 | } |
| 93 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
| 94 | 79 | ||
| 95 | static void vga_switcheroo_enable(void) | 80 | static void vga_switcheroo_enable(void) |
| 96 | { | 81 | { |
| @@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void) | |||
| 98 | struct vga_switcheroo_client *client; | 83 | struct vga_switcheroo_client *client; |
| 99 | 84 | ||
| 100 | /* call the handler to init */ | 85 | /* call the handler to init */ |
| 101 | vgasr_priv.handler->init(); | 86 | if (vgasr_priv.handler->init) |
| 87 | vgasr_priv.handler->init(); | ||
| 102 | 88 | ||
| 103 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 89 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
| 104 | if (client->id != -1) | 90 | if (client->id != -1) |
| @@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void) | |||
| 113 | vgasr_priv.active = true; | 99 | vgasr_priv.active = true; |
| 114 | } | 100 | } |
| 115 | 101 | ||
| 102 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | ||
| 103 | { | ||
| 104 | mutex_lock(&vgasr_mutex); | ||
| 105 | if (vgasr_priv.handler) { | ||
| 106 | mutex_unlock(&vgasr_mutex); | ||
| 107 | return -EINVAL; | ||
| 108 | } | ||
| 109 | |||
| 110 | vgasr_priv.handler = handler; | ||
| 111 | if (vga_switcheroo_ready()) { | ||
| 112 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | ||
| 113 | vga_switcheroo_enable(); | ||
| 114 | } | ||
| 115 | mutex_unlock(&vgasr_mutex); | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
| 119 | |||
| 120 | void vga_switcheroo_unregister_handler(void) | ||
| 121 | { | ||
| 122 | mutex_lock(&vgasr_mutex); | ||
| 123 | vgasr_priv.handler = NULL; | ||
| 124 | if (vgasr_priv.active) { | ||
| 125 | pr_info("vga_switcheroo: disabled\n"); | ||
| 126 | vga_switcheroo_debugfs_fini(&vgasr_priv); | ||
| 127 | vgasr_priv.active = false; | ||
| 128 | } | ||
| 129 | mutex_unlock(&vgasr_mutex); | ||
| 130 | } | ||
| 131 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
| 132 | |||
| 116 | static int register_client(struct pci_dev *pdev, | 133 | static int register_client(struct pci_dev *pdev, |
| 117 | const struct vga_switcheroo_client_ops *ops, | 134 | const struct vga_switcheroo_client_ops *ops, |
| 118 | int id, bool active) | 135 | int id, bool active) |
| @@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev, | |||
| 134 | if (client_is_vga(client)) | 151 | if (client_is_vga(client)) |
| 135 | vgasr_priv.registered_clients++; | 152 | vgasr_priv.registered_clients++; |
| 136 | 153 | ||
| 137 | /* if we get two clients + handler */ | 154 | if (vga_switcheroo_ready()) { |
| 138 | if (!vgasr_priv.active && | ||
| 139 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { | ||
| 140 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | 155 | printk(KERN_INFO "vga_switcheroo: enabled\n"); |
| 141 | vga_switcheroo_enable(); | 156 | vga_switcheroo_enable(); |
| 142 | } | 157 | } |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index faa16f80db9c..0fa356fe82cc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -196,7 +196,7 @@ struct tjmax { | |||
| 196 | int tjmax; | 196 | int tjmax; |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static struct tjmax __cpuinitconst tjmax_table[] = { | 199 | static const struct tjmax __cpuinitconst tjmax_table[] = { |
| 200 | { "CPU D410", 100000 }, | 200 | { "CPU D410", 100000 }, |
| 201 | { "CPU D425", 100000 }, | 201 | { "CPU D425", 100000 }, |
| 202 | { "CPU D510", 100000 }, | 202 | { "CPU D510", 100000 }, |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index ab4825205a9d..5b1a6a666441 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
| @@ -1206,7 +1206,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, | |||
| 1206 | int err = -ENODEV; | 1206 | int err = -ENODEV; |
| 1207 | u16 val; | 1207 | u16 val; |
| 1208 | 1208 | ||
| 1209 | static const __initdata char *names[] = { | 1209 | static __initconst char *const names[] = { |
| 1210 | "W83627HF", | 1210 | "W83627HF", |
| 1211 | "W83627THF", | 1211 | "W83627THF", |
| 1212 | "W83697HF", | 1212 | "W83697HF", |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index f559088869f6..e8726177d103 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -606,8 +606,9 @@ static int __init intel_idle_init(void) | |||
| 606 | intel_idle_cpuidle_driver_init(); | 606 | intel_idle_cpuidle_driver_init(); |
| 607 | retval = cpuidle_register_driver(&intel_idle_driver); | 607 | retval = cpuidle_register_driver(&intel_idle_driver); |
| 608 | if (retval) { | 608 | if (retval) { |
| 609 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
| 609 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | 610 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", |
| 610 | cpuidle_get_driver()->name); | 611 | drv ? drv->name : "none"); |
| 611 | return retval; | 612 | return retval; |
| 612 | } | 613 | } |
| 613 | 614 | ||
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 59fbb3ae40e7..e35bb8f6fe75 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c | |||
| @@ -129,7 +129,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
| 129 | { | 129 | { |
| 130 | struct adf4350_platform_data *pdata = st->pdata; | 130 | struct adf4350_platform_data *pdata = st->pdata; |
| 131 | u64 tmp; | 131 | u64 tmp; |
| 132 | u32 div_gcd, prescaler; | 132 | u32 div_gcd, prescaler, chspc; |
| 133 | u16 mdiv, r_cnt = 0; | 133 | u16 mdiv, r_cnt = 0; |
| 134 | u8 band_sel_div; | 134 | u8 band_sel_div; |
| 135 | 135 | ||
| @@ -158,14 +158,20 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
| 158 | if (pdata->ref_div_factor) | 158 | if (pdata->ref_div_factor) |
| 159 | r_cnt = pdata->ref_div_factor - 1; | 159 | r_cnt = pdata->ref_div_factor - 1; |
| 160 | 160 | ||
| 161 | do { | 161 | chspc = st->chspc; |
| 162 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | ||
| 163 | 162 | ||
| 164 | st->r1_mod = st->fpfd / st->chspc; | 163 | do { |
| 165 | while (st->r1_mod > ADF4350_MAX_MODULUS) { | 164 | do { |
| 166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | 165 | do { |
| 167 | st->r1_mod = st->fpfd / st->chspc; | 166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); |
| 168 | } | 167 | st->r1_mod = st->fpfd / chspc; |
| 168 | if (r_cnt > ADF4350_MAX_R_CNT) { | ||
| 169 | /* try higher spacing values */ | ||
| 170 | chspc++; | ||
| 171 | r_cnt = 0; | ||
| 172 | } | ||
| 173 | } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); | ||
| 174 | } while (r_cnt == 0); | ||
| 169 | 175 | ||
| 170 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); | 176 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); |
| 171 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ | 177 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ |
| @@ -194,7 +200,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
| 194 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | | 200 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | |
| 195 | ADF4350_REG0_FRACT(st->r0_fract); | 201 | ADF4350_REG0_FRACT(st->r0_fract); |
| 196 | 202 | ||
| 197 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) | | 203 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(1) | |
| 198 | ADF4350_REG1_MOD(st->r1_mod) | | 204 | ADF4350_REG1_MOD(st->r1_mod) | |
| 199 | prescaler; | 205 | prescaler; |
| 200 | 206 | ||
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 1cbb449b319a..9a99f43094f0 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c | |||
| @@ -271,9 +271,10 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev, | |||
| 271 | const unsigned long *scan_mask) | 271 | const unsigned long *scan_mask) |
| 272 | { | 272 | { |
| 273 | struct adjd_s311_data *data = iio_priv(indio_dev); | 273 | struct adjd_s311_data *data = iio_priv(indio_dev); |
| 274 | data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, | 274 | |
| 275 | GFP_KERNEL); | 275 | kfree(data->buffer); |
| 276 | if (!data->buffer) | 276 | data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); |
| 277 | if (data->buffer == NULL) | ||
| 277 | return -ENOMEM; | 278 | return -ENOMEM; |
| 278 | 279 | ||
| 279 | return 0; | 280 | return 0; |
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index c3e7bac13123..e45712a921ce 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c | |||
| @@ -404,7 +404,7 @@ out: | |||
| 404 | return ret; | 404 | return ret; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | static int show_thresh_either_en(struct device *dev, | 407 | static ssize_t show_thresh_either_en(struct device *dev, |
| 408 | struct device_attribute *attr, | 408 | struct device_attribute *attr, |
| 409 | char *buf) | 409 | char *buf) |
| 410 | { | 410 | { |
| @@ -424,7 +424,7 @@ static int show_thresh_either_en(struct device *dev, | |||
| 424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); | 424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static int store_thresh_either_en(struct device *dev, | 427 | static ssize_t store_thresh_either_en(struct device *dev, |
| 428 | struct device_attribute *attr, | 428 | struct device_attribute *attr, |
| 429 | const char *buf, size_t len) | 429 | const char *buf, size_t len) |
| 430 | { | 430 | { |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6bf850422895..055ed59838dc 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -267,6 +267,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
| 267 | if (!uevent) | 267 | if (!uevent) |
| 268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; | 268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; |
| 269 | 269 | ||
| 270 | mutex_lock(&ctx->file->mut); | ||
| 270 | uevent->cm_id = cm_id; | 271 | uevent->cm_id = cm_id; |
| 271 | ucma_set_event_context(ctx, event, uevent); | 272 | ucma_set_event_context(ctx, event, uevent); |
| 272 | uevent->resp.event = event->event; | 273 | uevent->resp.event = event->event; |
| @@ -277,7 +278,6 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
| 277 | ucma_copy_conn_event(&uevent->resp.param.conn, | 278 | ucma_copy_conn_event(&uevent->resp.param.conn, |
| 278 | &event->param.conn); | 279 | &event->param.conn); |
| 279 | 280 | ||
| 280 | mutex_lock(&ctx->file->mut); | ||
| 281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { | 281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { |
| 282 | if (!ctx->backlog) { | 282 | if (!ctx->backlog) { |
| 283 | ret = -ENOMEM; | 283 | ret = -ENOMEM; |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 8c81992fa6db..e4a73158fc7f 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
| @@ -439,7 +439,7 @@ static int c2_rnic_close(struct c2_dev *c2dev) | |||
| 439 | 439 | ||
| 440 | /* | 440 | /* |
| 441 | * Called by c2_probe to initialize the RNIC. This principally | 441 | * Called by c2_probe to initialize the RNIC. This principally |
| 442 | * involves initalizing the various limits and resouce pools that | 442 | * involves initializing the various limits and resource pools that |
| 443 | * comprise the RNIC instance. | 443 | * comprise the RNIC instance. |
| 444 | */ | 444 | */ |
| 445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) | 445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 77b6b182778a..aaf88ef9409c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
| @@ -1680,7 +1680,7 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1680 | * T3A does 3 things when a TERM is received: | 1680 | * T3A does 3 things when a TERM is received: |
| 1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet | 1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet |
| 1682 | * 2) generate an async event on the QP with the TERMINATE opcode | 1682 | * 2) generate an async event on the QP with the TERMINATE opcode |
| 1683 | * 3) post a TERMINATE opcde cqe into the associated CQ. | 1683 | * 3) post a TERMINATE opcode cqe into the associated CQ. |
| 1684 | * | 1684 | * |
| 1685 | * For (1), we save the message in the qp for later consumer consumption. | 1685 | * For (1), we save the message in the qp for later consumer consumption. |
| 1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. | 1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index c27141fef1ab..9c2ae7efd00f 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
| @@ -125,6 +125,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
| 125 | { | 125 | { |
| 126 | struct ib_ah *new_ah; | 126 | struct ib_ah *new_ah; |
| 127 | struct ib_ah_attr ah_attr; | 127 | struct ib_ah_attr ah_attr; |
| 128 | unsigned long flags; | ||
| 128 | 129 | ||
| 129 | if (!dev->send_agent[port_num - 1][0]) | 130 | if (!dev->send_agent[port_num - 1][0]) |
| 130 | return; | 131 | return; |
| @@ -139,11 +140,11 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
| 139 | if (IS_ERR(new_ah)) | 140 | if (IS_ERR(new_ah)) |
| 140 | return; | 141 | return; |
| 141 | 142 | ||
| 142 | spin_lock(&dev->sm_lock); | 143 | spin_lock_irqsave(&dev->sm_lock, flags); |
| 143 | if (dev->sm_ah[port_num - 1]) | 144 | if (dev->sm_ah[port_num - 1]) |
| 144 | ib_destroy_ah(dev->sm_ah[port_num - 1]); | 145 | ib_destroy_ah(dev->sm_ah[port_num - 1]); |
| 145 | dev->sm_ah[port_num - 1] = new_ah; | 146 | dev->sm_ah[port_num - 1] = new_ah; |
| 146 | spin_unlock(&dev->sm_lock); | 147 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
| 147 | } | 148 | } |
| 148 | 149 | ||
| 149 | /* | 150 | /* |
| @@ -197,13 +198,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
| 197 | static void node_desc_override(struct ib_device *dev, | 198 | static void node_desc_override(struct ib_device *dev, |
| 198 | struct ib_mad *mad) | 199 | struct ib_mad *mad) |
| 199 | { | 200 | { |
| 201 | unsigned long flags; | ||
| 202 | |||
| 200 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || | 203 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || |
| 201 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && | 204 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && |
| 202 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && | 205 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && |
| 203 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { | 206 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { |
| 204 | spin_lock(&to_mdev(dev)->sm_lock); | 207 | spin_lock_irqsave(&to_mdev(dev)->sm_lock, flags); |
| 205 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); | 208 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); |
| 206 | spin_unlock(&to_mdev(dev)->sm_lock); | 209 | spin_unlock_irqrestore(&to_mdev(dev)->sm_lock, flags); |
| 207 | } | 210 | } |
| 208 | } | 211 | } |
| 209 | 212 | ||
| @@ -213,6 +216,7 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
| 213 | struct ib_mad_send_buf *send_buf; | 216 | struct ib_mad_send_buf *send_buf; |
| 214 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; | 217 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; |
| 215 | int ret; | 218 | int ret; |
| 219 | unsigned long flags; | ||
| 216 | 220 | ||
| 217 | if (agent) { | 221 | if (agent) { |
| 218 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, | 222 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, |
| @@ -225,13 +229,13 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
| 225 | * wrong following the IB spec strictly, but we know | 229 | * wrong following the IB spec strictly, but we know |
| 226 | * it's OK for our devices). | 230 | * it's OK for our devices). |
| 227 | */ | 231 | */ |
| 228 | spin_lock(&dev->sm_lock); | 232 | spin_lock_irqsave(&dev->sm_lock, flags); |
| 229 | memcpy(send_buf->mad, mad, sizeof *mad); | 233 | memcpy(send_buf->mad, mad, sizeof *mad); |
| 230 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) | 234 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) |
| 231 | ret = ib_post_send_mad(send_buf, NULL); | 235 | ret = ib_post_send_mad(send_buf, NULL); |
| 232 | else | 236 | else |
| 233 | ret = -EINVAL; | 237 | ret = -EINVAL; |
| 234 | spin_unlock(&dev->sm_lock); | 238 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
| 235 | 239 | ||
| 236 | if (ret) | 240 | if (ret) |
| 237 | ib_free_send_mad(send_buf); | 241 | ib_free_send_mad(send_buf); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index fe2088cfa6ee..cc05579ebce7 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
| @@ -423,6 +423,7 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
| 423 | struct ib_device_modify *props) | 423 | struct ib_device_modify *props) |
| 424 | { | 424 | { |
| 425 | struct mlx4_cmd_mailbox *mailbox; | 425 | struct mlx4_cmd_mailbox *mailbox; |
| 426 | unsigned long flags; | ||
| 426 | 427 | ||
| 427 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) | 428 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) |
| 428 | return -EOPNOTSUPP; | 429 | return -EOPNOTSUPP; |
| @@ -430,9 +431,9 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
| 430 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) | 431 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) |
| 431 | return 0; | 432 | return 0; |
| 432 | 433 | ||
| 433 | spin_lock(&to_mdev(ibdev)->sm_lock); | 434 | spin_lock_irqsave(&to_mdev(ibdev)->sm_lock, flags); |
| 434 | memcpy(ibdev->node_desc, props->node_desc, 64); | 435 | memcpy(ibdev->node_desc, props->node_desc, 64); |
| 435 | spin_unlock(&to_mdev(ibdev)->sm_lock); | 436 | spin_unlock_irqrestore(&to_mdev(ibdev)->sm_lock, flags); |
| 436 | 437 | ||
| 437 | /* | 438 | /* |
| 438 | * If possible, pass node desc to FW, so it can generate | 439 | * If possible, pass node desc to FW, so it can generate |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a6d8ea060ea8..f585eddef4b7 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
| @@ -1407,6 +1407,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
| 1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; | 1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
| 1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; | 1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; |
| 1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); | 1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); |
| 1410 | struct net_device *ndev; | ||
| 1410 | union ib_gid sgid; | 1411 | union ib_gid sgid; |
| 1411 | u16 pkey; | 1412 | u16 pkey; |
| 1412 | int send_size; | 1413 | int send_size; |
| @@ -1483,7 +1484,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
| 1483 | 1484 | ||
| 1484 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); | 1485 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); |
| 1485 | /* FIXME: cache smac value? */ | 1486 | /* FIXME: cache smac value? */ |
| 1486 | smac = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]->dev_addr; | 1487 | ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]; |
| 1488 | if (!ndev) | ||
| 1489 | return -ENODEV; | ||
| 1490 | smac = ndev->dev_addr; | ||
| 1487 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); | 1491 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); |
| 1488 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) | 1492 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) |
| 1489 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); | 1493 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 5a044526e4f4..c4e0131f1b57 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
| @@ -161,7 +161,7 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) | |||
| 161 | ocrdma_get_guid(dev, &sgid->raw[8]); | 161 | ocrdma_get_guid(dev, &sgid->raw[8]); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 164 | #if IS_ENABLED(CONFIG_VLAN_8021Q) |
| 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) |
| 166 | { | 166 | { |
| 167 | struct net_device *netdev, *tmp; | 167 | struct net_device *netdev, *tmp; |
| @@ -202,14 +202,13 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
| 202 | return 0; | 202 | return 0; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_VLAN_8021Q) | 205 | #if IS_ENABLED(CONFIG_IPV6) |
| 206 | 206 | ||
| 207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, | 207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, |
| 208 | unsigned long event, void *ptr) | 208 | unsigned long event, void *ptr) |
| 209 | { | 209 | { |
| 210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; | 210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; |
| 211 | struct net_device *event_netdev = ifa->idev->dev; | 211 | struct net_device *netdev = ifa->idev->dev; |
| 212 | struct net_device *netdev = NULL; | ||
| 213 | struct ib_event gid_event; | 212 | struct ib_event gid_event; |
| 214 | struct ocrdma_dev *dev; | 213 | struct ocrdma_dev *dev; |
| 215 | bool found = false; | 214 | bool found = false; |
| @@ -217,11 +216,12 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
| 217 | bool is_vlan = false; | 216 | bool is_vlan = false; |
| 218 | u16 vid = 0; | 217 | u16 vid = 0; |
| 219 | 218 | ||
| 220 | netdev = vlan_dev_real_dev(event_netdev); | 219 | is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; |
| 221 | if (netdev != event_netdev) { | 220 | if (is_vlan) { |
| 222 | is_vlan = true; | 221 | vid = vlan_dev_vlan_id(netdev); |
| 223 | vid = vlan_dev_vlan_id(event_netdev); | 222 | netdev = vlan_dev_real_dev(netdev); |
| 224 | } | 223 | } |
| 224 | |||
| 225 | rcu_read_lock(); | 225 | rcu_read_lock(); |
| 226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { | 226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { |
| 227 | if (dev->nic_info.netdev == netdev) { | 227 | if (dev->nic_info.netdev == netdev) { |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 0d7280af99bc..3f6b21e9dc11 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
| @@ -6346,8 +6346,10 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
| 6346 | dd->piobcnt4k * dd->align4k; | 6346 | dd->piobcnt4k * dd->align4k; |
| 6347 | dd->piovl15base = ioremap_nocache(vl15off, | 6347 | dd->piovl15base = ioremap_nocache(vl15off, |
| 6348 | NUM_VL15_BUFS * dd->align4k); | 6348 | NUM_VL15_BUFS * dd->align4k); |
| 6349 | if (!dd->piovl15base) | 6349 | if (!dd->piovl15base) { |
| 6350 | ret = -ENOMEM; | ||
| 6350 | goto bail; | 6351 | goto bail; |
| 6352 | } | ||
| 6351 | } | 6353 | } |
| 6352 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ | 6354 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ |
| 6353 | 6355 | ||
diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c index a322d5171a2c..50a8a0d4fe67 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c | |||
| @@ -372,7 +372,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd, | |||
| 372 | /* Read CTRL reg for each channel to check TRIMDONE */ | 372 | /* Read CTRL reg for each channel to check TRIMDONE */ |
| 373 | if (baduns & (1 << chn)) { | 373 | if (baduns & (1 << chn)) { |
| 374 | qib_dev_err(dd, | 374 | qib_dev_err(dd, |
| 375 | "Reseting TRIMDONE on chn %d (%s)\n", | 375 | "Resetting TRIMDONE on chn %d (%s)\n", |
| 376 | chn, where); | 376 | chn, where); |
| 377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, | 377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, |
| 378 | IB_CTRL2(chn), 0x10, 0x10); | 378 | IB_CTRL2(chn), 0x10, 0x10); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 95ecf4eadf5f..24683fda8e21 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -1271,12 +1271,15 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path | |||
| 1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) | 1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) |
| 1272 | { | 1272 | { |
| 1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); | 1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); |
| 1274 | unsigned long flags; | ||
| 1274 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { | 1275 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { |
| 1276 | spin_lock_irqsave(&priv->lock, flags); | ||
| 1275 | list_move(&tx->list, &priv->cm.reap_list); | 1277 | list_move(&tx->list, &priv->cm.reap_list); |
| 1276 | queue_work(ipoib_workqueue, &priv->cm.reap_task); | 1278 | queue_work(ipoib_workqueue, &priv->cm.reap_task); |
| 1277 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", | 1279 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", |
| 1278 | tx->neigh->daddr + 4); | 1280 | tx->neigh->daddr + 4); |
| 1279 | tx->neigh = NULL; | 1281 | tx->neigh = NULL; |
| 1282 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 1280 | } | 1283 | } |
| 1281 | } | 1284 | } |
| 1282 | 1285 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 97920b77a5d0..3e2085a3ee47 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -1052,7 +1052,7 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh) | |||
| 1052 | for (n = rcu_dereference_protected(*np, | 1052 | for (n = rcu_dereference_protected(*np, |
| 1053 | lockdep_is_held(&ntbl->rwlock)); | 1053 | lockdep_is_held(&ntbl->rwlock)); |
| 1054 | n != NULL; | 1054 | n != NULL; |
| 1055 | n = rcu_dereference_protected(neigh->hnext, | 1055 | n = rcu_dereference_protected(*np, |
| 1056 | lockdep_is_held(&ntbl->rwlock))) { | 1056 | lockdep_is_held(&ntbl->rwlock))) { |
| 1057 | if (n == neigh) { | 1057 | if (n == neigh) { |
| 1058 | /* found */ | 1058 | /* found */ |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index bcbf22ee0aa7..1b5b0c730054 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
| @@ -586,24 +586,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
| 586 | scmnd->sc_data_direction); | 586 | scmnd->sc_data_direction); |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | static void srp_remove_req(struct srp_target_port *target, | 589 | /** |
| 590 | struct srp_request *req, s32 req_lim_delta) | 590 | * srp_claim_req - Take ownership of the scmnd associated with a request. |
| 591 | * @target: SRP target port. | ||
| 592 | * @req: SRP request. | ||
| 593 | * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take | ||
| 594 | * ownership of @req->scmnd if it equals @scmnd. | ||
| 595 | * | ||
| 596 | * Return value: | ||
| 597 | * Either NULL or a pointer to the SCSI command the caller became owner of. | ||
| 598 | */ | ||
| 599 | static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, | ||
| 600 | struct srp_request *req, | ||
| 601 | struct scsi_cmnd *scmnd) | ||
| 602 | { | ||
| 603 | unsigned long flags; | ||
| 604 | |||
| 605 | spin_lock_irqsave(&target->lock, flags); | ||
| 606 | if (!scmnd) { | ||
| 607 | scmnd = req->scmnd; | ||
| 608 | req->scmnd = NULL; | ||
| 609 | } else if (req->scmnd == scmnd) { | ||
| 610 | req->scmnd = NULL; | ||
| 611 | } else { | ||
| 612 | scmnd = NULL; | ||
| 613 | } | ||
| 614 | spin_unlock_irqrestore(&target->lock, flags); | ||
| 615 | |||
| 616 | return scmnd; | ||
| 617 | } | ||
| 618 | |||
| 619 | /** | ||
| 620 | * srp_free_req() - Unmap data and add request to the free request list. | ||
| 621 | */ | ||
| 622 | static void srp_free_req(struct srp_target_port *target, | ||
| 623 | struct srp_request *req, struct scsi_cmnd *scmnd, | ||
| 624 | s32 req_lim_delta) | ||
| 591 | { | 625 | { |
| 592 | unsigned long flags; | 626 | unsigned long flags; |
| 593 | 627 | ||
| 594 | srp_unmap_data(req->scmnd, target, req); | 628 | srp_unmap_data(scmnd, target, req); |
| 629 | |||
| 595 | spin_lock_irqsave(&target->lock, flags); | 630 | spin_lock_irqsave(&target->lock, flags); |
| 596 | target->req_lim += req_lim_delta; | 631 | target->req_lim += req_lim_delta; |
| 597 | req->scmnd = NULL; | ||
| 598 | list_add_tail(&req->list, &target->free_reqs); | 632 | list_add_tail(&req->list, &target->free_reqs); |
| 599 | spin_unlock_irqrestore(&target->lock, flags); | 633 | spin_unlock_irqrestore(&target->lock, flags); |
| 600 | } | 634 | } |
| 601 | 635 | ||
| 602 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) | 636 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) |
| 603 | { | 637 | { |
| 604 | req->scmnd->result = DID_RESET << 16; | 638 | struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL); |
| 605 | req->scmnd->scsi_done(req->scmnd); | 639 | |
| 606 | srp_remove_req(target, req, 0); | 640 | if (scmnd) { |
| 641 | scmnd->result = DID_RESET << 16; | ||
| 642 | scmnd->scsi_done(scmnd); | ||
| 643 | srp_free_req(target, req, scmnd, 0); | ||
| 644 | } | ||
| 607 | } | 645 | } |
| 608 | 646 | ||
| 609 | static int srp_reconnect_target(struct srp_target_port *target) | 647 | static int srp_reconnect_target(struct srp_target_port *target) |
| @@ -1073,11 +1111,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
| 1073 | complete(&target->tsk_mgmt_done); | 1111 | complete(&target->tsk_mgmt_done); |
| 1074 | } else { | 1112 | } else { |
| 1075 | req = &target->req_ring[rsp->tag]; | 1113 | req = &target->req_ring[rsp->tag]; |
| 1076 | scmnd = req->scmnd; | 1114 | scmnd = srp_claim_req(target, req, NULL); |
| 1077 | if (!scmnd) | 1115 | if (!scmnd) { |
| 1078 | shost_printk(KERN_ERR, target->scsi_host, | 1116 | shost_printk(KERN_ERR, target->scsi_host, |
| 1079 | "Null scmnd for RSP w/tag %016llx\n", | 1117 | "Null scmnd for RSP w/tag %016llx\n", |
| 1080 | (unsigned long long) rsp->tag); | 1118 | (unsigned long long) rsp->tag); |
| 1119 | |||
| 1120 | spin_lock_irqsave(&target->lock, flags); | ||
| 1121 | target->req_lim += be32_to_cpu(rsp->req_lim_delta); | ||
| 1122 | spin_unlock_irqrestore(&target->lock, flags); | ||
| 1123 | |||
| 1124 | return; | ||
| 1125 | } | ||
| 1081 | scmnd->result = rsp->status; | 1126 | scmnd->result = rsp->status; |
| 1082 | 1127 | ||
| 1083 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { | 1128 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { |
| @@ -1092,7 +1137,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
| 1092 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) | 1137 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) |
| 1093 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); | 1138 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); |
| 1094 | 1139 | ||
| 1095 | srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta)); | 1140 | srp_free_req(target, req, scmnd, |
| 1141 | be32_to_cpu(rsp->req_lim_delta)); | ||
| 1142 | |||
| 1096 | scmnd->host_scribble = NULL; | 1143 | scmnd->host_scribble = NULL; |
| 1097 | scmnd->scsi_done(scmnd); | 1144 | scmnd->scsi_done(scmnd); |
| 1098 | } | 1145 | } |
| @@ -1631,25 +1678,17 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
| 1631 | { | 1678 | { |
| 1632 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1679 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
| 1633 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; | 1680 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; |
| 1634 | int ret = SUCCESS; | ||
| 1635 | 1681 | ||
| 1636 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); | 1682 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
| 1637 | 1683 | ||
| 1638 | if (!req || target->qp_in_error) | 1684 | if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) |
| 1639 | return FAILED; | 1685 | return FAILED; |
| 1640 | if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, | 1686 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, |
| 1641 | SRP_TSK_ABORT_TASK)) | 1687 | SRP_TSK_ABORT_TASK); |
| 1642 | return FAILED; | 1688 | srp_free_req(target, req, scmnd, 0); |
| 1643 | 1689 | scmnd->result = DID_ABORT << 16; | |
| 1644 | if (req->scmnd) { | ||
| 1645 | if (!target->tsk_mgmt_status) { | ||
| 1646 | srp_remove_req(target, req, 0); | ||
| 1647 | scmnd->result = DID_ABORT << 16; | ||
| 1648 | } else | ||
| 1649 | ret = FAILED; | ||
| 1650 | } | ||
| 1651 | 1690 | ||
| 1652 | return ret; | 1691 | return SUCCESS; |
| 1653 | } | 1692 | } |
| 1654 | 1693 | ||
| 1655 | static int srp_reset_device(struct scsi_cmnd *scmnd) | 1694 | static int srp_reset_device(struct scsi_cmnd *scmnd) |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 7a0ce8d42887..9e1449f8c6a2 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
| @@ -1469,7 +1469,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, | |||
| 1469 | * | 1469 | * |
| 1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping | 1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping |
| 1471 | * the data that has been transferred via IB RDMA had to be postponed until the | 1471 | * the data that has been transferred via IB RDMA had to be postponed until the |
| 1472 | * check_stop_free() callback. None of this is nessecary anymore and needs to | 1472 | * check_stop_free() callback. None of this is necessary anymore and needs to |
| 1473 | * be cleaned up. | 1473 | * be cleaned up. |
| 1474 | */ | 1474 | */ |
| 1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, | 1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 0a2ea317120a..18a89b760aaa 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
| @@ -1111,7 +1111,7 @@ static void print_iommu_info(void) | |||
| 1111 | 1111 | ||
| 1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { | 1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { |
| 1113 | pr_info("AMD-Vi: Extended features: "); | 1113 | pr_info("AMD-Vi: Extended features: "); |
| 1114 | for (i = 0; ARRAY_SIZE(feat_str); ++i) { | 1114 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { |
| 1115 | if (iommu_feature(iommu, (1ULL << i))) | 1115 | if (iommu_feature(iommu, (1ULL << i))) |
| 1116 | pr_cont(" %s", feat_str[i]); | 1116 | pr_cont(" %s", feat_str[i]); |
| 1117 | } | 1117 | } |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index e0b18f3ae9a8..af8904de1d44 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
| @@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void) | |||
| 736 | { | 736 | { |
| 737 | struct dmar_drhd_unit *drhd; | 737 | struct dmar_drhd_unit *drhd; |
| 738 | int ir_supported = 0; | 738 | int ir_supported = 0; |
| 739 | int ioapic_idx; | ||
| 739 | 740 | ||
| 740 | for_each_drhd_unit(drhd) { | 741 | for_each_drhd_unit(drhd) { |
| 741 | struct intel_iommu *iommu = drhd->iommu; | 742 | struct intel_iommu *iommu = drhd->iommu; |
| @@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void) | |||
| 748 | } | 749 | } |
| 749 | } | 750 | } |
| 750 | 751 | ||
| 751 | if (ir_supported && ir_ioapic_num != nr_ioapics) { | 752 | if (!ir_supported) |
| 752 | printk(KERN_WARNING | 753 | return 0; |
| 753 | "Not all IO-APIC's listed under remapping hardware\n"); | 754 | |
| 754 | return -1; | 755 | for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) { |
| 756 | int ioapic_id = mpc_ioapic_id(ioapic_idx); | ||
| 757 | if (!map_ioapic_to_ir(ioapic_id)) { | ||
| 758 | pr_err(FW_BUG "ioapic %d has no mapping iommu, " | ||
| 759 | "interrupt remapping will be disabled\n", | ||
| 760 | ioapic_id); | ||
| 761 | return -1; | ||
| 762 | } | ||
| 755 | } | 763 | } |
| 756 | 764 | ||
| 757 | return ir_supported; | 765 | return 1; |
| 758 | } | 766 | } |
| 759 | 767 | ||
| 760 | int __init ir_dev_scope_init(void) | 768 | int __init ir_dev_scope_init(void) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index fcd098794d37..3f6203a4c7ea 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor | |||
| 1108 | ret = 0; | 1108 | ret = 0; |
| 1109 | } | 1109 | } |
| 1110 | rdev->sectors = rdev->sb_start; | 1110 | rdev->sectors = rdev->sb_start; |
| 1111 | /* Limit to 4TB as metadata cannot record more than that */ | 1111 | /* Limit to 4TB as metadata cannot record more than that. |
| 1112 | if (rdev->sectors >= (2ULL << 32)) | 1112 | * (not needed for Linear and RAID0 as metadata doesn't |
| 1113 | * record this size) | ||
| 1114 | */ | ||
| 1115 | if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) | ||
| 1113 | rdev->sectors = (2ULL << 32) - 2; | 1116 | rdev->sectors = (2ULL << 32) - 2; |
| 1114 | 1117 | ||
| 1115 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) | 1118 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
| @@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
| 1400 | /* Limit to 4TB as metadata cannot record more than that. | 1403 | /* Limit to 4TB as metadata cannot record more than that. |
| 1401 | * 4TB == 2^32 KB, or 2*2^32 sectors. | 1404 | * 4TB == 2^32 KB, or 2*2^32 sectors. |
| 1402 | */ | 1405 | */ |
| 1403 | if (num_sectors >= (2ULL << 32)) | 1406 | if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) |
| 1404 | num_sectors = (2ULL << 32) - 2; | 1407 | num_sectors = (2ULL << 32) - 2; |
| 1405 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1408 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
| 1406 | rdev->sb_page); | 1409 | rdev->sb_page); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de5ed6fd8806..1c2eb38f3c51 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
| 659 | max = biovec->bv_len; | 659 | max = biovec->bv_len; |
| 660 | 660 | ||
| 661 | if (mddev->merge_check_needed) { | 661 | if (mddev->merge_check_needed) { |
| 662 | struct r10bio r10_bio; | 662 | struct { |
| 663 | struct r10bio r10_bio; | ||
| 664 | struct r10dev devs[conf->copies]; | ||
| 665 | } on_stack; | ||
| 666 | struct r10bio *r10_bio = &on_stack.r10_bio; | ||
| 663 | int s; | 667 | int s; |
| 664 | if (conf->reshape_progress != MaxSector) { | 668 | if (conf->reshape_progress != MaxSector) { |
| 665 | /* Cannot give any guidance during reshape */ | 669 | /* Cannot give any guidance during reshape */ |
| @@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
| 667 | return biovec->bv_len; | 671 | return biovec->bv_len; |
| 668 | return 0; | 672 | return 0; |
| 669 | } | 673 | } |
| 670 | r10_bio.sector = sector; | 674 | r10_bio->sector = sector; |
| 671 | raid10_find_phys(conf, &r10_bio); | 675 | raid10_find_phys(conf, r10_bio); |
| 672 | rcu_read_lock(); | 676 | rcu_read_lock(); |
| 673 | for (s = 0; s < conf->copies; s++) { | 677 | for (s = 0; s < conf->copies; s++) { |
| 674 | int disk = r10_bio.devs[s].devnum; | 678 | int disk = r10_bio->devs[s].devnum; |
| 675 | struct md_rdev *rdev = rcu_dereference( | 679 | struct md_rdev *rdev = rcu_dereference( |
| 676 | conf->mirrors[disk].rdev); | 680 | conf->mirrors[disk].rdev); |
| 677 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | 681 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
| 678 | struct request_queue *q = | 682 | struct request_queue *q = |
| 679 | bdev_get_queue(rdev->bdev); | 683 | bdev_get_queue(rdev->bdev); |
| 680 | if (q->merge_bvec_fn) { | 684 | if (q->merge_bvec_fn) { |
| 681 | bvm->bi_sector = r10_bio.devs[s].addr | 685 | bvm->bi_sector = r10_bio->devs[s].addr |
| 682 | + rdev->data_offset; | 686 | + rdev->data_offset; |
| 683 | bvm->bi_bdev = rdev->bdev; | 687 | bvm->bi_bdev = rdev->bdev; |
| 684 | max = min(max, q->merge_bvec_fn( | 688 | max = min(max, q->merge_bvec_fn( |
| @@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
| 690 | struct request_queue *q = | 694 | struct request_queue *q = |
| 691 | bdev_get_queue(rdev->bdev); | 695 | bdev_get_queue(rdev->bdev); |
| 692 | if (q->merge_bvec_fn) { | 696 | if (q->merge_bvec_fn) { |
| 693 | bvm->bi_sector = r10_bio.devs[s].addr | 697 | bvm->bi_sector = r10_bio->devs[s].addr |
| 694 | + rdev->data_offset; | 698 | + rdev->data_offset; |
| 695 | bvm->bi_bdev = rdev->bdev; | 699 | bvm->bi_bdev = rdev->bdev; |
| 696 | max = min(max, q->merge_bvec_fn( | 700 | max = min(max, q->merge_bvec_fn( |
| @@ -4414,14 +4418,18 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
| 4414 | { | 4418 | { |
| 4415 | /* Use sync reads to get the blocks from somewhere else */ | 4419 | /* Use sync reads to get the blocks from somewhere else */ |
| 4416 | int sectors = r10_bio->sectors; | 4420 | int sectors = r10_bio->sectors; |
| 4417 | struct r10bio r10b; | ||
| 4418 | struct r10conf *conf = mddev->private; | 4421 | struct r10conf *conf = mddev->private; |
| 4422 | struct { | ||
| 4423 | struct r10bio r10_bio; | ||
| 4424 | struct r10dev devs[conf->copies]; | ||
| 4425 | } on_stack; | ||
| 4426 | struct r10bio *r10b = &on_stack.r10_bio; | ||
| 4419 | int slot = 0; | 4427 | int slot = 0; |
| 4420 | int idx = 0; | 4428 | int idx = 0; |
| 4421 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; | 4429 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; |
| 4422 | 4430 | ||
| 4423 | r10b.sector = r10_bio->sector; | 4431 | r10b->sector = r10_bio->sector; |
| 4424 | __raid10_find_phys(&conf->prev, &r10b); | 4432 | __raid10_find_phys(&conf->prev, r10b); |
| 4425 | 4433 | ||
| 4426 | while (sectors) { | 4434 | while (sectors) { |
| 4427 | int s = sectors; | 4435 | int s = sectors; |
| @@ -4432,7 +4440,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
| 4432 | s = PAGE_SIZE >> 9; | 4440 | s = PAGE_SIZE >> 9; |
| 4433 | 4441 | ||
| 4434 | while (!success) { | 4442 | while (!success) { |
| 4435 | int d = r10b.devs[slot].devnum; | 4443 | int d = r10b->devs[slot].devnum; |
| 4436 | struct md_rdev *rdev = conf->mirrors[d].rdev; | 4444 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
| 4437 | sector_t addr; | 4445 | sector_t addr; |
| 4438 | if (rdev == NULL || | 4446 | if (rdev == NULL || |
| @@ -4440,7 +4448,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
| 4440 | !test_bit(In_sync, &rdev->flags)) | 4448 | !test_bit(In_sync, &rdev->flags)) |
| 4441 | goto failed; | 4449 | goto failed; |
| 4442 | 4450 | ||
| 4443 | addr = r10b.devs[slot].addr + idx * PAGE_SIZE; | 4451 | addr = r10b->devs[slot].addr + idx * PAGE_SIZE; |
| 4444 | success = sync_page_io(rdev, | 4452 | success = sync_page_io(rdev, |
| 4445 | addr, | 4453 | addr, |
| 4446 | s << 9, | 4454 | s << 9, |
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 007c2c68dd83..1054cf602345 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h | |||
| @@ -110,7 +110,7 @@ struct r10bio { | |||
| 110 | * We choose the number when they are allocated. | 110 | * We choose the number when they are allocated. |
| 111 | * We sometimes need an extra bio to write to the replacement. | 111 | * We sometimes need an extra bio to write to the replacement. |
| 112 | */ | 112 | */ |
| 113 | struct { | 113 | struct r10dev { |
| 114 | struct bio *bio; | 114 | struct bio *bio; |
| 115 | union { | 115 | union { |
| 116 | struct bio *repl_bio; /* used for resync and | 116 | struct bio *repl_bio; /* used for resync and |
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 664e460f247b..aac622200e99 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c | |||
| @@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf) | |||
| 481 | return 0; | 481 | return 0; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static const struct usb_device_id smsusb_id_table[] __devinitconst = { | 484 | static const struct usb_device_id smsusb_id_table[] = { |
| 485 | { USB_DEVICE(0x187f, 0x0010), | 485 | { USB_DEVICE(0x187f, 0x0010), |
| 486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
| 487 | { USB_DEVICE(0x187f, 0x0100), | 487 | { USB_DEVICE(0x187f, 0x0100), |
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c index cf9d9fca5b84..234777116e5f 100644 --- a/drivers/media/video/gspca/jl2005bcd.c +++ b/drivers/media/video/gspca/jl2005bcd.c | |||
| @@ -512,7 +512,7 @@ static const struct sd_desc sd_desc = { | |||
| 512 | }; | 512 | }; |
| 513 | 513 | ||
| 514 | /* -- module initialisation -- */ | 514 | /* -- module initialisation -- */ |
| 515 | static const __devinitdata struct usb_device_id device_table[] = { | 515 | static const struct usb_device_id device_table[] = { |
| 516 | {USB_DEVICE(0x0979, 0x0227)}, | 516 | {USB_DEVICE(0x0979, 0x0227)}, |
| 517 | {} | 517 | {} |
| 518 | }; | 518 | }; |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 969bb5a4cd93..bab01c86c315 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
| @@ -579,7 +579,7 @@ static const struct sd_desc sd_desc = { | |||
| 579 | }; | 579 | }; |
| 580 | 580 | ||
| 581 | /* -- module initialisation -- */ | 581 | /* -- module initialisation -- */ |
| 582 | static const struct usb_device_id device_table[] __devinitconst = { | 582 | static const struct usb_device_id device_table[] = { |
| 583 | {USB_DEVICE(0x06e1, 0xa190)}, | 583 | {USB_DEVICE(0x06e1, 0xa190)}, |
| 584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 | 584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 |
| 585 | {USB_DEVICE(0x0733, 0x0430)}, */ | 585 | {USB_DEVICE(0x0733, 0x0430)}, */ |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d1facef28a60..b1a146205c08 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -395,7 +395,8 @@ config MFD_TC6387XB | |||
| 395 | 395 | ||
| 396 | config MFD_TC6393XB | 396 | config MFD_TC6393XB |
| 397 | bool "Support Toshiba TC6393XB" | 397 | bool "Support Toshiba TC6393XB" |
| 398 | depends on GPIOLIB && ARM && HAVE_CLK | 398 | depends on ARM && HAVE_CLK |
| 399 | select GPIOLIB | ||
| 399 | select MFD_CORE | 400 | select MFD_CORE |
| 400 | select MFD_TMIO | 401 | select MFD_TMIO |
| 401 | help | 402 | help |
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index c6ffbbe5a6c0..d78c05e693f7 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
| @@ -1253,7 +1253,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, | |||
| 1253 | if (dev->wd_timeout) | 1253 | if (dev->wd_timeout) |
| 1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); |
| 1255 | else | 1255 | else |
| 1256 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1256 | *slots -= mei_data2slots(MEI_WD_PARAMS_SIZE); |
| 1257 | } | 1257 | } |
| 1258 | } | 1258 | } |
| 1259 | if (dev->stop) | 1259 | if (dev->stop) |
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 092330208869..7422c7652845 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
| @@ -925,6 +925,27 @@ static struct miscdevice mei_misc_device = { | |||
| 925 | }; | 925 | }; |
| 926 | 926 | ||
| 927 | /** | 927 | /** |
| 928 | * mei_quirk_probe - probe for devices that doesn't valid ME interface | ||
| 929 | * @pdev: PCI device structure | ||
| 930 | * @ent: entry into pci_device_table | ||
| 931 | * | ||
| 932 | * returns true if ME Interface is valid, false otherwise | ||
| 933 | */ | ||
| 934 | static bool __devinit mei_quirk_probe(struct pci_dev *pdev, | ||
| 935 | const struct pci_device_id *ent) | ||
| 936 | { | ||
| 937 | u32 reg; | ||
| 938 | if (ent->device == MEI_DEV_ID_PBG_1) { | ||
| 939 | pci_read_config_dword(pdev, 0x48, ®); | ||
| 940 | /* make sure that bit 9 is up and bit 10 is down */ | ||
| 941 | if ((reg & 0x600) == 0x200) { | ||
| 942 | dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); | ||
| 943 | return false; | ||
| 944 | } | ||
| 945 | } | ||
| 946 | return true; | ||
| 947 | } | ||
| 948 | /** | ||
| 928 | * mei_probe - Device Initialization Routine | 949 | * mei_probe - Device Initialization Routine |
| 929 | * | 950 | * |
| 930 | * @pdev: PCI device structure | 951 | * @pdev: PCI device structure |
| @@ -939,6 +960,12 @@ static int __devinit mei_probe(struct pci_dev *pdev, | |||
| 939 | int err; | 960 | int err; |
| 940 | 961 | ||
| 941 | mutex_lock(&mei_mutex); | 962 | mutex_lock(&mei_mutex); |
| 963 | |||
| 964 | if (!mei_quirk_probe(pdev, ent)) { | ||
| 965 | err = -ENODEV; | ||
| 966 | goto end; | ||
| 967 | } | ||
| 968 | |||
| 942 | if (mei_device) { | 969 | if (mei_device) { |
| 943 | err = -EEXIST; | 970 | err = -EEXIST; |
| 944 | goto end; | 971 | goto end; |
diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index 1ff460a8e9c7..93b4d67cc4a3 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c | |||
| @@ -87,7 +87,7 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data) | |||
| 87 | /* communicate to platform about chip wakeup */ | 87 | /* communicate to platform about chip wakeup */ |
| 88 | kim_data = st_data->kim_data; | 88 | kim_data = st_data->kim_data; |
| 89 | pdata = kim_data->kim_pdev->dev.platform_data; | 89 | pdata = kim_data->kim_pdev->dev.platform_data; |
| 90 | if (pdata->chip_asleep) | 90 | if (pdata->chip_awake) |
| 91 | pdata->chip_awake(NULL); | 91 | pdata->chip_awake(NULL); |
| 92 | } | 92 | } |
| 93 | 93 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 88b7b3e75ab1..daf417923661 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c | |||
| @@ -358,13 +358,14 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 360 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
| 361 | u64 virt, int obj_size, int nobj, int reserved, | 361 | u64 virt, int obj_size, u32 nobj, int reserved, |
| 362 | int use_lowmem, int use_coherent) | 362 | int use_lowmem, int use_coherent) |
| 363 | { | 363 | { |
| 364 | int obj_per_chunk; | 364 | int obj_per_chunk; |
| 365 | int num_icm; | 365 | int num_icm; |
| 366 | unsigned chunk_size; | 366 | unsigned chunk_size; |
| 367 | int i; | 367 | int i; |
| 368 | u64 size; | ||
| 368 | 369 | ||
| 369 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; | 370 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; |
| 370 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; | 371 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; |
| @@ -380,10 +381,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
| 380 | table->coherent = use_coherent; | 381 | table->coherent = use_coherent; |
| 381 | mutex_init(&table->mutex); | 382 | mutex_init(&table->mutex); |
| 382 | 383 | ||
| 384 | size = (u64) nobj * obj_size; | ||
| 383 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { | 385 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { |
| 384 | chunk_size = MLX4_TABLE_CHUNK_SIZE; | 386 | chunk_size = MLX4_TABLE_CHUNK_SIZE; |
| 385 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size) | 387 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size) |
| 386 | chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE); | 388 | chunk_size = PAGE_ALIGN(size - |
| 389 | i * MLX4_TABLE_CHUNK_SIZE); | ||
| 387 | 390 | ||
| 388 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, | 391 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, |
| 389 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | | 392 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h index 19e4efc0b342..a67744f53506 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.h +++ b/drivers/net/ethernet/mellanox/mlx4/icm.h | |||
| @@ -78,7 +78,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
| 78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
| 79 | int start, int end); | 79 | int start, int end); |
| 80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
| 81 | u64 virt, int obj_size, int nobj, int reserved, | 81 | u64 virt, int obj_size, u32 nobj, int reserved, |
| 82 | int use_lowmem, int use_coherent); | 82 | int use_lowmem, int use_coherent); |
| 83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); | 83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); |
| 84 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); | 84 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 59ebc0339638..4d9df8f2a126 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -249,7 +249,7 @@ struct mlx4_bitmap { | |||
| 249 | struct mlx4_buddy { | 249 | struct mlx4_buddy { |
| 250 | unsigned long **bits; | 250 | unsigned long **bits; |
| 251 | unsigned int *num_free; | 251 | unsigned int *num_free; |
| 252 | int max_order; | 252 | u32 max_order; |
| 253 | spinlock_t lock; | 253 | spinlock_t lock; |
| 254 | }; | 254 | }; |
| 255 | 255 | ||
| @@ -258,7 +258,7 @@ struct mlx4_icm; | |||
| 258 | struct mlx4_icm_table { | 258 | struct mlx4_icm_table { |
| 259 | u64 virt; | 259 | u64 virt; |
| 260 | int num_icm; | 260 | int num_icm; |
| 261 | int num_obj; | 261 | u32 num_obj; |
| 262 | int obj_size; | 262 | int obj_size; |
| 263 | int lowmem; | 263 | int lowmem; |
| 264 | int coherent; | 264 | int coherent; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index af55b7ce5341..c202d3ad2a0e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/export.h> | 37 | #include <linux/export.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
| 40 | #include <linux/vmalloc.h> | ||
| 40 | 41 | ||
| 41 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
| 42 | 43 | ||
| @@ -120,7 +121,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
| 120 | buddy->max_order = max_order; | 121 | buddy->max_order = max_order; |
| 121 | spin_lock_init(&buddy->lock); | 122 | spin_lock_init(&buddy->lock); |
| 122 | 123 | ||
| 123 | buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), | 124 | buddy->bits = kcalloc(buddy->max_order + 1, sizeof (long *), |
| 124 | GFP_KERNEL); | 125 | GFP_KERNEL); |
| 125 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, | 126 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, |
| 126 | GFP_KERNEL); | 127 | GFP_KERNEL); |
| @@ -129,10 +130,12 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
| 129 | 130 | ||
| 130 | for (i = 0; i <= buddy->max_order; ++i) { | 131 | for (i = 0; i <= buddy->max_order; ++i) { |
| 131 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); | 132 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); |
| 132 | buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL); | 133 | buddy->bits[i] = kcalloc(s, sizeof (long), GFP_KERNEL | __GFP_NOWARN); |
| 133 | if (!buddy->bits[i]) | 134 | if (!buddy->bits[i]) { |
| 134 | goto err_out_free; | 135 | buddy->bits[i] = vzalloc(s * sizeof(long)); |
| 135 | bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i)); | 136 | if (!buddy->bits[i]) |
| 137 | goto err_out_free; | ||
| 138 | } | ||
| 136 | } | 139 | } |
| 137 | 140 | ||
| 138 | set_bit(0, buddy->bits[buddy->max_order]); | 141 | set_bit(0, buddy->bits[buddy->max_order]); |
| @@ -142,7 +145,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
| 142 | 145 | ||
| 143 | err_out_free: | 146 | err_out_free: |
| 144 | for (i = 0; i <= buddy->max_order; ++i) | 147 | for (i = 0; i <= buddy->max_order; ++i) |
| 145 | kfree(buddy->bits[i]); | 148 | if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i])) |
| 149 | vfree(buddy->bits[i]); | ||
| 150 | else | ||
| 151 | kfree(buddy->bits[i]); | ||
| 146 | 152 | ||
| 147 | err_out: | 153 | err_out: |
| 148 | kfree(buddy->bits); | 154 | kfree(buddy->bits); |
| @@ -156,7 +162,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) | |||
| 156 | int i; | 162 | int i; |
| 157 | 163 | ||
| 158 | for (i = 0; i <= buddy->max_order; ++i) | 164 | for (i = 0; i <= buddy->max_order; ++i) |
| 159 | kfree(buddy->bits[i]); | 165 | if (is_vmalloc_addr(buddy->bits[i])) |
| 166 | vfree(buddy->bits[i]); | ||
| 167 | else | ||
| 168 | kfree(buddy->bits[i]); | ||
| 160 | 169 | ||
| 161 | kfree(buddy->bits); | 170 | kfree(buddy->bits); |
| 162 | kfree(buddy->num_free); | 171 | kfree(buddy->num_free); |
| @@ -668,7 +677,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
| 668 | return err; | 677 | return err; |
| 669 | 678 | ||
| 670 | err = mlx4_buddy_init(&mr_table->mtt_buddy, | 679 | err = mlx4_buddy_init(&mr_table->mtt_buddy, |
| 671 | ilog2(dev->caps.num_mtts / | 680 | ilog2((u32)dev->caps.num_mtts / |
| 672 | (1 << log_mtts_per_seg))); | 681 | (1 << log_mtts_per_seg))); |
| 673 | if (err) | 682 | if (err) |
| 674 | goto err_buddy; | 683 | goto err_buddy; |
| @@ -678,7 +687,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
| 678 | mlx4_alloc_mtt_range(dev, | 687 | mlx4_alloc_mtt_range(dev, |
| 679 | fls(dev->caps.reserved_mtts - 1)); | 688 | fls(dev->caps.reserved_mtts - 1)); |
| 680 | if (priv->reserved_mtts < 0) { | 689 | if (priv->reserved_mtts < 0) { |
| 681 | mlx4_warn(dev, "MTT table of order %d is too small.\n", | 690 | mlx4_warn(dev, "MTT table of order %u is too small.\n", |
| 682 | mr_table->mtt_buddy.max_order); | 691 | mr_table->mtt_buddy.max_order); |
| 683 | err = -ENOMEM; | 692 | err = -ENOMEM; |
| 684 | goto err_reserve_mtts; | 693 | goto err_reserve_mtts; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 9ee4725363d5..8e0c3cc2a1ec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c | |||
| @@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
| 76 | u64 size; | 76 | u64 size; |
| 77 | u64 start; | 77 | u64 start; |
| 78 | int type; | 78 | int type; |
| 79 | int num; | 79 | u32 num; |
| 80 | int log_num; | 80 | int log_num; |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| @@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
| 105 | si_meminfo(&si); | 105 | si_meminfo(&si); |
| 106 | request->num_mtt = | 106 | request->num_mtt = |
| 107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, | 107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, |
| 108 | min(1UL << 31, | 108 | min(1UL << (31 - log_mtts_per_seg), |
| 109 | si.totalram >> (log_mtts_per_seg - 1)))); | 109 | si.totalram >> (log_mtts_per_seg - 1)))); |
| 110 | 110 | ||
| 111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; | 111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 7f207b6e9552..effb044a8a9d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
| @@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb"); | |||
| 42 | * whenever you add a new device. | 42 | * whenever you add a new device. |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | static struct usb_device_id p54u_table[] __devinitdata = { | 45 | static struct usb_device_id p54u_table[] = { |
| 46 | /* Version 1 devices (pci chip + net2280) */ | 46 | /* Version 1 devices (pci chip + net2280) */ |
| 47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ | 47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ |
| 48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ | 48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 71a30b026089..533024095c43 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
| @@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | |||
| 44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); | 44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); |
| 45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
| 46 | 46 | ||
| 47 | static struct usb_device_id rtl8187_table[] __devinitdata = { | 47 | static struct usb_device_id rtl8187_table[] = { |
| 48 | /* Asus */ | 48 | /* Asus */ |
| 49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, | 49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, |
| 50 | /* Belkin */ | 50 | /* Belkin */ |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index fbf7b26c7c8a..c5792d622dc4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -266,8 +266,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | if (!error) | 268 | if (!error) |
| 269 | dev_printk(KERN_INFO, &dev->dev, | 269 | dev_info(&dev->dev, "power state changed by ACPI to %s\n", |
| 270 | "power state changed by ACPI to D%d\n", state); | 270 | pci_power_name(state)); |
| 271 | 271 | ||
| 272 | return error; | 272 | return error; |
| 273 | } | 273 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 185be3703343..5270f1a99328 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -959,6 +959,13 @@ static int pci_pm_poweroff_noirq(struct device *dev) | |||
| 959 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) | 959 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) |
| 960 | pci_prepare_to_sleep(pci_dev); | 960 | pci_prepare_to_sleep(pci_dev); |
| 961 | 961 | ||
| 962 | /* | ||
| 963 | * The reason for doing this here is the same as for the analogous code | ||
| 964 | * in pci_pm_suspend_noirq(). | ||
| 965 | */ | ||
| 966 | if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
| 967 | pci_write_config_word(pci_dev, PCI_COMMAND, 0); | ||
| 968 | |||
| 962 | return 0; | 969 | return 0; |
| 963 | } | 970 | } |
| 964 | 971 | ||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2a262f5c5c0c..c86bae828c28 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
| @@ -289,6 +289,7 @@ config IDEAPAD_LAPTOP | |||
| 289 | tristate "Lenovo IdeaPad Laptop Extras" | 289 | tristate "Lenovo IdeaPad Laptop Extras" |
| 290 | depends on ACPI | 290 | depends on ACPI |
| 291 | depends on RFKILL && INPUT | 291 | depends on RFKILL && INPUT |
| 292 | depends on SERIO_I8042 | ||
| 292 | select INPUT_SPARSEKMAP | 293 | select INPUT_SPARSEKMAP |
| 293 | help | 294 | help |
| 294 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. | 295 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. |
| @@ -758,8 +759,11 @@ config SAMSUNG_Q10 | |||
| 758 | 759 | ||
| 759 | config APPLE_GMUX | 760 | config APPLE_GMUX |
| 760 | tristate "Apple Gmux Driver" | 761 | tristate "Apple Gmux Driver" |
| 762 | depends on ACPI | ||
| 761 | depends on PNP | 763 | depends on PNP |
| 762 | select BACKLIGHT_CLASS_DEVICE | 764 | depends on BACKLIGHT_CLASS_DEVICE |
| 765 | depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE | ||
| 766 | depends on ACPI_VIDEO=n || ACPI_VIDEO | ||
| 763 | ---help--- | 767 | ---help--- |
| 764 | This driver provides support for the gmux device found on many | 768 | This driver provides support for the gmux device found on many |
| 765 | Apple laptops, which controls the display mux for the hybrid | 769 | Apple laptops, which controls the display mux for the hybrid |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 905fa01ac8df..dfb1a92ce949 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Gmux driver for Apple laptops | 2 | * Gmux driver for Apple laptops |
| 3 | * | 3 | * |
| 4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> | 4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> |
| 5 | * Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de> | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -18,16 +19,30 @@ | |||
| 18 | #include <linux/pnp.h> | 19 | #include <linux/pnp.h> |
| 19 | #include <linux/apple_bl.h> | 20 | #include <linux/apple_bl.h> |
| 20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/pci.h> | ||
| 24 | #include <linux/vga_switcheroo.h> | ||
| 21 | #include <acpi/video.h> | 25 | #include <acpi/video.h> |
| 22 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| 23 | 27 | ||
| 24 | struct apple_gmux_data { | 28 | struct apple_gmux_data { |
| 25 | unsigned long iostart; | 29 | unsigned long iostart; |
| 26 | unsigned long iolen; | 30 | unsigned long iolen; |
| 31 | bool indexed; | ||
| 32 | struct mutex index_lock; | ||
| 27 | 33 | ||
| 28 | struct backlight_device *bdev; | 34 | struct backlight_device *bdev; |
| 35 | |||
| 36 | /* switcheroo data */ | ||
| 37 | acpi_handle dhandle; | ||
| 38 | int gpe; | ||
| 39 | enum vga_switcheroo_client_id resume_client_id; | ||
| 40 | enum vga_switcheroo_state power_state; | ||
| 41 | struct completion powerchange_done; | ||
| 29 | }; | 42 | }; |
| 30 | 43 | ||
| 44 | static struct apple_gmux_data *apple_gmux_data; | ||
| 45 | |||
| 31 | /* | 46 | /* |
| 32 | * gmux port offsets. Many of these are not yet used, but may be in the | 47 | * gmux port offsets. Many of these are not yet used, but may be in the |
| 33 | * future, and it's useful to have them documented here anyhow. | 48 | * future, and it's useful to have them documented here anyhow. |
| @@ -45,6 +60,9 @@ struct apple_gmux_data { | |||
| 45 | #define GMUX_PORT_DISCRETE_POWER 0x50 | 60 | #define GMUX_PORT_DISCRETE_POWER 0x50 |
| 46 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 | 61 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 |
| 47 | #define GMUX_PORT_BRIGHTNESS 0x74 | 62 | #define GMUX_PORT_BRIGHTNESS 0x74 |
| 63 | #define GMUX_PORT_VALUE 0xc2 | ||
| 64 | #define GMUX_PORT_READ 0xd0 | ||
| 65 | #define GMUX_PORT_WRITE 0xd4 | ||
| 48 | 66 | ||
| 49 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) | 67 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) |
| 50 | 68 | ||
| @@ -59,22 +77,172 @@ struct apple_gmux_data { | |||
| 59 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff | 77 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff |
| 60 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK | 78 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK |
| 61 | 79 | ||
| 62 | static inline u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | 80 | static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) |
| 63 | { | 81 | { |
| 64 | return inb(gmux_data->iostart + port); | 82 | return inb(gmux_data->iostart + port); |
| 65 | } | 83 | } |
| 66 | 84 | ||
| 67 | static inline void gmux_write8(struct apple_gmux_data *gmux_data, int port, | 85 | static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port, |
| 68 | u8 val) | 86 | u8 val) |
| 69 | { | 87 | { |
| 70 | outb(val, gmux_data->iostart + port); | 88 | outb(val, gmux_data->iostart + port); |
| 71 | } | 89 | } |
| 72 | 90 | ||
| 73 | static inline u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | 91 | static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port) |
| 74 | { | 92 | { |
| 75 | return inl(gmux_data->iostart + port); | 93 | return inl(gmux_data->iostart + port); |
| 76 | } | 94 | } |
| 77 | 95 | ||
| 96 | static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, | ||
| 97 | u32 val) | ||
| 98 | { | ||
| 99 | int i; | ||
| 100 | u8 tmpval; | ||
| 101 | |||
| 102 | for (i = 0; i < 4; i++) { | ||
| 103 | tmpval = (val >> (i * 8)) & 0xff; | ||
| 104 | outb(tmpval, port + i); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data) | ||
| 109 | { | ||
| 110 | int i = 200; | ||
| 111 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 112 | |||
| 113 | while (i && (gwr & 0x01)) { | ||
| 114 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
| 115 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 116 | udelay(100); | ||
| 117 | i--; | ||
| 118 | } | ||
| 119 | |||
| 120 | return !!i; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data) | ||
| 124 | { | ||
| 125 | int i = 200; | ||
| 126 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 127 | |||
| 128 | while (i && !(gwr & 0x01)) { | ||
| 129 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 130 | udelay(100); | ||
| 131 | i--; | ||
| 132 | } | ||
| 133 | |||
| 134 | if (gwr & 0x01) | ||
| 135 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
| 136 | |||
| 137 | return !!i; | ||
| 138 | } | ||
| 139 | |||
| 140 | static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) | ||
| 141 | { | ||
| 142 | u8 val; | ||
| 143 | |||
| 144 | mutex_lock(&gmux_data->index_lock); | ||
| 145 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
| 146 | gmux_index_wait_ready(gmux_data); | ||
| 147 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); | ||
| 148 | mutex_unlock(&gmux_data->index_lock); | ||
| 149 | |||
| 150 | return val; | ||
| 151 | } | ||
| 152 | |||
| 153 | static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port, | ||
| 154 | u8 val) | ||
| 155 | { | ||
| 156 | mutex_lock(&gmux_data->index_lock); | ||
| 157 | outb(val, gmux_data->iostart + GMUX_PORT_VALUE); | ||
| 158 | gmux_index_wait_ready(gmux_data); | ||
| 159 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 160 | gmux_index_wait_complete(gmux_data); | ||
| 161 | mutex_unlock(&gmux_data->index_lock); | ||
| 162 | } | ||
| 163 | |||
| 164 | static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) | ||
| 165 | { | ||
| 166 | u32 val; | ||
| 167 | |||
| 168 | mutex_lock(&gmux_data->index_lock); | ||
| 169 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
| 170 | gmux_index_wait_ready(gmux_data); | ||
| 171 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); | ||
| 172 | mutex_unlock(&gmux_data->index_lock); | ||
| 173 | |||
| 174 | return val; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port, | ||
| 178 | u32 val) | ||
| 179 | { | ||
| 180 | int i; | ||
| 181 | u8 tmpval; | ||
| 182 | |||
| 183 | mutex_lock(&gmux_data->index_lock); | ||
| 184 | |||
| 185 | for (i = 0; i < 4; i++) { | ||
| 186 | tmpval = (val >> (i * 8)) & 0xff; | ||
| 187 | outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i); | ||
| 188 | } | ||
| 189 | |||
| 190 | gmux_index_wait_ready(gmux_data); | ||
| 191 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
| 192 | gmux_index_wait_complete(gmux_data); | ||
| 193 | mutex_unlock(&gmux_data->index_lock); | ||
| 194 | } | ||
| 195 | |||
| 196 | static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | ||
| 197 | { | ||
| 198 | if (gmux_data->indexed) | ||
| 199 | return gmux_index_read8(gmux_data, port); | ||
| 200 | else | ||
| 201 | return gmux_pio_read8(gmux_data, port); | ||
| 202 | } | ||
| 203 | |||
| 204 | static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val) | ||
| 205 | { | ||
| 206 | if (gmux_data->indexed) | ||
| 207 | gmux_index_write8(gmux_data, port, val); | ||
| 208 | else | ||
| 209 | gmux_pio_write8(gmux_data, port, val); | ||
| 210 | } | ||
| 211 | |||
| 212 | static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | ||
| 213 | { | ||
| 214 | if (gmux_data->indexed) | ||
| 215 | return gmux_index_read32(gmux_data, port); | ||
| 216 | else | ||
| 217 | return gmux_pio_read32(gmux_data, port); | ||
| 218 | } | ||
| 219 | |||
| 220 | static void gmux_write32(struct apple_gmux_data *gmux_data, int port, | ||
| 221 | u32 val) | ||
| 222 | { | ||
| 223 | if (gmux_data->indexed) | ||
| 224 | gmux_index_write32(gmux_data, port, val); | ||
| 225 | else | ||
| 226 | gmux_pio_write32(gmux_data, port, val); | ||
| 227 | } | ||
| 228 | |||
| 229 | static bool gmux_is_indexed(struct apple_gmux_data *gmux_data) | ||
| 230 | { | ||
| 231 | u16 val; | ||
| 232 | |||
| 233 | outb(0xaa, gmux_data->iostart + 0xcc); | ||
| 234 | outb(0x55, gmux_data->iostart + 0xcd); | ||
| 235 | outb(0x00, gmux_data->iostart + 0xce); | ||
| 236 | |||
| 237 | val = inb(gmux_data->iostart + 0xcc) | | ||
| 238 | (inb(gmux_data->iostart + 0xcd) << 8); | ||
| 239 | |||
| 240 | if (val == 0x55aa) | ||
| 241 | return true; | ||
| 242 | |||
| 243 | return false; | ||
| 244 | } | ||
| 245 | |||
| 78 | static int gmux_get_brightness(struct backlight_device *bd) | 246 | static int gmux_get_brightness(struct backlight_device *bd) |
| 79 | { | 247 | { |
| 80 | struct apple_gmux_data *gmux_data = bl_get_data(bd); | 248 | struct apple_gmux_data *gmux_data = bl_get_data(bd); |
| @@ -90,16 +258,7 @@ static int gmux_update_status(struct backlight_device *bd) | |||
| 90 | if (bd->props.state & BL_CORE_SUSPENDED) | 258 | if (bd->props.state & BL_CORE_SUSPENDED) |
| 91 | return 0; | 259 | return 0; |
| 92 | 260 | ||
| 93 | /* | 261 | gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); |
| 94 | * Older gmux versions require writing out lower bytes first then | ||
| 95 | * setting the upper byte to 0 to flush the values. Newer versions | ||
| 96 | * accept a single u32 write, but the old method also works, so we | ||
| 97 | * just use the old method for all gmux versions. | ||
| 98 | */ | ||
| 99 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); | ||
| 100 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 1, brightness >> 8); | ||
| 101 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 2, brightness >> 16); | ||
| 102 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 3, 0); | ||
| 103 | 262 | ||
| 104 | return 0; | 263 | return 0; |
| 105 | } | 264 | } |
| @@ -110,6 +269,146 @@ static const struct backlight_ops gmux_bl_ops = { | |||
| 110 | .update_status = gmux_update_status, | 269 | .update_status = gmux_update_status, |
| 111 | }; | 270 | }; |
| 112 | 271 | ||
| 272 | static int gmux_switchto(enum vga_switcheroo_client_id id) | ||
| 273 | { | ||
| 274 | if (id == VGA_SWITCHEROO_IGD) { | ||
| 275 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); | ||
| 276 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); | ||
| 277 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); | ||
| 278 | } else { | ||
| 279 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); | ||
| 280 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); | ||
| 281 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); | ||
| 282 | } | ||
| 283 | |||
| 284 | return 0; | ||
| 285 | } | ||
| 286 | |||
| 287 | static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, | ||
| 288 | enum vga_switcheroo_state state) | ||
| 289 | { | ||
| 290 | INIT_COMPLETION(gmux_data->powerchange_done); | ||
| 291 | |||
| 292 | if (state == VGA_SWITCHEROO_ON) { | ||
| 293 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
| 294 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); | ||
| 295 | pr_debug("Discrete card powered up\n"); | ||
| 296 | } else { | ||
| 297 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
| 298 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); | ||
| 299 | pr_debug("Discrete card powered down\n"); | ||
| 300 | } | ||
| 301 | |||
| 302 | gmux_data->power_state = state; | ||
| 303 | |||
| 304 | if (gmux_data->gpe >= 0 && | ||
| 305 | !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done, | ||
| 306 | msecs_to_jiffies(200))) | ||
| 307 | pr_warn("Timeout waiting for gmux switch to complete\n"); | ||
| 308 | |||
| 309 | return 0; | ||
| 310 | } | ||
| 311 | |||
| 312 | static int gmux_set_power_state(enum vga_switcheroo_client_id id, | ||
| 313 | enum vga_switcheroo_state state) | ||
| 314 | { | ||
| 315 | if (id == VGA_SWITCHEROO_IGD) | ||
| 316 | return 0; | ||
| 317 | |||
| 318 | return gmux_set_discrete_state(apple_gmux_data, state); | ||
| 319 | } | ||
| 320 | |||
| 321 | static int gmux_get_client_id(struct pci_dev *pdev) | ||
| 322 | { | ||
| 323 | /* | ||
| 324 | * Early Macbook Pros with switchable graphics use nvidia | ||
| 325 | * integrated graphics. Hardcode that the 9400M is integrated. | ||
| 326 | */ | ||
| 327 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) | ||
| 328 | return VGA_SWITCHEROO_IGD; | ||
| 329 | else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && | ||
| 330 | pdev->device == 0x0863) | ||
| 331 | return VGA_SWITCHEROO_IGD; | ||
| 332 | else | ||
| 333 | return VGA_SWITCHEROO_DIS; | ||
| 334 | } | ||
| 335 | |||
| 336 | static enum vga_switcheroo_client_id | ||
| 337 | gmux_active_client(struct apple_gmux_data *gmux_data) | ||
| 338 | { | ||
| 339 | if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) | ||
| 340 | return VGA_SWITCHEROO_IGD; | ||
| 341 | |||
| 342 | return VGA_SWITCHEROO_DIS; | ||
| 343 | } | ||
| 344 | |||
| 345 | static struct vga_switcheroo_handler gmux_handler = { | ||
| 346 | .switchto = gmux_switchto, | ||
| 347 | .power_state = gmux_set_power_state, | ||
| 348 | .get_client_id = gmux_get_client_id, | ||
| 349 | }; | ||
| 350 | |||
| 351 | static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) | ||
| 352 | { | ||
| 353 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
| 354 | GMUX_INTERRUPT_DISABLE); | ||
| 355 | } | ||
| 356 | |||
| 357 | static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data) | ||
| 358 | { | ||
| 359 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
| 360 | GMUX_INTERRUPT_ENABLE); | ||
| 361 | } | ||
| 362 | |||
| 363 | static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data) | ||
| 364 | { | ||
| 365 | return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS); | ||
| 366 | } | ||
| 367 | |||
| 368 | static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data) | ||
| 369 | { | ||
| 370 | u8 status; | ||
| 371 | |||
| 372 | /* to clear interrupts write back current status */ | ||
| 373 | status = gmux_interrupt_get_status(gmux_data); | ||
| 374 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status); | ||
| 375 | } | ||
| 376 | |||
| 377 | static void gmux_notify_handler(acpi_handle device, u32 value, void *context) | ||
| 378 | { | ||
| 379 | u8 status; | ||
| 380 | struct pnp_dev *pnp = (struct pnp_dev *)context; | ||
| 381 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
| 382 | |||
| 383 | status = gmux_interrupt_get_status(gmux_data); | ||
| 384 | gmux_disable_interrupts(gmux_data); | ||
| 385 | pr_debug("Notify handler called: status %d\n", status); | ||
| 386 | |||
| 387 | gmux_clear_interrupts(gmux_data); | ||
| 388 | gmux_enable_interrupts(gmux_data); | ||
| 389 | |||
| 390 | if (status & GMUX_INTERRUPT_STATUS_POWER) | ||
| 391 | complete(&gmux_data->powerchange_done); | ||
| 392 | } | ||
| 393 | |||
| 394 | static int gmux_suspend(struct pnp_dev *pnp, pm_message_t state) | ||
| 395 | { | ||
| 396 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
| 397 | gmux_data->resume_client_id = gmux_active_client(gmux_data); | ||
| 398 | gmux_disable_interrupts(gmux_data); | ||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | static int gmux_resume(struct pnp_dev *pnp) | ||
| 403 | { | ||
| 404 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
| 405 | gmux_enable_interrupts(gmux_data); | ||
| 406 | gmux_switchto(gmux_data->resume_client_id); | ||
| 407 | if (gmux_data->power_state == VGA_SWITCHEROO_OFF) | ||
| 408 | gmux_set_discrete_state(gmux_data, gmux_data->power_state); | ||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | |||
| 113 | static int __devinit gmux_probe(struct pnp_dev *pnp, | 412 | static int __devinit gmux_probe(struct pnp_dev *pnp, |
| 114 | const struct pnp_device_id *id) | 413 | const struct pnp_device_id *id) |
| 115 | { | 414 | { |
| @@ -119,6 +418,11 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
| 119 | struct backlight_device *bdev; | 418 | struct backlight_device *bdev; |
| 120 | u8 ver_major, ver_minor, ver_release; | 419 | u8 ver_major, ver_minor, ver_release; |
| 121 | int ret = -ENXIO; | 420 | int ret = -ENXIO; |
| 421 | acpi_status status; | ||
| 422 | unsigned long long gpe; | ||
| 423 | |||
| 424 | if (apple_gmux_data) | ||
| 425 | return -EBUSY; | ||
| 122 | 426 | ||
| 123 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); | 427 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); |
| 124 | if (!gmux_data) | 428 | if (!gmux_data) |
| @@ -147,22 +451,29 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
| 147 | } | 451 | } |
| 148 | 452 | ||
| 149 | /* | 453 | /* |
| 150 | * On some machines the gmux is in ACPI even thought the machine | 454 | * Invalid version information may indicate either that the gmux |
| 151 | * doesn't really have a gmux. Check for invalid version information | 455 | * device isn't present or that it's a new one that uses indexed |
| 152 | * to detect this. | 456 | * io |
| 153 | */ | 457 | */ |
| 458 | |||
| 154 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); | 459 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); |
| 155 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); | 460 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); |
| 156 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); | 461 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); |
| 157 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { | 462 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { |
| 158 | pr_info("gmux device not present\n"); | 463 | if (gmux_is_indexed(gmux_data)) { |
| 159 | ret = -ENODEV; | 464 | mutex_init(&gmux_data->index_lock); |
| 160 | goto err_release; | 465 | gmux_data->indexed = true; |
| 466 | } else { | ||
| 467 | pr_info("gmux device not present\n"); | ||
| 468 | ret = -ENODEV; | ||
| 469 | goto err_release; | ||
| 470 | } | ||
| 471 | pr_info("Found indexed gmux\n"); | ||
| 472 | } else { | ||
| 473 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
| 474 | ver_release); | ||
| 161 | } | 475 | } |
| 162 | 476 | ||
| 163 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
| 164 | ver_release); | ||
| 165 | |||
| 166 | memset(&props, 0, sizeof(props)); | 477 | memset(&props, 0, sizeof(props)); |
| 167 | props.type = BACKLIGHT_PLATFORM; | 478 | props.type = BACKLIGHT_PLATFORM; |
| 168 | props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); | 479 | props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); |
| @@ -194,13 +505,67 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
| 194 | * Disable the other backlight choices. | 505 | * Disable the other backlight choices. |
| 195 | */ | 506 | */ |
| 196 | acpi_video_dmi_promote_vendor(); | 507 | acpi_video_dmi_promote_vendor(); |
| 197 | #ifdef CONFIG_ACPI_VIDEO | 508 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) |
| 198 | acpi_video_unregister(); | 509 | acpi_video_unregister(); |
| 199 | #endif | 510 | #endif |
| 200 | apple_bl_unregister(); | 511 | apple_bl_unregister(); |
| 201 | 512 | ||
| 513 | gmux_data->power_state = VGA_SWITCHEROO_ON; | ||
| 514 | |||
| 515 | gmux_data->dhandle = DEVICE_ACPI_HANDLE(&pnp->dev); | ||
| 516 | if (!gmux_data->dhandle) { | ||
| 517 | pr_err("Cannot find acpi handle for pnp device %s\n", | ||
| 518 | dev_name(&pnp->dev)); | ||
| 519 | ret = -ENODEV; | ||
| 520 | goto err_notify; | ||
| 521 | } | ||
| 522 | |||
| 523 | status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe); | ||
| 524 | if (ACPI_SUCCESS(status)) { | ||
| 525 | gmux_data->gpe = (int)gpe; | ||
| 526 | |||
| 527 | status = acpi_install_notify_handler(gmux_data->dhandle, | ||
| 528 | ACPI_DEVICE_NOTIFY, | ||
| 529 | &gmux_notify_handler, pnp); | ||
| 530 | if (ACPI_FAILURE(status)) { | ||
| 531 | pr_err("Install notify handler failed: %s\n", | ||
| 532 | acpi_format_exception(status)); | ||
| 533 | ret = -ENODEV; | ||
| 534 | goto err_notify; | ||
| 535 | } | ||
| 536 | |||
| 537 | status = acpi_enable_gpe(NULL, gmux_data->gpe); | ||
| 538 | if (ACPI_FAILURE(status)) { | ||
| 539 | pr_err("Cannot enable gpe: %s\n", | ||
| 540 | acpi_format_exception(status)); | ||
| 541 | goto err_enable_gpe; | ||
| 542 | } | ||
| 543 | } else { | ||
| 544 | pr_warn("No GPE found for gmux\n"); | ||
| 545 | gmux_data->gpe = -1; | ||
| 546 | } | ||
| 547 | |||
| 548 | if (vga_switcheroo_register_handler(&gmux_handler)) { | ||
| 549 | ret = -ENODEV; | ||
| 550 | goto err_register_handler; | ||
| 551 | } | ||
| 552 | |||
| 553 | init_completion(&gmux_data->powerchange_done); | ||
| 554 | apple_gmux_data = gmux_data; | ||
| 555 | gmux_enable_interrupts(gmux_data); | ||
| 556 | |||
| 202 | return 0; | 557 | return 0; |
| 203 | 558 | ||
| 559 | err_register_handler: | ||
| 560 | if (gmux_data->gpe >= 0) | ||
| 561 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
| 562 | err_enable_gpe: | ||
| 563 | if (gmux_data->gpe >= 0) | ||
| 564 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
| 565 | ACPI_DEVICE_NOTIFY, | ||
| 566 | &gmux_notify_handler); | ||
| 567 | err_notify: | ||
| 568 | backlight_device_unregister(bdev); | ||
| 204 | err_release: | 569 | err_release: |
| 205 | release_region(gmux_data->iostart, gmux_data->iolen); | 570 | release_region(gmux_data->iostart, gmux_data->iolen); |
| 206 | err_free: | 571 | err_free: |
| @@ -212,12 +577,23 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
| 212 | { | 577 | { |
| 213 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | 578 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); |
| 214 | 579 | ||
| 580 | vga_switcheroo_unregister_handler(); | ||
| 581 | gmux_disable_interrupts(gmux_data); | ||
| 582 | if (gmux_data->gpe >= 0) { | ||
| 583 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
| 584 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
| 585 | ACPI_DEVICE_NOTIFY, | ||
| 586 | &gmux_notify_handler); | ||
| 587 | } | ||
| 588 | |||
| 215 | backlight_device_unregister(gmux_data->bdev); | 589 | backlight_device_unregister(gmux_data->bdev); |
| 590 | |||
| 216 | release_region(gmux_data->iostart, gmux_data->iolen); | 591 | release_region(gmux_data->iostart, gmux_data->iolen); |
| 592 | apple_gmux_data = NULL; | ||
| 217 | kfree(gmux_data); | 593 | kfree(gmux_data); |
| 218 | 594 | ||
| 219 | acpi_video_dmi_demote_vendor(); | 595 | acpi_video_dmi_demote_vendor(); |
| 220 | #ifdef CONFIG_ACPI_VIDEO | 596 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) |
| 221 | acpi_video_register(); | 597 | acpi_video_register(); |
| 222 | #endif | 598 | #endif |
| 223 | apple_bl_register(); | 599 | apple_bl_register(); |
| @@ -233,6 +609,8 @@ static struct pnp_driver gmux_pnp_driver = { | |||
| 233 | .probe = gmux_probe, | 609 | .probe = gmux_probe, |
| 234 | .remove = __devexit_p(gmux_remove), | 610 | .remove = __devexit_p(gmux_remove), |
| 235 | .id_table = gmux_device_ids, | 611 | .id_table = gmux_device_ids, |
| 612 | .suspend = gmux_suspend, | ||
| 613 | .resume = gmux_resume | ||
| 236 | }; | 614 | }; |
| 237 | 615 | ||
| 238 | static int __init apple_gmux_init(void) | 616 | static int __init apple_gmux_init(void) |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index c7a36f6b0580..2eb9fe8e8efd 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
| @@ -101,6 +101,7 @@ MODULE_LICENSE("GPL"); | |||
| 101 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 | 101 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 |
| 102 | #define ASUS_WMI_DEVID_CWAP 0x00010003 | 102 | #define ASUS_WMI_DEVID_CWAP 0x00010003 |
| 103 | #define ASUS_WMI_DEVID_WLAN 0x00010011 | 103 | #define ASUS_WMI_DEVID_WLAN 0x00010011 |
| 104 | #define ASUS_WMI_DEVID_WLAN_LED 0x00010012 | ||
| 104 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 | 105 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 |
| 105 | #define ASUS_WMI_DEVID_GPS 0x00010015 | 106 | #define ASUS_WMI_DEVID_GPS 0x00010015 |
| 106 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 | 107 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 |
| @@ -731,8 +732,21 @@ static int asus_rfkill_set(void *data, bool blocked) | |||
| 731 | { | 732 | { |
| 732 | struct asus_rfkill *priv = data; | 733 | struct asus_rfkill *priv = data; |
| 733 | u32 ctrl_param = !blocked; | 734 | u32 ctrl_param = !blocked; |
| 735 | u32 dev_id = priv->dev_id; | ||
| 734 | 736 | ||
| 735 | return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL); | 737 | /* |
| 738 | * If the user bit is set, BIOS can't set and record the wlan status, | ||
| 739 | * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED | ||
| 740 | * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN). | ||
| 741 | * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED | ||
| 742 | * while setting the wlan status through WMI. | ||
| 743 | * This is also the behavior that windows app will do. | ||
| 744 | */ | ||
| 745 | if ((dev_id == ASUS_WMI_DEVID_WLAN) && | ||
| 746 | priv->asus->driver->wlan_ctrl_by_user) | ||
| 747 | dev_id = ASUS_WMI_DEVID_WLAN_LED; | ||
| 748 | |||
| 749 | return asus_wmi_set_devstate(dev_id, ctrl_param, NULL); | ||
| 736 | } | 750 | } |
| 737 | 751 | ||
| 738 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) | 752 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) |
| @@ -1653,6 +1667,7 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
| 1653 | struct asus_wmi *asus; | 1667 | struct asus_wmi *asus; |
| 1654 | acpi_status status; | 1668 | acpi_status status; |
| 1655 | int err; | 1669 | int err; |
| 1670 | u32 result; | ||
| 1656 | 1671 | ||
| 1657 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); | 1672 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); |
| 1658 | if (!asus) | 1673 | if (!asus) |
| @@ -1711,6 +1726,10 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
| 1711 | if (err) | 1726 | if (err) |
| 1712 | goto fail_debugfs; | 1727 | goto fail_debugfs; |
| 1713 | 1728 | ||
| 1729 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
| 1730 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
| 1731 | asus->driver->wlan_ctrl_by_user = 1; | ||
| 1732 | |||
| 1714 | return 0; | 1733 | return 0; |
| 1715 | 1734 | ||
| 1716 | fail_debugfs: | 1735 | fail_debugfs: |
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 9c1da8b81bea..4c9bd38bb0a2 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h | |||
| @@ -46,6 +46,7 @@ struct quirk_entry { | |||
| 46 | struct asus_wmi_driver { | 46 | struct asus_wmi_driver { |
| 47 | int brightness; | 47 | int brightness; |
| 48 | int panel_power; | 48 | int panel_power; |
| 49 | int wlan_ctrl_by_user; | ||
| 49 | 50 | ||
| 50 | const char *name; | 51 | const char *name; |
| 51 | struct module *owner; | 52 | struct module *owner; |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index cd33add118ce..c87ff16873f9 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
| @@ -725,8 +725,10 @@ static void cmpc_tablet_handler(struct acpi_device *dev, u32 event) | |||
| 725 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | 725 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); |
| 726 | 726 | ||
| 727 | if (event == 0x81) { | 727 | if (event == 0x81) { |
| 728 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) | 728 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) { |
| 729 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 729 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
| 730 | input_sync(inputdev); | ||
| 731 | } | ||
| 730 | } | 732 | } |
| 731 | } | 733 | } |
| 732 | 734 | ||
| @@ -739,8 +741,10 @@ static void cmpc_tablet_idev_init(struct input_dev *inputdev) | |||
| 739 | set_bit(SW_TABLET_MODE, inputdev->swbit); | 741 | set_bit(SW_TABLET_MODE, inputdev->swbit); |
| 740 | 742 | ||
| 741 | acpi = to_acpi_device(inputdev->dev.parent); | 743 | acpi = to_acpi_device(inputdev->dev.parent); |
| 742 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) | 744 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) { |
| 743 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 745 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
| 746 | input_sync(inputdev); | ||
| 747 | } | ||
| 744 | } | 748 | } |
| 745 | 749 | ||
| 746 | static int cmpc_tablet_add(struct acpi_device *acpi) | 750 | static int cmpc_tablet_add(struct acpi_device *acpi) |
| @@ -760,8 +764,10 @@ static int cmpc_tablet_resume(struct device *dev) | |||
| 760 | struct input_dev *inputdev = dev_get_drvdata(dev); | 764 | struct input_dev *inputdev = dev_get_drvdata(dev); |
| 761 | 765 | ||
| 762 | unsigned long long val = 0; | 766 | unsigned long long val = 0; |
| 763 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) | 767 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) { |
| 764 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 768 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
| 769 | input_sync(inputdev); | ||
| 770 | } | ||
| 765 | return 0; | 771 | return 0; |
| 766 | } | 772 | } |
| 767 | #endif | 773 | #endif |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 4e96e8c0b60f..927c33af67ec 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
| @@ -211,7 +211,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 211 | .ident = "Dell Inspiron 5420", | 211 | .ident = "Dell Inspiron 5420", |
| 212 | .matches = { | 212 | .matches = { |
| 213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 214 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5420"), | 214 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"), |
| 215 | }, | 215 | }, |
| 216 | .driver_data = &quirk_dell_vostro_v130, | 216 | .driver_data = &quirk_dell_vostro_v130, |
| 217 | }, | 217 | }, |
| @@ -220,7 +220,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 220 | .ident = "Dell Inspiron 5520", | 220 | .ident = "Dell Inspiron 5520", |
| 221 | .matches = { | 221 | .matches = { |
| 222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 223 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5520"), | 223 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"), |
| 224 | }, | 224 | }, |
| 225 | .driver_data = &quirk_dell_vostro_v130, | 225 | .driver_data = &quirk_dell_vostro_v130, |
| 226 | }, | 226 | }, |
| @@ -229,7 +229,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 229 | .ident = "Dell Inspiron 5720", | 229 | .ident = "Dell Inspiron 5720", |
| 230 | .matches = { | 230 | .matches = { |
| 231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 232 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5720"), | 232 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"), |
| 233 | }, | 233 | }, |
| 234 | .driver_data = &quirk_dell_vostro_v130, | 234 | .driver_data = &quirk_dell_vostro_v130, |
| 235 | }, | 235 | }, |
| @@ -238,7 +238,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 238 | .ident = "Dell Inspiron 7420", | 238 | .ident = "Dell Inspiron 7420", |
| 239 | .matches = { | 239 | .matches = { |
| 240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 241 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7420"), | 241 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"), |
| 242 | }, | 242 | }, |
| 243 | .driver_data = &quirk_dell_vostro_v130, | 243 | .driver_data = &quirk_dell_vostro_v130, |
| 244 | }, | 244 | }, |
| @@ -247,7 +247,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 247 | .ident = "Dell Inspiron 7520", | 247 | .ident = "Dell Inspiron 7520", |
| 248 | .matches = { | 248 | .matches = { |
| 249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 250 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7520"), | 250 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), |
| 251 | }, | 251 | }, |
| 252 | .driver_data = &quirk_dell_vostro_v130, | 252 | .driver_data = &quirk_dell_vostro_v130, |
| 253 | }, | 253 | }, |
| @@ -256,7 +256,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
| 256 | .ident = "Dell Inspiron 7720", | 256 | .ident = "Dell Inspiron 7720", |
| 257 | .matches = { | 257 | .matches = { |
| 258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
| 259 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7720"), | 259 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"), |
| 260 | }, | 260 | }, |
| 261 | .driver_data = &quirk_dell_vostro_v130, | 261 | .driver_data = &quirk_dell_vostro_v130, |
| 262 | }, | 262 | }, |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 17f6dfd8dbfb..dae7abe1d711 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/fb.h> | 36 | #include <linux/fb.h> |
| 37 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
| 38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
| 39 | #include <linux/i8042.h> | ||
| 39 | 40 | ||
| 40 | #define IDEAPAD_RFKILL_DEV_NUM (3) | 41 | #define IDEAPAD_RFKILL_DEV_NUM (3) |
| 41 | 42 | ||
| @@ -63,8 +64,11 @@ enum { | |||
| 63 | VPCCMD_R_3G, | 64 | VPCCMD_R_3G, |
| 64 | VPCCMD_W_3G, | 65 | VPCCMD_W_3G, |
| 65 | VPCCMD_R_ODD, /* 0x21 */ | 66 | VPCCMD_R_ODD, /* 0x21 */ |
| 66 | VPCCMD_R_RF = 0x23, | 67 | VPCCMD_W_FAN, |
| 68 | VPCCMD_R_RF, | ||
| 67 | VPCCMD_W_RF, | 69 | VPCCMD_W_RF, |
| 70 | VPCCMD_R_FAN = 0x2B, | ||
| 71 | VPCCMD_R_SPECIAL_BUTTONS = 0x31, | ||
| 68 | VPCCMD_W_BL_POWER = 0x33, | 72 | VPCCMD_W_BL_POWER = 0x33, |
| 69 | }; | 73 | }; |
| 70 | 74 | ||
| @@ -356,14 +360,46 @@ static ssize_t store_ideapad_cam(struct device *dev, | |||
| 356 | return -EINVAL; | 360 | return -EINVAL; |
| 357 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); | 361 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); |
| 358 | if (ret < 0) | 362 | if (ret < 0) |
| 359 | return ret; | 363 | return -EIO; |
| 360 | return count; | 364 | return count; |
| 361 | } | 365 | } |
| 362 | 366 | ||
| 363 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); | 367 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); |
| 364 | 368 | ||
| 369 | static ssize_t show_ideapad_fan(struct device *dev, | ||
| 370 | struct device_attribute *attr, | ||
| 371 | char *buf) | ||
| 372 | { | ||
| 373 | unsigned long result; | ||
| 374 | |||
| 375 | if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) | ||
| 376 | return sprintf(buf, "-1\n"); | ||
| 377 | return sprintf(buf, "%lu\n", result); | ||
| 378 | } | ||
| 379 | |||
| 380 | static ssize_t store_ideapad_fan(struct device *dev, | ||
| 381 | struct device_attribute *attr, | ||
| 382 | const char *buf, size_t count) | ||
| 383 | { | ||
| 384 | int ret, state; | ||
| 385 | |||
| 386 | if (!count) | ||
| 387 | return 0; | ||
| 388 | if (sscanf(buf, "%i", &state) != 1) | ||
| 389 | return -EINVAL; | ||
| 390 | if (state < 0 || state > 4 || state == 3) | ||
| 391 | return -EINVAL; | ||
| 392 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); | ||
| 393 | if (ret < 0) | ||
| 394 | return -EIO; | ||
| 395 | return count; | ||
| 396 | } | ||
| 397 | |||
| 398 | static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan); | ||
| 399 | |||
| 365 | static struct attribute *ideapad_attributes[] = { | 400 | static struct attribute *ideapad_attributes[] = { |
| 366 | &dev_attr_camera_power.attr, | 401 | &dev_attr_camera_power.attr, |
| 402 | &dev_attr_fan_mode.attr, | ||
| 367 | NULL | 403 | NULL |
| 368 | }; | 404 | }; |
| 369 | 405 | ||
| @@ -377,7 +413,10 @@ static umode_t ideapad_is_visible(struct kobject *kobj, | |||
| 377 | 413 | ||
| 378 | if (attr == &dev_attr_camera_power.attr) | 414 | if (attr == &dev_attr_camera_power.attr) |
| 379 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); | 415 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); |
| 380 | else | 416 | else if (attr == &dev_attr_fan_mode.attr) { |
| 417 | unsigned long value; | ||
| 418 | supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); | ||
| 419 | } else | ||
| 381 | supported = true; | 420 | supported = true; |
| 382 | 421 | ||
| 383 | return supported ? attr->mode : 0; | 422 | return supported ? attr->mode : 0; |
| @@ -518,9 +557,15 @@ static void ideapad_platform_exit(struct ideapad_private *priv) | |||
| 518 | */ | 557 | */ |
| 519 | static const struct key_entry ideapad_keymap[] = { | 558 | static const struct key_entry ideapad_keymap[] = { |
| 520 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, | 559 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, |
| 560 | { KE_KEY, 7, { KEY_CAMERA } }, | ||
| 561 | { KE_KEY, 11, { KEY_F16 } }, | ||
| 521 | { KE_KEY, 13, { KEY_WLAN } }, | 562 | { KE_KEY, 13, { KEY_WLAN } }, |
| 522 | { KE_KEY, 16, { KEY_PROG1 } }, | 563 | { KE_KEY, 16, { KEY_PROG1 } }, |
| 523 | { KE_KEY, 17, { KEY_PROG2 } }, | 564 | { KE_KEY, 17, { KEY_PROG2 } }, |
| 565 | { KE_KEY, 64, { KEY_PROG3 } }, | ||
| 566 | { KE_KEY, 65, { KEY_PROG4 } }, | ||
| 567 | { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, | ||
| 568 | { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, | ||
| 524 | { KE_END, 0 }, | 569 | { KE_END, 0 }, |
| 525 | }; | 570 | }; |
| 526 | 571 | ||
| @@ -587,6 +632,28 @@ static void ideapad_input_novokey(struct ideapad_private *priv) | |||
| 587 | ideapad_input_report(priv, 16); | 632 | ideapad_input_report(priv, 16); |
| 588 | } | 633 | } |
| 589 | 634 | ||
| 635 | static void ideapad_check_special_buttons(struct ideapad_private *priv) | ||
| 636 | { | ||
| 637 | unsigned long bit, value; | ||
| 638 | |||
| 639 | read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); | ||
| 640 | |||
| 641 | for (bit = 0; bit < 16; bit++) { | ||
| 642 | if (test_bit(bit, &value)) { | ||
| 643 | switch (bit) { | ||
| 644 | case 6: | ||
| 645 | /* Thermal Management button */ | ||
| 646 | ideapad_input_report(priv, 65); | ||
| 647 | break; | ||
| 648 | case 1: | ||
| 649 | /* OneKey Theater button */ | ||
| 650 | ideapad_input_report(priv, 64); | ||
| 651 | break; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | } | ||
| 655 | } | ||
| 656 | |||
| 590 | /* | 657 | /* |
| 591 | * backlight | 658 | * backlight |
| 592 | */ | 659 | */ |
| @@ -691,6 +758,24 @@ static const struct acpi_device_id ideapad_device_ids[] = { | |||
| 691 | }; | 758 | }; |
| 692 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); | 759 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); |
| 693 | 760 | ||
| 761 | static void ideapad_sync_touchpad_state(struct acpi_device *adevice) | ||
| 762 | { | ||
| 763 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
| 764 | unsigned long value; | ||
| 765 | |||
| 766 | /* Without reading from EC touchpad LED doesn't switch state */ | ||
| 767 | if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { | ||
| 768 | /* Some IdeaPads don't really turn off touchpad - they only | ||
| 769 | * switch the LED state. We (de)activate KBC AUX port to turn | ||
| 770 | * touchpad off and on. We send KEY_TOUCHPAD_OFF and | ||
| 771 | * KEY_TOUCHPAD_ON to not to get out of sync with LED */ | ||
| 772 | unsigned char param; | ||
| 773 | i8042_command(¶m, value ? I8042_CMD_AUX_ENABLE : | ||
| 774 | I8042_CMD_AUX_DISABLE); | ||
| 775 | ideapad_input_report(priv, value ? 67 : 66); | ||
| 776 | } | ||
| 777 | } | ||
| 778 | |||
| 694 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | 779 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) |
| 695 | { | 780 | { |
| 696 | int ret, i; | 781 | int ret, i; |
| @@ -727,6 +812,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | |||
| 727 | priv->rfk[i] = NULL; | 812 | priv->rfk[i] = NULL; |
| 728 | } | 813 | } |
| 729 | ideapad_sync_rfk_state(priv); | 814 | ideapad_sync_rfk_state(priv); |
| 815 | ideapad_sync_touchpad_state(adevice); | ||
| 730 | 816 | ||
| 731 | if (!acpi_video_backlight_support()) { | 817 | if (!acpi_video_backlight_support()) { |
| 732 | ret = ideapad_backlight_init(priv); | 818 | ret = ideapad_backlight_init(priv); |
| @@ -785,9 +871,14 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
| 785 | ideapad_sync_rfk_state(priv); | 871 | ideapad_sync_rfk_state(priv); |
| 786 | break; | 872 | break; |
| 787 | case 13: | 873 | case 13: |
| 874 | case 11: | ||
| 875 | case 7: | ||
| 788 | case 6: | 876 | case 6: |
| 789 | ideapad_input_report(priv, vpc_bit); | 877 | ideapad_input_report(priv, vpc_bit); |
| 790 | break; | 878 | break; |
| 879 | case 5: | ||
| 880 | ideapad_sync_touchpad_state(adevice); | ||
| 881 | break; | ||
| 791 | case 4: | 882 | case 4: |
| 792 | ideapad_backlight_notify_brightness(priv); | 883 | ideapad_backlight_notify_brightness(priv); |
| 793 | break; | 884 | break; |
| @@ -797,6 +888,9 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
| 797 | case 2: | 888 | case 2: |
| 798 | ideapad_backlight_notify_power(priv); | 889 | ideapad_backlight_notify_power(priv); |
| 799 | break; | 890 | break; |
| 891 | case 0: | ||
| 892 | ideapad_check_special_buttons(priv); | ||
| 893 | break; | ||
| 800 | default: | 894 | default: |
| 801 | pr_info("Unknown event: %lu\n", vpc_bit); | 895 | pr_info("Unknown event: %lu\n", vpc_bit); |
| 802 | } | 896 | } |
| @@ -804,6 +898,15 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
| 804 | } | 898 | } |
| 805 | } | 899 | } |
| 806 | 900 | ||
| 901 | static int ideapad_acpi_resume(struct device *device) | ||
| 902 | { | ||
| 903 | ideapad_sync_rfk_state(ideapad_priv); | ||
| 904 | ideapad_sync_touchpad_state(to_acpi_device(device)); | ||
| 905 | return 0; | ||
| 906 | } | ||
| 907 | |||
| 908 | static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); | ||
| 909 | |||
| 807 | static struct acpi_driver ideapad_acpi_driver = { | 910 | static struct acpi_driver ideapad_acpi_driver = { |
| 808 | .name = "ideapad_acpi", | 911 | .name = "ideapad_acpi", |
| 809 | .class = "IdeaPad", | 912 | .class = "IdeaPad", |
| @@ -811,6 +914,7 @@ static struct acpi_driver ideapad_acpi_driver = { | |||
| 811 | .ops.add = ideapad_acpi_add, | 914 | .ops.add = ideapad_acpi_add, |
| 812 | .ops.remove = ideapad_acpi_remove, | 915 | .ops.remove = ideapad_acpi_remove, |
| 813 | .ops.notify = ideapad_acpi_notify, | 916 | .ops.notify = ideapad_acpi_notify, |
| 917 | .drv.pm = &ideapad_pm, | ||
| 814 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
| 815 | }; | 919 | }; |
| 816 | 920 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f28f36ccdcf4..80e377949314 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -8664,6 +8664,13 @@ static int __must_check __init get_thinkpad_model_data( | |||
| 8664 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8664 | tp->model_str = kstrdup(s, GFP_KERNEL); |
| 8665 | if (!tp->model_str) | 8665 | if (!tp->model_str) |
| 8666 | return -ENOMEM; | 8666 | return -ENOMEM; |
| 8667 | } else { | ||
| 8668 | s = dmi_get_system_info(DMI_BIOS_VENDOR); | ||
| 8669 | if (s && !(strnicmp(s, "Lenovo", 6))) { | ||
| 8670 | tp->model_str = kstrdup(s, GFP_KERNEL); | ||
| 8671 | if (!tp->model_str) | ||
| 8672 | return -ENOMEM; | ||
| 8673 | } | ||
| 8667 | } | 8674 | } |
| 8668 | 8675 | ||
| 8669 | s = dmi_get_system_info(DMI_PRODUCT_NAME); | 8676 | s = dmi_get_system_info(DMI_PRODUCT_NAME); |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 182b553059c9..c151fd5d8c97 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
| @@ -486,6 +486,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { | |||
| 486 | .id = AB3100_BUCK, | 486 | .id = AB3100_BUCK, |
| 487 | .ops = ®ulator_ops_variable_sleepable, | 487 | .ops = ®ulator_ops_variable_sleepable, |
| 488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), | 488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), |
| 489 | .volt_table = ldo_e_buck_typ_voltages, | ||
| 489 | .type = REGULATOR_VOLTAGE, | 490 | .type = REGULATOR_VOLTAGE, |
| 490 | .owner = THIS_MODULE, | 491 | .owner = THIS_MODULE, |
| 491 | .enable_time = 1000, | 492 | .enable_time = 1000, |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..ce0fe72a428e 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
| @@ -64,14 +64,15 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) | |||
| 64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) | 64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) |
| 65 | { | 65 | { |
| 66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
| 67 | u32 val; | 67 | u32 val, mask; |
| 68 | 68 | ||
| 69 | if (!anatop_reg->control_reg) | 69 | if (!anatop_reg->control_reg) |
| 70 | return -ENOTSUPP; | 70 | return -ENOTSUPP; |
| 71 | 71 | ||
| 72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); | 72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); |
| 73 | val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> | 73 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << |
| 74 | anatop_reg->vol_bit_shift; | 74 | anatop_reg->vol_bit_shift; |
| 75 | val = (val & mask) >> anatop_reg->vol_bit_shift; | ||
| 75 | 76 | ||
| 76 | return val - anatop_reg->min_bit_val; | 77 | return val - anatop_reg->min_bit_val; |
| 77 | } | 78 | } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index f092588a078c..48385318175a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -3217,7 +3217,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
| 3217 | 3217 | ||
| 3218 | dev_set_drvdata(&rdev->dev, rdev); | 3218 | dev_set_drvdata(&rdev->dev, rdev); |
| 3219 | 3219 | ||
| 3220 | if (config->ena_gpio) { | 3220 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { |
| 3221 | ret = gpio_request_one(config->ena_gpio, | 3221 | ret = gpio_request_one(config->ena_gpio, |
| 3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, | 3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, |
| 3223 | rdev_get_name(rdev)); | 3223 | rdev_get_name(rdev)); |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 34b67bee9323..8b5944f2d7d1 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
| @@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) | |||
| 57 | return -EINVAL; | 57 | return -EINVAL; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static int gpio_regulator_set_value(struct regulator_dev *dev, | 60 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, |
| 61 | int min, int max, unsigned *selector) | 61 | int min_uV, int max_uV, |
| 62 | unsigned *selector) | ||
| 62 | { | 63 | { |
| 63 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | 64 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
| 64 | int ptr, target = 0, state, best_val = INT_MAX; | 65 | int ptr, target = 0, state, best_val = INT_MAX; |
| 65 | 66 | ||
| 66 | for (ptr = 0; ptr < data->nr_states; ptr++) | 67 | for (ptr = 0; ptr < data->nr_states; ptr++) |
| 67 | if (data->states[ptr].value < best_val && | 68 | if (data->states[ptr].value < best_val && |
| 68 | data->states[ptr].value >= min && | 69 | data->states[ptr].value >= min_uV && |
| 69 | data->states[ptr].value <= max) { | 70 | data->states[ptr].value <= max_uV) { |
| 70 | target = data->states[ptr].gpios; | 71 | target = data->states[ptr].gpios; |
| 71 | best_val = data->states[ptr].value; | 72 | best_val = data->states[ptr].value; |
| 72 | if (selector) | 73 | if (selector) |
| @@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, | |||
| 85 | return 0; | 86 | return 0; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, | ||
| 89 | int min_uV, int max_uV, | ||
| 90 | unsigned *selector) | ||
| 91 | { | ||
| 92 | return gpio_regulator_set_value(dev, min_uV, max_uV, selector); | ||
| 93 | } | ||
| 94 | |||
| 95 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, | 89 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, |
| 96 | unsigned selector) | 90 | unsigned selector) |
| 97 | { | 91 | { |
| @@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, | |||
| 106 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, | 100 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, |
| 107 | int min_uA, int max_uA) | 101 | int min_uA, int max_uA) |
| 108 | { | 102 | { |
| 109 | return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); | 103 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
| 104 | int ptr, target = 0, state, best_val = 0; | ||
| 105 | |||
| 106 | for (ptr = 0; ptr < data->nr_states; ptr++) | ||
| 107 | if (data->states[ptr].value > best_val && | ||
| 108 | data->states[ptr].value >= min_uA && | ||
| 109 | data->states[ptr].value <= max_uA) { | ||
| 110 | target = data->states[ptr].gpios; | ||
| 111 | best_val = data->states[ptr].value; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (best_val == 0) | ||
| 115 | return -EINVAL; | ||
| 116 | |||
| 117 | for (ptr = 0; ptr < data->nr_gpios; ptr++) { | ||
| 118 | state = (target & (1 << ptr)) >> ptr; | ||
| 119 | gpio_set_value(data->gpios[ptr].gpio, state); | ||
| 120 | } | ||
| 121 | data->state = target; | ||
| 122 | |||
| 123 | return 0; | ||
| 110 | } | 124 | } |
| 111 | 125 | ||
| 112 | static struct regulator_ops gpio_regulator_voltage_ops = { | 126 | static struct regulator_ops gpio_regulator_voltage_ops = { |
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..46c7e88f8381 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
| @@ -486,9 +486,12 @@ static int palmas_map_voltage_ldo(struct regulator_dev *rdev, | |||
| 486 | { | 486 | { |
| 487 | int ret, voltage; | 487 | int ret, voltage; |
| 488 | 488 | ||
| 489 | ret = ((min_uV - 900000) / 50000) + 1; | 489 | if (min_uV == 0) |
| 490 | if (ret < 0) | 490 | return 0; |
| 491 | return ret; | 491 | |
| 492 | if (min_uV < 900000) | ||
| 493 | min_uV = 900000; | ||
| 494 | ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; | ||
| 492 | 495 | ||
| 493 | /* Map back into a voltage to verify we're still in bounds */ | 496 | /* Map back into a voltage to verify we're still in bounds */ |
| 494 | voltage = palmas_list_voltage_ldo(rdev, ret); | 497 | voltage = palmas_list_voltage_ldo(rdev, ret); |
| @@ -586,7 +589,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
| 586 | 589 | ||
| 587 | addr = palmas_regs_info[id].ctrl_addr; | 590 | addr = palmas_regs_info[id].ctrl_addr; |
| 588 | 591 | ||
| 589 | ret = palmas_smps_read(palmas, addr, ®); | 592 | ret = palmas_ldo_read(palmas, addr, ®); |
| 590 | if (ret) | 593 | if (ret) |
| 591 | return ret; | 594 | return ret; |
| 592 | 595 | ||
| @@ -596,7 +599,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
| 596 | if (reg_init->mode_sleep) | 599 | if (reg_init->mode_sleep) |
| 597 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; | 600 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; |
| 598 | 601 | ||
| 599 | ret = palmas_smps_write(palmas, addr, reg); | 602 | ret = palmas_ldo_write(palmas, addr, reg); |
| 600 | if (ret) | 603 | if (ret) |
| 601 | return ret; | 604 | return ret; |
| 602 | 605 | ||
| @@ -630,7 +633,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
| 630 | 633 | ||
| 631 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); | 634 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); |
| 632 | if (ret) | 635 | if (ret) |
| 633 | goto err_unregister_regulator; | 636 | return ret; |
| 634 | 637 | ||
| 635 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) | 638 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) |
| 636 | pmic->smps123 = 1; | 639 | pmic->smps123 = 1; |
| @@ -676,7 +679,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
| 676 | case PALMAS_REG_SMPS10: | 679 | case PALMAS_REG_SMPS10: |
| 677 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; | 680 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; |
| 678 | pmic->desc[id].ops = &palmas_ops_smps10; | 681 | pmic->desc[id].ops = &palmas_ops_smps10; |
| 679 | pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; | 682 | pmic->desc[id].vsel_reg = |
| 683 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | ||
| 684 | PALMAS_SMPS10_CTRL); | ||
| 680 | pmic->desc[id].vsel_mask = SMPS10_VSEL; | 685 | pmic->desc[id].vsel_mask = SMPS10_VSEL; |
| 681 | pmic->desc[id].enable_reg = | 686 | pmic->desc[id].enable_reg = |
| 682 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | 687 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, |
| @@ -778,8 +783,10 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
| 778 | reg_init = pdata->reg_init[id]; | 783 | reg_init = pdata->reg_init[id]; |
| 779 | if (reg_init) { | 784 | if (reg_init) { |
| 780 | ret = palmas_ldo_init(palmas, id, reg_init); | 785 | ret = palmas_ldo_init(palmas, id, reg_init); |
| 781 | if (ret) | 786 | if (ret) { |
| 787 | regulator_unregister(pmic->rdev[id]); | ||
| 782 | goto err_unregister_regulator; | 788 | goto err_unregister_regulator; |
| 789 | } | ||
| 783 | } | 790 | } |
| 784 | } | 791 | } |
| 785 | } | 792 | } |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index e6da90ab5153..19241fc30050 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
| @@ -240,14 +240,16 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
| 240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
| 241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), | 241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
| 242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
| 243 | TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), | 243 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
| 244 | 244 | ||
| 245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, | 245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, |
| 246 | ENB, 3, VCC2, 6), | 246 | ENB, 3, VCC2, 6), |
| 247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, | 247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, |
| 248 | END, 3, VCC1, 6), | 248 | END, 3, VCC1, 6), |
| 249 | TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), | 249 | TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1, |
| 250 | TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), | 250 | ENB, 1, VCC1, 2), |
| 251 | TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0, | ||
| 252 | ENB, 0, VCC1, 0), | ||
| 251 | }; | 253 | }; |
| 252 | 254 | ||
| 253 | /* | 255 | /* |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 242fe90dc565..77a71a5c17c3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
| @@ -1037,7 +1037,7 @@ TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); | |||
| 1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); | 1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
| 1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); | 1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
| 1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | 1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); |
| 1040 | TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08); | 1040 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); |
| 1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); | 1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
| 1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); | 1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
| 1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); | 1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
| @@ -1048,7 +1048,6 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); | |||
| 1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); | 1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
| 1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); | 1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
| 1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | 1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); |
| 1051 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0); | ||
| 1052 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); | 1051 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
| 1053 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); | 1052 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
| 1054 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); | 1053 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
| @@ -1117,7 +1116,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { | |||
| 1117 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | 1116 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), |
| 1118 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | 1117 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), |
| 1119 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | 1118 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), |
| 1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | 1119 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), |
| 1121 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | 1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), |
| 1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | 1121 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), |
| 1123 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | 1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 6e25ef1bce91..ea0aaa3f13d0 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
| @@ -438,7 +438,7 @@ out: | |||
| 438 | 438 | ||
| 439 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | 439 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) |
| 440 | { | 440 | { |
| 441 | struct spi_master *master = platform_get_drvdata(pdev); | 441 | struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); |
| 442 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); | 442 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); |
| 443 | 443 | ||
| 444 | spi_unregister_master(master); | 444 | spi_unregister_master(master); |
| @@ -452,6 +452,8 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | |||
| 452 | 452 | ||
| 453 | platform_set_drvdata(pdev, 0); | 453 | platform_set_drvdata(pdev, 0); |
| 454 | 454 | ||
| 455 | spi_master_put(master); | ||
| 456 | |||
| 455 | return 0; | 457 | return 0; |
| 456 | } | 458 | } |
| 457 | 459 | ||
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index b2d4b9e4e010..764bfee75920 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
| @@ -533,7 +533,6 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
| 533 | iounmap(mcfqspi->iobase); | 533 | iounmap(mcfqspi->iobase); |
| 534 | release_mem_region(res->start, resource_size(res)); | 534 | release_mem_region(res->start, resource_size(res)); |
| 535 | spi_unregister_master(master); | 535 | spi_unregister_master(master); |
| 536 | spi_master_put(master); | ||
| 537 | 536 | ||
| 538 | return 0; | 537 | return 0; |
| 539 | } | 538 | } |
| @@ -541,7 +540,7 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
| 541 | #ifdef CONFIG_PM_SLEEP | 540 | #ifdef CONFIG_PM_SLEEP |
| 542 | static int mcfqspi_suspend(struct device *dev) | 541 | static int mcfqspi_suspend(struct device *dev) |
| 543 | { | 542 | { |
| 544 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 543 | struct spi_master *master = dev_get_drvdata(dev); |
| 545 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 544 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
| 546 | 545 | ||
| 547 | spi_master_suspend(master); | 546 | spi_master_suspend(master); |
| @@ -553,7 +552,7 @@ static int mcfqspi_suspend(struct device *dev) | |||
| 553 | 552 | ||
| 554 | static int mcfqspi_resume(struct device *dev) | 553 | static int mcfqspi_resume(struct device *dev) |
| 555 | { | 554 | { |
| 556 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 555 | struct spi_master *master = dev_get_drvdata(dev); |
| 557 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 556 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
| 558 | 557 | ||
| 559 | spi_master_resume(master); | 558 | spi_master_resume(master); |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bc4778175e34..b2fb141da375 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -1228,18 +1228,16 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
| 1228 | 1228 | ||
| 1229 | status = spi_register_master(master); | 1229 | status = spi_register_master(master); |
| 1230 | if (status < 0) | 1230 | if (status < 0) |
| 1231 | goto err_spi_register; | 1231 | goto disable_pm; |
| 1232 | 1232 | ||
| 1233 | return status; | 1233 | return status; |
| 1234 | 1234 | ||
| 1235 | err_spi_register: | ||
| 1236 | spi_master_put(master); | ||
| 1237 | disable_pm: | 1235 | disable_pm: |
| 1238 | pm_runtime_disable(&pdev->dev); | 1236 | pm_runtime_disable(&pdev->dev); |
| 1239 | dma_chnl_free: | 1237 | dma_chnl_free: |
| 1240 | kfree(mcspi->dma_channels); | 1238 | kfree(mcspi->dma_channels); |
| 1241 | free_master: | 1239 | free_master: |
| 1242 | kfree(master); | 1240 | spi_master_put(master); |
| 1243 | platform_set_drvdata(pdev, NULL); | 1241 | platform_set_drvdata(pdev, NULL); |
| 1244 | return status; | 1242 | return status; |
| 1245 | } | 1243 | } |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index aab518ec2bbc..6abbe23c39b4 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -2053,7 +2053,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
| 2054 | adev->res.start, pl022->virtbase); | 2054 | adev->res.start, pl022->virtbase); |
| 2055 | 2055 | ||
| 2056 | pm_runtime_enable(dev); | ||
| 2057 | pm_runtime_resume(dev); | 2056 | pm_runtime_resume(dev); |
| 2058 | 2057 | ||
| 2059 | pl022->clk = clk_get(&adev->dev, NULL); | 2058 | pl022->clk = clk_get(&adev->dev, NULL); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index cfa2c35dfeed..d1c8441f638c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
| @@ -1479,40 +1479,40 @@ static const struct dev_pm_ops s3c64xx_spi_pm = { | |||
| 1479 | s3c64xx_spi_runtime_resume, NULL) | 1479 | s3c64xx_spi_runtime_resume, NULL) |
| 1480 | }; | 1480 | }; |
| 1481 | 1481 | ||
| 1482 | struct s3c64xx_spi_port_config s3c2443_spi_port_config = { | 1482 | static struct s3c64xx_spi_port_config s3c2443_spi_port_config = { |
| 1483 | .fifo_lvl_mask = { 0x7f }, | 1483 | .fifo_lvl_mask = { 0x7f }, |
| 1484 | .rx_lvl_offset = 13, | 1484 | .rx_lvl_offset = 13, |
| 1485 | .tx_st_done = 21, | 1485 | .tx_st_done = 21, |
| 1486 | .high_speed = true, | 1486 | .high_speed = true, |
| 1487 | }; | 1487 | }; |
| 1488 | 1488 | ||
| 1489 | struct s3c64xx_spi_port_config s3c6410_spi_port_config = { | 1489 | static struct s3c64xx_spi_port_config s3c6410_spi_port_config = { |
| 1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
| 1491 | .rx_lvl_offset = 13, | 1491 | .rx_lvl_offset = 13, |
| 1492 | .tx_st_done = 21, | 1492 | .tx_st_done = 21, |
| 1493 | }; | 1493 | }; |
| 1494 | 1494 | ||
| 1495 | struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { | 1495 | static struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { |
| 1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
| 1497 | .rx_lvl_offset = 15, | 1497 | .rx_lvl_offset = 15, |
| 1498 | .tx_st_done = 25, | 1498 | .tx_st_done = 25, |
| 1499 | }; | 1499 | }; |
| 1500 | 1500 | ||
| 1501 | struct s3c64xx_spi_port_config s5pc100_spi_port_config = { | 1501 | static struct s3c64xx_spi_port_config s5pc100_spi_port_config = { |
| 1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
| 1503 | .rx_lvl_offset = 13, | 1503 | .rx_lvl_offset = 13, |
| 1504 | .tx_st_done = 21, | 1504 | .tx_st_done = 21, |
| 1505 | .high_speed = true, | 1505 | .high_speed = true, |
| 1506 | }; | 1506 | }; |
| 1507 | 1507 | ||
| 1508 | struct s3c64xx_spi_port_config s5pv210_spi_port_config = { | 1508 | static struct s3c64xx_spi_port_config s5pv210_spi_port_config = { |
| 1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
| 1510 | .rx_lvl_offset = 15, | 1510 | .rx_lvl_offset = 15, |
| 1511 | .tx_st_done = 25, | 1511 | .tx_st_done = 25, |
| 1512 | .high_speed = true, | 1512 | .high_speed = true, |
| 1513 | }; | 1513 | }; |
| 1514 | 1514 | ||
| 1515 | struct s3c64xx_spi_port_config exynos4_spi_port_config = { | 1515 | static struct s3c64xx_spi_port_config exynos4_spi_port_config = { |
| 1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, | 1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, |
| 1517 | .rx_lvl_offset = 15, | 1517 | .rx_lvl_offset = 15, |
| 1518 | .tx_st_done = 25, | 1518 | .tx_st_done = 25, |
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c0fdb00783ed..2359151af7e1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c | |||
| @@ -168,7 +168,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
| 168 | dev->board_ptr = comedi_recognize(driv, it->board_name); | 168 | dev->board_ptr = comedi_recognize(driv, it->board_name); |
| 169 | if (dev->board_ptr) | 169 | if (dev->board_ptr) |
| 170 | break; | 170 | break; |
| 171 | } else if (strcmp(driv->driver_name, it->board_name)) | 171 | } else if (strcmp(driv->driver_name, it->board_name) == 0) |
| 172 | break; | 172 | break; |
| 173 | module_put(driv->module); | 173 | module_put(driv->module); |
| 174 | } | 174 | } |
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 31986608eaf1..6b4d0d68e637 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c | |||
| @@ -1349,9 +1349,6 @@ static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, | |||
| 1349 | } | 1349 | } |
| 1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
| 1351 | continue; | 1351 | continue; |
| 1352 | if (pci_is_enabled(pcidev)) | ||
| 1353 | continue; | ||
| 1354 | |||
| 1355 | if (strcmp(this_board->name, DRV_NAME) == 0) { | 1352 | if (strcmp(this_board->name, DRV_NAME) == 0) { |
| 1356 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1353 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
| 1357 | if (pcidev->device == boardtypes[i].device_id) { | 1354 | if (pcidev->device == boardtypes[i].device_id) { |
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index da5ee69d2c9d..dfde0f6328dd 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c | |||
| @@ -301,8 +301,6 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, | |||
| 301 | } | 301 | } |
| 302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
| 303 | continue; | 303 | continue; |
| 304 | if (pci_is_enabled(pcidev)) | ||
| 305 | continue; | ||
| 306 | return pcidev; | 304 | return pcidev; |
| 307 | } | 305 | } |
| 308 | dev_err(dev->class_dev, | 306 | dev_err(dev->class_dev, |
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 97f06dc8e48d..2d4cb7f638b2 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c | |||
| @@ -1064,8 +1064,6 @@ static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev, | |||
| 1064 | slot != PCI_SLOT(pcidev->devfn)) | 1064 | slot != PCI_SLOT(pcidev->devfn)) |
| 1065 | continue; | 1065 | continue; |
| 1066 | } | 1066 | } |
| 1067 | if (pci_is_enabled(pcidev)) | ||
| 1068 | continue; | ||
| 1069 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1067 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
| 1070 | if (boardtypes[i].vendor_id != pcidev->vendor) | 1068 | if (boardtypes[i].vendor_id != pcidev->vendor) |
| 1071 | continue; | 1069 | continue; |
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index ef28385c1482..cad559a1a730 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c | |||
| @@ -718,7 +718,8 @@ static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, | |||
| 718 | continue; | 718 | continue; |
| 719 | } | 719 | } |
| 720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || | 720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || |
| 721 | pcidev->device != 0x0409) | 721 | pcidev->device != 0x0409 || |
| 722 | pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) | ||
| 722 | continue; | 723 | continue; |
| 723 | 724 | ||
| 724 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { | 725 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { |
| @@ -739,6 +740,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
| 739 | { | 740 | { |
| 740 | struct pci_dev *pcidev; | 741 | struct pci_dev *pcidev; |
| 741 | struct comedi_subdevice *s; | 742 | struct comedi_subdevice *s; |
| 743 | resource_size_t pci_base; | ||
| 742 | void *aux_data; | 744 | void *aux_data; |
| 743 | unsigned int aux_len; | 745 | unsigned int aux_len; |
| 744 | int result; | 746 | int result; |
| @@ -758,11 +760,12 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
| 758 | "failed to enable PCI device and request regions\n"); | 760 | "failed to enable PCI device and request regions\n"); |
| 759 | return -EIO; | 761 | return -EIO; |
| 760 | } | 762 | } |
| 761 | dev->iobase = pci_resource_start(pcidev, 2); | 763 | dev->iobase = 1; /* the "detach" needs this */ |
| 762 | 764 | ||
| 763 | devpriv->plx = | 765 | pci_base = pci_resource_start(pcidev, 0); |
| 764 | ioremap(pci_resource_start(pcidev, 0), DAQBOARD2000_PLX_SIZE); | 766 | devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE); |
| 765 | devpriv->daq = ioremap(dev->iobase, DAQBOARD2000_DAQ_SIZE); | 767 | pci_base = pci_resource_start(pcidev, 2); |
| 768 | devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE); | ||
| 766 | if (!devpriv->plx || !devpriv->daq) | 769 | if (!devpriv->plx || !devpriv->daq) |
| 767 | return -ENOMEM; | 770 | return -ENOMEM; |
| 768 | 771 | ||
| @@ -799,8 +802,6 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
| 799 | printk("Interrupt after is: %x\n", interrupt); | 802 | printk("Interrupt after is: %x\n", interrupt); |
| 800 | */ | 803 | */ |
| 801 | 804 | ||
| 802 | dev->iobase = (unsigned long)devpriv->daq; | ||
| 803 | |||
| 804 | dev->board_name = this_board->name; | 805 | dev->board_name = this_board->name; |
| 805 | 806 | ||
| 806 | s = dev->subdevices + 0; | 807 | s = dev->subdevices + 0; |
| @@ -824,7 +825,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
| 824 | 825 | ||
| 825 | s = dev->subdevices + 2; | 826 | s = dev->subdevices + 2; |
| 826 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, | 827 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, |
| 827 | (unsigned long)(dev->iobase + 0x40)); | 828 | (unsigned long)(devpriv->daq + 0x40)); |
| 828 | 829 | ||
| 829 | out: | 830 | out: |
| 830 | return result; | 831 | return result; |
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index a6fe6c9be87e..3476cda0fff0 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c | |||
| @@ -804,6 +804,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
| 804 | { | 804 | { |
| 805 | struct pci_dev *pcidev; | 805 | struct pci_dev *pcidev; |
| 806 | struct comedi_subdevice *s; | 806 | struct comedi_subdevice *s; |
| 807 | resource_size_t pci_base; | ||
| 807 | int ret = 0; | 808 | int ret = 0; |
| 808 | 809 | ||
| 809 | dev_dbg(dev->class_dev, "dt3000:\n"); | 810 | dev_dbg(dev->class_dev, "dt3000:\n"); |
| @@ -820,9 +821,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
| 820 | ret = comedi_pci_enable(pcidev, "dt3000"); | 821 | ret = comedi_pci_enable(pcidev, "dt3000"); |
| 821 | if (ret < 0) | 822 | if (ret < 0) |
| 822 | return ret; | 823 | return ret; |
| 824 | dev->iobase = 1; /* the "detach" needs this */ | ||
| 823 | 825 | ||
| 824 | dev->iobase = pci_resource_start(pcidev, 0); | 826 | pci_base = pci_resource_start(pcidev, 0); |
| 825 | devpriv->io_addr = ioremap(dev->iobase, DT3000_SIZE); | 827 | devpriv->io_addr = ioremap(pci_base, DT3000_SIZE); |
| 826 | if (!devpriv->io_addr) | 828 | if (!devpriv->io_addr) |
| 827 | return -ENOMEM; | 829 | return -ENOMEM; |
| 828 | 830 | ||
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 112fdc3e9c69..5aa8be1e7b92 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c | |||
| @@ -1619,9 +1619,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
| 1619 | struct rtdPrivate *devpriv; | 1619 | struct rtdPrivate *devpriv; |
| 1620 | struct pci_dev *pcidev; | 1620 | struct pci_dev *pcidev; |
| 1621 | struct comedi_subdevice *s; | 1621 | struct comedi_subdevice *s; |
| 1622 | resource_size_t pci_base; | ||
| 1622 | int ret; | 1623 | int ret; |
| 1623 | resource_size_t physLas1; /* data area */ | ||
| 1624 | resource_size_t physLcfg; /* PLX9080 */ | ||
| 1625 | #ifdef USE_DMA | 1624 | #ifdef USE_DMA |
| 1626 | int index; | 1625 | int index; |
| 1627 | #endif | 1626 | #endif |
| @@ -1655,20 +1654,15 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
| 1655 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); | 1654 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); |
| 1656 | return ret; | 1655 | return ret; |
| 1657 | } | 1656 | } |
| 1658 | 1657 | dev->iobase = 1; /* the "detach" needs this */ | |
| 1659 | /* | 1658 | |
| 1660 | * Initialize base addresses | 1659 | /* Initialize the base addresses */ |
| 1661 | */ | 1660 | pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX); |
| 1662 | /* Get the physical address from PCI config */ | 1661 | devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE); |
| 1663 | dev->iobase = pci_resource_start(pcidev, LAS0_PCIINDEX); | 1662 | pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX); |
| 1664 | physLas1 = pci_resource_start(pcidev, LAS1_PCIINDEX); | 1663 | devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE); |
| 1665 | physLcfg = pci_resource_start(pcidev, LCFG_PCIINDEX); | 1664 | pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX); |
| 1666 | /* Now have the kernel map this into memory */ | 1665 | devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE); |
| 1667 | /* ASSUME page aligned */ | ||
| 1668 | devpriv->las0 = ioremap_nocache(dev->iobase, LAS0_PCISIZE); | ||
| 1669 | devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); | ||
| 1670 | devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); | ||
| 1671 | |||
| 1672 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) | 1666 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) |
| 1673 | return -ENOMEM; | 1667 | return -ENOMEM; |
| 1674 | 1668 | ||
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 848c7ec06976..11ee83681da7 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c | |||
| @@ -102,6 +102,7 @@ sampling rate. If you sample two channels you get 4kHz and so on. | |||
| 102 | #define BULK_TIMEOUT 1000 | 102 | #define BULK_TIMEOUT 1000 |
| 103 | 103 | ||
| 104 | /* constants for "firmware" upload and download */ | 104 | /* constants for "firmware" upload and download */ |
| 105 | #define FIRMWARE "usbdux_firmware.bin" | ||
| 105 | #define USBDUXSUB_FIRMWARE 0xA0 | 106 | #define USBDUXSUB_FIRMWARE 0xA0 |
| 106 | #define VENDOR_DIR_IN 0xC0 | 107 | #define VENDOR_DIR_IN 0xC0 |
| 107 | #define VENDOR_DIR_OUT 0x40 | 108 | #define VENDOR_DIR_OUT 0x40 |
| @@ -2791,7 +2792,7 @@ static int usbdux_usb_probe(struct usb_interface *uinterf, | |||
| 2791 | 2792 | ||
| 2792 | ret = request_firmware_nowait(THIS_MODULE, | 2793 | ret = request_firmware_nowait(THIS_MODULE, |
| 2793 | FW_ACTION_HOTPLUG, | 2794 | FW_ACTION_HOTPLUG, |
| 2794 | "usbdux_firmware.bin", | 2795 | FIRMWARE, |
| 2795 | &udev->dev, | 2796 | &udev->dev, |
| 2796 | GFP_KERNEL, | 2797 | GFP_KERNEL, |
| 2797 | usbduxsub + index, | 2798 | usbduxsub + index, |
| @@ -2850,3 +2851,4 @@ module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); | |||
| 2850 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2851 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
| 2851 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); | 2852 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); |
| 2852 | MODULE_LICENSE("GPL"); | 2853 | MODULE_LICENSE("GPL"); |
| 2854 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index d9911588c10a..8eb41257c6ce 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | /* | 57 | /* |
| 58 | * constants for "firmware" upload and download | 58 | * constants for "firmware" upload and download |
| 59 | */ | 59 | */ |
| 60 | #define FIRMWARE "usbduxfast_firmware.bin" | ||
| 60 | #define USBDUXFASTSUB_FIRMWARE 0xA0 | 61 | #define USBDUXFASTSUB_FIRMWARE 0xA0 |
| 61 | #define VENDOR_DIR_IN 0xC0 | 62 | #define VENDOR_DIR_IN 0xC0 |
| 62 | #define VENDOR_DIR_OUT 0x40 | 63 | #define VENDOR_DIR_OUT 0x40 |
| @@ -1706,7 +1707,7 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, | |||
| 1706 | 1707 | ||
| 1707 | ret = request_firmware_nowait(THIS_MODULE, | 1708 | ret = request_firmware_nowait(THIS_MODULE, |
| 1708 | FW_ACTION_HOTPLUG, | 1709 | FW_ACTION_HOTPLUG, |
| 1709 | "usbduxfast_firmware.bin", | 1710 | FIRMWARE, |
| 1710 | &udev->dev, | 1711 | &udev->dev, |
| 1711 | GFP_KERNEL, | 1712 | GFP_KERNEL, |
| 1712 | usbduxfastsub + index, | 1713 | usbduxfastsub + index, |
| @@ -1774,3 +1775,4 @@ module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver); | |||
| 1774 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 1775 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
| 1775 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); | 1776 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); |
| 1776 | MODULE_LICENSE("GPL"); | 1777 | MODULE_LICENSE("GPL"); |
| 1778 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 543e604791e2..f54ab8c2fcfd 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c | |||
| @@ -63,6 +63,7 @@ Status: testing | |||
| 63 | #define BULK_TIMEOUT 1000 | 63 | #define BULK_TIMEOUT 1000 |
| 64 | 64 | ||
| 65 | /* constants for "firmware" upload and download */ | 65 | /* constants for "firmware" upload and download */ |
| 66 | #define FIRMWARE "usbduxsigma_firmware.bin" | ||
| 66 | #define USBDUXSUB_FIRMWARE 0xA0 | 67 | #define USBDUXSUB_FIRMWARE 0xA0 |
| 67 | #define VENDOR_DIR_IN 0xC0 | 68 | #define VENDOR_DIR_IN 0xC0 |
| 68 | #define VENDOR_DIR_OUT 0x40 | 69 | #define VENDOR_DIR_OUT 0x40 |
| @@ -2780,7 +2781,7 @@ static int usbduxsigma_usb_probe(struct usb_interface *uinterf, | |||
| 2780 | 2781 | ||
| 2781 | ret = request_firmware_nowait(THIS_MODULE, | 2782 | ret = request_firmware_nowait(THIS_MODULE, |
| 2782 | FW_ACTION_HOTPLUG, | 2783 | FW_ACTION_HOTPLUG, |
| 2783 | "usbduxsigma_firmware.bin", | 2784 | FIRMWARE, |
| 2784 | &udev->dev, | 2785 | &udev->dev, |
| 2785 | GFP_KERNEL, | 2786 | GFP_KERNEL, |
| 2786 | usbduxsub + index, | 2787 | usbduxsub + index, |
| @@ -2845,3 +2846,4 @@ module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); | |||
| 2845 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2846 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
| 2846 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); | 2847 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); |
| 2847 | MODULE_LICENSE("GPL"); | 2848 | MODULE_LICENSE("GPL"); |
| 2849 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig index cee8d48d2af9..ad2a1096e920 100644 --- a/drivers/staging/csr/Kconfig +++ b/drivers/staging/csr/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config CSR_WIFI | 1 | config CSR_WIFI |
| 2 | tristate "CSR wireless driver" | 2 | tristate "CSR wireless driver" |
| 3 | depends on MMC && CFG80211_WEXT | 3 | depends on MMC && CFG80211_WEXT && INET |
| 4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
| 5 | select WEXT_PRIV | 5 | select WEXT_PRIV |
| 6 | help | 6 | help |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 22c3923d55eb..095837285f4f 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
| @@ -754,7 +754,7 @@ static ssize_t ad7192_set(struct device *dev, | |||
| 754 | else | 754 | else |
| 755 | st->mode &= ~AD7192_MODE_ACX; | 755 | st->mode &= ~AD7192_MODE_ACX; |
| 756 | 756 | ||
| 757 | ad7192_write_reg(st, AD7192_REG_GPOCON, 3, st->mode); | 757 | ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); |
| 758 | break; | 758 | break; |
| 759 | default: | 759 | default: |
| 760 | ret = -EINVAL; | 760 | ret = -EINVAL; |
| @@ -798,6 +798,11 @@ static const struct attribute_group ad7195_attribute_group = { | |||
| 798 | .attrs = ad7195_attributes, | 798 | .attrs = ad7195_attributes, |
| 799 | }; | 799 | }; |
| 800 | 800 | ||
| 801 | static unsigned int ad7192_get_temp_scale(bool unipolar) | ||
| 802 | { | ||
| 803 | return unipolar ? 2815 * 2 : 2815; | ||
| 804 | } | ||
| 805 | |||
| 801 | static int ad7192_read_raw(struct iio_dev *indio_dev, | 806 | static int ad7192_read_raw(struct iio_dev *indio_dev, |
| 802 | struct iio_chan_spec const *chan, | 807 | struct iio_chan_spec const *chan, |
| 803 | int *val, | 808 | int *val, |
| @@ -824,19 +829,6 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
| 824 | *val = (smpl >> chan->scan_type.shift) & | 829 | *val = (smpl >> chan->scan_type.shift) & |
| 825 | ((1 << (chan->scan_type.realbits)) - 1); | 830 | ((1 << (chan->scan_type.realbits)) - 1); |
| 826 | 831 | ||
| 827 | switch (chan->type) { | ||
| 828 | case IIO_VOLTAGE: | ||
| 829 | if (!unipolar) | ||
| 830 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
| 831 | break; | ||
| 832 | case IIO_TEMP: | ||
| 833 | *val -= 0x800000; | ||
| 834 | *val /= 2815; /* temp Kelvin */ | ||
| 835 | *val -= 273; /* temp Celsius */ | ||
| 836 | break; | ||
| 837 | default: | ||
| 838 | return -EINVAL; | ||
| 839 | } | ||
| 840 | return IIO_VAL_INT; | 832 | return IIO_VAL_INT; |
| 841 | 833 | ||
| 842 | case IIO_CHAN_INFO_SCALE: | 834 | case IIO_CHAN_INFO_SCALE: |
| @@ -848,11 +840,21 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
| 848 | mutex_unlock(&indio_dev->mlock); | 840 | mutex_unlock(&indio_dev->mlock); |
| 849 | return IIO_VAL_INT_PLUS_NANO; | 841 | return IIO_VAL_INT_PLUS_NANO; |
| 850 | case IIO_TEMP: | 842 | case IIO_TEMP: |
| 851 | *val = 1000; | 843 | *val = 0; |
| 852 | return IIO_VAL_INT; | 844 | *val2 = 1000000000 / ad7192_get_temp_scale(unipolar); |
| 845 | return IIO_VAL_INT_PLUS_NANO; | ||
| 853 | default: | 846 | default: |
| 854 | return -EINVAL; | 847 | return -EINVAL; |
| 855 | } | 848 | } |
| 849 | case IIO_CHAN_INFO_OFFSET: | ||
| 850 | if (!unipolar) | ||
| 851 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
| 852 | else | ||
| 853 | *val = 0; | ||
| 854 | /* Kelvin to Celsius */ | ||
| 855 | if (chan->type == IIO_TEMP) | ||
| 856 | *val -= 273 * ad7192_get_temp_scale(unipolar); | ||
| 857 | return IIO_VAL_INT; | ||
| 856 | } | 858 | } |
| 857 | 859 | ||
| 858 | return -EINVAL; | 860 | return -EINVAL; |
| @@ -890,7 +892,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, | |||
| 890 | } | 892 | } |
| 891 | ret = 0; | 893 | ret = 0; |
| 892 | } | 894 | } |
| 893 | 895 | break; | |
| 894 | default: | 896 | default: |
| 895 | ret = -EINVAL; | 897 | ret = -EINVAL; |
| 896 | } | 898 | } |
| @@ -942,20 +944,22 @@ static const struct iio_info ad7195_info = { | |||
| 942 | .channel = _chan, \ | 944 | .channel = _chan, \ |
| 943 | .channel2 = _chan2, \ | 945 | .channel2 = _chan2, \ |
| 944 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 946 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
| 945 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 947 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
| 948 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
| 946 | .address = _address, \ | 949 | .address = _address, \ |
| 947 | .scan_index = _si, \ | 950 | .scan_index = _si, \ |
| 948 | .scan_type = IIO_ST('s', 24, 32, 0)} | 951 | .scan_type = IIO_ST('u', 24, 32, 0)} |
| 949 | 952 | ||
| 950 | #define AD7192_CHAN(_chan, _address, _si) \ | 953 | #define AD7192_CHAN(_chan, _address, _si) \ |
| 951 | { .type = IIO_VOLTAGE, \ | 954 | { .type = IIO_VOLTAGE, \ |
| 952 | .indexed = 1, \ | 955 | .indexed = 1, \ |
| 953 | .channel = _chan, \ | 956 | .channel = _chan, \ |
| 954 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 957 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
| 955 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 958 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
| 959 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
| 956 | .address = _address, \ | 960 | .address = _address, \ |
| 957 | .scan_index = _si, \ | 961 | .scan_index = _si, \ |
| 958 | .scan_type = IIO_ST('s', 24, 32, 0)} | 962 | .scan_type = IIO_ST('u', 24, 32, 0)} |
| 959 | 963 | ||
| 960 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ | 964 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ |
| 961 | { .type = IIO_TEMP, \ | 965 | { .type = IIO_TEMP, \ |
| @@ -965,7 +969,7 @@ static const struct iio_info ad7195_info = { | |||
| 965 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ | 969 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ |
| 966 | .address = _address, \ | 970 | .address = _address, \ |
| 967 | .scan_index = _si, \ | 971 | .scan_index = _si, \ |
| 968 | .scan_type = IIO_ST('s', 24, 32, 0)} | 972 | .scan_type = IIO_ST('u', 24, 32, 0)} |
| 969 | 973 | ||
| 970 | static struct iio_chan_spec ad7192_channels[] = { | 974 | static struct iio_chan_spec ad7192_channels[] = { |
| 971 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), | 975 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), |
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index fd1d855ff57a..506016f01593 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c | |||
| @@ -76,7 +76,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) | |||
| 76 | struct iio_dev *indio_dev = pf->indio_dev; | 76 | struct iio_dev *indio_dev = pf->indio_dev; |
| 77 | struct ad7298_state *st = iio_priv(indio_dev); | 77 | struct ad7298_state *st = iio_priv(indio_dev); |
| 78 | struct iio_buffer *ring = indio_dev->buffer; | 78 | struct iio_buffer *ring = indio_dev->buffer; |
| 79 | s64 time_ns; | 79 | s64 time_ns = 0; |
| 80 | __u16 buf[16]; | 80 | __u16 buf[16]; |
| 81 | int b_sent, i; | 81 | int b_sent, i; |
| 82 | 82 | ||
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 1ece2ac8de56..19ee49c95de4 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c | |||
| @@ -131,9 +131,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
| 131 | .indexed = 1, | 131 | .indexed = 1, |
| 132 | .channel = 0, | 132 | .channel = 0, |
| 133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 134 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 134 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 135 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 135 | .scan_type = { | 136 | .scan_type = { |
| 136 | .sign = 's', | 137 | .sign = 'u', |
| 137 | .realbits = 24, | 138 | .realbits = 24, |
| 138 | .storagebits = 32, | 139 | .storagebits = 32, |
| 139 | .shift = 8, | 140 | .shift = 8, |
| @@ -146,9 +147,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
| 146 | .indexed = 1, | 147 | .indexed = 1, |
| 147 | .channel = 0, | 148 | .channel = 0, |
| 148 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 149 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 149 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 150 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 151 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 150 | .scan_type = { | 152 | .scan_type = { |
| 151 | .sign = 's', | 153 | .sign = 'u', |
| 152 | .realbits = 20, | 154 | .realbits = 20, |
| 153 | .storagebits = 32, | 155 | .storagebits = 32, |
| 154 | .shift = 12, | 156 | .shift = 12, |
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 76fdd7145fc5..112e2b7b5bc4 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c | |||
| @@ -563,8 +563,9 @@ static ssize_t ad7793_show_scale_available(struct device *dev, | |||
| 563 | return len; | 563 | return len; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, | 566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, |
| 567 | S_IRUGO, ad7793_show_scale_available, NULL, 0); | 567 | in_voltage-voltage_scale_available, S_IRUGO, |
| 568 | ad7793_show_scale_available, NULL, 0); | ||
| 568 | 569 | ||
| 569 | static struct attribute *ad7793_attributes[] = { | 570 | static struct attribute *ad7793_attributes[] = { |
| 570 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | 571 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
| @@ -604,9 +605,6 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
| 604 | *val = (smpl >> chan->scan_type.shift) & | 605 | *val = (smpl >> chan->scan_type.shift) & |
| 605 | ((1 << (chan->scan_type.realbits)) - 1); | 606 | ((1 << (chan->scan_type.realbits)) - 1); |
| 606 | 607 | ||
| 607 | if (!unipolar) | ||
| 608 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
| 609 | |||
| 610 | return IIO_VAL_INT; | 608 | return IIO_VAL_INT; |
| 611 | 609 | ||
| 612 | case IIO_CHAN_INFO_SCALE: | 610 | case IIO_CHAN_INFO_SCALE: |
| @@ -620,25 +618,38 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
| 620 | return IIO_VAL_INT_PLUS_NANO; | 618 | return IIO_VAL_INT_PLUS_NANO; |
| 621 | } else { | 619 | } else { |
| 622 | /* 1170mV / 2^23 * 6 */ | 620 | /* 1170mV / 2^23 * 6 */ |
| 623 | scale_uv = (1170ULL * 100000000ULL * 6ULL) | 621 | scale_uv = (1170ULL * 100000000ULL * 6ULL); |
| 624 | >> (chan->scan_type.realbits - | ||
| 625 | (unipolar ? 0 : 1)); | ||
| 626 | } | 622 | } |
| 627 | break; | 623 | break; |
| 628 | case IIO_TEMP: | 624 | case IIO_TEMP: |
| 629 | /* Always uses unity gain and internal ref */ | 625 | /* 1170mV / 0.81 mV/C / 2^23 */ |
| 630 | scale_uv = (2500ULL * 100000000ULL) | 626 | scale_uv = 1444444444444ULL; |
| 631 | >> (chan->scan_type.realbits - | ||
| 632 | (unipolar ? 0 : 1)); | ||
| 633 | break; | 627 | break; |
| 634 | default: | 628 | default: |
| 635 | return -EINVAL; | 629 | return -EINVAL; |
| 636 | } | 630 | } |
| 637 | 631 | ||
| 638 | *val2 = do_div(scale_uv, 100000000) * 10; | 632 | scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1)); |
| 639 | *val = scale_uv; | 633 | *val = 0; |
| 640 | 634 | *val2 = scale_uv; | |
| 641 | return IIO_VAL_INT_PLUS_NANO; | 635 | return IIO_VAL_INT_PLUS_NANO; |
| 636 | case IIO_CHAN_INFO_OFFSET: | ||
| 637 | if (!unipolar) | ||
| 638 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
| 639 | else | ||
| 640 | *val = 0; | ||
| 641 | |||
| 642 | /* Kelvin to Celsius */ | ||
| 643 | if (chan->type == IIO_TEMP) { | ||
| 644 | unsigned long long offset; | ||
| 645 | unsigned int shift; | ||
| 646 | |||
| 647 | shift = chan->scan_type.realbits - (unipolar ? 0 : 1); | ||
| 648 | offset = 273ULL << shift; | ||
| 649 | do_div(offset, 1444); | ||
| 650 | *val -= offset; | ||
| 651 | } | ||
| 652 | return IIO_VAL_INT; | ||
| 642 | } | 653 | } |
| 643 | return -EINVAL; | 654 | return -EINVAL; |
| 644 | } | 655 | } |
| @@ -676,7 +687,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, | |||
| 676 | } | 687 | } |
| 677 | ret = 0; | 688 | ret = 0; |
| 678 | } | 689 | } |
| 679 | 690 | break; | |
| 680 | default: | 691 | default: |
| 681 | ret = -EINVAL; | 692 | ret = -EINVAL; |
| 682 | } | 693 | } |
| @@ -720,9 +731,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 720 | .channel2 = 0, | 731 | .channel2 = 0, |
| 721 | .address = AD7793_CH_AIN1P_AIN1M, | 732 | .address = AD7793_CH_AIN1P_AIN1M, |
| 722 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 733 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 723 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 734 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 735 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 724 | .scan_index = 0, | 736 | .scan_index = 0, |
| 725 | .scan_type = IIO_ST('s', 24, 32, 0) | 737 | .scan_type = IIO_ST('u', 24, 32, 0) |
| 726 | }, | 738 | }, |
| 727 | .channel[1] = { | 739 | .channel[1] = { |
| 728 | .type = IIO_VOLTAGE, | 740 | .type = IIO_VOLTAGE, |
| @@ -732,9 +744,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 732 | .channel2 = 1, | 744 | .channel2 = 1, |
| 733 | .address = AD7793_CH_AIN2P_AIN2M, | 745 | .address = AD7793_CH_AIN2P_AIN2M, |
| 734 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 735 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 747 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 748 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 736 | .scan_index = 1, | 749 | .scan_index = 1, |
| 737 | .scan_type = IIO_ST('s', 24, 32, 0) | 750 | .scan_type = IIO_ST('u', 24, 32, 0) |
| 738 | }, | 751 | }, |
| 739 | .channel[2] = { | 752 | .channel[2] = { |
| 740 | .type = IIO_VOLTAGE, | 753 | .type = IIO_VOLTAGE, |
| @@ -744,9 +757,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 744 | .channel2 = 2, | 757 | .channel2 = 2, |
| 745 | .address = AD7793_CH_AIN3P_AIN3M, | 758 | .address = AD7793_CH_AIN3P_AIN3M, |
| 746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 747 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 760 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 761 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 748 | .scan_index = 2, | 762 | .scan_index = 2, |
| 749 | .scan_type = IIO_ST('s', 24, 32, 0) | 763 | .scan_type = IIO_ST('u', 24, 32, 0) |
| 750 | }, | 764 | }, |
| 751 | .channel[3] = { | 765 | .channel[3] = { |
| 752 | .type = IIO_VOLTAGE, | 766 | .type = IIO_VOLTAGE, |
| @@ -757,9 +771,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 757 | .channel2 = 2, | 771 | .channel2 = 2, |
| 758 | .address = AD7793_CH_AIN1M_AIN1M, | 772 | .address = AD7793_CH_AIN1M_AIN1M, |
| 759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 773 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 760 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 774 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 775 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 761 | .scan_index = 3, | 776 | .scan_index = 3, |
| 762 | .scan_type = IIO_ST('s', 24, 32, 0) | 777 | .scan_type = IIO_ST('u', 24, 32, 0) |
| 763 | }, | 778 | }, |
| 764 | .channel[4] = { | 779 | .channel[4] = { |
| 765 | .type = IIO_TEMP, | 780 | .type = IIO_TEMP, |
| @@ -769,7 +784,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 769 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 784 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 770 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 785 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
| 771 | .scan_index = 4, | 786 | .scan_index = 4, |
| 772 | .scan_type = IIO_ST('s', 24, 32, 0), | 787 | .scan_type = IIO_ST('u', 24, 32, 0), |
| 773 | }, | 788 | }, |
| 774 | .channel[5] = { | 789 | .channel[5] = { |
| 775 | .type = IIO_VOLTAGE, | 790 | .type = IIO_VOLTAGE, |
| @@ -778,9 +793,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 778 | .channel = 4, | 793 | .channel = 4, |
| 779 | .address = AD7793_CH_AVDD_MONITOR, | 794 | .address = AD7793_CH_AVDD_MONITOR, |
| 780 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 781 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 796 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
| 797 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 782 | .scan_index = 5, | 798 | .scan_index = 5, |
| 783 | .scan_type = IIO_ST('s', 24, 32, 0), | 799 | .scan_type = IIO_ST('u', 24, 32, 0), |
| 784 | }, | 800 | }, |
| 785 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 801 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
| 786 | }, | 802 | }, |
| @@ -793,9 +809,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 793 | .channel2 = 0, | 809 | .channel2 = 0, |
| 794 | .address = AD7793_CH_AIN1P_AIN1M, | 810 | .address = AD7793_CH_AIN1P_AIN1M, |
| 795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 811 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 796 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 812 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 813 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 797 | .scan_index = 0, | 814 | .scan_index = 0, |
| 798 | .scan_type = IIO_ST('s', 16, 32, 0) | 815 | .scan_type = IIO_ST('u', 16, 32, 0) |
| 799 | }, | 816 | }, |
| 800 | .channel[1] = { | 817 | .channel[1] = { |
| 801 | .type = IIO_VOLTAGE, | 818 | .type = IIO_VOLTAGE, |
| @@ -805,9 +822,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 805 | .channel2 = 1, | 822 | .channel2 = 1, |
| 806 | .address = AD7793_CH_AIN2P_AIN2M, | 823 | .address = AD7793_CH_AIN2P_AIN2M, |
| 807 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 824 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 808 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 825 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 826 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 809 | .scan_index = 1, | 827 | .scan_index = 1, |
| 810 | .scan_type = IIO_ST('s', 16, 32, 0) | 828 | .scan_type = IIO_ST('u', 16, 32, 0) |
| 811 | }, | 829 | }, |
| 812 | .channel[2] = { | 830 | .channel[2] = { |
| 813 | .type = IIO_VOLTAGE, | 831 | .type = IIO_VOLTAGE, |
| @@ -817,9 +835,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 817 | .channel2 = 2, | 835 | .channel2 = 2, |
| 818 | .address = AD7793_CH_AIN3P_AIN3M, | 836 | .address = AD7793_CH_AIN3P_AIN3M, |
| 819 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 837 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 820 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 838 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 839 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 821 | .scan_index = 2, | 840 | .scan_index = 2, |
| 822 | .scan_type = IIO_ST('s', 16, 32, 0) | 841 | .scan_type = IIO_ST('u', 16, 32, 0) |
| 823 | }, | 842 | }, |
| 824 | .channel[3] = { | 843 | .channel[3] = { |
| 825 | .type = IIO_VOLTAGE, | 844 | .type = IIO_VOLTAGE, |
| @@ -830,9 +849,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 830 | .channel2 = 2, | 849 | .channel2 = 2, |
| 831 | .address = AD7793_CH_AIN1M_AIN1M, | 850 | .address = AD7793_CH_AIN1M_AIN1M, |
| 832 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 851 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 833 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 852 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
| 853 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 834 | .scan_index = 3, | 854 | .scan_index = 3, |
| 835 | .scan_type = IIO_ST('s', 16, 32, 0) | 855 | .scan_type = IIO_ST('u', 16, 32, 0) |
| 836 | }, | 856 | }, |
| 837 | .channel[4] = { | 857 | .channel[4] = { |
| 838 | .type = IIO_TEMP, | 858 | .type = IIO_TEMP, |
| @@ -842,7 +862,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 842 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 862 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 843 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 863 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
| 844 | .scan_index = 4, | 864 | .scan_index = 4, |
| 845 | .scan_type = IIO_ST('s', 16, 32, 0), | 865 | .scan_type = IIO_ST('u', 16, 32, 0), |
| 846 | }, | 866 | }, |
| 847 | .channel[5] = { | 867 | .channel[5] = { |
| 848 | .type = IIO_VOLTAGE, | 868 | .type = IIO_VOLTAGE, |
| @@ -851,9 +871,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
| 851 | .channel = 4, | 871 | .channel = 4, |
| 852 | .address = AD7793_CH_AVDD_MONITOR, | 872 | .address = AD7793_CH_AVDD_MONITOR, |
| 853 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 873 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
| 854 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 874 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
| 875 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
| 855 | .scan_index = 5, | 876 | .scan_index = 5, |
| 856 | .scan_type = IIO_ST('s', 16, 32, 0), | 877 | .scan_type = IIO_ST('u', 16, 32, 0), |
| 857 | }, | 878 | }, |
| 858 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 879 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
| 859 | }, | 880 | }, |
| @@ -901,7 +922,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) | |||
| 901 | else if (voltage_uv) | 922 | else if (voltage_uv) |
| 902 | st->int_vref_mv = voltage_uv / 1000; | 923 | st->int_vref_mv = voltage_uv / 1000; |
| 903 | else | 924 | else |
| 904 | st->int_vref_mv = 2500; /* Build-in ref */ | 925 | st->int_vref_mv = 1170; /* Build-in ref */ |
| 905 | 926 | ||
| 906 | spi_set_drvdata(spi, indio_dev); | 927 | spi_set_drvdata(spi, indio_dev); |
| 907 | st->spi = spi; | 928 | st->spi = spi; |
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index b06fd5b723fa..d536756549e6 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c | |||
| @@ -189,7 +189,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); | |||
| 189 | // Static vars definitions | 189 | // Static vars definitions |
| 190 | // | 190 | // |
| 191 | 191 | ||
| 192 | static struct usb_device_id vt6656_table[] __devinitdata = { | 192 | static struct usb_device_id vt6656_table[] = { |
| 193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, | 193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, |
| 194 | {} | 194 | {} |
| 195 | }; | 195 | }; |
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index ef360547ecec..0ca857ac473e 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c | |||
| @@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); | |||
| 25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
| 26 | MODULE_VERSION("0.1"); | 26 | MODULE_VERSION("0.1"); |
| 27 | 27 | ||
| 28 | static const struct usb_device_id wb35_table[] __devinitconst = { | 28 | static const struct usb_device_id wb35_table[] = { |
| 29 | { USB_DEVICE(0x0416, 0x0035) }, | 29 | { USB_DEVICE(0x0416, 0x0035) }, |
| 30 | { USB_DEVICE(0x18E8, 0x6201) }, | 30 | { USB_DEVICE(0x18E8, 0x6201) }, |
| 31 | { USB_DEVICE(0x18E8, 0x6206) }, | 31 | { USB_DEVICE(0x18E8, 0x6206) }, |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 070b442c1f81..4720b4ba096a 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -160,10 +160,12 @@ config SERIAL_KS8695_CONSOLE | |||
| 160 | 160 | ||
| 161 | config SERIAL_CLPS711X | 161 | config SERIAL_CLPS711X |
| 162 | tristate "CLPS711X serial port support" | 162 | tristate "CLPS711X serial port support" |
| 163 | depends on ARM && ARCH_CLPS711X | 163 | depends on ARCH_CLPS711X |
| 164 | select SERIAL_CORE | 164 | select SERIAL_CORE |
| 165 | default y | ||
| 165 | help | 166 | help |
| 166 | ::: To be written ::: | 167 | This enables the driver for the on-chip UARTs of the Cirrus |
| 168 | Logic EP711x/EP721x/EP731x processors. | ||
| 167 | 169 | ||
| 168 | config SERIAL_CLPS711X_CONSOLE | 170 | config SERIAL_CLPS711X_CONSOLE |
| 169 | bool "Support for console on CLPS711X serial port" | 171 | bool "Support for console on CLPS711X serial port" |
| @@ -173,9 +175,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
| 173 | Even if you say Y here, the currently visible virtual console | 175 | Even if you say Y here, the currently visible virtual console |
| 174 | (/dev/tty0) will still be used as the system console by default, but | 176 | (/dev/tty0) will still be used as the system console by default, but |
| 175 | you can alter that using a kernel command line option such as | 177 | you can alter that using a kernel command line option such as |
| 176 | "console=ttyCL1". (Try "man bootparam" or see the documentation of | 178 | "console=ttyCL1". |
| 177 | your boot loader (lilo or loadlin) about how to pass options to the | ||
| 178 | kernel at boot time.) | ||
| 179 | 179 | ||
| 180 | config SERIAL_SAMSUNG | 180 | config SERIAL_SAMSUNG |
| 181 | tristate "Samsung SoC serial support" | 181 | tristate "Samsung SoC serial support" |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 144cd3987d4c..3ad079ffd049 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
| @@ -1331,7 +1331,7 @@ static const struct spi_device_id ifx_id_table[] = { | |||
| 1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); | 1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); |
| 1332 | 1332 | ||
| 1333 | /* spi operations */ | 1333 | /* spi operations */ |
| 1334 | static const struct spi_driver ifx_spi_driver = { | 1334 | static struct spi_driver ifx_spi_driver = { |
| 1335 | .driver = { | 1335 | .driver = { |
| 1336 | .name = DRVNAME, | 1336 | .name = DRVNAME, |
| 1337 | .pm = &ifx_spi_pm, | 1337 | .pm = &ifx_spi_pm, |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 2e341b81ff89..3a667eed63d6 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
| @@ -73,6 +73,7 @@ | |||
| 73 | #define AUART_CTRL0_CLKGATE (1 << 30) | 73 | #define AUART_CTRL0_CLKGATE (1 << 30) |
| 74 | 74 | ||
| 75 | #define AUART_CTRL2_CTSEN (1 << 15) | 75 | #define AUART_CTRL2_CTSEN (1 << 15) |
| 76 | #define AUART_CTRL2_RTSEN (1 << 14) | ||
| 76 | #define AUART_CTRL2_RTS (1 << 11) | 77 | #define AUART_CTRL2_RTS (1 << 11) |
| 77 | #define AUART_CTRL2_RXE (1 << 9) | 78 | #define AUART_CTRL2_RXE (1 << 9) |
| 78 | #define AUART_CTRL2_TXE (1 << 8) | 79 | #define AUART_CTRL2_TXE (1 << 8) |
| @@ -259,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
| 259 | 260 | ||
| 260 | u32 ctrl = readl(u->membase + AUART_CTRL2); | 261 | u32 ctrl = readl(u->membase + AUART_CTRL2); |
| 261 | 262 | ||
| 262 | ctrl &= ~AUART_CTRL2_RTS; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
| 263 | if (mctrl & TIOCM_RTS) | 264 | if (mctrl & TIOCM_RTS) { |
| 264 | ctrl |= AUART_CTRL2_RTS; | 265 | if (u->state->port.flags & ASYNC_CTS_FLOW) |
| 266 | ctrl |= AUART_CTRL2_RTSEN; | ||
| 267 | } | ||
| 268 | |||
| 265 | s->ctrl = mctrl; | 269 | s->ctrl = mctrl; |
| 266 | writel(ctrl, u->membase + AUART_CTRL2); | 270 | writel(ctrl, u->membase + AUART_CTRL2); |
| 267 | } | 271 | } |
| @@ -359,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
| 359 | 363 | ||
| 360 | /* figure out the hardware flow control settings */ | 364 | /* figure out the hardware flow control settings */ |
| 361 | if (cflag & CRTSCTS) | 365 | if (cflag & CRTSCTS) |
| 362 | ctrl2 |= AUART_CTRL2_CTSEN; | 366 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; |
| 363 | else | 367 | else |
| 364 | ctrl2 &= ~AUART_CTRL2_CTSEN; | 368 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); |
| 365 | 369 | ||
| 366 | /* set baud rate */ | 370 | /* set baud rate */ |
| 367 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); | 371 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 654755a990df..333c8d012b0e 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
| @@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
| 1348 | static int pmz_poll_get_char(struct uart_port *port) | 1348 | static int pmz_poll_get_char(struct uart_port *port) |
| 1349 | { | 1349 | { |
| 1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | 1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; |
| 1351 | int tries = 2; | ||
| 1351 | 1352 | ||
| 1352 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) | 1353 | while (tries) { |
| 1353 | udelay(5); | 1354 | if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0) |
| 1354 | return read_zsdata(uap); | 1355 | return read_zsdata(uap); |
| 1356 | if (tries--) | ||
| 1357 | udelay(5); | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | return NO_POLL_CHAR; | ||
| 1355 | } | 1361 | } |
| 1356 | 1362 | ||
| 1357 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | 1363 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index a7773a3e02b1..7065df6036ca 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -13,7 +13,7 @@ config USB_ARCH_HAS_OHCI | |||
| 13 | default y if PXA3xx | 13 | default y if PXA3xx |
| 14 | default y if ARCH_EP93XX | 14 | default y if ARCH_EP93XX |
| 15 | default y if ARCH_AT91 | 15 | default y if ARCH_AT91 |
| 16 | default y if ARCH_PNX4008 && I2C | 16 | default y if ARCH_PNX4008 |
| 17 | default y if MFD_TC6393XB | 17 | default y if MFD_TC6393XB |
| 18 | default y if ARCH_W90X900 | 18 | default y if ARCH_W90X900 |
| 19 | default y if ARCH_DAVINCI_DA8XX | 19 | default y if ARCH_DAVINCI_DA8XX |
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 8337fb5d988d..47e499c9c0b6 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | config USB_CHIPIDEA | 1 | config USB_CHIPIDEA |
| 2 | tristate "ChipIdea Highspeed Dual Role Controller" | 2 | tristate "ChipIdea Highspeed Dual Role Controller" |
| 3 | depends on USB | 3 | depends on USB || USB_GADGET |
| 4 | help | 4 | help |
| 5 | Say Y here if your system has a dual role high speed USB | 5 | Say Y here if your system has a dual role high speed USB |
| 6 | controller based on ChipIdea silicon IP. Currently, only the | 6 | controller based on ChipIdea silicon IP. Currently, only the |
| 7 | peripheral mode is supported. | 7 | peripheral mode is supported. |
| 8 | 8 | ||
| 9 | When compiled dynamically, the module will be called ci-hdrc.ko. | 9 | When compiled dynamically, the module will be called ci-hdrc.ko. |
| @@ -12,7 +12,7 @@ if USB_CHIPIDEA | |||
| 12 | 12 | ||
| 13 | config USB_CHIPIDEA_UDC | 13 | config USB_CHIPIDEA_UDC |
| 14 | bool "ChipIdea device controller" | 14 | bool "ChipIdea device controller" |
| 15 | depends on USB_GADGET | 15 | depends on USB_GADGET=y || USB_GADGET=USB_CHIPIDEA |
| 16 | select USB_GADGET_DUALSPEED | 16 | select USB_GADGET_DUALSPEED |
| 17 | help | 17 | help |
| 18 | Say Y here to enable device controller functionality of the | 18 | Say Y here to enable device controller functionality of the |
| @@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC | |||
| 20 | 20 | ||
| 21 | config USB_CHIPIDEA_HOST | 21 | config USB_CHIPIDEA_HOST |
| 22 | bool "ChipIdea host controller" | 22 | bool "ChipIdea host controller" |
| 23 | depends on USB=y || USB=USB_CHIPIDEA | ||
| 23 | select USB_EHCI_ROOT_HUB_TT | 24 | select USB_EHCI_ROOT_HUB_TT |
| 24 | help | 25 | help |
| 25 | Say Y here to enable host controller functionality of the | 26 | Say Y here to enable host controller functionality of the |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 56d6bf668488..f763ed7ba91e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -1104,7 +1104,8 @@ skip_normal_probe: | |||
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | 1106 | ||
| 1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) | 1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || |
| 1108 | control_interface->cur_altsetting->desc.bNumEndpoints == 0) | ||
| 1108 | return -EINVAL; | 1109 | return -EINVAL; |
| 1109 | 1110 | ||
| 1110 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; | 1111 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 90e82e288eb9..0e5230926154 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net) | |||
| 669 | spin_lock_irqsave(&dev->lock, flags); | 669 | spin_lock_irqsave(&dev->lock, flags); |
| 670 | if (dev->port_usb) { | 670 | if (dev->port_usb) { |
| 671 | struct gether *link = dev->port_usb; | 671 | struct gether *link = dev->port_usb; |
| 672 | const struct usb_endpoint_descriptor *in; | ||
| 673 | const struct usb_endpoint_descriptor *out; | ||
| 672 | 674 | ||
| 673 | if (link->close) | 675 | if (link->close) |
| 674 | link->close(link); | 676 | link->close(link); |
| @@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net) | |||
| 682 | * their own pace; the network stack can handle old packets. | 684 | * their own pace; the network stack can handle old packets. |
| 683 | * For the moment we leave this here, since it works. | 685 | * For the moment we leave this here, since it works. |
| 684 | */ | 686 | */ |
| 687 | in = link->in_ep->desc; | ||
| 688 | out = link->out_ep->desc; | ||
| 685 | usb_ep_disable(link->in_ep); | 689 | usb_ep_disable(link->in_ep); |
| 686 | usb_ep_disable(link->out_ep); | 690 | usb_ep_disable(link->out_ep); |
| 687 | if (netif_carrier_ok(net)) { | 691 | if (netif_carrier_ok(net)) { |
| 688 | DBG(dev, "host still using in/out endpoints\n"); | 692 | DBG(dev, "host still using in/out endpoints\n"); |
| 693 | link->in_ep->desc = in; | ||
| 694 | link->out_ep->desc = out; | ||
| 689 | usb_ep_enable(link->in_ep); | 695 | usb_ep_enable(link->in_ep); |
| 690 | usb_ep_enable(link->out_ep); | 696 | usb_ep_enable(link->out_ep); |
| 691 | } | 697 | } |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bb55eb4a7d48..d7fe287d0678 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
| @@ -56,15 +56,6 @@ | |||
| 56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
| 57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
| 58 | 58 | ||
| 59 | /* Errata i693 */ | ||
| 60 | static struct clk *utmi_p1_fck; | ||
| 61 | static struct clk *utmi_p2_fck; | ||
| 62 | static struct clk *xclk60mhsp1_ck; | ||
| 63 | static struct clk *xclk60mhsp2_ck; | ||
| 64 | static struct clk *usbhost_p1_fck; | ||
| 65 | static struct clk *usbhost_p2_fck; | ||
| 66 | static struct clk *init_60m_fclk; | ||
| 67 | |||
| 68 | /*-------------------------------------------------------------------------*/ | 59 | /*-------------------------------------------------------------------------*/ |
| 69 | 60 | ||
| 70 | static const struct hc_driver ehci_omap_hc_driver; | 61 | static const struct hc_driver ehci_omap_hc_driver; |
| @@ -80,40 +71,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) | |||
| 80 | return __raw_readl(base + reg); | 71 | return __raw_readl(base + reg); |
| 81 | } | 72 | } |
| 82 | 73 | ||
| 83 | /* Erratum i693 workaround sequence */ | ||
| 84 | static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) | ||
| 85 | { | ||
| 86 | int ret = 0; | ||
| 87 | |||
| 88 | /* Switch to the internal 60 MHz clock */ | ||
| 89 | ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); | ||
| 90 | if (ret != 0) | ||
| 91 | ehci_err(ehci, "init_60m_fclk set parent" | ||
| 92 | "failed error:%d\n", ret); | ||
| 93 | |||
| 94 | ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); | ||
| 95 | if (ret != 0) | ||
| 96 | ehci_err(ehci, "init_60m_fclk set parent" | ||
| 97 | "failed error:%d\n", ret); | ||
| 98 | |||
| 99 | clk_enable(usbhost_p1_fck); | ||
| 100 | clk_enable(usbhost_p2_fck); | ||
| 101 | |||
| 102 | /* Wait 1ms and switch back to the external clock */ | ||
| 103 | mdelay(1); | ||
| 104 | ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); | ||
| 105 | if (ret != 0) | ||
| 106 | ehci_err(ehci, "xclk60mhsp1_ck set parent" | ||
| 107 | "failed error:%d\n", ret); | ||
| 108 | |||
| 109 | ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); | ||
| 110 | if (ret != 0) | ||
| 111 | ehci_err(ehci, "xclk60mhsp2_ck set parent" | ||
| 112 | "failed error:%d\n", ret); | ||
| 113 | |||
| 114 | clk_disable(usbhost_p1_fck); | ||
| 115 | clk_disable(usbhost_p2_fck); | ||
| 116 | } | ||
| 117 | 74 | ||
| 118 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) | 75 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) |
| 119 | { | 76 | { |
| @@ -195,50 +152,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) | |||
| 195 | return rc; | 152 | return rc; |
| 196 | } | 153 | } |
| 197 | 154 | ||
| 198 | static int omap_ehci_hub_control( | ||
| 199 | struct usb_hcd *hcd, | ||
| 200 | u16 typeReq, | ||
| 201 | u16 wValue, | ||
| 202 | u16 wIndex, | ||
| 203 | char *buf, | ||
| 204 | u16 wLength | ||
| 205 | ) | ||
| 206 | { | ||
| 207 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 208 | u32 __iomem *status_reg = &ehci->regs->port_status[ | ||
| 209 | (wIndex & 0xff) - 1]; | ||
| 210 | u32 temp; | ||
| 211 | unsigned long flags; | ||
| 212 | int retval = 0; | ||
| 213 | |||
| 214 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 215 | |||
| 216 | if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { | ||
| 217 | temp = ehci_readl(ehci, status_reg); | ||
| 218 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { | ||
| 219 | retval = -EPIPE; | ||
| 220 | goto done; | ||
| 221 | } | ||
| 222 | |||
| 223 | temp &= ~PORT_WKCONN_E; | ||
| 224 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
| 225 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
| 226 | |||
| 227 | omap_ehci_erratum_i693(ehci); | ||
| 228 | |||
| 229 | set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); | ||
| 230 | goto done; | ||
| 231 | } | ||
| 232 | |||
| 233 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
| 234 | |||
| 235 | /* Handle the hub control events here */ | ||
| 236 | return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
| 237 | done: | ||
| 238 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
| 239 | return retval; | ||
| 240 | } | ||
| 241 | |||
| 242 | static void disable_put_regulator( | 155 | static void disable_put_regulator( |
| 243 | struct ehci_hcd_omap_platform_data *pdata) | 156 | struct ehci_hcd_omap_platform_data *pdata) |
| 244 | { | 157 | { |
| @@ -351,79 +264,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
| 351 | goto err_pm_runtime; | 264 | goto err_pm_runtime; |
| 352 | } | 265 | } |
| 353 | 266 | ||
| 354 | /* get clocks */ | ||
| 355 | utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | ||
| 356 | if (IS_ERR(utmi_p1_fck)) { | ||
| 357 | ret = PTR_ERR(utmi_p1_fck); | ||
| 358 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
| 359 | goto err_add_hcd; | ||
| 360 | } | ||
| 361 | |||
| 362 | xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | ||
| 363 | if (IS_ERR(xclk60mhsp1_ck)) { | ||
| 364 | ret = PTR_ERR(xclk60mhsp1_ck); | ||
| 365 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
| 366 | goto err_utmi_p1_fck; | ||
| 367 | } | ||
| 368 | |||
| 369 | utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); | ||
| 370 | if (IS_ERR(utmi_p2_fck)) { | ||
| 371 | ret = PTR_ERR(utmi_p2_fck); | ||
| 372 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
| 373 | goto err_xclk60mhsp1_ck; | ||
| 374 | } | ||
| 375 | |||
| 376 | xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | ||
| 377 | if (IS_ERR(xclk60mhsp2_ck)) { | ||
| 378 | ret = PTR_ERR(xclk60mhsp2_ck); | ||
| 379 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
| 380 | goto err_utmi_p2_fck; | ||
| 381 | } | ||
| 382 | |||
| 383 | usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); | ||
| 384 | if (IS_ERR(usbhost_p1_fck)) { | ||
| 385 | ret = PTR_ERR(usbhost_p1_fck); | ||
| 386 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
| 387 | goto err_xclk60mhsp2_ck; | ||
| 388 | } | ||
| 389 | |||
| 390 | usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); | ||
| 391 | if (IS_ERR(usbhost_p2_fck)) { | ||
| 392 | ret = PTR_ERR(usbhost_p2_fck); | ||
| 393 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
| 394 | goto err_usbhost_p1_fck; | ||
| 395 | } | ||
| 396 | |||
| 397 | init_60m_fclk = clk_get(dev, "init_60m_fclk"); | ||
| 398 | if (IS_ERR(init_60m_fclk)) { | ||
| 399 | ret = PTR_ERR(init_60m_fclk); | ||
| 400 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | ||
| 401 | goto err_usbhost_p2_fck; | ||
| 402 | } | ||
| 403 | 267 | ||
| 404 | return 0; | 268 | return 0; |
| 405 | 269 | ||
| 406 | err_usbhost_p2_fck: | ||
| 407 | clk_put(usbhost_p2_fck); | ||
| 408 | |||
| 409 | err_usbhost_p1_fck: | ||
| 410 | clk_put(usbhost_p1_fck); | ||
| 411 | |||
| 412 | err_xclk60mhsp2_ck: | ||
| 413 | clk_put(xclk60mhsp2_ck); | ||
| 414 | |||
| 415 | err_utmi_p2_fck: | ||
| 416 | clk_put(utmi_p2_fck); | ||
| 417 | |||
| 418 | err_xclk60mhsp1_ck: | ||
| 419 | clk_put(xclk60mhsp1_ck); | ||
| 420 | |||
| 421 | err_utmi_p1_fck: | ||
| 422 | clk_put(utmi_p1_fck); | ||
| 423 | |||
| 424 | err_add_hcd: | ||
| 425 | usb_remove_hcd(hcd); | ||
| 426 | |||
| 427 | err_pm_runtime: | 270 | err_pm_runtime: |
| 428 | disable_put_regulator(pdata); | 271 | disable_put_regulator(pdata); |
| 429 | pm_runtime_put_sync(dev); | 272 | pm_runtime_put_sync(dev); |
| @@ -454,14 +297,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
| 454 | iounmap(hcd->regs); | 297 | iounmap(hcd->regs); |
| 455 | usb_put_hcd(hcd); | 298 | usb_put_hcd(hcd); |
| 456 | 299 | ||
| 457 | clk_put(utmi_p1_fck); | ||
| 458 | clk_put(utmi_p2_fck); | ||
| 459 | clk_put(xclk60mhsp1_ck); | ||
| 460 | clk_put(xclk60mhsp2_ck); | ||
| 461 | clk_put(usbhost_p1_fck); | ||
| 462 | clk_put(usbhost_p2_fck); | ||
| 463 | clk_put(init_60m_fclk); | ||
| 464 | |||
| 465 | pm_runtime_put_sync(dev); | 300 | pm_runtime_put_sync(dev); |
| 466 | pm_runtime_disable(dev); | 301 | pm_runtime_disable(dev); |
| 467 | 302 | ||
| @@ -532,7 +367,7 @@ static const struct hc_driver ehci_omap_hc_driver = { | |||
| 532 | * root hub support | 367 | * root hub support |
| 533 | */ | 368 | */ |
| 534 | .hub_status_data = ehci_hub_status_data, | 369 | .hub_status_data = ehci_hub_status_data, |
| 535 | .hub_control = omap_ehci_hub_control, | 370 | .hub_control = ehci_hub_control, |
| 536 | .bus_suspend = ehci_bus_suspend, | 371 | .bus_suspend = ehci_bus_suspend, |
| 537 | .bus_resume = ehci_bus_resume, | 372 | .bus_resume = ehci_bus_resume, |
| 538 | 373 | ||
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 58c96bd50d22..0c9e43cfaff5 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c | |||
| @@ -40,7 +40,7 @@ static int ehci_sead3_setup(struct usb_hcd *hcd) | |||
| 40 | ehci->need_io_watchdog = 0; | 40 | ehci->need_io_watchdog = 0; |
| 41 | 41 | ||
| 42 | /* Set burst length to 16 words. */ | 42 | /* Set burst length to 16 words. */ |
| 43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]); | 43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]); |
| 44 | 44 | ||
| 45 | return ret; | 45 | return ret; |
| 46 | } | 46 | } |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 950e95efa381..26dedb30ad0b 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
| @@ -799,11 +799,12 @@ static int tegra_ehci_remove(struct platform_device *pdev) | |||
| 799 | #endif | 799 | #endif |
| 800 | 800 | ||
| 801 | usb_remove_hcd(hcd); | 801 | usb_remove_hcd(hcd); |
| 802 | usb_put_hcd(hcd); | ||
| 803 | 802 | ||
| 804 | tegra_usb_phy_close(tegra->phy); | 803 | tegra_usb_phy_close(tegra->phy); |
| 805 | iounmap(hcd->regs); | 804 | iounmap(hcd->regs); |
| 806 | 805 | ||
| 806 | usb_put_hcd(hcd); | ||
| 807 | |||
| 807 | clk_disable_unprepare(tegra->clk); | 808 | clk_disable_unprepare(tegra->clk); |
| 808 | clk_put(tegra->clk); | 809 | clk_put(tegra->clk); |
| 809 | 810 | ||
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 2ed112d3e159..256326322cfd 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
| @@ -543,12 +543,12 @@ static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) | |||
| 543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, | 543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, |
| 544 | short_ok ? "" : "not_", | 544 | short_ok ? "" : "not_", |
| 545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); | 545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); |
| 546 | /* save the data underrun error code for later and | ||
| 547 | * proceed with the status stage | ||
| 548 | */ | ||
| 549 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
| 546 | if (usb_pipecontrol(urb->pipe)) { | 550 | if (usb_pipecontrol(urb->pipe)) { |
| 547 | ep->nextpid = USB_PID_ACK; | 551 | ep->nextpid = USB_PID_ACK; |
| 548 | /* save the data underrun error code for later and | ||
| 549 | * proceed with the status stage | ||
| 550 | */ | ||
| 551 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
| 552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); | 552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); |
| 553 | 553 | ||
| 554 | if (urb->status == -EINPROGRESS) | 554 | if (urb->status == -EINPROGRESS) |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index df0828cb2aa3..c5e9e4a76f14 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -800,6 +800,13 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
| 800 | } | 800 | } |
| 801 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | 801 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); |
| 802 | 802 | ||
| 803 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) | ||
| 804 | { | ||
| 805 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0); | ||
| 806 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0); | ||
| 807 | } | ||
| 808 | EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); | ||
| 809 | |||
| 803 | /** | 810 | /** |
| 804 | * PCI Quirks for xHCI. | 811 | * PCI Quirks for xHCI. |
| 805 | * | 812 | * |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index b1002a8ef96f..ef004a5de20f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
| @@ -10,6 +10,7 @@ void usb_amd_quirk_pll_disable(void); | |||
| 10 | void usb_amd_quirk_pll_enable(void); | 10 | void usb_amd_quirk_pll_enable(void); |
| 11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); | 11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); |
| 12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); | 12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); |
| 13 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | ||
| 13 | #else | 14 | #else |
| 14 | static inline void usb_amd_quirk_pll_disable(void) {} | 15 | static inline void usb_amd_quirk_pll_disable(void) {} |
| 15 | static inline void usb_amd_quirk_pll_enable(void) {} | 16 | static inline void usb_amd_quirk_pll_enable(void) {} |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 18b231b0c5d3..9bfd4ca1153c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -94,11 +94,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | 94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; |
| 95 | xhci->limit_active_eps = 64; | 95 | xhci->limit_active_eps = 64; |
| 96 | xhci->quirks |= XHCI_SW_BW_CHECKING; | 96 | xhci->quirks |= XHCI_SW_BW_CHECKING; |
| 97 | /* | ||
| 98 | * PPT desktop boards DH77EB and DH77DF will power back on after | ||
| 99 | * a few seconds of being shutdown. The fix for this is to | ||
| 100 | * switch the ports from xHCI to EHCI on shutdown. We can't use | ||
| 101 | * DMI information to find those particular boards (since each | ||
| 102 | * vendor will change the board name), so we have to key off all | ||
| 103 | * PPT chipsets. | ||
| 104 | */ | ||
| 105 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | ||
| 97 | } | 106 | } |
| 98 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 107 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| 99 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 108 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { |
| 100 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 109 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
| 101 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); | 110 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); |
| 111 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
| 102 | } | 112 | } |
| 103 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 113 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
| 104 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 114 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8275645889da..643c2f3f3e73 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -145,29 +145,37 @@ static void next_trb(struct xhci_hcd *xhci, | |||
| 145 | */ | 145 | */ |
| 146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) | 146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) |
| 147 | { | 147 | { |
| 148 | union xhci_trb *next; | ||
| 149 | unsigned long long addr; | 148 | unsigned long long addr; |
| 150 | 149 | ||
| 151 | ring->deq_updates++; | 150 | ring->deq_updates++; |
| 152 | 151 | ||
| 153 | /* If this is not event ring, there is one more usable TRB */ | 152 | /* |
| 153 | * If this is not event ring, and the dequeue pointer | ||
| 154 | * is not on a link TRB, there is one more usable TRB | ||
| 155 | */ | ||
| 154 | if (ring->type != TYPE_EVENT && | 156 | if (ring->type != TYPE_EVENT && |
| 155 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) | 157 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) |
| 156 | ring->num_trbs_free++; | 158 | ring->num_trbs_free++; |
| 157 | next = ++(ring->dequeue); | ||
| 158 | 159 | ||
| 159 | /* Update the dequeue pointer further if that was a link TRB or we're at | 160 | do { |
| 160 | * the end of an event ring segment (which doesn't have link TRBS) | 161 | /* |
| 161 | */ | 162 | * Update the dequeue pointer further if that was a link TRB or |
| 162 | while (last_trb(xhci, ring, ring->deq_seg, next)) { | 163 | * we're at the end of an event ring segment (which doesn't have |
| 163 | if (ring->type == TYPE_EVENT && last_trb_on_last_seg(xhci, | 164 | * link TRBS) |
| 164 | ring, ring->deq_seg, next)) { | 165 | */ |
| 165 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 166 | if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) { |
| 167 | if (ring->type == TYPE_EVENT && | ||
| 168 | last_trb_on_last_seg(xhci, ring, | ||
| 169 | ring->deq_seg, ring->dequeue)) { | ||
| 170 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | ||
| 171 | } | ||
| 172 | ring->deq_seg = ring->deq_seg->next; | ||
| 173 | ring->dequeue = ring->deq_seg->trbs; | ||
| 174 | } else { | ||
| 175 | ring->dequeue++; | ||
| 166 | } | 176 | } |
| 167 | ring->deq_seg = ring->deq_seg->next; | 177 | } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); |
| 168 | ring->dequeue = ring->deq_seg->trbs; | 178 | |
| 169 | next = ring->dequeue; | ||
| 170 | } | ||
| 171 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 179 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
| 172 | } | 180 | } |
| 173 | 181 | ||
| @@ -2073,8 +2081,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
| 2073 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) | 2081 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
| 2074 | trb_comp_code = COMP_SHORT_TX; | 2082 | trb_comp_code = COMP_SHORT_TX; |
| 2075 | else | 2083 | else |
| 2076 | xhci_warn(xhci, "WARN Successful completion on short TX: " | 2084 | xhci_warn_ratelimited(xhci, |
| 2077 | "needs XHCI_TRUST_TX_LENGTH quirk?\n"); | 2085 | "WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n"); |
| 2078 | case COMP_SHORT_TX: | 2086 | case COMP_SHORT_TX: |
| 2079 | break; | 2087 | break; |
| 2080 | case COMP_STOP: | 2088 | case COMP_STOP: |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7648b2d4b268..c59d5b5b6c7d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -166,7 +166,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
| 166 | xhci_writel(xhci, command, &xhci->op_regs->command); | 166 | xhci_writel(xhci, command, &xhci->op_regs->command); |
| 167 | 167 | ||
| 168 | ret = handshake(xhci, &xhci->op_regs->command, | 168 | ret = handshake(xhci, &xhci->op_regs->command, |
| 169 | CMD_RESET, 0, 250 * 1000); | 169 | CMD_RESET, 0, 10 * 1000 * 1000); |
| 170 | if (ret) | 170 | if (ret) |
| 171 | return ret; | 171 | return ret; |
| 172 | 172 | ||
| @@ -175,7 +175,8 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
| 175 | * xHCI cannot write to any doorbells or operational registers other | 175 | * xHCI cannot write to any doorbells or operational registers other |
| 176 | * than status until the "Controller Not Ready" flag is cleared. | 176 | * than status until the "Controller Not Ready" flag is cleared. |
| 177 | */ | 177 | */ |
| 178 | ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); | 178 | ret = handshake(xhci, &xhci->op_regs->status, |
| 179 | STS_CNR, 0, 10 * 1000 * 1000); | ||
| 179 | 180 | ||
| 180 | for (i = 0; i < 2; ++i) { | 181 | for (i = 0; i < 2; ++i) { |
| 181 | xhci->bus_state[i].port_c_suspend = 0; | 182 | xhci->bus_state[i].port_c_suspend = 0; |
| @@ -658,6 +659,9 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
| 658 | { | 659 | { |
| 659 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 660 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 660 | 661 | ||
| 662 | if (xhci->quirks && XHCI_SPURIOUS_REBOOT) | ||
| 663 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); | ||
| 664 | |||
| 661 | spin_lock_irq(&xhci->lock); | 665 | spin_lock_irq(&xhci->lock); |
| 662 | xhci_halt(xhci); | 666 | xhci_halt(xhci); |
| 663 | spin_unlock_irq(&xhci->lock); | 667 | spin_unlock_irq(&xhci->lock); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 55c0785810c9..c713256297ac 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
| @@ -1494,6 +1494,7 @@ struct xhci_hcd { | |||
| 1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) | 1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) |
| 1495 | #define XHCI_LPM_SUPPORT (1 << 11) | 1495 | #define XHCI_LPM_SUPPORT (1 << 11) |
| 1496 | #define XHCI_INTEL_HOST (1 << 12) | 1496 | #define XHCI_INTEL_HOST (1 << 12) |
| 1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) | ||
| 1497 | unsigned int num_active_eps; | 1498 | unsigned int num_active_eps; |
| 1498 | unsigned int limit_active_eps; | 1499 | unsigned int limit_active_eps; |
| 1499 | /* There are two roothubs to keep track of bus suspend info for */ | 1500 | /* There are two roothubs to keep track of bus suspend info for */ |
| @@ -1537,6 +1538,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
| 1537 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1538 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
| 1538 | #define xhci_warn(xhci, fmt, args...) \ | 1539 | #define xhci_warn(xhci, fmt, args...) \ |
| 1539 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1540 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
| 1541 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | ||
| 1542 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | ||
| 1540 | 1543 | ||
| 1541 | /* TODO: copied from ehci.h - can be refactored? */ | 1544 | /* TODO: copied from ehci.h - can be refactored? */ |
| 1542 | /* xHCI spec says all registers are little endian */ | 1545 | /* xHCI spec says all registers are little endian */ |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index ff08015b230c..ae794b90766b 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
| @@ -232,7 +232,7 @@ wraperr: | |||
| 232 | return err; | 232 | return err; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static const struct usb_device_id id_table[] __devinitconst = { | 235 | static const struct usb_device_id id_table[] = { |
| 236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, | 236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, |
| 237 | { } /* Terminating entry */ | 237 | { } /* Terminating entry */ |
| 238 | }; | 238 | }; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ef0c3f9f0947..6259f0d99324 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
| @@ -8,7 +8,7 @@ config USB_MUSB_HDRC | |||
| 8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
| 9 | depends on USB && USB_GADGET | 9 | depends on USB && USB_GADGET |
| 10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) | 10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) |
| 11 | select NOP_USB_XCEIV if (SOC_OMAPTI81XX || SOC_OMAPAM33XX) | 11 | select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) |
| 12 | select TWL4030_USB if MACH_OMAP_3430SDP | 12 | select TWL4030_USB if MACH_OMAP_3430SDP |
| 13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
| 14 | select USB_OTG_UTILS | 14 | select USB_OTG_UTILS |
| @@ -57,7 +57,7 @@ config USB_MUSB_AM35X | |||
| 57 | 57 | ||
| 58 | config USB_MUSB_DSPS | 58 | config USB_MUSB_DSPS |
| 59 | tristate "TI DSPS platforms" | 59 | tristate "TI DSPS platforms" |
| 60 | depends on SOC_OMAPTI81XX || SOC_OMAPAM33XX | 60 | depends on SOC_TI81XX || SOC_AM33XX |
| 61 | 61 | ||
| 62 | config USB_MUSB_BLACKFIN | 62 | config USB_MUSB_BLACKFIN |
| 63 | tristate "Blackfin" | 63 | tristate "Blackfin" |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 217808d9fbe1..494772fc9e23 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
| @@ -479,9 +479,9 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
| 479 | ret = -ENODEV; | 479 | ret = -ENODEV; |
| 480 | goto err0; | 480 | goto err0; |
| 481 | } | 481 | } |
| 482 | strcpy((u8 *)res->name, "mc"); | ||
| 483 | res->parent = NULL; | 482 | res->parent = NULL; |
| 484 | resources[1] = *res; | 483 | resources[1] = *res; |
| 484 | resources[1].name = "mc"; | ||
| 485 | 485 | ||
| 486 | /* allocate the child platform device */ | 486 | /* allocate the child platform device */ |
| 487 | musb = platform_device_alloc("musb-hdrc", -1); | 487 | musb = platform_device_alloc("musb-hdrc", -1); |
| @@ -566,27 +566,28 @@ static int __devinit dsps_probe(struct platform_device *pdev) | |||
| 566 | } | 566 | } |
| 567 | platform_set_drvdata(pdev, glue); | 567 | platform_set_drvdata(pdev, glue); |
| 568 | 568 | ||
| 569 | /* create the child platform device for first instances of musb */ | ||
| 570 | ret = dsps_create_musb_pdev(glue, 0); | ||
| 571 | if (ret != 0) { | ||
| 572 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
| 573 | goto err2; | ||
| 574 | } | ||
| 575 | |||
| 576 | /* enable the usbss clocks */ | 569 | /* enable the usbss clocks */ |
| 577 | pm_runtime_enable(&pdev->dev); | 570 | pm_runtime_enable(&pdev->dev); |
| 578 | 571 | ||
| 579 | ret = pm_runtime_get_sync(&pdev->dev); | 572 | ret = pm_runtime_get_sync(&pdev->dev); |
| 580 | if (ret < 0) { | 573 | if (ret < 0) { |
| 581 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); | 574 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); |
| 575 | goto err2; | ||
| 576 | } | ||
| 577 | |||
| 578 | /* create the child platform device for first instances of musb */ | ||
| 579 | ret = dsps_create_musb_pdev(glue, 0); | ||
| 580 | if (ret != 0) { | ||
| 581 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
| 582 | goto err3; | 582 | goto err3; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | return 0; | 585 | return 0; |
| 586 | 586 | ||
| 587 | err3: | 587 | err3: |
| 588 | pm_runtime_disable(&pdev->dev); | 588 | pm_runtime_put(&pdev->dev); |
| 589 | err2: | 589 | err2: |
| 590 | pm_runtime_disable(&pdev->dev); | ||
| 590 | kfree(glue->wrp); | 591 | kfree(glue->wrp); |
| 591 | err1: | 592 | err1: |
| 592 | kfree(glue); | 593 | kfree(glue); |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 8c9bb1ad3069..681da06170c2 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
| @@ -603,12 +603,12 @@ static int usbhsc_resume(struct device *dev) | |||
| 603 | struct usbhs_priv *priv = dev_get_drvdata(dev); | 603 | struct usbhs_priv *priv = dev_get_drvdata(dev); |
| 604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | 604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
| 605 | 605 | ||
| 606 | usbhs_platform_call(priv, phy_reset, pdev); | ||
| 607 | |||
| 608 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) | 606 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) |
| 609 | usbhsc_power_ctrl(priv, 1); | 607 | usbhsc_power_ctrl(priv, 1); |
| 610 | 608 | ||
| 611 | usbhsc_hotplug(priv); | 609 | usbhs_platform_call(priv, phy_reset, pdev); |
| 610 | |||
| 611 | usbhsc_drvcllbck_notify_hotplug(pdev); | ||
| 612 | 612 | ||
| 613 | return 0; | 613 | return 0; |
| 614 | } | 614 | } |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 1834cf50888c..9b69a1323294 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
| @@ -1266,6 +1266,12 @@ static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 1266 | return ret; | 1266 | return ret; |
| 1267 | } | 1267 | } |
| 1268 | 1268 | ||
| 1269 | static int usbhsh_bus_nop(struct usb_hcd *hcd) | ||
| 1270 | { | ||
| 1271 | /* nothing to do */ | ||
| 1272 | return 0; | ||
| 1273 | } | ||
| 1274 | |||
| 1269 | static struct hc_driver usbhsh_driver = { | 1275 | static struct hc_driver usbhsh_driver = { |
| 1270 | .description = usbhsh_hcd_name, | 1276 | .description = usbhsh_hcd_name, |
| 1271 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), | 1277 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), |
| @@ -1290,6 +1296,8 @@ static struct hc_driver usbhsh_driver = { | |||
| 1290 | */ | 1296 | */ |
| 1291 | .hub_status_data = usbhsh_hub_status_data, | 1297 | .hub_status_data = usbhsh_hub_status_data, |
| 1292 | .hub_control = usbhsh_hub_control, | 1298 | .hub_control = usbhsh_hub_control, |
| 1299 | .bus_suspend = usbhsh_bus_nop, | ||
| 1300 | .bus_resume = usbhsh_bus_nop, | ||
| 1293 | }; | 1301 | }; |
| 1294 | 1302 | ||
| 1295 | /* | 1303 | /* |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index f398d1e34474..c15f2e7cefc7 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
| @@ -61,18 +61,23 @@ static int usb_serial_device_probe(struct device *dev) | |||
| 61 | goto exit; | 61 | goto exit; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /* make sure suspend/resume doesn't race against port_probe */ | ||
| 65 | retval = usb_autopm_get_interface(port->serial->interface); | ||
| 66 | if (retval) | ||
| 67 | goto exit; | ||
| 68 | |||
| 64 | driver = port->serial->type; | 69 | driver = port->serial->type; |
| 65 | if (driver->port_probe) { | 70 | if (driver->port_probe) { |
| 66 | retval = driver->port_probe(port); | 71 | retval = driver->port_probe(port); |
| 67 | if (retval) | 72 | if (retval) |
| 68 | goto exit; | 73 | goto exit_with_autopm; |
| 69 | } | 74 | } |
| 70 | 75 | ||
| 71 | retval = device_create_file(dev, &dev_attr_port_number); | 76 | retval = device_create_file(dev, &dev_attr_port_number); |
| 72 | if (retval) { | 77 | if (retval) { |
| 73 | if (driver->port_remove) | 78 | if (driver->port_remove) |
| 74 | retval = driver->port_remove(port); | 79 | retval = driver->port_remove(port); |
| 75 | goto exit; | 80 | goto exit_with_autopm; |
| 76 | } | 81 | } |
| 77 | 82 | ||
| 78 | minor = port->number; | 83 | minor = port->number; |
| @@ -81,6 +86,8 @@ static int usb_serial_device_probe(struct device *dev) | |||
| 81 | "%s converter now attached to ttyUSB%d\n", | 86 | "%s converter now attached to ttyUSB%d\n", |
| 82 | driver->description, minor); | 87 | driver->description, minor); |
| 83 | 88 | ||
| 89 | exit_with_autopm: | ||
| 90 | usb_autopm_put_interface(port->serial->interface); | ||
| 84 | exit: | 91 | exit: |
| 85 | return retval; | 92 | return retval; |
| 86 | } | 93 | } |
| @@ -96,6 +103,9 @@ static int usb_serial_device_remove(struct device *dev) | |||
| 96 | if (!port) | 103 | if (!port) |
| 97 | return -ENODEV; | 104 | return -ENODEV; |
| 98 | 105 | ||
| 106 | /* make sure suspend/resume doesn't race against port_remove */ | ||
| 107 | usb_autopm_get_interface(port->serial->interface); | ||
| 108 | |||
| 99 | device_remove_file(&port->dev, &dev_attr_port_number); | 109 | device_remove_file(&port->dev, &dev_attr_port_number); |
| 100 | 110 | ||
| 101 | driver = port->serial->type; | 111 | driver = port->serial->type; |
| @@ -107,6 +117,7 @@ static int usb_serial_device_remove(struct device *dev) | |||
| 107 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", | 117 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", |
| 108 | driver->description, minor); | 118 | driver->description, minor); |
| 109 | 119 | ||
| 120 | usb_autopm_put_interface(port->serial->interface); | ||
| 110 | return retval; | 121 | return retval; |
| 111 | } | 122 | } |
| 112 | 123 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bc912e5a3beb..5620db6469e5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -811,6 +811,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
| 812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | 812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, |
| 813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, | 813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, |
| 814 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, | ||
| 814 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 815 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
| 815 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 816 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
| 816 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 817 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5661c7e2d415..5dd96ca6c380 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -795,6 +795,13 @@ | |||
| 795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ | 795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ |
| 796 | 796 | ||
| 797 | /* | 797 | /* |
| 798 | * Kondo Kagaku Co.Ltd. | ||
| 799 | * http://www.kondo-robot.com/EN | ||
| 800 | */ | ||
| 801 | #define KONDO_VID 0x165c | ||
| 802 | #define KONDO_USB_SERIAL_PID 0x0002 | ||
| 803 | |||
| 804 | /* | ||
| 798 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. | 805 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. |
| 799 | * http://winglucofacts.com/cables/ | 806 | * http://winglucofacts.com/cables/ |
| 800 | */ | 807 | */ |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 5811d34b6c6b..2cb30c535839 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
| @@ -227,7 +227,6 @@ static void ipw_release(struct usb_serial *serial) | |||
| 227 | { | 227 | { |
| 228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); | 228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); |
| 229 | 229 | ||
| 230 | usb_wwan_release(serial); | ||
| 231 | usb_set_serial_data(serial, NULL); | 230 | usb_set_serial_data(serial, NULL); |
| 232 | kfree(data); | 231 | kfree(data); |
| 233 | } | 232 | } |
| @@ -309,12 +308,12 @@ static struct usb_serial_driver ipw_device = { | |||
| 309 | .description = "IPWireless converter", | 308 | .description = "IPWireless converter", |
| 310 | .id_table = id_table, | 309 | .id_table = id_table, |
| 311 | .num_ports = 1, | 310 | .num_ports = 1, |
| 312 | .disconnect = usb_wwan_disconnect, | ||
| 313 | .open = ipw_open, | 311 | .open = ipw_open, |
| 314 | .close = ipw_close, | 312 | .close = ipw_close, |
| 315 | .probe = ipw_probe, | 313 | .probe = ipw_probe, |
| 316 | .attach = usb_wwan_startup, | 314 | .attach = usb_wwan_startup, |
| 317 | .release = ipw_release, | 315 | .release = ipw_release, |
| 316 | .port_remove = usb_wwan_port_remove, | ||
| 318 | .dtr_rts = ipw_dtr_rts, | 317 | .dtr_rts = ipw_dtr_rts, |
| 319 | .write = usb_wwan_write, | 318 | .write = usb_wwan_write, |
| 320 | }; | 319 | }; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 57eca2448424..2f6da1e89bfa 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -82,8 +82,7 @@ | |||
| 82 | * Defines used for sending commands to port | 82 | * Defines used for sending commands to port |
| 83 | */ | 83 | */ |
| 84 | 84 | ||
| 85 | #define WAIT_FOR_EVER (HZ * 0) /* timeout urb is wait for ever */ | 85 | #define MOS_WDR_TIMEOUT 5000 /* default urb timeout */ |
| 86 | #define MOS_WDR_TIMEOUT (HZ * 5) /* default urb timeout */ | ||
| 87 | 86 | ||
| 88 | #define MOS_PORT1 0x0200 | 87 | #define MOS_PORT1 0x0200 |
| 89 | #define MOS_PORT2 0x0300 | 88 | #define MOS_PORT2 0x0300 |
| @@ -1232,9 +1231,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | |||
| 1232 | return 0; | 1231 | return 0; |
| 1233 | 1232 | ||
| 1234 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | 1233 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); |
| 1235 | for (i = 0; i < NUM_URBS; ++i) | 1234 | for (i = 0; i < NUM_URBS; ++i) { |
| 1236 | if (mos7840_port->busy[i]) | 1235 | if (mos7840_port->busy[i]) { |
| 1237 | chars += URB_TRANSFER_BUFFER_SIZE; | 1236 | struct urb *urb = mos7840_port->write_urb_pool[i]; |
| 1237 | chars += urb->transfer_buffer_length; | ||
| 1238 | } | ||
| 1239 | } | ||
| 1238 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | 1240 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); |
| 1239 | dbg("%s - returns %d", __func__, chars); | 1241 | dbg("%s - returns %d", __func__, chars); |
| 1240 | return chars; | 1242 | return chars; |
| @@ -1344,7 +1346,7 @@ static void mos7840_close(struct usb_serial_port *port) | |||
| 1344 | static void mos7840_block_until_chase_response(struct tty_struct *tty, | 1346 | static void mos7840_block_until_chase_response(struct tty_struct *tty, |
| 1345 | struct moschip_port *mos7840_port) | 1347 | struct moschip_port *mos7840_port) |
| 1346 | { | 1348 | { |
| 1347 | int timeout = 1 * HZ; | 1349 | int timeout = msecs_to_jiffies(1000); |
| 1348 | int wait = 10; | 1350 | int wait = 10; |
| 1349 | int count; | 1351 | int count; |
| 1350 | 1352 | ||
| @@ -2672,7 +2674,7 @@ static int mos7840_startup(struct usb_serial *serial) | |||
| 2672 | 2674 | ||
| 2673 | /* setting configuration feature to one */ | 2675 | /* setting configuration feature to one */ |
| 2674 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2676 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
| 2675 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); | 2677 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); |
| 2676 | return 0; | 2678 | return 0; |
| 2677 | error: | 2679 | error: |
| 2678 | for (/* nothing */; i >= 0; i--) { | 2680 | for (/* nothing */; i >= 0; i--) { |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 08ff9b862049..cc40f47ecea1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -80,85 +80,9 @@ static void option_instat_callback(struct urb *urb); | |||
| 80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 | 80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 |
| 81 | 81 | ||
| 82 | #define HUAWEI_VENDOR_ID 0x12D1 | 82 | #define HUAWEI_VENDOR_ID 0x12D1 |
| 83 | #define HUAWEI_PRODUCT_E600 0x1001 | ||
| 84 | #define HUAWEI_PRODUCT_E220 0x1003 | ||
| 85 | #define HUAWEI_PRODUCT_E220BIS 0x1004 | ||
| 86 | #define HUAWEI_PRODUCT_E1401 0x1401 | ||
| 87 | #define HUAWEI_PRODUCT_E1402 0x1402 | ||
| 88 | #define HUAWEI_PRODUCT_E1403 0x1403 | ||
| 89 | #define HUAWEI_PRODUCT_E1404 0x1404 | ||
| 90 | #define HUAWEI_PRODUCT_E1405 0x1405 | ||
| 91 | #define HUAWEI_PRODUCT_E1406 0x1406 | ||
| 92 | #define HUAWEI_PRODUCT_E1407 0x1407 | ||
| 93 | #define HUAWEI_PRODUCT_E1408 0x1408 | ||
| 94 | #define HUAWEI_PRODUCT_E1409 0x1409 | ||
| 95 | #define HUAWEI_PRODUCT_E140A 0x140A | ||
| 96 | #define HUAWEI_PRODUCT_E140B 0x140B | ||
| 97 | #define HUAWEI_PRODUCT_E140C 0x140C | ||
| 98 | #define HUAWEI_PRODUCT_E140D 0x140D | ||
| 99 | #define HUAWEI_PRODUCT_E140E 0x140E | ||
| 100 | #define HUAWEI_PRODUCT_E140F 0x140F | ||
| 101 | #define HUAWEI_PRODUCT_E1410 0x1410 | ||
| 102 | #define HUAWEI_PRODUCT_E1411 0x1411 | ||
| 103 | #define HUAWEI_PRODUCT_E1412 0x1412 | ||
| 104 | #define HUAWEI_PRODUCT_E1413 0x1413 | ||
| 105 | #define HUAWEI_PRODUCT_E1414 0x1414 | ||
| 106 | #define HUAWEI_PRODUCT_E1415 0x1415 | ||
| 107 | #define HUAWEI_PRODUCT_E1416 0x1416 | ||
| 108 | #define HUAWEI_PRODUCT_E1417 0x1417 | ||
| 109 | #define HUAWEI_PRODUCT_E1418 0x1418 | ||
| 110 | #define HUAWEI_PRODUCT_E1419 0x1419 | ||
| 111 | #define HUAWEI_PRODUCT_E141A 0x141A | ||
| 112 | #define HUAWEI_PRODUCT_E141B 0x141B | ||
| 113 | #define HUAWEI_PRODUCT_E141C 0x141C | ||
| 114 | #define HUAWEI_PRODUCT_E141D 0x141D | ||
| 115 | #define HUAWEI_PRODUCT_E141E 0x141E | ||
| 116 | #define HUAWEI_PRODUCT_E141F 0x141F | ||
| 117 | #define HUAWEI_PRODUCT_E1420 0x1420 | ||
| 118 | #define HUAWEI_PRODUCT_E1421 0x1421 | ||
| 119 | #define HUAWEI_PRODUCT_E1422 0x1422 | ||
| 120 | #define HUAWEI_PRODUCT_E1423 0x1423 | ||
| 121 | #define HUAWEI_PRODUCT_E1424 0x1424 | ||
| 122 | #define HUAWEI_PRODUCT_E1425 0x1425 | ||
| 123 | #define HUAWEI_PRODUCT_E1426 0x1426 | ||
| 124 | #define HUAWEI_PRODUCT_E1427 0x1427 | ||
| 125 | #define HUAWEI_PRODUCT_E1428 0x1428 | ||
| 126 | #define HUAWEI_PRODUCT_E1429 0x1429 | ||
| 127 | #define HUAWEI_PRODUCT_E142A 0x142A | ||
| 128 | #define HUAWEI_PRODUCT_E142B 0x142B | ||
| 129 | #define HUAWEI_PRODUCT_E142C 0x142C | ||
| 130 | #define HUAWEI_PRODUCT_E142D 0x142D | ||
| 131 | #define HUAWEI_PRODUCT_E142E 0x142E | ||
| 132 | #define HUAWEI_PRODUCT_E142F 0x142F | ||
| 133 | #define HUAWEI_PRODUCT_E1430 0x1430 | ||
| 134 | #define HUAWEI_PRODUCT_E1431 0x1431 | ||
| 135 | #define HUAWEI_PRODUCT_E1432 0x1432 | ||
| 136 | #define HUAWEI_PRODUCT_E1433 0x1433 | ||
| 137 | #define HUAWEI_PRODUCT_E1434 0x1434 | ||
| 138 | #define HUAWEI_PRODUCT_E1435 0x1435 | ||
| 139 | #define HUAWEI_PRODUCT_E1436 0x1436 | ||
| 140 | #define HUAWEI_PRODUCT_E1437 0x1437 | ||
| 141 | #define HUAWEI_PRODUCT_E1438 0x1438 | ||
| 142 | #define HUAWEI_PRODUCT_E1439 0x1439 | ||
| 143 | #define HUAWEI_PRODUCT_E143A 0x143A | ||
| 144 | #define HUAWEI_PRODUCT_E143B 0x143B | ||
| 145 | #define HUAWEI_PRODUCT_E143C 0x143C | ||
| 146 | #define HUAWEI_PRODUCT_E143D 0x143D | ||
| 147 | #define HUAWEI_PRODUCT_E143E 0x143E | ||
| 148 | #define HUAWEI_PRODUCT_E143F 0x143F | ||
| 149 | #define HUAWEI_PRODUCT_K4505 0x1464 | 83 | #define HUAWEI_PRODUCT_K4505 0x1464 |
| 150 | #define HUAWEI_PRODUCT_K3765 0x1465 | 84 | #define HUAWEI_PRODUCT_K3765 0x1465 |
| 151 | #define HUAWEI_PRODUCT_E14AC 0x14AC | ||
| 152 | #define HUAWEI_PRODUCT_K3806 0x14AE | ||
| 153 | #define HUAWEI_PRODUCT_K4605 0x14C6 | 85 | #define HUAWEI_PRODUCT_K4605 0x14C6 |
| 154 | #define HUAWEI_PRODUCT_K5005 0x14C8 | ||
| 155 | #define HUAWEI_PRODUCT_K3770 0x14C9 | ||
| 156 | #define HUAWEI_PRODUCT_K3771 0x14CA | ||
| 157 | #define HUAWEI_PRODUCT_K4510 0x14CB | ||
| 158 | #define HUAWEI_PRODUCT_K4511 0x14CC | ||
| 159 | #define HUAWEI_PRODUCT_ETS1220 0x1803 | ||
| 160 | #define HUAWEI_PRODUCT_E353 0x1506 | ||
| 161 | #define HUAWEI_PRODUCT_E173S 0x1C05 | ||
| 162 | 86 | ||
| 163 | #define QUANTA_VENDOR_ID 0x0408 | 87 | #define QUANTA_VENDOR_ID 0x0408 |
| 164 | #define QUANTA_PRODUCT_Q101 0xEA02 | 88 | #define QUANTA_PRODUCT_Q101 0xEA02 |
| @@ -615,104 +539,123 @@ static const struct usb_device_id option_ids[] = { | |||
| 615 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, | 539 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, |
| 616 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, | 540 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, |
| 617 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, | 541 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, |
| 618 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, | ||
| 619 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | ||
| 620 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | ||
| 621 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, | ||
| 622 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, | ||
| 623 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, | ||
| 624 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, | ||
| 625 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, | ||
| 626 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, | ||
| 627 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, | ||
| 628 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, | ||
| 629 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, | ||
| 630 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, | ||
| 631 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, | ||
| 632 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, | ||
| 633 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, | ||
| 634 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, | ||
| 635 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, | ||
| 636 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, | ||
| 637 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, | ||
| 638 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, | ||
| 639 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, | ||
| 640 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, | ||
| 641 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, | ||
| 642 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, | ||
| 643 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, | ||
| 644 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, | ||
| 645 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, | ||
| 646 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, | ||
| 647 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, | ||
| 648 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, | ||
| 649 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, | ||
| 650 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, | ||
| 651 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, | ||
| 652 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, | ||
| 653 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, | ||
| 654 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, | ||
| 655 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, | ||
| 656 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, | ||
| 657 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, | ||
| 658 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, | ||
| 659 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, | ||
| 660 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, | ||
| 661 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, | ||
| 662 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, | ||
| 663 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, | ||
| 664 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, | ||
| 665 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, | ||
| 666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, | ||
| 667 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, | ||
| 668 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, | ||
| 669 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, | ||
| 670 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, | ||
| 671 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, | ||
| 672 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, | ||
| 673 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, | ||
| 674 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, | ||
| 675 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, | ||
| 676 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, | ||
| 677 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, | ||
| 678 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, | ||
| 679 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, | ||
| 680 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, | ||
| 681 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, | ||
| 682 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, | ||
| 683 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, | ||
| 684 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, | ||
| 685 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 542 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
| 686 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 543 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
| 687 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), | 544 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), |
| 688 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 545 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
| 689 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, | ||
| 690 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, | ||
| 691 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, | ||
| 692 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), | 546 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), |
| 693 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 547 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
| 694 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, | 548 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, |
| 695 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, | 549 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, |
| 696 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, | 550 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, |
| 697 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, | 551 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) }, |
| 698 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, | 552 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) }, |
| 699 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, | 553 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) }, |
| 700 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, | 554 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) }, |
| 701 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, | 555 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) }, |
| 702 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, | 556 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) }, |
| 703 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, | 557 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) }, |
| 704 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, | 558 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) }, |
| 705 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, | 559 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) }, |
| 706 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, | 560 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) }, |
| 707 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, | 561 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) }, |
| 708 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, | 562 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) }, |
| 709 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, | 563 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) }, |
| 710 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, | 564 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) }, |
| 711 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, | 565 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) }, |
| 712 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, | 566 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) }, |
| 713 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ | 567 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) }, |
| 714 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ | 568 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) }, |
| 715 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ | 569 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) }, |
| 570 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) }, | ||
| 571 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) }, | ||
| 572 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) }, | ||
| 573 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) }, | ||
| 574 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) }, | ||
| 575 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) }, | ||
| 576 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) }, | ||
| 577 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) }, | ||
| 578 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) }, | ||
| 579 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) }, | ||
| 580 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) }, | ||
| 581 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) }, | ||
| 582 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) }, | ||
| 583 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) }, | ||
| 584 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) }, | ||
| 585 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) }, | ||
| 586 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) }, | ||
| 587 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) }, | ||
| 588 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) }, | ||
| 589 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) }, | ||
| 590 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) }, | ||
| 591 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) }, | ||
| 592 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) }, | ||
| 593 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) }, | ||
| 594 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) }, | ||
| 595 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, | ||
| 596 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, | ||
| 597 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, | ||
| 598 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, | ||
| 599 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, | ||
| 600 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, | ||
| 601 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) }, | ||
| 602 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) }, | ||
| 603 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
| 604 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) }, | ||
| 605 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) }, | ||
| 606 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) }, | ||
| 607 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
| 608 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) }, | ||
| 609 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) }, | ||
| 610 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) }, | ||
| 611 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) }, | ||
| 612 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) }, | ||
| 613 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) }, | ||
| 614 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) }, | ||
| 615 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) }, | ||
| 616 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) }, | ||
| 617 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) }, | ||
| 618 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) }, | ||
| 619 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) }, | ||
| 620 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) }, | ||
| 621 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) }, | ||
| 622 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) }, | ||
| 623 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) }, | ||
| 624 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) }, | ||
| 625 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) }, | ||
| 626 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) }, | ||
| 627 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) }, | ||
| 628 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) }, | ||
| 629 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) }, | ||
| 630 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) }, | ||
| 631 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) }, | ||
| 632 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) }, | ||
| 633 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) }, | ||
| 634 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) }, | ||
| 635 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) }, | ||
| 636 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) }, | ||
| 637 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) }, | ||
| 638 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) }, | ||
| 639 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) }, | ||
| 640 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) }, | ||
| 641 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) }, | ||
| 642 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) }, | ||
| 643 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) }, | ||
| 644 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) }, | ||
| 645 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) }, | ||
| 646 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) }, | ||
| 647 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) }, | ||
| 648 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) }, | ||
| 649 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, | ||
| 650 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, | ||
| 651 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, | ||
| 652 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, | ||
| 653 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, | ||
| 654 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, | ||
| 655 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, | ||
| 656 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, | ||
| 657 | |||
| 658 | |||
| 716 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, | 659 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
| 717 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, | 660 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
| 718 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, | 661 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
| @@ -943,6 +886,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 943 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), | 886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), |
| 944 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
| 945 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | 888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, |
| 889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), | ||
| 890 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
| 946 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | 891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, |
| 947 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | 892 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, |
| 948 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | 893 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, |
| @@ -1297,8 +1242,8 @@ static struct usb_serial_driver option_1port_device = { | |||
| 1297 | .tiocmset = usb_wwan_tiocmset, | 1242 | .tiocmset = usb_wwan_tiocmset, |
| 1298 | .ioctl = usb_wwan_ioctl, | 1243 | .ioctl = usb_wwan_ioctl, |
| 1299 | .attach = usb_wwan_startup, | 1244 | .attach = usb_wwan_startup, |
| 1300 | .disconnect = usb_wwan_disconnect, | ||
| 1301 | .release = option_release, | 1245 | .release = option_release, |
| 1246 | .port_remove = usb_wwan_port_remove, | ||
| 1302 | .read_int_callback = option_instat_callback, | 1247 | .read_int_callback = option_instat_callback, |
| 1303 | #ifdef CONFIG_PM | 1248 | #ifdef CONFIG_PM |
| 1304 | .suspend = usb_wwan_suspend, | 1249 | .suspend = usb_wwan_suspend, |
| @@ -1414,8 +1359,6 @@ static void option_release(struct usb_serial *serial) | |||
| 1414 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); | 1359 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); |
| 1415 | struct option_private *priv = intfdata->private; | 1360 | struct option_private *priv = intfdata->private; |
| 1416 | 1361 | ||
| 1417 | usb_wwan_release(serial); | ||
| 1418 | |||
| 1419 | kfree(priv); | 1362 | kfree(priv); |
| 1420 | kfree(intfdata); | 1363 | kfree(intfdata); |
| 1421 | } | 1364 | } |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 8d103019d6aa..bfd50779f0c9 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
| @@ -199,43 +199,49 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
| 199 | 199 | ||
| 200 | /* default to enabling interface */ | 200 | /* default to enabling interface */ |
| 201 | altsetting = 0; | 201 | altsetting = 0; |
| 202 | switch (ifnum) { | ||
| 203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
| 204 | * gets handled by other drivers. | ||
| 205 | */ | ||
| 206 | 202 | ||
| 203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
| 204 | * gets handled by other drivers. | ||
| 205 | */ | ||
| 206 | |||
| 207 | if (is_gobi1k) { | ||
| 207 | /* Gobi 1K USB layout: | 208 | /* Gobi 1K USB layout: |
| 208 | * 0: serial port (doesn't respond) | 209 | * 0: serial port (doesn't respond) |
| 209 | * 1: serial port (doesn't respond) | 210 | * 1: serial port (doesn't respond) |
| 210 | * 2: AT-capable modem port | 211 | * 2: AT-capable modem port |
| 211 | * 3: QMI/net | 212 | * 3: QMI/net |
| 212 | * | 213 | */ |
| 213 | * Gobi 2K+ USB layout: | 214 | if (ifnum == 2) |
| 215 | dev_dbg(dev, "Modem port found\n"); | ||
| 216 | else | ||
| 217 | altsetting = -1; | ||
| 218 | } else { | ||
| 219 | /* Gobi 2K+ USB layout: | ||
| 214 | * 0: QMI/net | 220 | * 0: QMI/net |
| 215 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) | 221 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) |
| 216 | * 2: AT-capable modem port | 222 | * 2: AT-capable modem port |
| 217 | * 3: NMEA | 223 | * 3: NMEA |
| 218 | */ | 224 | */ |
| 219 | 225 | switch (ifnum) { | |
| 220 | case 1: | 226 | case 0: |
| 221 | if (is_gobi1k) | 227 | /* Don't claim the QMI/net interface */ |
| 222 | altsetting = -1; | 228 | altsetting = -1; |
| 223 | else | 229 | break; |
| 230 | case 1: | ||
| 224 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); | 231 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); |
| 225 | break; | 232 | break; |
| 226 | case 2: | 233 | case 2: |
| 227 | dev_dbg(dev, "Modem port found\n"); | 234 | dev_dbg(dev, "Modem port found\n"); |
| 228 | break; | 235 | break; |
| 229 | case 3: | 236 | case 3: |
| 230 | if (is_gobi1k) | ||
| 231 | altsetting = -1; | ||
| 232 | else | ||
| 233 | /* | 237 | /* |
| 234 | * NMEA (serial line 9600 8N1) | 238 | * NMEA (serial line 9600 8N1) |
| 235 | * # echo "\$GPS_START" > /dev/ttyUSBx | 239 | * # echo "\$GPS_START" > /dev/ttyUSBx |
| 236 | * # echo "\$GPS_STOP" > /dev/ttyUSBx | 240 | * # echo "\$GPS_STOP" > /dev/ttyUSBx |
| 237 | */ | 241 | */ |
| 238 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); | 242 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); |
| 243 | break; | ||
| 244 | } | ||
| 239 | } | 245 | } |
| 240 | 246 | ||
| 241 | done: | 247 | done: |
| @@ -262,8 +268,7 @@ static void qc_release(struct usb_serial *serial) | |||
| 262 | { | 268 | { |
| 263 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | 269 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); |
| 264 | 270 | ||
| 265 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | 271 | /* Free the private data allocated in qcprobe */ |
| 266 | usb_wwan_release(serial); | ||
| 267 | usb_set_serial_data(serial, NULL); | 272 | usb_set_serial_data(serial, NULL); |
| 268 | kfree(priv); | 273 | kfree(priv); |
| 269 | } | 274 | } |
| @@ -283,8 +288,8 @@ static struct usb_serial_driver qcdevice = { | |||
| 283 | .write_room = usb_wwan_write_room, | 288 | .write_room = usb_wwan_write_room, |
| 284 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 289 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
| 285 | .attach = usb_wwan_startup, | 290 | .attach = usb_wwan_startup, |
| 286 | .disconnect = usb_wwan_disconnect, | ||
| 287 | .release = qc_release, | 291 | .release = qc_release, |
| 292 | .port_remove = usb_wwan_port_remove, | ||
| 288 | #ifdef CONFIG_PM | 293 | #ifdef CONFIG_PM |
| 289 | .suspend = usb_wwan_suspend, | 294 | .suspend = usb_wwan_suspend, |
| 290 | .resume = usb_wwan_resume, | 295 | .resume = usb_wwan_resume, |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index c47b6ec03063..1f034d2397c6 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
| @@ -9,8 +9,7 @@ extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | |||
| 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); |
| 10 | extern void usb_wwan_close(struct usb_serial_port *port); | 10 | extern void usb_wwan_close(struct usb_serial_port *port); |
| 11 | extern int usb_wwan_startup(struct usb_serial *serial); | 11 | extern int usb_wwan_startup(struct usb_serial *serial); |
| 12 | extern void usb_wwan_disconnect(struct usb_serial *serial); | 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); |
| 13 | extern void usb_wwan_release(struct usb_serial *serial); | ||
| 14 | extern int usb_wwan_write_room(struct tty_struct *tty); | 13 | extern int usb_wwan_write_room(struct tty_struct *tty); |
| 15 | extern void usb_wwan_set_termios(struct tty_struct *tty, | 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, |
| 16 | struct usb_serial_port *port, | 15 | struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index f35971dff4a5..6855d5ed0331 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -565,62 +565,52 @@ bail_out_error: | |||
| 565 | } | 565 | } |
| 566 | EXPORT_SYMBOL(usb_wwan_startup); | 566 | EXPORT_SYMBOL(usb_wwan_startup); |
| 567 | 567 | ||
| 568 | static void stop_read_write_urbs(struct usb_serial *serial) | 568 | int usb_wwan_port_remove(struct usb_serial_port *port) |
| 569 | { | 569 | { |
| 570 | int i, j; | 570 | int i; |
| 571 | struct usb_serial_port *port; | ||
| 572 | struct usb_wwan_port_private *portdata; | 571 | struct usb_wwan_port_private *portdata; |
| 573 | 572 | ||
| 574 | /* Stop reading/writing urbs */ | 573 | portdata = usb_get_serial_port_data(port); |
| 575 | for (i = 0; i < serial->num_ports; ++i) { | 574 | usb_set_serial_port_data(port, NULL); |
| 576 | port = serial->port[i]; | 575 | |
| 577 | portdata = usb_get_serial_port_data(port); | 576 | /* Stop reading/writing urbs and free them */ |
| 578 | for (j = 0; j < N_IN_URB; j++) | 577 | for (i = 0; i < N_IN_URB; i++) { |
| 579 | usb_kill_urb(portdata->in_urbs[j]); | 578 | usb_kill_urb(portdata->in_urbs[i]); |
| 580 | for (j = 0; j < N_OUT_URB; j++) | 579 | usb_free_urb(portdata->in_urbs[i]); |
| 581 | usb_kill_urb(portdata->out_urbs[j]); | 580 | free_page((unsigned long)portdata->in_buffer[i]); |
| 581 | } | ||
| 582 | for (i = 0; i < N_OUT_URB; i++) { | ||
| 583 | usb_kill_urb(portdata->out_urbs[i]); | ||
| 584 | usb_free_urb(portdata->out_urbs[i]); | ||
| 585 | kfree(portdata->out_buffer[i]); | ||
| 582 | } | 586 | } |
| 583 | } | ||
| 584 | 587 | ||
| 585 | void usb_wwan_disconnect(struct usb_serial *serial) | 588 | /* Now free port private data */ |
| 586 | { | 589 | kfree(portdata); |
| 587 | stop_read_write_urbs(serial); | 590 | return 0; |
| 588 | } | 591 | } |
| 589 | EXPORT_SYMBOL(usb_wwan_disconnect); | 592 | EXPORT_SYMBOL(usb_wwan_port_remove); |
| 590 | 593 | ||
| 591 | void usb_wwan_release(struct usb_serial *serial) | 594 | #ifdef CONFIG_PM |
| 595 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
| 592 | { | 596 | { |
| 593 | int i, j; | 597 | int i, j; |
| 594 | struct usb_serial_port *port; | 598 | struct usb_serial_port *port; |
| 595 | struct usb_wwan_port_private *portdata; | 599 | struct usb_wwan_port_private *portdata; |
| 596 | 600 | ||
| 597 | /* Now free them */ | 601 | /* Stop reading/writing urbs */ |
| 598 | for (i = 0; i < serial->num_ports; ++i) { | 602 | for (i = 0; i < serial->num_ports; ++i) { |
| 599 | port = serial->port[i]; | 603 | port = serial->port[i]; |
| 600 | portdata = usb_get_serial_port_data(port); | 604 | portdata = usb_get_serial_port_data(port); |
| 601 | 605 | if (!portdata) | |
| 602 | for (j = 0; j < N_IN_URB; j++) { | 606 | continue; |
| 603 | usb_free_urb(portdata->in_urbs[j]); | 607 | for (j = 0; j < N_IN_URB; j++) |
| 604 | free_page((unsigned long) | 608 | usb_kill_urb(portdata->in_urbs[j]); |
| 605 | portdata->in_buffer[j]); | 609 | for (j = 0; j < N_OUT_URB; j++) |
| 606 | portdata->in_urbs[j] = NULL; | 610 | usb_kill_urb(portdata->out_urbs[j]); |
| 607 | } | ||
| 608 | for (j = 0; j < N_OUT_URB; j++) { | ||
| 609 | usb_free_urb(portdata->out_urbs[j]); | ||
| 610 | kfree(portdata->out_buffer[j]); | ||
| 611 | portdata->out_urbs[j] = NULL; | ||
| 612 | } | ||
| 613 | } | ||
| 614 | |||
| 615 | /* Now free per port private data */ | ||
| 616 | for (i = 0; i < serial->num_ports; i++) { | ||
| 617 | port = serial->port[i]; | ||
| 618 | kfree(usb_get_serial_port_data(port)); | ||
| 619 | } | 611 | } |
| 620 | } | 612 | } |
| 621 | EXPORT_SYMBOL(usb_wwan_release); | ||
| 622 | 613 | ||
| 623 | #ifdef CONFIG_PM | ||
| 624 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) | 614 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) |
| 625 | { | 615 | { |
| 626 | struct usb_wwan_intf_private *intfdata = serial->private; | 616 | struct usb_wwan_intf_private *intfdata = serial->private; |
| @@ -712,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial) | |||
| 712 | 702 | ||
| 713 | /* skip closed ports */ | 703 | /* skip closed ports */ |
| 714 | spin_lock_irq(&intfdata->susp_lock); | 704 | spin_lock_irq(&intfdata->susp_lock); |
| 715 | if (!portdata->opened) { | 705 | if (!portdata || !portdata->opened) { |
| 716 | spin_unlock_irq(&intfdata->susp_lock); | 706 | spin_unlock_irq(&intfdata->susp_lock); |
| 717 | continue; | 707 | continue; |
| 718 | } | 708 | } |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 2e471c22abf5..f8a79fca4a22 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
| @@ -372,8 +372,12 @@ static void fb_flashcursor(struct work_struct *work) | |||
| 372 | struct vc_data *vc = NULL; | 372 | struct vc_data *vc = NULL; |
| 373 | int c; | 373 | int c; |
| 374 | int mode; | 374 | int mode; |
| 375 | int ret; | ||
| 376 | |||
| 377 | ret = console_trylock(); | ||
| 378 | if (ret == 0) | ||
| 379 | return; | ||
| 375 | 380 | ||
| 376 | console_lock(); | ||
| 377 | if (ops && ops->currcon != -1) | 381 | if (ops && ops->currcon != -1) |
| 378 | vc = vc_cons[ops->currcon].d; | 382 | vc = vc_cons[ops->currcon].d; |
| 379 | 383 | ||
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index d90062b211f8..92d08e7fcba2 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
| @@ -91,6 +91,11 @@ static struct w1_family w1_therm_family_DS28EA00 = { | |||
| 91 | .fops = &w1_therm_fops, | 91 | .fops = &w1_therm_fops, |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static struct w1_family w1_therm_family_DS1825 = { | ||
| 95 | .fid = W1_THERM_DS1825, | ||
| 96 | .fops = &w1_therm_fops, | ||
| 97 | }; | ||
| 98 | |||
| 94 | struct w1_therm_family_converter | 99 | struct w1_therm_family_converter |
| 95 | { | 100 | { |
| 96 | u8 broken; | 101 | u8 broken; |
| @@ -120,6 +125,10 @@ static struct w1_therm_family_converter w1_therm_families[] = { | |||
| 120 | .f = &w1_therm_family_DS28EA00, | 125 | .f = &w1_therm_family_DS28EA00, |
| 121 | .convert = w1_DS18B20_convert_temp | 126 | .convert = w1_DS18B20_convert_temp |
| 122 | }, | 127 | }, |
| 128 | { | ||
| 129 | .f = &w1_therm_family_DS1825, | ||
| 130 | .convert = w1_DS18B20_convert_temp | ||
| 131 | } | ||
| 123 | }; | 132 | }; |
| 124 | 133 | ||
| 125 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) | 134 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index b00ada44a89b..a1f0ce151d53 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #define W1_EEPROM_DS2431 0x2D | 39 | #define W1_EEPROM_DS2431 0x2D |
| 40 | #define W1_FAMILY_DS2760 0x30 | 40 | #define W1_FAMILY_DS2760 0x30 |
| 41 | #define W1_FAMILY_DS2780 0x32 | 41 | #define W1_FAMILY_DS2780 0x32 |
| 42 | #define W1_THERM_DS1825 0x3B | ||
| 42 | #define W1_FAMILY_DS2781 0x3D | 43 | #define W1_FAMILY_DS2781 0x3D |
| 43 | #define W1_THERM_DS28EA00 0x42 | 44 | #define W1_THERM_DS28EA00 0x42 |
| 44 | 45 | ||
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 8c0e56d92938..842d00048a65 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
| @@ -399,11 +399,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
| 399 | DPRINTK("checking mountpoint %p %.*s", | 399 | DPRINTK("checking mountpoint %p %.*s", |
| 400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | 400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); |
| 401 | 401 | ||
| 402 | /* Path walk currently on this dentry? */ | ||
| 403 | ino_count = atomic_read(&ino->count) + 2; | ||
| 404 | if (dentry->d_count > ino_count) | ||
| 405 | goto next; | ||
| 406 | |||
| 407 | /* Can we umount this guy */ | 402 | /* Can we umount this guy */ |
| 408 | if (autofs4_mount_busy(mnt, dentry)) | 403 | if (autofs4_mount_busy(mnt, dentry)) |
| 409 | goto next; | 404 | goto next; |
diff --git a/fs/compat.c b/fs/compat.c index 6161255fac45..1bdb350ea5d3 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1155,11 +1155,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, | |||
| 1155 | struct file *file; | 1155 | struct file *file; |
| 1156 | int fput_needed; | 1156 | int fput_needed; |
| 1157 | ssize_t ret; | 1157 | ssize_t ret; |
| 1158 | loff_t pos; | ||
| 1158 | 1159 | ||
| 1159 | file = fget_light(fd, &fput_needed); | 1160 | file = fget_light(fd, &fput_needed); |
| 1160 | if (!file) | 1161 | if (!file) |
| 1161 | return -EBADF; | 1162 | return -EBADF; |
| 1162 | ret = compat_readv(file, vec, vlen, &file->f_pos); | 1163 | pos = file->f_pos; |
| 1164 | ret = compat_readv(file, vec, vlen, &pos); | ||
| 1165 | file->f_pos = pos; | ||
| 1163 | fput_light(file, fput_needed); | 1166 | fput_light(file, fput_needed); |
| 1164 | return ret; | 1167 | return ret; |
| 1165 | } | 1168 | } |
| @@ -1221,11 +1224,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, | |||
| 1221 | struct file *file; | 1224 | struct file *file; |
| 1222 | int fput_needed; | 1225 | int fput_needed; |
| 1223 | ssize_t ret; | 1226 | ssize_t ret; |
| 1227 | loff_t pos; | ||
| 1224 | 1228 | ||
| 1225 | file = fget_light(fd, &fput_needed); | 1229 | file = fget_light(fd, &fput_needed); |
| 1226 | if (!file) | 1230 | if (!file) |
| 1227 | return -EBADF; | 1231 | return -EBADF; |
| 1228 | ret = compat_writev(file, vec, vlen, &file->f_pos); | 1232 | pos = file->f_pos; |
| 1233 | ret = compat_writev(file, vec, vlen, &pos); | ||
| 1234 | file->f_pos = pos; | ||
| 1229 | fput_light(file, fput_needed); | 1235 | fput_light(file, fput_needed); |
| 1230 | return ret; | 1236 | return ret; |
| 1231 | } | 1237 | } |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index d23b31ca9d7a..1b5089067d01 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -280,14 +280,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
| 280 | return desc; | 280 | return desc; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static int ext4_valid_block_bitmap(struct super_block *sb, | 283 | /* |
| 284 | struct ext4_group_desc *desc, | 284 | * Return the block number which was discovered to be invalid, or 0 if |
| 285 | unsigned int block_group, | 285 | * the block bitmap is valid. |
| 286 | struct buffer_head *bh) | 286 | */ |
| 287 | static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, | ||
| 288 | struct ext4_group_desc *desc, | ||
| 289 | unsigned int block_group, | ||
| 290 | struct buffer_head *bh) | ||
| 287 | { | 291 | { |
| 288 | ext4_grpblk_t offset; | 292 | ext4_grpblk_t offset; |
| 289 | ext4_grpblk_t next_zero_bit; | 293 | ext4_grpblk_t next_zero_bit; |
| 290 | ext4_fsblk_t bitmap_blk; | 294 | ext4_fsblk_t blk; |
| 291 | ext4_fsblk_t group_first_block; | 295 | ext4_fsblk_t group_first_block; |
| 292 | 296 | ||
| 293 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { | 297 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { |
| @@ -297,37 +301,33 @@ static int ext4_valid_block_bitmap(struct super_block *sb, | |||
| 297 | * or it has to also read the block group where the bitmaps | 301 | * or it has to also read the block group where the bitmaps |
| 298 | * are located to verify they are set. | 302 | * are located to verify they are set. |
| 299 | */ | 303 | */ |
| 300 | return 1; | 304 | return 0; |
| 301 | } | 305 | } |
| 302 | group_first_block = ext4_group_first_block_no(sb, block_group); | 306 | group_first_block = ext4_group_first_block_no(sb, block_group); |
| 303 | 307 | ||
| 304 | /* check whether block bitmap block number is set */ | 308 | /* check whether block bitmap block number is set */ |
| 305 | bitmap_blk = ext4_block_bitmap(sb, desc); | 309 | blk = ext4_block_bitmap(sb, desc); |
| 306 | offset = bitmap_blk - group_first_block; | 310 | offset = blk - group_first_block; |
| 307 | if (!ext4_test_bit(offset, bh->b_data)) | 311 | if (!ext4_test_bit(offset, bh->b_data)) |
| 308 | /* bad block bitmap */ | 312 | /* bad block bitmap */ |
| 309 | goto err_out; | 313 | return blk; |
| 310 | 314 | ||
| 311 | /* check whether the inode bitmap block number is set */ | 315 | /* check whether the inode bitmap block number is set */ |
| 312 | bitmap_blk = ext4_inode_bitmap(sb, desc); | 316 | blk = ext4_inode_bitmap(sb, desc); |
| 313 | offset = bitmap_blk - group_first_block; | 317 | offset = blk - group_first_block; |
| 314 | if (!ext4_test_bit(offset, bh->b_data)) | 318 | if (!ext4_test_bit(offset, bh->b_data)) |
| 315 | /* bad block bitmap */ | 319 | /* bad block bitmap */ |
| 316 | goto err_out; | 320 | return blk; |
| 317 | 321 | ||
| 318 | /* check whether the inode table block number is set */ | 322 | /* check whether the inode table block number is set */ |
| 319 | bitmap_blk = ext4_inode_table(sb, desc); | 323 | blk = ext4_inode_table(sb, desc); |
| 320 | offset = bitmap_blk - group_first_block; | 324 | offset = blk - group_first_block; |
| 321 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, | 325 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, |
| 322 | offset + EXT4_SB(sb)->s_itb_per_group, | 326 | offset + EXT4_SB(sb)->s_itb_per_group, |
| 323 | offset); | 327 | offset); |
| 324 | if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) | 328 | if (next_zero_bit < offset + EXT4_SB(sb)->s_itb_per_group) |
| 325 | /* good bitmap for inode tables */ | 329 | /* bad bitmap for inode tables */ |
| 326 | return 1; | 330 | return blk; |
| 327 | |||
| 328 | err_out: | ||
| 329 | ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu", | ||
| 330 | block_group, bitmap_blk); | ||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| 333 | 333 | ||
| @@ -336,14 +336,26 @@ void ext4_validate_block_bitmap(struct super_block *sb, | |||
| 336 | unsigned int block_group, | 336 | unsigned int block_group, |
| 337 | struct buffer_head *bh) | 337 | struct buffer_head *bh) |
| 338 | { | 338 | { |
| 339 | ext4_fsblk_t blk; | ||
| 340 | |||
| 339 | if (buffer_verified(bh)) | 341 | if (buffer_verified(bh)) |
| 340 | return; | 342 | return; |
| 341 | 343 | ||
| 342 | ext4_lock_group(sb, block_group); | 344 | ext4_lock_group(sb, block_group); |
| 343 | if (ext4_valid_block_bitmap(sb, desc, block_group, bh) && | 345 | blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); |
| 344 | ext4_block_bitmap_csum_verify(sb, block_group, desc, bh, | 346 | if (unlikely(blk != 0)) { |
| 345 | EXT4_BLOCKS_PER_GROUP(sb) / 8)) | 347 | ext4_unlock_group(sb, block_group); |
| 346 | set_buffer_verified(bh); | 348 | ext4_error(sb, "bg %u: block %llu: invalid block bitmap", |
| 349 | block_group, blk); | ||
| 350 | return; | ||
| 351 | } | ||
| 352 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, | ||
| 353 | desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { | ||
| 354 | ext4_unlock_group(sb, block_group); | ||
| 355 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); | ||
| 356 | return; | ||
| 357 | } | ||
| 358 | set_buffer_verified(bh); | ||
| 347 | ext4_unlock_group(sb, block_group); | 359 | ext4_unlock_group(sb, block_group); |
| 348 | } | 360 | } |
| 349 | 361 | ||
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index f8716eab9995..5c2d1813ebe9 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c | |||
| @@ -79,7 +79,6 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | |||
| 79 | if (provided == calculated) | 79 | if (provided == calculated) |
| 80 | return 1; | 80 | return 1; |
| 81 | 81 | ||
| 82 | ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); | ||
| 83 | return 0; | 82 | return 0; |
| 84 | } | 83 | } |
| 85 | 84 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index cd0c7ed06772..aabbb3f53683 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -2662,6 +2662,7 @@ cont: | |||
| 2662 | } | 2662 | } |
| 2663 | path[0].p_depth = depth; | 2663 | path[0].p_depth = depth; |
| 2664 | path[0].p_hdr = ext_inode_hdr(inode); | 2664 | path[0].p_hdr = ext_inode_hdr(inode); |
| 2665 | i = 0; | ||
| 2665 | 2666 | ||
| 2666 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { | 2667 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { |
| 2667 | err = -EIO; | 2668 | err = -EIO; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3e0851e4f468..c6e0cb3d1f4a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -948,6 +948,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
| 948 | ei->i_reserved_meta_blocks = 0; | 948 | ei->i_reserved_meta_blocks = 0; |
| 949 | ei->i_allocated_meta_blocks = 0; | 949 | ei->i_allocated_meta_blocks = 0; |
| 950 | ei->i_da_metadata_calc_len = 0; | 950 | ei->i_da_metadata_calc_len = 0; |
| 951 | ei->i_da_metadata_calc_last_lblock = 0; | ||
| 951 | spin_lock_init(&(ei->i_block_reservation_lock)); | 952 | spin_lock_init(&(ei->i_block_reservation_lock)); |
| 952 | #ifdef CONFIG_QUOTA | 953 | #ifdef CONFIG_QUOTA |
| 953 | ei->i_reserved_quota = 0; | 954 | ei->i_reserved_quota = 0; |
| @@ -3108,6 +3109,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp, | |||
| 3108 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | 3109 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
| 3109 | int s, j, count = 0; | 3110 | int s, j, count = 0; |
| 3110 | 3111 | ||
| 3112 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) | ||
| 3113 | return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) + | ||
| 3114 | sbi->s_itb_per_group + 2); | ||
| 3115 | |||
| 3111 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + | 3116 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + |
| 3112 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); | 3117 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); |
| 3113 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; | 3118 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; |
| @@ -4419,6 +4424,7 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
| 4419 | ext4_commit_super(sb, 1); | 4424 | ext4_commit_super(sb, 1); |
| 4420 | 4425 | ||
| 4421 | jbd2_journal_clear_err(journal); | 4426 | jbd2_journal_clear_err(journal); |
| 4427 | jbd2_journal_update_sb_errno(journal); | ||
| 4422 | } | 4428 | } |
| 4423 | } | 4429 | } |
| 4424 | 4430 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8964cf3999b2..324bc0850534 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
| 383 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
| 384 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
| 385 | 385 | ||
| 386 | /* Userspace expects S_IFREG in create mode */ | ||
| 387 | BUG_ON((mode & S_IFMT) != S_IFREG); | ||
| 388 | |||
| 386 | forget = fuse_alloc_forget(); | 389 | forget = fuse_alloc_forget(); |
| 387 | err = -ENOMEM; | 390 | err = -ENOMEM; |
| 388 | if (!forget) | 391 | if (!forget) |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 8625da27eccf..e149b99a7ffb 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -1377,7 +1377,7 @@ static void jbd2_mark_journal_empty(journal_t *journal) | |||
| 1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO | 1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO |
| 1378 | * to complete. | 1378 | * to complete. |
| 1379 | */ | 1379 | */ |
| 1380 | static void jbd2_journal_update_sb_errno(journal_t *journal) | 1380 | void jbd2_journal_update_sb_errno(journal_t *journal) |
| 1381 | { | 1381 | { |
| 1382 | journal_superblock_t *sb = journal->j_superblock; | 1382 | journal_superblock_t *sb = journal->j_superblock; |
| 1383 | 1383 | ||
| @@ -1390,6 +1390,7 @@ static void jbd2_journal_update_sb_errno(journal_t *journal) | |||
| 1390 | 1390 | ||
| 1391 | jbd2_write_superblock(journal, WRITE_SYNC); | 1391 | jbd2_write_superblock(journal, WRITE_SYNC); |
| 1392 | } | 1392 | } |
| 1393 | EXPORT_SYMBOL(jbd2_journal_update_sb_errno); | ||
| 1393 | 1394 | ||
| 1394 | /* | 1395 | /* |
| 1395 | * Read the superblock for a given journal, performing initial | 1396 | * Read the superblock for a given journal, performing initial |
diff --git a/fs/namei.c b/fs/namei.c index 1b464390dde8..db76b866a097 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
| 2414 | goto out; | 2414 | goto out; |
| 2415 | } | 2415 | } |
| 2416 | 2416 | ||
| 2417 | mode = op->mode & S_IALLUGO; | 2417 | mode = op->mode; |
| 2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) | 2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) |
| 2419 | mode &= ~current_umask(); | 2419 | mode &= ~current_umask(); |
| 2420 | 2420 | ||
| @@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
| 2452 | } | 2452 | } |
| 2453 | 2453 | ||
| 2454 | if (open_flag & O_CREAT) { | 2454 | if (open_flag & O_CREAT) { |
| 2455 | error = may_o_create(&nd->path, dentry, op->mode); | 2455 | error = may_o_create(&nd->path, dentry, mode); |
| 2456 | if (error) { | 2456 | if (error) { |
| 2457 | create_error = error; | 2457 | create_error = error; |
| 2458 | if (open_flag & O_EXCL) | 2458 | if (open_flag & O_EXCL) |
| @@ -2489,6 +2489,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
| 2489 | dput(dentry); | 2489 | dput(dentry); |
| 2490 | dentry = file->f_path.dentry; | 2490 | dentry = file->f_path.dentry; |
| 2491 | } | 2491 | } |
| 2492 | if (create_error && dentry->d_inode == NULL) { | ||
| 2493 | error = create_error; | ||
| 2494 | goto out; | ||
| 2495 | } | ||
| 2492 | goto looked_up; | 2496 | goto looked_up; |
| 2493 | } | 2497 | } |
| 2494 | 2498 | ||
| @@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
| 852 | int lookup_flags = 0; | 852 | int lookup_flags = 0; |
| 853 | int acc_mode; | 853 | int acc_mode; |
| 854 | 854 | ||
| 855 | if (!(flags & O_CREAT)) | 855 | if (flags & O_CREAT) |
| 856 | mode = 0; | 856 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
| 857 | op->mode = mode; | 857 | else |
| 858 | op->mode = 0; | ||
| 858 | 859 | ||
| 859 | /* Must never be set by userspace */ | 860 | /* Must never be set by userspace */ |
| 860 | flags &= ~FMODE_NONOTIFY; | 861 | flags &= ~FMODE_NONOTIFY; |
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h index 580a6d35c700..c04e0db8a2d6 100644 --- a/include/asm-generic/mutex-xchg.h +++ b/include/asm-generic/mutex-xchg.h | |||
| @@ -26,7 +26,13 @@ static inline void | |||
| 26 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) | 26 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) |
| 27 | { | 27 | { |
| 28 | if (unlikely(atomic_xchg(count, 0) != 1)) | 28 | if (unlikely(atomic_xchg(count, 0) != 1)) |
| 29 | fail_fn(count); | 29 | /* |
| 30 | * We failed to acquire the lock, so mark it contended | ||
| 31 | * to ensure that any waiting tasks are woken up by the | ||
| 32 | * unlock slow path. | ||
| 33 | */ | ||
| 34 | if (likely(atomic_xchg(count, -1) != 1)) | ||
| 35 | fail_fn(count); | ||
| 30 | } | 36 | } |
| 31 | 37 | ||
| 32 | /** | 38 | /** |
| @@ -43,7 +49,8 @@ static inline int | |||
| 43 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | 49 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) |
| 44 | { | 50 | { |
| 45 | if (unlikely(atomic_xchg(count, 0) != 1)) | 51 | if (unlikely(atomic_xchg(count, 0) != 1)) |
| 46 | return fail_fn(count); | 52 | if (likely(atomic_xchg(count, -1) != 1)) |
| 53 | return fail_fn(count); | ||
| 47 | return 0; | 54 | return 0; |
| 48 | } | 55 | } |
| 49 | 56 | ||
diff --git a/include/linux/efi.h b/include/linux/efi.h index 103adc6d7e3a..ec45ccd8708a 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
| @@ -503,6 +503,8 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); | |||
| 503 | extern int __init efi_uart_console_only (void); | 503 | extern int __init efi_uart_console_only (void); |
| 504 | extern void efi_initialize_iomem_resources(struct resource *code_resource, | 504 | extern void efi_initialize_iomem_resources(struct resource *code_resource, |
| 505 | struct resource *data_resource, struct resource *bss_resource); | 505 | struct resource *data_resource, struct resource *bss_resource); |
| 506 | extern unsigned long efi_get_time(void); | ||
| 507 | extern int efi_set_rtc_mmss(unsigned long nowtime); | ||
| 506 | extern void efi_reserve_boot_services(void); | 508 | extern void efi_reserve_boot_services(void); |
| 507 | extern struct efi_memory_map memmap; | 509 | extern struct efi_memory_map memmap; |
| 508 | 510 | ||
diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h index b76b4a87065e..be91f344d5fc 100644 --- a/include/linux/iio/frequency/adf4350.h +++ b/include/linux/iio/frequency/adf4350.h | |||
| @@ -87,6 +87,8 @@ | |||
| 87 | #define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ | 87 | #define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ |
| 88 | #define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ | 88 | #define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ |
| 89 | #define ADF4350_MAX_MODULUS 4095 | 89 | #define ADF4350_MAX_MODULUS 4095 |
| 90 | #define ADF4350_MAX_R_CNT 1023 | ||
| 91 | |||
| 90 | 92 | ||
| 91 | /** | 93 | /** |
| 92 | * struct adf4350_platform_data - platform specific information | 94 | * struct adf4350_platform_data - platform specific information |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index f334c7fab967..3efc43f3f162 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
| @@ -1125,6 +1125,7 @@ extern int jbd2_journal_destroy (journal_t *); | |||
| 1125 | extern int jbd2_journal_recover (journal_t *journal); | 1125 | extern int jbd2_journal_recover (journal_t *journal); |
| 1126 | extern int jbd2_journal_wipe (journal_t *, int); | 1126 | extern int jbd2_journal_wipe (journal_t *, int); |
| 1127 | extern int jbd2_journal_skip_recovery (journal_t *); | 1127 | extern int jbd2_journal_skip_recovery (journal_t *); |
| 1128 | extern void jbd2_journal_update_sb_errno(journal_t *); | ||
| 1128 | extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, | 1129 | extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, |
| 1129 | unsigned long, int); | 1130 | unsigned long, int); |
| 1130 | extern void __jbd2_journal_abort_hard (journal_t *); | 1131 | extern void __jbd2_journal_abort_hard (journal_t *); |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index c75c0d1a85e2..cdca2ab1e711 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
| @@ -1075,7 +1075,8 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) | |||
| 1075 | const char *snd_pcm_format_name(snd_pcm_format_t format); | 1075 | const char *snd_pcm_format_name(snd_pcm_format_t format); |
| 1076 | 1076 | ||
| 1077 | /** | 1077 | /** |
| 1078 | * Get a string naming the direction of a stream | 1078 | * snd_pcm_stream_str - Get a string naming the direction of a stream |
| 1079 | * @substream: the pcm substream instance | ||
| 1079 | */ | 1080 | */ |
| 1080 | static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) | 1081 | static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) |
| 1081 | { | 1082 | { |
diff --git a/init/main.c b/init/main.c index e60679de61c3..b28673087ac0 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -461,10 +461,6 @@ static void __init mm_init(void) | |||
| 461 | percpu_init_late(); | 461 | percpu_init_late(); |
| 462 | pgtable_cache_init(); | 462 | pgtable_cache_init(); |
| 463 | vmalloc_init(); | 463 | vmalloc_init(); |
| 464 | #ifdef CONFIG_X86 | ||
| 465 | if (efi_enabled) | ||
| 466 | efi_enter_virtual_mode(); | ||
| 467 | #endif | ||
| 468 | } | 464 | } |
| 469 | 465 | ||
| 470 | asmlinkage void __init start_kernel(void) | 466 | asmlinkage void __init start_kernel(void) |
| @@ -606,6 +602,10 @@ asmlinkage void __init start_kernel(void) | |||
| 606 | calibrate_delay(); | 602 | calibrate_delay(); |
| 607 | pidmap_init(); | 603 | pidmap_init(); |
| 608 | anon_vma_init(); | 604 | anon_vma_init(); |
| 605 | #ifdef CONFIG_X86 | ||
| 606 | if (efi_enabled) | ||
| 607 | efi_enter_virtual_mode(); | ||
| 608 | #endif | ||
| 609 | thread_info_cache_init(); | 609 | thread_info_cache_init(); |
| 610 | cred_init(); | 610 | cred_init(); |
| 611 | fork_init(totalram_pages); | 611 | fork_init(totalram_pages); |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 82ad284f823b..fbf1fd098dc6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -3142,6 +3142,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
| 3142 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) | 3142 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) |
| 3143 | #endif | 3143 | #endif |
| 3144 | 3144 | ||
| 3145 | static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total) | ||
| 3146 | { | ||
| 3147 | u64 temp = (__force u64) rtime; | ||
| 3148 | |||
| 3149 | temp *= (__force u64) utime; | ||
| 3150 | |||
| 3151 | if (sizeof(cputime_t) == 4) | ||
| 3152 | temp = div_u64(temp, (__force u32) total); | ||
| 3153 | else | ||
| 3154 | temp = div64_u64(temp, (__force u64) total); | ||
| 3155 | |||
| 3156 | return (__force cputime_t) temp; | ||
| 3157 | } | ||
| 3158 | |||
| 3145 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | 3159 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) |
| 3146 | { | 3160 | { |
| 3147 | cputime_t rtime, utime = p->utime, total = utime + p->stime; | 3161 | cputime_t rtime, utime = p->utime, total = utime + p->stime; |
| @@ -3151,13 +3165,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
| 3151 | */ | 3165 | */ |
| 3152 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); | 3166 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); |
| 3153 | 3167 | ||
| 3154 | if (total) { | 3168 | if (total) |
| 3155 | u64 temp = (__force u64) rtime; | 3169 | utime = scale_utime(utime, rtime, total); |
| 3156 | 3170 | else | |
| 3157 | temp *= (__force u64) utime; | ||
| 3158 | do_div(temp, (__force u32) total); | ||
| 3159 | utime = (__force cputime_t) temp; | ||
| 3160 | } else | ||
| 3161 | utime = rtime; | 3171 | utime = rtime; |
| 3162 | 3172 | ||
| 3163 | /* | 3173 | /* |
| @@ -3184,13 +3194,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
| 3184 | total = cputime.utime + cputime.stime; | 3194 | total = cputime.utime + cputime.stime; |
| 3185 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); | 3195 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); |
| 3186 | 3196 | ||
| 3187 | if (total) { | 3197 | if (total) |
| 3188 | u64 temp = (__force u64) rtime; | 3198 | utime = scale_utime(cputime.utime, rtime, total); |
| 3189 | 3199 | else | |
| 3190 | temp *= (__force u64) cputime.utime; | ||
| 3191 | do_div(temp, (__force u32) total); | ||
| 3192 | utime = (__force cputime_t) temp; | ||
| 3193 | } else | ||
| 3194 | utime = rtime; | 3200 | utime = rtime; |
| 3195 | 3201 | ||
| 3196 | sig->prev_utime = max(sig->prev_utime, utime); | 3202 | sig->prev_utime = max(sig->prev_utime, utime); |
| @@ -7246,6 +7252,7 @@ int in_sched_functions(unsigned long addr) | |||
| 7246 | 7252 | ||
| 7247 | #ifdef CONFIG_CGROUP_SCHED | 7253 | #ifdef CONFIG_CGROUP_SCHED |
| 7248 | struct task_group root_task_group; | 7254 | struct task_group root_task_group; |
| 7255 | LIST_HEAD(task_groups); | ||
| 7249 | #endif | 7256 | #endif |
| 7250 | 7257 | ||
| 7251 | DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask); | 7258 | DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index d0cc03b3e70b..c219bf8d704c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -3387,6 +3387,14 @@ static int tg_load_down(struct task_group *tg, void *data) | |||
| 3387 | 3387 | ||
| 3388 | static void update_h_load(long cpu) | 3388 | static void update_h_load(long cpu) |
| 3389 | { | 3389 | { |
| 3390 | struct rq *rq = cpu_rq(cpu); | ||
| 3391 | unsigned long now = jiffies; | ||
| 3392 | |||
| 3393 | if (rq->h_load_throttle == now) | ||
| 3394 | return; | ||
| 3395 | |||
| 3396 | rq->h_load_throttle = now; | ||
| 3397 | |||
| 3390 | rcu_read_lock(); | 3398 | rcu_read_lock(); |
| 3391 | walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); | 3399 | walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); |
| 3392 | rcu_read_unlock(); | 3400 | rcu_read_unlock(); |
| @@ -4293,11 +4301,10 @@ redo: | |||
| 4293 | env.src_rq = busiest; | 4301 | env.src_rq = busiest; |
| 4294 | env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running); | 4302 | env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running); |
| 4295 | 4303 | ||
| 4304 | update_h_load(env.src_cpu); | ||
| 4296 | more_balance: | 4305 | more_balance: |
| 4297 | local_irq_save(flags); | 4306 | local_irq_save(flags); |
| 4298 | double_rq_lock(this_rq, busiest); | 4307 | double_rq_lock(this_rq, busiest); |
| 4299 | if (!env.loop) | ||
| 4300 | update_h_load(env.src_cpu); | ||
| 4301 | 4308 | ||
| 4302 | /* | 4309 | /* |
| 4303 | * cur_ld_moved - load moved in current iteration | 4310 | * cur_ld_moved - load moved in current iteration |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 573e1ca01102..944cb68420e9 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
| @@ -788,6 +788,19 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) | |||
| 788 | const struct cpumask *span; | 788 | const struct cpumask *span; |
| 789 | 789 | ||
| 790 | span = sched_rt_period_mask(); | 790 | span = sched_rt_period_mask(); |
| 791 | #ifdef CONFIG_RT_GROUP_SCHED | ||
| 792 | /* | ||
| 793 | * FIXME: isolated CPUs should really leave the root task group, | ||
| 794 | * whether they are isolcpus or were isolated via cpusets, lest | ||
| 795 | * the timer run on a CPU which does not service all runqueues, | ||
| 796 | * potentially leaving other CPUs indefinitely throttled. If | ||
| 797 | * isolation is really required, the user will turn the throttle | ||
| 798 | * off to kill the perturbations it causes anyway. Meanwhile, | ||
| 799 | * this maintains functionality for boot and/or troubleshooting. | ||
| 800 | */ | ||
| 801 | if (rt_b == &root_task_group.rt_bandwidth) | ||
| 802 | span = cpu_online_mask; | ||
| 803 | #endif | ||
| 791 | for_each_cpu(i, span) { | 804 | for_each_cpu(i, span) { |
| 792 | int enqueue = 0; | 805 | int enqueue = 0; |
| 793 | struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); | 806 | struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c35a1a7dd4d6..f6714d009e77 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
| @@ -80,7 +80,7 @@ extern struct mutex sched_domains_mutex; | |||
| 80 | struct cfs_rq; | 80 | struct cfs_rq; |
| 81 | struct rt_rq; | 81 | struct rt_rq; |
| 82 | 82 | ||
| 83 | static LIST_HEAD(task_groups); | 83 | extern struct list_head task_groups; |
| 84 | 84 | ||
| 85 | struct cfs_bandwidth { | 85 | struct cfs_bandwidth { |
| 86 | #ifdef CONFIG_CFS_BANDWIDTH | 86 | #ifdef CONFIG_CFS_BANDWIDTH |
| @@ -374,7 +374,11 @@ struct rq { | |||
| 374 | #ifdef CONFIG_FAIR_GROUP_SCHED | 374 | #ifdef CONFIG_FAIR_GROUP_SCHED |
| 375 | /* list of leaf cfs_rq on this cpu: */ | 375 | /* list of leaf cfs_rq on this cpu: */ |
| 376 | struct list_head leaf_cfs_rq_list; | 376 | struct list_head leaf_cfs_rq_list; |
| 377 | #endif | 377 | #ifdef CONFIG_SMP |
| 378 | unsigned long h_load_throttle; | ||
| 379 | #endif /* CONFIG_SMP */ | ||
| 380 | #endif /* CONFIG_FAIR_GROUP_SCHED */ | ||
| 381 | |||
| 378 | #ifdef CONFIG_RT_GROUP_SCHED | 382 | #ifdef CONFIG_RT_GROUP_SCHED |
| 379 | struct list_head leaf_rt_rq_list; | 383 | struct list_head leaf_rt_rq_list; |
| 380 | #endif | 384 | #endif |
diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index 7b386e86fd23..da5eb5bed84a 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c | |||
| @@ -27,8 +27,10 @@ static struct task_struct *pick_next_task_stop(struct rq *rq) | |||
| 27 | { | 27 | { |
| 28 | struct task_struct *stop = rq->stop; | 28 | struct task_struct *stop = rq->stop; |
| 29 | 29 | ||
| 30 | if (stop && stop->on_rq) | 30 | if (stop && stop->on_rq) { |
| 31 | stop->se.exec_start = rq->clock_task; | ||
| 31 | return stop; | 32 | return stop; |
| 33 | } | ||
| 32 | 34 | ||
| 33 | return NULL; | 35 | return NULL; |
| 34 | } | 36 | } |
| @@ -52,6 +54,21 @@ static void yield_task_stop(struct rq *rq) | |||
| 52 | 54 | ||
| 53 | static void put_prev_task_stop(struct rq *rq, struct task_struct *prev) | 55 | static void put_prev_task_stop(struct rq *rq, struct task_struct *prev) |
| 54 | { | 56 | { |
| 57 | struct task_struct *curr = rq->curr; | ||
| 58 | u64 delta_exec; | ||
| 59 | |||
| 60 | delta_exec = rq->clock_task - curr->se.exec_start; | ||
| 61 | if (unlikely((s64)delta_exec < 0)) | ||
| 62 | delta_exec = 0; | ||
| 63 | |||
| 64 | schedstat_set(curr->se.statistics.exec_max, | ||
| 65 | max(curr->se.statistics.exec_max, delta_exec)); | ||
| 66 | |||
| 67 | curr->se.sum_exec_runtime += delta_exec; | ||
| 68 | account_group_exec_runtime(curr, delta_exec); | ||
| 69 | |||
| 70 | curr->se.exec_start = rq->clock_task; | ||
| 71 | cpuacct_charge(curr, delta_exec); | ||
| 55 | } | 72 | } |
| 56 | 73 | ||
| 57 | static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) | 74 | static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) |
| @@ -60,6 +77,9 @@ static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) | |||
| 60 | 77 | ||
| 61 | static void set_curr_task_stop(struct rq *rq) | 78 | static void set_curr_task_stop(struct rq *rq) |
| 62 | { | 79 | { |
| 80 | struct task_struct *stop = rq->stop; | ||
| 81 | |||
| 82 | stop->se.exec_start = rq->clock_task; | ||
| 63 | } | 83 | } |
| 64 | 84 | ||
| 65 | static void switched_to_stop(struct rq *rq, struct task_struct *p) | 85 | static void switched_to_stop(struct rq *rq, struct task_struct *p) |
diff --git a/kernel/task_work.c b/kernel/task_work.c index 91d4e1742a0c..d320d44903bd 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c | |||
| @@ -75,6 +75,7 @@ void task_work_run(void) | |||
| 75 | p = q->next; | 75 | p = q->next; |
| 76 | q->func(q); | 76 | q->func(q); |
| 77 | q = p; | 77 | q = p; |
| 78 | cond_resched(); | ||
| 78 | } | 79 | } |
| 79 | } | 80 | } |
| 80 | } | 81 | } |
diff --git a/kernel/timer.c b/kernel/timer.c index a61c09374eba..8c5e7b908c68 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -1407,13 +1407,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, seconds) | |||
| 1407 | 1407 | ||
| 1408 | #endif | 1408 | #endif |
| 1409 | 1409 | ||
| 1410 | #ifndef __alpha__ | ||
| 1411 | |||
| 1412 | /* | ||
| 1413 | * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this | ||
| 1414 | * should be moved into arch/i386 instead? | ||
| 1415 | */ | ||
| 1416 | |||
| 1417 | /** | 1410 | /** |
| 1418 | * sys_getpid - return the thread group id of the current process | 1411 | * sys_getpid - return the thread group id of the current process |
| 1419 | * | 1412 | * |
| @@ -1469,8 +1462,6 @@ SYSCALL_DEFINE0(getegid) | |||
| 1469 | return from_kgid_munged(current_user_ns(), current_egid()); | 1462 | return from_kgid_munged(current_user_ns(), current_egid()); |
| 1470 | } | 1463 | } |
| 1471 | 1464 | ||
| 1472 | #endif | ||
| 1473 | |||
| 1474 | static void process_timeout(unsigned long __data) | 1465 | static void process_timeout(unsigned long __data) |
| 1475 | { | 1466 | { |
| 1476 | wake_up_process((struct task_struct *)__data); | 1467 | wake_up_process((struct task_struct *)__data); |
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9b0c0b8b4ab4..8fd107a3fac4 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
| @@ -1786,6 +1786,7 @@ sub dump_function($$) { | |||
| 1786 | $prototype =~ s/__init +//; | 1786 | $prototype =~ s/__init +//; |
| 1787 | $prototype =~ s/__init_or_module +//; | 1787 | $prototype =~ s/__init_or_module +//; |
| 1788 | $prototype =~ s/__must_check +//; | 1788 | $prototype =~ s/__must_check +//; |
| 1789 | $prototype =~ s/__weak +//; | ||
| 1789 | $prototype =~ s/^#\s*define\s+//; #ak added | 1790 | $prototype =~ s/^#\s*define\s+//; #ak added |
| 1790 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; | 1791 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; |
| 1791 | 1792 | ||
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index d51b7c76c37d..0cc99a3ea42d 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c | |||
| @@ -279,12 +279,9 @@ static int yama_ptrace_access_check(struct task_struct *child, | |||
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | if (rc) { | 281 | if (rc) { |
| 282 | char name[sizeof(current->comm)]; | ||
| 283 | printk_ratelimited(KERN_NOTICE | 282 | printk_ratelimited(KERN_NOTICE |
| 284 | "ptrace of pid %d was attempted by: %s (pid %d)\n", | 283 | "ptrace of pid %d was attempted by: %s (pid %d)\n", |
| 285 | child->pid, | 284 | child->pid, current->comm, current->pid); |
| 286 | get_task_comm(name, current), | ||
| 287 | current->pid); | ||
| 288 | } | 285 | } |
| 289 | 286 | ||
| 290 | return rc; | 287 | return rc; |
| @@ -319,12 +316,9 @@ static int yama_ptrace_traceme(struct task_struct *parent) | |||
| 319 | } | 316 | } |
| 320 | 317 | ||
| 321 | if (rc) { | 318 | if (rc) { |
| 322 | char name[sizeof(current->comm)]; | ||
| 323 | printk_ratelimited(KERN_NOTICE | 319 | printk_ratelimited(KERN_NOTICE |
| 324 | "ptraceme of pid %d was attempted by: %s (pid %d)\n", | 320 | "ptraceme of pid %d was attempted by: %s (pid %d)\n", |
| 325 | current->pid, | 321 | current->pid, parent->comm, parent->pid); |
| 326 | get_task_comm(name, parent), | ||
| 327 | parent->pid); | ||
| 328 | } | 322 | } |
| 329 | 323 | ||
| 330 | return rc; | 324 | return rc; |
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 0d7b25e81643..4e1fda75c1c9 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
| @@ -106,7 +106,7 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = { | |||
| 106 | .prepare = pxa2xx_ac97_pcm_prepare, | 106 | .prepare = pxa2xx_ac97_pcm_prepare, |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | #ifdef CONFIG_PM | 109 | #ifdef CONFIG_PM_SLEEP |
| 110 | 110 | ||
| 111 | static int pxa2xx_ac97_do_suspend(struct snd_card *card) | 111 | static int pxa2xx_ac97_do_suspend(struct snd_card *card) |
| 112 | { | 112 | { |
| @@ -243,7 +243,7 @@ static struct platform_driver pxa2xx_ac97_driver = { | |||
| 243 | .driver = { | 243 | .driver = { |
| 244 | .name = "pxa2xx-ac97", | 244 | .name = "pxa2xx-ac97", |
| 245 | .owner = THIS_MODULE, | 245 | .owner = THIS_MODULE, |
| 246 | #ifdef CONFIG_PM | 246 | #ifdef CONFIG_PM_SLEEP |
| 247 | .pm = &pxa2xx_ac97_pm_ops, | 247 | .pm = &pxa2xx_ac97_pm_ops, |
| 248 | #endif | 248 | #endif |
| 249 | }, | 249 | }, |
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index eb4ceb71123e..277ebce23a45 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c | |||
| @@ -452,6 +452,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev) | |||
| 452 | dac->regs = ioremap(regs->start, resource_size(regs)); | 452 | dac->regs = ioremap(regs->start, resource_size(regs)); |
| 453 | if (!dac->regs) { | 453 | if (!dac->regs) { |
| 454 | dev_dbg(&pdev->dev, "could not remap register memory\n"); | 454 | dev_dbg(&pdev->dev, "could not remap register memory\n"); |
| 455 | retval = -ENOMEM; | ||
| 455 | goto out_free_card; | 456 | goto out_free_card; |
| 456 | } | 457 | } |
| 457 | 458 | ||
| @@ -534,7 +535,7 @@ out_put_pclk: | |||
| 534 | return retval; | 535 | return retval; |
| 535 | } | 536 | } |
| 536 | 537 | ||
| 537 | #ifdef CONFIG_PM | 538 | #ifdef CONFIG_PM_SLEEP |
| 538 | static int atmel_abdac_suspend(struct device *pdev) | 539 | static int atmel_abdac_suspend(struct device *pdev) |
| 539 | { | 540 | { |
| 540 | struct snd_card *card = dev_get_drvdata(pdev); | 541 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index bf47025bdf45..9052aff37f64 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
| @@ -278,14 +278,9 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
| 278 | if (retval < 0) | 278 | if (retval < 0) |
| 279 | return retval; | 279 | return retval; |
| 280 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | 280 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ |
| 281 | if (cpu_is_at32ap7000()) { | 281 | if (cpu_is_at32ap7000() && retval == 1) |
| 282 | if (retval < 0) | 282 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) |
| 283 | return retval; | 283 | dw_dma_cyclic_free(chip->dma.rx_chan); |
| 284 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
| 285 | if (retval == 1) | ||
| 286 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | ||
| 287 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
| 288 | } | ||
| 289 | 284 | ||
| 290 | /* Set restrictions to params. */ | 285 | /* Set restrictions to params. */ |
| 291 | mutex_lock(&opened_mutex); | 286 | mutex_lock(&opened_mutex); |
| @@ -980,6 +975,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) | |||
| 980 | 975 | ||
| 981 | if (!chip->regs) { | 976 | if (!chip->regs) { |
| 982 | dev_dbg(&pdev->dev, "could not remap register memory\n"); | 977 | dev_dbg(&pdev->dev, "could not remap register memory\n"); |
| 978 | retval = -ENOMEM; | ||
| 983 | goto err_ioremap; | 979 | goto err_ioremap; |
| 984 | } | 980 | } |
| 985 | 981 | ||
| @@ -1134,7 +1130,7 @@ err_snd_card_new: | |||
| 1134 | return retval; | 1130 | return retval; |
| 1135 | } | 1131 | } |
| 1136 | 1132 | ||
| 1137 | #ifdef CONFIG_PM | 1133 | #ifdef CONFIG_PM_SLEEP |
| 1138 | static int atmel_ac97c_suspend(struct device *pdev) | 1134 | static int atmel_ac97c_suspend(struct device *pdev) |
| 1139 | { | 1135 | { |
| 1140 | struct snd_card *card = dev_get_drvdata(pdev); | 1136 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 1128b35b2b05..5a34355e78e8 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
| @@ -1176,7 +1176,7 @@ static int __devexit loopback_remove(struct platform_device *devptr) | |||
| 1176 | return 0; | 1176 | return 0; |
| 1177 | } | 1177 | } |
| 1178 | 1178 | ||
| 1179 | #ifdef CONFIG_PM | 1179 | #ifdef CONFIG_PM_SLEEP |
| 1180 | static int loopback_suspend(struct device *pdev) | 1180 | static int loopback_suspend(struct device *pdev) |
| 1181 | { | 1181 | { |
| 1182 | struct snd_card *card = dev_get_drvdata(pdev); | 1182 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index f7d3bfc6bca8..54bb6644a598 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
| @@ -1064,7 +1064,7 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr) | |||
| 1064 | return 0; | 1064 | return 0; |
| 1065 | } | 1065 | } |
| 1066 | 1066 | ||
| 1067 | #ifdef CONFIG_PM | 1067 | #ifdef CONFIG_PM_SLEEP |
| 1068 | static int snd_dummy_suspend(struct device *pdev) | 1068 | static int snd_dummy_suspend(struct device *pdev) |
| 1069 | { | 1069 | { |
| 1070 | struct snd_card *card = dev_get_drvdata(pdev); | 1070 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 6ca59fc6dcb9..ef171295f6d4 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c | |||
| @@ -199,7 +199,7 @@ static void pcsp_stop_beep(struct snd_pcsp *chip) | |||
| 199 | pcspkr_stop_sound(); | 199 | pcspkr_stop_sound(); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | #ifdef CONFIG_PM | 202 | #ifdef CONFIG_PM_SLEEP |
| 203 | static int pcsp_suspend(struct device *dev) | 203 | static int pcsp_suspend(struct device *dev) |
| 204 | { | 204 | { |
| 205 | struct snd_pcsp *chip = dev_get_drvdata(dev); | 205 | struct snd_pcsp *chip = dev_get_drvdata(dev); |
| @@ -212,7 +212,7 @@ static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL); | |||
| 212 | #define PCSP_PM_OPS &pcsp_pm | 212 | #define PCSP_PM_OPS &pcsp_pm |
| 213 | #else | 213 | #else |
| 214 | #define PCSP_PM_OPS NULL | 214 | #define PCSP_PM_OPS NULL |
| 215 | #endif /* CONFIG_PM */ | 215 | #endif /* CONFIG_PM_SLEEP */ |
| 216 | 216 | ||
| 217 | static void pcsp_shutdown(struct platform_device *dev) | 217 | static void pcsp_shutdown(struct platform_device *dev) |
| 218 | { | 218 | { |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 2d67c78c9f4b..f7cdaf51512d 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
| @@ -233,7 +233,7 @@ static int __devinit snd_card_als100_probe(int dev, | |||
| 233 | irq[dev], dma8[dev], dma16[dev]); | 233 | irq[dev], dma8[dev], dma16[dev]); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { | 236 | if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) { |
| 237 | snd_card_free(card); | 237 | snd_card_free(card); |
| 238 | return error; | 238 | return error; |
| 239 | } | 239 | } |
diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c index 733b014ec7d1..b2b3c014221a 100644 --- a/sound/oss/sb_audio.c +++ b/sound/oss/sb_audio.c | |||
| @@ -575,13 +575,15 @@ static int jazz16_audio_set_speed(int dev, int speed) | |||
| 575 | if (speed > 0) | 575 | if (speed > 0) |
| 576 | { | 576 | { |
| 577 | int tmp; | 577 | int tmp; |
| 578 | int s = speed * devc->channels; | 578 | int s; |
| 579 | 579 | ||
| 580 | if (speed < 5000) | 580 | if (speed < 5000) |
| 581 | speed = 5000; | 581 | speed = 5000; |
| 582 | if (speed > 44100) | 582 | if (speed > 44100) |
| 583 | speed = 44100; | 583 | speed = 44100; |
| 584 | 584 | ||
| 585 | s = speed * devc->channels; | ||
| 586 | |||
| 585 | devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff; | 587 | devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff; |
| 586 | 588 | ||
| 587 | tmp = 256 - devc->tconst; | 589 | tmp = 256 - devc->tconst; |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index f75f5ffdfdfb..a71d1c14a0f6 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
| @@ -94,7 +94,7 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, | |||
| 94 | 94 | ||
| 95 | if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && | 95 | if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && |
| 96 | codec_index != CS46XX_SECONDARY_CODEC_INDEX)) | 96 | codec_index != CS46XX_SECONDARY_CODEC_INDEX)) |
| 97 | return -EINVAL; | 97 | return 0xffff; |
| 98 | 98 | ||
| 99 | chip->active_ctrl(chip, 1); | 99 | chip->active_ctrl(chip, 1); |
| 100 | 100 | ||
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 8e40262d4117..2f6e9c762d3f 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
| @@ -1725,8 +1725,10 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1725 | atc_connect_resources(atc); | 1725 | atc_connect_resources(atc); |
| 1726 | 1726 | ||
| 1727 | atc->timer = ct_timer_new(atc); | 1727 | atc->timer = ct_timer_new(atc); |
| 1728 | if (!atc->timer) | 1728 | if (!atc->timer) { |
| 1729 | err = -ENOMEM; | ||
| 1729 | goto error1; | 1730 | goto error1; |
| 1731 | } | ||
| 1730 | 1732 | ||
| 1731 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); | 1733 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); |
| 1732 | if (err < 0) | 1734 | if (err < 0) |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0bc2315b181d..0849aac449f2 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
| @@ -231,16 +231,22 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); | 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); |
| 233 | 233 | ||
| 234 | static bool ctl_has_mute(struct snd_kcontrol *kcontrol) | ||
| 235 | { | ||
| 236 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 237 | return query_amp_caps(codec, get_amp_nid(kcontrol), | ||
| 238 | get_amp_direction(kcontrol)) & AC_AMPCAP_MUTE; | ||
| 239 | } | ||
| 240 | |||
| 234 | /* get/put callbacks for beep mute mixer switches */ | 241 | /* get/put callbacks for beep mute mixer switches */ |
| 235 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | 242 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, |
| 236 | struct snd_ctl_elem_value *ucontrol) | 243 | struct snd_ctl_elem_value *ucontrol) |
| 237 | { | 244 | { |
| 238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 245 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
| 239 | struct hda_beep *beep = codec->beep; | 246 | struct hda_beep *beep = codec->beep; |
| 240 | if (beep) { | 247 | if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) { |
| 241 | ucontrol->value.integer.value[0] = | 248 | ucontrol->value.integer.value[0] = |
| 242 | ucontrol->value.integer.value[1] = | 249 | ucontrol->value.integer.value[1] = beep->enabled; |
| 243 | beep->enabled; | ||
| 244 | return 0; | 250 | return 0; |
| 245 | } | 251 | } |
| 246 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | 252 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); |
| @@ -252,9 +258,20 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | |||
| 252 | { | 258 | { |
| 253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 259 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
| 254 | struct hda_beep *beep = codec->beep; | 260 | struct hda_beep *beep = codec->beep; |
| 255 | if (beep) | 261 | if (beep) { |
| 256 | snd_hda_enable_beep_device(codec, | 262 | u8 chs = get_amp_channels(kcontrol); |
| 257 | *ucontrol->value.integer.value); | 263 | int enable = 0; |
| 264 | long *valp = ucontrol->value.integer.value; | ||
| 265 | if (chs & 1) { | ||
| 266 | enable |= *valp; | ||
| 267 | valp++; | ||
| 268 | } | ||
| 269 | if (chs & 2) | ||
| 270 | enable |= *valp; | ||
| 271 | snd_hda_enable_beep_device(codec, enable); | ||
| 272 | } | ||
| 273 | if (!ctl_has_mute(kcontrol)) | ||
| 274 | return 0; | ||
| 258 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 275 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
| 259 | } | 276 | } |
| 260 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | 277 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 88a9c20eb7a2..f560051a949e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
| 1386 | } | 1386 | } |
| 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); | 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); |
| 1388 | 1388 | ||
| 1389 | /* update the stream-id if changed */ | ||
| 1390 | static void update_pcm_stream_id(struct hda_codec *codec, | ||
| 1391 | struct hda_cvt_setup *p, hda_nid_t nid, | ||
| 1392 | u32 stream_tag, int channel_id) | ||
| 1393 | { | ||
| 1394 | unsigned int oldval, newval; | ||
| 1395 | |||
| 1396 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | ||
| 1397 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
| 1398 | newval = (stream_tag << 4) | channel_id; | ||
| 1399 | if (oldval != newval) | ||
| 1400 | snd_hda_codec_write(codec, nid, 0, | ||
| 1401 | AC_VERB_SET_CHANNEL_STREAMID, | ||
| 1402 | newval); | ||
| 1403 | p->stream_tag = stream_tag; | ||
| 1404 | p->channel_id = channel_id; | ||
| 1405 | } | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | /* update the format-id if changed */ | ||
| 1409 | static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p, | ||
| 1410 | hda_nid_t nid, int format) | ||
| 1411 | { | ||
| 1412 | unsigned int oldval; | ||
| 1413 | |||
| 1414 | if (p->format_id != format) { | ||
| 1415 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 1416 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
| 1417 | if (oldval != format) { | ||
| 1418 | msleep(1); | ||
| 1419 | snd_hda_codec_write(codec, nid, 0, | ||
| 1420 | AC_VERB_SET_STREAM_FORMAT, | ||
| 1421 | format); | ||
| 1422 | } | ||
| 1423 | p->format_id = format; | ||
| 1424 | } | ||
| 1425 | } | ||
| 1426 | |||
| 1389 | /** | 1427 | /** |
| 1390 | * snd_hda_codec_setup_stream - set up the codec for streaming | 1428 | * snd_hda_codec_setup_stream - set up the codec for streaming |
| 1391 | * @codec: the CODEC to set up | 1429 | * @codec: the CODEC to set up |
| @@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1400 | { | 1438 | { |
| 1401 | struct hda_codec *c; | 1439 | struct hda_codec *c; |
| 1402 | struct hda_cvt_setup *p; | 1440 | struct hda_cvt_setup *p; |
| 1403 | unsigned int oldval, newval; | ||
| 1404 | int type; | 1441 | int type; |
| 1405 | int i; | 1442 | int i; |
| 1406 | 1443 | ||
| @@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1413 | p = get_hda_cvt_setup(codec, nid); | 1450 | p = get_hda_cvt_setup(codec, nid); |
| 1414 | if (!p) | 1451 | if (!p) |
| 1415 | return; | 1452 | return; |
| 1416 | /* update the stream-id if changed */ | 1453 | |
| 1417 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | 1454 | if (codec->pcm_format_first) |
| 1418 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | 1455 | update_pcm_format(codec, p, nid, format); |
| 1419 | newval = (stream_tag << 4) | channel_id; | 1456 | update_pcm_stream_id(codec, p, nid, stream_tag, channel_id); |
| 1420 | if (oldval != newval) | 1457 | if (!codec->pcm_format_first) |
| 1421 | snd_hda_codec_write(codec, nid, 0, | 1458 | update_pcm_format(codec, p, nid, format); |
| 1422 | AC_VERB_SET_CHANNEL_STREAMID, | 1459 | |
| 1423 | newval); | ||
| 1424 | p->stream_tag = stream_tag; | ||
| 1425 | p->channel_id = channel_id; | ||
| 1426 | } | ||
| 1427 | /* update the format-id if changed */ | ||
| 1428 | if (p->format_id != format) { | ||
| 1429 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 1430 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
| 1431 | if (oldval != format) { | ||
| 1432 | msleep(1); | ||
| 1433 | snd_hda_codec_write(codec, nid, 0, | ||
| 1434 | AC_VERB_SET_STREAM_FORMAT, | ||
| 1435 | format); | ||
| 1436 | } | ||
| 1437 | p->format_id = format; | ||
| 1438 | } | ||
| 1439 | p->active = 1; | 1460 | p->active = 1; |
| 1440 | p->dirty = 0; | 1461 | p->dirty = 0; |
| 1441 | 1462 | ||
| @@ -3497,7 +3518,7 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg | |||
| 3497 | { | 3518 | { |
| 3498 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); | 3519 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); |
| 3499 | 3520 | ||
| 3500 | if (sup < 0) | 3521 | if (sup == -1) |
| 3501 | return false; | 3522 | return false; |
| 3502 | if (sup & power_state) | 3523 | if (sup & power_state) |
| 3503 | return true; | 3524 | return true; |
| @@ -4433,6 +4454,8 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | |||
| 4433 | * then there is no need to go through power up here. | 4454 | * then there is no need to go through power up here. |
| 4434 | */ | 4455 | */ |
| 4435 | if (codec->power_on) { | 4456 | if (codec->power_on) { |
| 4457 | if (codec->power_transition < 0) | ||
| 4458 | codec->power_transition = 0; | ||
| 4436 | spin_unlock(&codec->power_lock); | 4459 | spin_unlock(&codec->power_lock); |
| 4437 | return; | 4460 | return; |
| 4438 | } | 4461 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c422d330ca54..7fbc1bcaf1a9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -861,6 +861,7 @@ struct hda_codec { | |||
| 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
| 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
| 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ |
| 864 | unsigned int pcm_format_first:1; /* PCM format must be set first */ | ||
| 864 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 865 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 865 | unsigned int power_on :1; /* current (global) power-state */ | 866 | unsigned int power_on :1; /* current (global) power-state */ |
| 866 | int power_transition; /* power-state in transition */ | 867 | int power_transition; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c8aced182fd1..60882c62f180 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
| 151 | "{Intel, CPT}," | 151 | "{Intel, CPT}," |
| 152 | "{Intel, PPT}," | 152 | "{Intel, PPT}," |
| 153 | "{Intel, LPT}," | 153 | "{Intel, LPT}," |
| 154 | "{Intel, LPT_LP}," | ||
| 154 | "{Intel, HPT}," | 155 | "{Intel, HPT}," |
| 155 | "{Intel, PBG}," | 156 | "{Intel, PBG}," |
| 156 | "{Intel, SCH}," | 157 | "{Intel, SCH}," |
| @@ -3270,6 +3271,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 3270 | { PCI_DEVICE(0x8086, 0x8c20), | 3271 | { PCI_DEVICE(0x8086, 0x8c20), |
| 3271 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3272 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| 3272 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | 3273 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| 3274 | /* Lynx Point-LP */ | ||
| 3275 | { PCI_DEVICE(0x8086, 0x9c20), | ||
| 3276 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
| 3277 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
| 3278 | /* Lynx Point-LP */ | ||
| 3279 | { PCI_DEVICE(0x8086, 0x9c21), | ||
| 3280 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
| 3281 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
| 3273 | /* Haswell */ | 3282 | /* Haswell */ |
| 3274 | { PCI_DEVICE(0x8086, 0x0c0c), | 3283 | { PCI_DEVICE(0x8086, 0x0c0c), |
| 3275 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3284 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 7e46258fc700..6894ec66258c 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
| @@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
| 412 | if (digi1 & AC_DIG1_EMPHASIS) | 412 | if (digi1 & AC_DIG1_EMPHASIS) |
| 413 | snd_iprintf(buffer, " Preemphasis"); | 413 | snd_iprintf(buffer, " Preemphasis"); |
| 414 | if (digi1 & AC_DIG1_COPYRIGHT) | 414 | if (digi1 & AC_DIG1_COPYRIGHT) |
| 415 | snd_iprintf(buffer, " Copyright"); | 415 | snd_iprintf(buffer, " Non-Copyright"); |
| 416 | if (digi1 & AC_DIG1_NONAUDIO) | 416 | if (digi1 & AC_DIG1_NONAUDIO) |
| 417 | snd_iprintf(buffer, " Non-Audio"); | 417 | snd_iprintf(buffer, " Non-Audio"); |
| 418 | if (digi1 & AC_DIG1_PROFESSIONAL) | 418 | if (digi1 & AC_DIG1_PROFESSIONAL) |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index d0d3540e39e7..49750a96d649 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
| @@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | |||
| 246 | AC_VERB_SET_AMP_GAIN_MUTE, | 246 | AC_VERB_SET_AMP_GAIN_MUTE, |
| 247 | AMP_OUT_UNMUTE); | 247 | AMP_OUT_UNMUTE); |
| 248 | } | 248 | } |
| 249 | if (dac) | 249 | if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP)) |
| 250 | snd_hda_codec_write(codec, dac, 0, | 250 | snd_hda_codec_write(codec, dac, 0, |
| 251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | 251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); |
| 252 | } | 252 | } |
| @@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | |||
| 261 | AC_VERB_SET_AMP_GAIN_MUTE, | 261 | AC_VERB_SET_AMP_GAIN_MUTE, |
| 262 | AMP_IN_UNMUTE(0)); | 262 | AMP_IN_UNMUTE(0)); |
| 263 | } | 263 | } |
| 264 | if (adc) | 264 | if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) |
| 265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
| 266 | AMP_IN_UNMUTE(0)); | 266 | AMP_IN_UNMUTE(0)); |
| 267 | } | 267 | } |
| @@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
| 275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
| 276 | struct snd_kcontrol_new knew = | 276 | struct snd_kcontrol_new knew = |
| 277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | 277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); |
| 278 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) { | ||
| 279 | snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
| 280 | return 0; | ||
| 281 | } | ||
| 278 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | 282 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); |
| 279 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 283 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
| 280 | } | 284 | } |
| @@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
| 286 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 290 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
| 287 | struct snd_kcontrol_new knew = | 291 | struct snd_kcontrol_new knew = |
| 288 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | 292 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); |
| 293 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) { | ||
| 294 | snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
| 295 | return 0; | ||
| 296 | } | ||
| 289 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | 297 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); |
| 290 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 298 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
| 291 | } | 299 | } |
| @@ -464,50 +472,17 @@ exit: | |||
| 464 | } | 472 | } |
| 465 | 473 | ||
| 466 | /* | 474 | /* |
| 467 | * PCM stuffs | 475 | * PCM callbacks |
| 468 | */ | 476 | */ |
| 469 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 477 | static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 470 | u32 stream_tag, | 478 | struct hda_codec *codec, |
| 471 | int channel_id, int format) | 479 | struct snd_pcm_substream *substream) |
| 472 | { | 480 | { |
| 473 | unsigned int oldval, newval; | 481 | struct ca0132_spec *spec = codec->spec; |
| 474 | 482 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | |
| 475 | if (!nid) | 483 | hinfo); |
| 476 | return; | ||
| 477 | |||
| 478 | snd_printdd("ca0132_setup_stream: " | ||
| 479 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | ||
| 480 | nid, stream_tag, channel_id, format); | ||
| 481 | |||
| 482 | /* update the format-id if changed */ | ||
| 483 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 484 | AC_VERB_GET_STREAM_FORMAT, | ||
| 485 | 0); | ||
| 486 | if (oldval != format) { | ||
| 487 | msleep(20); | ||
| 488 | snd_hda_codec_write(codec, nid, 0, | ||
| 489 | AC_VERB_SET_STREAM_FORMAT, | ||
| 490 | format); | ||
| 491 | } | ||
| 492 | |||
| 493 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
| 494 | newval = (stream_tag << 4) | channel_id; | ||
| 495 | if (oldval != newval) { | ||
| 496 | snd_hda_codec_write(codec, nid, 0, | ||
| 497 | AC_VERB_SET_CHANNEL_STREAMID, | ||
| 498 | newval); | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | ||
| 503 | { | ||
| 504 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
| 505 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
| 506 | } | 484 | } |
| 507 | 485 | ||
| 508 | /* | ||
| 509 | * PCM callbacks | ||
| 510 | */ | ||
| 511 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 486 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| 512 | struct hda_codec *codec, | 487 | struct hda_codec *codec, |
| 513 | unsigned int stream_tag, | 488 | unsigned int stream_tag, |
| @@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 515 | struct snd_pcm_substream *substream) | 490 | struct snd_pcm_substream *substream) |
| 516 | { | 491 | { |
| 517 | struct ca0132_spec *spec = codec->spec; | 492 | struct ca0132_spec *spec = codec->spec; |
| 518 | 493 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | |
| 519 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 494 | stream_tag, format, substream); |
| 520 | |||
| 521 | return 0; | ||
| 522 | } | 495 | } |
| 523 | 496 | ||
| 524 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 497 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| @@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 526 | struct snd_pcm_substream *substream) | 499 | struct snd_pcm_substream *substream) |
| 527 | { | 500 | { |
| 528 | struct ca0132_spec *spec = codec->spec; | 501 | struct ca0132_spec *spec = codec->spec; |
| 529 | 502 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | |
| 530 | ca0132_cleanup_stream(codec, spec->dacs[0]); | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | 503 | } |
| 534 | 504 | ||
| 535 | /* | 505 | /* |
| 536 | * Digital out | 506 | * Digital out |
| 537 | */ | 507 | */ |
| 538 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 508 | static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 539 | struct hda_codec *codec, | 509 | struct hda_codec *codec, |
| 540 | unsigned int stream_tag, | 510 | struct snd_pcm_substream *substream) |
| 541 | unsigned int format, | ||
| 542 | struct snd_pcm_substream *substream) | ||
| 543 | { | 511 | { |
| 544 | struct ca0132_spec *spec = codec->spec; | 512 | struct ca0132_spec *spec = codec->spec; |
| 545 | 513 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | |
| 546 | ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format); | ||
| 547 | |||
| 548 | return 0; | ||
| 549 | } | 514 | } |
| 550 | 515 | ||
| 551 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 516 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| 552 | struct hda_codec *codec, | ||
| 553 | struct snd_pcm_substream *substream) | ||
| 554 | { | ||
| 555 | struct ca0132_spec *spec = codec->spec; | ||
| 556 | |||
| 557 | ca0132_cleanup_stream(codec, spec->dig_out); | ||
| 558 | |||
| 559 | return 0; | ||
| 560 | } | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Analog capture | ||
| 564 | */ | ||
| 565 | static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 566 | struct hda_codec *codec, | 517 | struct hda_codec *codec, |
| 567 | unsigned int stream_tag, | 518 | unsigned int stream_tag, |
| 568 | unsigned int format, | 519 | unsigned int format, |
| 569 | struct snd_pcm_substream *substream) | 520 | struct snd_pcm_substream *substream) |
| 570 | { | 521 | { |
| 571 | struct ca0132_spec *spec = codec->spec; | 522 | struct ca0132_spec *spec = codec->spec; |
| 572 | 523 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | |
| 573 | ca0132_setup_stream(codec, spec->adcs[substream->number], | 524 | stream_tag, format, substream); |
| 574 | stream_tag, 0, format); | ||
| 575 | |||
| 576 | return 0; | ||
| 577 | } | 525 | } |
| 578 | 526 | ||
| 579 | static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 527 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| 580 | struct hda_codec *codec, | 528 | struct hda_codec *codec, |
| 581 | struct snd_pcm_substream *substream) | 529 | struct snd_pcm_substream *substream) |
| 582 | { | 530 | { |
| 583 | struct ca0132_spec *spec = codec->spec; | 531 | struct ca0132_spec *spec = codec->spec; |
| 584 | 532 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | |
| 585 | ca0132_cleanup_stream(codec, spec->adcs[substream->number]); | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | } | 533 | } |
| 589 | 534 | ||
| 590 | /* | 535 | static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
| 591 | * Digital capture | 536 | struct hda_codec *codec, |
| 592 | */ | 537 | struct snd_pcm_substream *substream) |
| 593 | static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 594 | struct hda_codec *codec, | ||
| 595 | unsigned int stream_tag, | ||
| 596 | unsigned int format, | ||
| 597 | struct snd_pcm_substream *substream) | ||
| 598 | { | 538 | { |
| 599 | struct ca0132_spec *spec = codec->spec; | 539 | struct ca0132_spec *spec = codec->spec; |
| 600 | 540 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | |
| 601 | ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format); | ||
| 602 | |||
| 603 | return 0; | ||
| 604 | } | ||
| 605 | |||
| 606 | static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 607 | struct hda_codec *codec, | ||
| 608 | struct snd_pcm_substream *substream) | ||
| 609 | { | ||
| 610 | struct ca0132_spec *spec = codec->spec; | ||
| 611 | |||
| 612 | ca0132_cleanup_stream(codec, spec->dig_in); | ||
| 613 | |||
| 614 | return 0; | ||
| 615 | } | 541 | } |
| 616 | 542 | ||
| 617 | /* | 543 | /* |
| @@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
| 621 | .channels_min = 2, | 547 | .channels_min = 2, |
| 622 | .channels_max = 2, | 548 | .channels_max = 2, |
| 623 | .ops = { | 549 | .ops = { |
| 550 | .open = ca0132_playback_pcm_open, | ||
| 624 | .prepare = ca0132_playback_pcm_prepare, | 551 | .prepare = ca0132_playback_pcm_prepare, |
| 625 | .cleanup = ca0132_playback_pcm_cleanup | 552 | .cleanup = ca0132_playback_pcm_cleanup |
| 626 | }, | 553 | }, |
| @@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
| 630 | .substreams = 1, | 557 | .substreams = 1, |
| 631 | .channels_min = 2, | 558 | .channels_min = 2, |
| 632 | .channels_max = 2, | 559 | .channels_max = 2, |
| 633 | .ops = { | ||
| 634 | .prepare = ca0132_capture_pcm_prepare, | ||
| 635 | .cleanup = ca0132_capture_pcm_cleanup | ||
| 636 | }, | ||
| 637 | }; | 560 | }; |
| 638 | 561 | ||
| 639 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 562 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { |
| @@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = { | |||
| 641 | .channels_min = 2, | 564 | .channels_min = 2, |
| 642 | .channels_max = 2, | 565 | .channels_max = 2, |
| 643 | .ops = { | 566 | .ops = { |
| 567 | .open = ca0132_dig_playback_pcm_open, | ||
| 568 | .close = ca0132_dig_playback_pcm_close, | ||
| 644 | .prepare = ca0132_dig_playback_pcm_prepare, | 569 | .prepare = ca0132_dig_playback_pcm_prepare, |
| 645 | .cleanup = ca0132_dig_playback_pcm_cleanup | 570 | .cleanup = ca0132_dig_playback_pcm_cleanup |
| 646 | }, | 571 | }, |
| @@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = { | |||
| 650 | .substreams = 1, | 575 | .substreams = 1, |
| 651 | .channels_min = 2, | 576 | .channels_min = 2, |
| 652 | .channels_max = 2, | 577 | .channels_max = 2, |
| 653 | .ops = { | ||
| 654 | .prepare = ca0132_dig_capture_pcm_prepare, | ||
| 655 | .cleanup = ca0132_dig_capture_pcm_cleanup | ||
| 656 | }, | ||
| 657 | }; | 578 | }; |
| 658 | 579 | ||
| 659 | static int ca0132_build_pcms(struct hda_codec *codec) | 580 | static int ca0132_build_pcms(struct hda_codec *codec) |
| @@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
| 928 | spec->dig_out); | 849 | spec->dig_out); |
| 929 | if (err < 0) | 850 | if (err < 0) |
| 930 | return err; | 851 | return err; |
| 931 | err = add_out_volume(codec, spec->dig_out, "IEC958"); | 852 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); |
| 932 | if (err < 0) | 853 | if (err < 0) |
| 933 | return err; | 854 | return err; |
| 855 | /* spec->multiout.share_spdif = 1; */ | ||
| 934 | } | 856 | } |
| 935 | 857 | ||
| 936 | if (spec->dig_in) { | 858 | if (spec->dig_in) { |
| 937 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | 859 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); |
| 938 | if (err < 0) | 860 | if (err < 0) |
| 939 | return err; | 861 | return err; |
| 940 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
| 941 | if (err < 0) | ||
| 942 | return err; | ||
| 943 | } | 862 | } |
| 944 | return 0; | 863 | return 0; |
| 945 | } | 864 | } |
| @@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec) | |||
| 961 | struct ca0132_spec *spec = codec->spec; | 880 | struct ca0132_spec *spec = codec->spec; |
| 962 | struct auto_pin_cfg *cfg = &spec->autocfg; | 881 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 963 | 882 | ||
| 883 | codec->pcm_format_first = 1; | ||
| 884 | codec->no_sticky_stream = 1; | ||
| 885 | |||
| 964 | /* line-outs */ | 886 | /* line-outs */ |
| 965 | cfg->line_outs = 1; | 887 | cfg->line_outs = 1; |
| 966 | cfg->line_out_pins[0] = 0x0b; /* front */ | 888 | cfg->line_out_pins[0] = 0x0b; /* front */ |
| @@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec) | |||
| 988 | 910 | ||
| 989 | /* Mic-in */ | 911 | /* Mic-in */ |
| 990 | spec->input_pins[0] = 0x12; | 912 | spec->input_pins[0] = 0x12; |
| 991 | spec->input_labels[0] = "Mic-In"; | 913 | spec->input_labels[0] = "Mic"; |
| 992 | spec->adcs[0] = 0x07; | 914 | spec->adcs[0] = 0x07; |
| 993 | 915 | ||
| 994 | /* Line-In */ | 916 | /* Line-In */ |
| 995 | spec->input_pins[1] = 0x11; | 917 | spec->input_pins[1] = 0x11; |
| 996 | spec->input_labels[1] = "Line-In"; | 918 | spec->input_labels[1] = "Line"; |
| 997 | spec->adcs[1] = 0x08; | 919 | spec->adcs[1] = 0x08; |
| 998 | spec->num_inputs = 2; | 920 | spec->num_inputs = 2; |
| 921 | |||
| 922 | /* SPDIF I/O */ | ||
| 923 | spec->dig_out = 0x05; | ||
| 924 | spec->multiout.dig_out_nid = spec->dig_out; | ||
| 925 | cfg->dig_out_pins[0] = 0x0c; | ||
| 926 | cfg->dig_outs = 1; | ||
| 927 | cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; | ||
| 928 | spec->dig_in = 0x09; | ||
| 929 | cfg->dig_in_pin = 0x0e; | ||
| 930 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
| 999 | } | 931 | } |
| 1000 | 932 | ||
| 1001 | static void ca0132_init_chip(struct hda_codec *codec) | 933 | static void ca0132_init_chip(struct hda_codec *codec) |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 94040ccf8e8f..ea5775a1a7db 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -4272,7 +4272,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
| 4272 | unsigned int gpio; | 4272 | unsigned int gpio; |
| 4273 | int i; | 4273 | int i; |
| 4274 | 4274 | ||
| 4275 | snd_hda_sequence_write(codec, spec->init); | 4275 | if (spec->init) |
| 4276 | snd_hda_sequence_write(codec, spec->init); | ||
| 4276 | 4277 | ||
| 4277 | /* power down adcs initially */ | 4278 | /* power down adcs initially */ |
| 4278 | if (spec->powerdown_adcs) | 4279 | if (spec->powerdown_adcs) |
| @@ -5748,7 +5749,6 @@ again: | |||
| 5748 | /* fallthru */ | 5749 | /* fallthru */ |
| 5749 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5750 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
| 5750 | case 0x111d76b5: | 5751 | case 0x111d76b5: |
| 5751 | spec->init = stac92hd71bxx_core_init; | ||
| 5752 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5752 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
| 5753 | spec->num_dmics = stac92xx_connected_ports(codec, | 5753 | spec->num_dmics = stac92xx_connected_ports(codec, |
| 5754 | stac92hd71bxx_dmic_nids, | 5754 | stac92hd71bxx_dmic_nids, |
| @@ -5773,7 +5773,6 @@ again: | |||
| 5773 | spec->stream_delay = 40; /* 40 milliseconds */ | 5773 | spec->stream_delay = 40; /* 40 milliseconds */ |
| 5774 | 5774 | ||
| 5775 | /* disable VSW */ | 5775 | /* disable VSW */ |
| 5776 | spec->init = stac92hd71bxx_core_init; | ||
| 5777 | unmute_init++; | 5776 | unmute_init++; |
| 5778 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 5777 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
| 5779 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 5778 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
| @@ -5788,7 +5787,6 @@ again: | |||
| 5788 | 5787 | ||
| 5789 | /* fallthru */ | 5788 | /* fallthru */ |
| 5790 | default: | 5789 | default: |
| 5791 | spec->init = stac92hd71bxx_core_init; | ||
| 5792 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5790 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
| 5793 | spec->num_dmics = stac92xx_connected_ports(codec, | 5791 | spec->num_dmics = stac92xx_connected_ports(codec, |
| 5794 | stac92hd71bxx_dmic_nids, | 5792 | stac92hd71bxx_dmic_nids, |
| @@ -5796,6 +5794,9 @@ again: | |||
| 5796 | break; | 5794 | break; |
| 5797 | } | 5795 | } |
| 5798 | 5796 | ||
| 5797 | if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) | ||
| 5798 | spec->init = stac92hd71bxx_core_init; | ||
| 5799 | |||
| 5799 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5800 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
| 5800 | snd_hda_sequence_write_cache(codec, unmute_init); | 5801 | snd_hda_sequence_write_cache(codec, unmute_init); |
| 5801 | 5802 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 80d90cb42853..430771776915 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
| @@ -1752,6 +1752,14 @@ static int via_suspend(struct hda_codec *codec) | |||
| 1752 | { | 1752 | { |
| 1753 | struct via_spec *spec = codec->spec; | 1753 | struct via_spec *spec = codec->spec; |
| 1754 | vt1708_stop_hp_work(spec); | 1754 | vt1708_stop_hp_work(spec); |
| 1755 | |||
| 1756 | if (spec->codec_type == VT1802) { | ||
| 1757 | /* Fix pop noise on headphones */ | ||
| 1758 | int i; | ||
| 1759 | for (i = 0; i < spec->autocfg.hp_outs; i++) | ||
| 1760 | snd_hda_set_pin_ctl(codec, spec->autocfg.hp_pins[i], 0); | ||
| 1761 | } | ||
| 1762 | |||
| 1755 | return 0; | 1763 | return 0; |
| 1756 | } | 1764 | } |
| 1757 | #endif | 1765 | #endif |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index d1ab43706735..5579b08bb35b 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
| @@ -851,6 +851,8 @@ static int __devinit lx_pcm_create(struct lx6464es *chip) | |||
| 851 | /* hardcoded device name & channel count */ | 851 | /* hardcoded device name & channel count */ |
| 852 | err = snd_pcm_new(chip->card, (char *)card_name, 0, | 852 | err = snd_pcm_new(chip->card, (char *)card_name, 0, |
| 853 | 1, 1, &pcm); | 853 | 1, 1, &pcm); |
| 854 | if (err < 0) | ||
| 855 | return err; | ||
| 854 | 856 | ||
| 855 | pcm->private_data = chip; | 857 | pcm->private_data = chip; |
| 856 | 858 | ||
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index b8ac8710f47f..b12308b5ba2a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
| @@ -6585,7 +6585,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
| 6585 | snd_printk(KERN_ERR "HDSPM: " | 6585 | snd_printk(KERN_ERR "HDSPM: " |
| 6586 | "unable to kmalloc Mixer memory of %d Bytes\n", | 6586 | "unable to kmalloc Mixer memory of %d Bytes\n", |
| 6587 | (int)sizeof(struct hdspm_mixer)); | 6587 | (int)sizeof(struct hdspm_mixer)); |
| 6588 | return err; | 6588 | return -ENOMEM; |
| 6589 | } | 6589 | } |
| 6590 | 6590 | ||
| 6591 | hdspm->port_names_in = NULL; | 6591 | hdspm->port_names_in = NULL; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 512434efcc31..805ab6e9a78f 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
| @@ -1377,8 +1377,9 @@ static int __devinit sis_chip_create(struct snd_card *card, | |||
| 1377 | if (rc) | 1377 | if (rc) |
| 1378 | goto error_out_cleanup; | 1378 | goto error_out_cleanup; |
| 1379 | 1379 | ||
| 1380 | if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, | 1380 | rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, |
| 1381 | sis)) { | 1381 | sis); |
| 1382 | if (rc) { | ||
| 1382 | dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); | 1383 | dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); |
| 1383 | goto error_out_cleanup; | 1384 | goto error_out_cleanup; |
| 1384 | } | 1385 | } |
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index f5ceb6f282de..210cafe04890 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c | |||
| @@ -143,7 +143,7 @@ static int __devexit snd_pmac_remove(struct platform_device *devptr) | |||
| 143 | return 0; | 143 | return 0; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM_SLEEP |
| 147 | static int snd_pmac_driver_suspend(struct device *dev) | 147 | static int snd_pmac_driver_suspend(struct device *dev) |
| 148 | { | 148 | { |
| 149 | struct snd_card *card = dev_get_drvdata(dev); | 149 | struct snd_card *card = dev_get_drvdata(dev); |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 1aa52eff526a..9b18b5243a56 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
| @@ -1040,6 +1040,7 @@ static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | |||
| 1040 | GFP_KERNEL); | 1040 | GFP_KERNEL); |
| 1041 | if (!the_card.null_buffer_start_vaddr) { | 1041 | if (!the_card.null_buffer_start_vaddr) { |
| 1042 | pr_info("%s: nullbuffer alloc failed\n", __func__); | 1042 | pr_info("%s: nullbuffer alloc failed\n", __func__); |
| 1043 | ret = -ENOMEM; | ||
| 1043 | goto clean_preallocate; | 1044 | goto clean_preallocate; |
| 1044 | } | 1045 | } |
| 1045 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, | 1046 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, |
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c index 318c5ba5360f..dfb744381c42 100644 --- a/sound/soc/blackfin/bf6xx-sport.c +++ b/sound/soc/blackfin/bf6xx-sport.c | |||
| @@ -413,7 +413,14 @@ EXPORT_SYMBOL(sport_create); | |||
| 413 | 413 | ||
| 414 | void sport_delete(struct sport_device *sport) | 414 | void sport_delete(struct sport_device *sport) |
| 415 | { | 415 | { |
| 416 | if (sport->tx_desc) | ||
| 417 | dma_free_coherent(NULL, sport->tx_desc_size, | ||
| 418 | sport->tx_desc, 0); | ||
| 419 | if (sport->rx_desc) | ||
| 420 | dma_free_coherent(NULL, sport->rx_desc_size, | ||
| 421 | sport->rx_desc, 0); | ||
| 416 | sport_free_resource(sport); | 422 | sport_free_resource(sport); |
| 423 | kfree(sport); | ||
| 417 | } | 424 | } |
| 418 | EXPORT_SYMBOL(sport_delete); | 425 | EXPORT_SYMBOL(sport_delete); |
| 419 | 426 | ||
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 6537f16d383e..e33d327396ad 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
| @@ -128,13 +128,9 @@ SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT, | |||
| 128 | 128 | ||
| 129 | ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE), | 129 | ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE), |
| 130 | ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE), | 130 | ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE), |
| 131 | ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE), | ||
| 132 | ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE), | ||
| 133 | 131 | ||
| 134 | SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5, | 132 | SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5, |
| 135 | ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA), | 133 | ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA), |
| 136 | SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5, | ||
| 137 | ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA), | ||
| 138 | 134 | ||
| 139 | ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE), | 135 | ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE), |
| 140 | ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), | 136 | ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), |
| @@ -236,8 +232,6 @@ ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE); | |||
| 236 | 232 | ||
| 237 | ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE); | 233 | ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE); |
| 238 | ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE); | 234 | ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE); |
| 239 | ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE); | ||
| 240 | ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE); | ||
| 241 | 235 | ||
| 242 | ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE); | 236 | ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE); |
| 243 | ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); | 237 | ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); |
| @@ -349,10 +343,6 @@ SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0, | |||
| 349 | NULL, 0), | 343 | NULL, 0), |
| 350 | SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0, | 344 | SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0, |
| 351 | NULL, 0), | 345 | NULL, 0), |
| 352 | SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0, | ||
| 353 | NULL, 0), | ||
| 354 | SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0, | ||
| 355 | NULL, 0), | ||
| 356 | 346 | ||
| 357 | SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0, | 347 | SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0, |
| 358 | NULL, 0), | 348 | NULL, 0), |
| @@ -466,8 +456,6 @@ ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"), | |||
| 466 | 456 | ||
| 467 | ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"), | 457 | ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"), |
| 468 | ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"), | 458 | ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"), |
| 469 | ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"), | ||
| 470 | ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"), | ||
| 471 | 459 | ||
| 472 | ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"), | 460 | ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"), |
| 473 | ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"), | 461 | ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"), |
| @@ -553,8 +541,6 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
| 553 | { name, "EQ4", "EQ4" }, \ | 541 | { name, "EQ4", "EQ4" }, \ |
| 554 | { name, "DRC1L", "DRC1L" }, \ | 542 | { name, "DRC1L", "DRC1L" }, \ |
| 555 | { name, "DRC1R", "DRC1R" }, \ | 543 | { name, "DRC1R", "DRC1R" }, \ |
| 556 | { name, "DRC2L", "DRC2L" }, \ | ||
| 557 | { name, "DRC2R", "DRC2R" }, \ | ||
| 558 | { name, "LHPF1", "LHPF1" }, \ | 544 | { name, "LHPF1", "LHPF1" }, \ |
| 559 | { name, "LHPF2", "LHPF2" }, \ | 545 | { name, "LHPF2", "LHPF2" }, \ |
| 560 | { name, "LHPF3", "LHPF3" }, \ | 546 | { name, "LHPF3", "LHPF3" }, \ |
| @@ -639,6 +625,15 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
| 639 | { "AIF2 Capture", NULL, "SYSCLK" }, | 625 | { "AIF2 Capture", NULL, "SYSCLK" }, |
| 640 | { "AIF3 Capture", NULL, "SYSCLK" }, | 626 | { "AIF3 Capture", NULL, "SYSCLK" }, |
| 641 | 627 | ||
| 628 | { "IN1L PGA", NULL, "IN1L" }, | ||
| 629 | { "IN1R PGA", NULL, "IN1R" }, | ||
| 630 | |||
| 631 | { "IN2L PGA", NULL, "IN2L" }, | ||
| 632 | { "IN2R PGA", NULL, "IN2R" }, | ||
| 633 | |||
| 634 | { "IN3L PGA", NULL, "IN3L" }, | ||
| 635 | { "IN3R PGA", NULL, "IN3R" }, | ||
| 636 | |||
| 642 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 637 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
| 643 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 638 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
| 644 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 639 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
| @@ -675,8 +670,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
| 675 | 670 | ||
| 676 | ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"), | 671 | ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"), |
| 677 | ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"), | 672 | ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"), |
| 678 | ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"), | ||
| 679 | ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"), | ||
| 680 | 673 | ||
| 681 | ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"), | 674 | ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"), |
| 682 | ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"), | 675 | ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"), |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 8033f7065189..01ebbcc5c6a4 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
| @@ -681,6 +681,18 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
| 681 | { "AIF2 Capture", NULL, "SYSCLK" }, | 681 | { "AIF2 Capture", NULL, "SYSCLK" }, |
| 682 | { "AIF3 Capture", NULL, "SYSCLK" }, | 682 | { "AIF3 Capture", NULL, "SYSCLK" }, |
| 683 | 683 | ||
| 684 | { "IN1L PGA", NULL, "IN1L" }, | ||
| 685 | { "IN1R PGA", NULL, "IN1R" }, | ||
| 686 | |||
| 687 | { "IN2L PGA", NULL, "IN2L" }, | ||
| 688 | { "IN2R PGA", NULL, "IN2R" }, | ||
| 689 | |||
| 690 | { "IN3L PGA", NULL, "IN3L" }, | ||
| 691 | { "IN3R PGA", NULL, "IN3R" }, | ||
| 692 | |||
| 693 | { "IN4L PGA", NULL, "IN4L" }, | ||
| 694 | { "IN4R PGA", NULL, "IN4R" }, | ||
| 695 | |||
| 684 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 696 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
| 685 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 697 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
| 686 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 698 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index aa9ce9dd7d8a..ce6720073798 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
| @@ -3733,21 +3733,6 @@ static int wm8962_runtime_resume(struct device *dev) | |||
| 3733 | 3733 | ||
| 3734 | regcache_sync(wm8962->regmap); | 3734 | regcache_sync(wm8962->regmap); |
| 3735 | 3735 | ||
| 3736 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, | ||
| 3737 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA, | ||
| 3738 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA); | ||
| 3739 | |||
| 3740 | /* Bias enable at 2*50k for ramp */ | ||
| 3741 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
| 3742 | WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, | ||
| 3743 | WM8962_BIAS_ENA | 0x180); | ||
| 3744 | |||
| 3745 | msleep(5); | ||
| 3746 | |||
| 3747 | /* VMID back to 2x250k for standby */ | ||
| 3748 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
| 3749 | WM8962_VMID_SEL_MASK, 0x100); | ||
| 3750 | |||
| 3751 | return 0; | 3736 | return 0; |
| 3752 | } | 3737 | } |
| 3753 | 3738 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 04ef03175c51..6c9eeca85b95 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -4038,6 +4038,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 4038 | break; | 4038 | break; |
| 4039 | case WM8958: | 4039 | case WM8958: |
| 4040 | if (wm8994->revision < 1) { | 4040 | if (wm8994->revision < 1) { |
| 4041 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | ||
| 4042 | ARRAY_SIZE(wm8994_intercon)); | ||
| 4041 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4043 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
| 4042 | ARRAY_SIZE(wm8994_revd_intercon)); | 4044 | ARRAY_SIZE(wm8994_revd_intercon)); |
| 4043 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, | 4045 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index f16fb361a4eb..c6d2076a796b 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
| @@ -148,7 +148,7 @@ SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), | |||
| 148 | 148 | ||
| 149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), | 149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), |
| 150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), | 150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), |
| 151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), | 151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), |
| 152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | 152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), |
| 153 | 153 | ||
| 154 | SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), | 154 | SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), |
| @@ -272,7 +272,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]); | |||
| 272 | 272 | ||
| 273 | /* Mic select */ | 273 | /* Mic select */ |
| 274 | static const struct snd_kcontrol_new wm9712_mic_src_controls = | 274 | static const struct snd_kcontrol_new wm9712_mic_src_controls = |
| 275 | SOC_DAPM_ENUM("Route", wm9712_enum[7]); | 275 | SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]); |
| 276 | 276 | ||
| 277 | /* diff select */ | 277 | /* diff select */ |
| 278 | static const struct snd_kcontrol_new wm9712_diff_sel_controls = | 278 | static const struct snd_kcontrol_new wm9712_diff_sel_controls = |
| @@ -291,7 +291,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0, | |||
| 291 | &wm9712_capture_selectl_controls), | 291 | &wm9712_capture_selectl_controls), |
| 292 | SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, | 292 | SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, |
| 293 | &wm9712_capture_selectr_controls), | 293 | &wm9712_capture_selectr_controls), |
| 294 | SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0, | 294 | SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0, |
| 295 | &wm9712_mic_src_controls), | ||
| 296 | SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0, | ||
| 295 | &wm9712_mic_src_controls), | 297 | &wm9712_mic_src_controls), |
| 296 | SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, | 298 | SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, |
| 297 | &wm9712_diff_sel_controls), | 299 | &wm9712_diff_sel_controls), |
| @@ -319,6 +321,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0), | |||
| 319 | SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), | 321 | SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), |
| 320 | SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), | 322 | SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), |
| 321 | SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), | 323 | SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), |
| 324 | SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 322 | SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), | 325 | SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), |
| 323 | SND_SOC_DAPM_OUTPUT("MONOOUT"), | 326 | SND_SOC_DAPM_OUTPUT("MONOOUT"), |
| 324 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | 327 | SND_SOC_DAPM_OUTPUT("HPOUTL"), |
| @@ -379,6 +382,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { | |||
| 379 | {"Mic PGA", NULL, "MIC1"}, | 382 | {"Mic PGA", NULL, "MIC1"}, |
| 380 | {"Mic PGA", NULL, "MIC2"}, | 383 | {"Mic PGA", NULL, "MIC2"}, |
| 381 | 384 | ||
| 385 | /* microphones */ | ||
| 386 | {"Differential Mic", NULL, "MIC1"}, | ||
| 387 | {"Differential Mic", NULL, "MIC2"}, | ||
| 388 | {"Left Mic Select Source", "Mic 1", "MIC1"}, | ||
| 389 | {"Left Mic Select Source", "Mic 2", "MIC2"}, | ||
| 390 | {"Left Mic Select Source", "Stereo", "MIC1"}, | ||
| 391 | {"Left Mic Select Source", "Differential", "Differential Mic"}, | ||
| 392 | {"Right Mic Select Source", "Mic 1", "MIC1"}, | ||
| 393 | {"Right Mic Select Source", "Mic 2", "MIC2"}, | ||
| 394 | {"Right Mic Select Source", "Stereo", "MIC2"}, | ||
| 395 | {"Right Mic Select Source", "Differential", "Differential Mic"}, | ||
| 396 | |||
| 382 | /* left capture selector */ | 397 | /* left capture selector */ |
| 383 | {"Left Capture Select", "Mic", "MIC1"}, | 398 | {"Left Capture Select", "Mic", "MIC1"}, |
| 384 | {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, | 399 | {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 95441bfc8190..ce5e5cd254dd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
| @@ -380,14 +380,20 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) | |||
| 380 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | 380 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) |
| 381 | { | 381 | { |
| 382 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 382 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 383 | if (dev->txnumevt) /* enable FIFO */ | 383 | if (dev->txnumevt) { /* enable FIFO */ |
| 384 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
| 385 | FIFO_ENABLE); | ||
| 384 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 386 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, |
| 385 | FIFO_ENABLE); | 387 | FIFO_ENABLE); |
| 388 | } | ||
| 386 | mcasp_start_tx(dev); | 389 | mcasp_start_tx(dev); |
| 387 | } else { | 390 | } else { |
| 388 | if (dev->rxnumevt) /* enable FIFO */ | 391 | if (dev->rxnumevt) { /* enable FIFO */ |
| 392 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
| 393 | FIFO_ENABLE); | ||
| 389 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 394 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, |
| 390 | FIFO_ENABLE); | 395 | FIFO_ENABLE); |
| 396 | } | ||
| 391 | mcasp_start_rx(dev); | 397 | mcasp_start_rx(dev); |
| 392 | } | 398 | } |
| 393 | } | 399 | } |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 28dd76c7cb1c..81d7728cf67f 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
| @@ -380,13 +380,14 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) | |||
| 380 | static struct snd_soc_dai_driver imx_ssi_dai = { | 380 | static struct snd_soc_dai_driver imx_ssi_dai = { |
| 381 | .probe = imx_ssi_dai_probe, | 381 | .probe = imx_ssi_dai_probe, |
| 382 | .playback = { | 382 | .playback = { |
| 383 | .channels_min = 1, | 383 | /* The SSI does not support monaural audio. */ |
| 384 | .channels_min = 2, | ||
| 384 | .channels_max = 2, | 385 | .channels_max = 2, |
| 385 | .rates = SNDRV_PCM_RATE_8000_96000, | 386 | .rates = SNDRV_PCM_RATE_8000_96000, |
| 386 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 387 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 387 | }, | 388 | }, |
| 388 | .capture = { | 389 | .capture = { |
| 389 | .channels_min = 1, | 390 | .channels_min = 2, |
| 390 | .channels_max = 2, | 391 | .channels_max = 2, |
| 391 | .rates = SNDRV_PCM_RATE_8000_96000, | 392 | .rates = SNDRV_PCM_RATE_8000_96000, |
| 392 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 393 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index 99a997f19bb9..b6fa77678d97 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
| @@ -10,7 +10,7 @@ menuconfig SND_MXS_SOC | |||
| 10 | if SND_MXS_SOC | 10 | if SND_MXS_SOC |
| 11 | 11 | ||
| 12 | config SND_SOC_MXS_SGTL5000 | 12 | config SND_SOC_MXS_SGTL5000 |
| 13 | tristate "SoC Audio support for i.MX boards with sgtl5000" | 13 | tristate "SoC Audio support for MXS boards with sgtl5000" |
| 14 | depends on I2C | 14 | depends on I2C |
| 15 | select SND_SOC_SGTL5000 | 15 | select SND_SOC_SGTL5000 |
| 16 | help | 16 | help |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 34835e8a9160..d33c48baaf71 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
| @@ -745,7 +745,7 @@ int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) | |||
| 745 | { | 745 | { |
| 746 | const char *signal, *src; | 746 | const char *signal, *src; |
| 747 | 747 | ||
| 748 | if (mcbsp->pdata->mux_signal) | 748 | if (!mcbsp->pdata->mux_signal) |
| 749 | return -EINVAL; | 749 | return -EINVAL; |
| 750 | 750 | ||
| 751 | switch (mux) { | 751 | switch (mux) { |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index b7b2a1f91425..89b064650f14 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <sound/pcm_params.h> | 20 | #include <sound/pcm_params.h> |
| 21 | 21 | ||
| 22 | #include <plat/audio.h> | 22 | #include <plat/audio.h> |
| 23 | #include <plat/dma.h> | 23 | #include <mach/dma.h> |
| 24 | 24 | ||
| 25 | #include "dma.h" | 25 | #include "dma.h" |
| 26 | #include "pcm.h" | 26 | #include "pcm.h" |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f81c5976b961..c501af6d8dbe 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -826,7 +826,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | if (!rtd->cpu_dai) { | 828 | if (!rtd->cpu_dai) { |
| 829 | dev_dbg(card->dev, "CPU DAI %s not registered\n", | 829 | dev_err(card->dev, "CPU DAI %s not registered\n", |
| 830 | dai_link->cpu_dai_name); | 830 | dai_link->cpu_dai_name); |
| 831 | return -EPROBE_DEFER; | 831 | return -EPROBE_DEFER; |
| 832 | } | 832 | } |
| @@ -857,14 +857,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
| 857 | } | 857 | } |
| 858 | 858 | ||
| 859 | if (!rtd->codec_dai) { | 859 | if (!rtd->codec_dai) { |
| 860 | dev_dbg(card->dev, "CODEC DAI %s not registered\n", | 860 | dev_err(card->dev, "CODEC DAI %s not registered\n", |
| 861 | dai_link->codec_dai_name); | 861 | dai_link->codec_dai_name); |
| 862 | return -EPROBE_DEFER; | 862 | return -EPROBE_DEFER; |
| 863 | } | 863 | } |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | if (!rtd->codec) { | 866 | if (!rtd->codec) { |
| 867 | dev_dbg(card->dev, "CODEC %s not registered\n", | 867 | dev_err(card->dev, "CODEC %s not registered\n", |
| 868 | dai_link->codec_name); | 868 | dai_link->codec_name); |
| 869 | return -EPROBE_DEFER; | 869 | return -EPROBE_DEFER; |
| 870 | } | 870 | } |
| @@ -888,7 +888,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
| 888 | rtd->platform = platform; | 888 | rtd->platform = platform; |
| 889 | } | 889 | } |
| 890 | if (!rtd->platform) { | 890 | if (!rtd->platform) { |
| 891 | dev_dbg(card->dev, "platform %s not registered\n", | 891 | dev_err(card->dev, "platform %s not registered\n", |
| 892 | dai_link->platform_name); | 892 | dai_link->platform_name); |
| 893 | return -EPROBE_DEFER; | 893 | return -EPROBE_DEFER; |
| 894 | } | 894 | } |
| @@ -1481,6 +1481,8 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num) | |||
| 1481 | return 0; | 1481 | return 0; |
| 1482 | } | 1482 | } |
| 1483 | 1483 | ||
| 1484 | dev_err(card->dev, "%s not registered\n", aux_dev->codec_name); | ||
| 1485 | |||
| 1484 | return -EPROBE_DEFER; | 1486 | return -EPROBE_DEFER; |
| 1485 | } | 1487 | } |
| 1486 | 1488 | ||
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7f8b3b7428bb..0c172938b82a 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
| @@ -103,7 +103,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | /* Report before the DAPM sync to help users updating micbias status */ | 105 | /* Report before the DAPM sync to help users updating micbias status */ |
| 106 | blocking_notifier_call_chain(&jack->notifier, status, jack); | 106 | blocking_notifier_call_chain(&jack->notifier, jack->status, jack); |
| 107 | 107 | ||
| 108 | snd_soc_dapm_sync(dapm); | 108 | snd_soc_dapm_sync(dapm); |
| 109 | 109 | ||
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 0f647d22cb4a..c41181202688 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
| @@ -821,10 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) | |||
| 821 | if (++ep->use_count != 1) | 821 | if (++ep->use_count != 1) |
| 822 | return 0; | 822 | return 0; |
| 823 | 823 | ||
| 824 | /* just to be sure */ | ||
| 825 | deactivate_urbs(ep, 0, 1); | ||
| 826 | wait_clear_urbs(ep); | ||
| 827 | |||
| 828 | ep->active_mask = 0; | 824 | ep->active_mask = 0; |
| 829 | ep->unlink_mask = 0; | 825 | ep->unlink_mask = 0; |
| 830 | ep->phase = 0; | 826 | ep->phase = 0; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index a1298f379428..62ec808ed792 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
| @@ -544,6 +544,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 544 | subs->last_frame_number = 0; | 544 | subs->last_frame_number = 0; |
| 545 | runtime->delay = 0; | 545 | runtime->delay = 0; |
| 546 | 546 | ||
| 547 | /* clear the pending deactivation on the target EPs */ | ||
| 548 | deactivate_endpoints(subs); | ||
| 549 | |||
| 547 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | 550 | /* for playback, submit the URBs now; otherwise, the first hwptr_done |
| 548 | * updates for all URBs would happen at the same time when starting */ | 551 | * updates for all URBs would happen at the same time when starting */ |
| 549 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | 552 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) |
