diff options
100 files changed, 849 insertions, 543 deletions
diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index 6d1c0988cfc7..c67b975c8906 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | * Samsung Exynos specific extensions to the Synopsis Designware Mobile | 1 | * Samsung Exynos specific extensions to the Synopsys Designware Mobile |
| 2 | Storage Host Controller | 2 | Storage Host Controller |
| 3 | 3 | ||
| 4 | The Synopsis designware mobile storage host controller is used to interface | 4 | The Synopsys designware mobile storage host controller is used to interface |
| 5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | 5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents |
| 6 | differences between the core Synopsis dw mshc controller properties described | 6 | differences between the core Synopsys dw mshc controller properties described |
| 7 | by synopsis-dw-mshc.txt and the properties used by the Samsung Exynos specific | 7 | by synopsys-dw-mshc.txt and the properties used by the Samsung Exynos specific |
| 8 | extensions to the Synopsis Designware Mobile Storage Host Controller. | 8 | extensions to the Synopsys Designware Mobile Storage Host Controller. |
| 9 | 9 | ||
| 10 | Required Properties: | 10 | Required Properties: |
| 11 | 11 | ||
diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 8a3d91d47b6a..c559f3f36309 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | * Rockchip specific extensions to the Synopsis Designware Mobile | 1 | * Rockchip specific extensions to the Synopsys Designware Mobile |
| 2 | Storage Host Controller | 2 | Storage Host Controller |
| 3 | 3 | ||
| 4 | The Synopsis designware mobile storage host controller is used to interface | 4 | The Synopsys designware mobile storage host controller is used to interface |
| 5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | 5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents |
| 6 | differences between the core Synopsis dw mshc controller properties described | 6 | differences between the core Synopsys dw mshc controller properties described |
| 7 | by synopsis-dw-mshc.txt and the properties used by the Rockchip specific | 7 | by synopsys-dw-mshc.txt and the properties used by the Rockchip specific |
| 8 | extensions to the Synopsis Designware Mobile Storage Host Controller. | 8 | extensions to the Synopsys Designware Mobile Storage Host Controller. |
| 9 | 9 | ||
| 10 | Required Properties: | 10 | Required Properties: |
| 11 | 11 | ||
diff --git a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt index cdcebea9c6f5..066a78b034ca 100644 --- a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt | |||
| @@ -1,14 +1,14 @@ | |||
| 1 | * Synopsis Designware Mobile Storage Host Controller | 1 | * Synopsys Designware Mobile Storage Host Controller |
| 2 | 2 | ||
| 3 | The Synopsis designware mobile storage host controller is used to interface | 3 | The Synopsys designware mobile storage host controller is used to interface |
| 4 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | 4 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents |
| 5 | differences between the core mmc properties described by mmc.txt and the | 5 | differences between the core mmc properties described by mmc.txt and the |
| 6 | properties used by the Synopsis Designware Mobile Storage Host Controller. | 6 | properties used by the Synopsys Designware Mobile Storage Host Controller. |
| 7 | 7 | ||
| 8 | Required Properties: | 8 | Required Properties: |
| 9 | 9 | ||
| 10 | * compatible: should be | 10 | * compatible: should be |
| 11 | - snps,dw-mshc: for controllers compliant with synopsis dw-mshc. | 11 | - snps,dw-mshc: for controllers compliant with synopsys dw-mshc. |
| 12 | * #address-cells: should be 1. | 12 | * #address-cells: should be 1. |
| 13 | * #size-cells: should be 0. | 13 | * #size-cells: should be 0. |
| 14 | 14 | ||
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index eabcb4b5db6e..e216af356847 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | * Synopsis Designware PCIe interface | 1 | * Synopsys Designware PCIe interface |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: should contain "snps,dw-pcie" to identify the | 4 | - compatible: should contain "snps,dw-pcie" to identify the |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 1a036cd972fb..539a23631990 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -3485,6 +3485,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
| 3485 | the unplug protocol | 3485 | the unplug protocol |
| 3486 | never -- do not unplug even if version check succeeds | 3486 | never -- do not unplug even if version check succeeds |
| 3487 | 3487 | ||
| 3488 | xen_nopvspin [X86,XEN] | ||
| 3489 | Disables the ticketlock slowpath using Xen PV | ||
| 3490 | optimizations. | ||
| 3491 | |||
| 3488 | xirc2ps_cs= [NET,PCMCIA] | 3492 | xirc2ps_cs= [NET,PCMCIA] |
| 3489 | Format: | 3493 | Format: |
| 3490 | <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]] | 3494 | <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]] |
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index a46ddb85e83a..f911e3656209 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
| @@ -296,6 +296,12 @@ Cirrus Logic CS4206/4207 | |||
| 296 | imac27 IMac 27 Inch | 296 | imac27 IMac 27 Inch |
| 297 | auto BIOS setup (default) | 297 | auto BIOS setup (default) |
| 298 | 298 | ||
| 299 | Cirrus Logic CS4208 | ||
| 300 | =================== | ||
| 301 | mba6 MacBook Air 6,1 and 6,2 | ||
| 302 | gpio0 Enable GPIO 0 amp | ||
| 303 | auto BIOS setup (default) | ||
| 304 | |||
| 299 | VIA VT17xx/VT18xx/VT20xx | 305 | VIA VT17xx/VT18xx/VT20xx |
| 300 | ======================== | 306 | ======================== |
| 301 | auto BIOS setup (default) | 307 | auto BIOS setup (default) |
diff --git a/arch/Kconfig b/arch/Kconfig index 1feb169274fe..af2cc6eabcc7 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -286,9 +286,6 @@ config HAVE_PERF_USER_STACK_DUMP | |||
| 286 | config HAVE_ARCH_JUMP_LABEL | 286 | config HAVE_ARCH_JUMP_LABEL |
| 287 | bool | 287 | bool |
| 288 | 288 | ||
| 289 | config HAVE_ARCH_MUTEX_CPU_RELAX | ||
| 290 | bool | ||
| 291 | |||
| 292 | config HAVE_RCU_TABLE_FREE | 289 | config HAVE_RCU_TABLE_FREE |
| 293 | bool | 290 | bool |
| 294 | 291 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3f7714d8d2d2..1ad6fb6c094d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -2217,8 +2217,7 @@ config NEON | |||
| 2217 | 2217 | ||
| 2218 | config KERNEL_MODE_NEON | 2218 | config KERNEL_MODE_NEON |
| 2219 | bool "Support for NEON in kernel mode" | 2219 | bool "Support for NEON in kernel mode" |
| 2220 | default n | 2220 | depends on NEON && AEABI |
| 2221 | depends on NEON | ||
| 2222 | help | 2221 | help |
| 2223 | Say Y to include support for NEON in kernel mode. | 2222 | Say Y to include support for NEON in kernel mode. |
| 2224 | 2223 | ||
diff --git a/arch/arm/crypto/aes-armv4.S b/arch/arm/crypto/aes-armv4.S index 19d6cd6f29f9..3a14ea8fe97e 100644 --- a/arch/arm/crypto/aes-armv4.S +++ b/arch/arm/crypto/aes-armv4.S | |||
| @@ -148,7 +148,7 @@ AES_Te: | |||
| 148 | @ const AES_KEY *key) { | 148 | @ const AES_KEY *key) { |
| 149 | .align 5 | 149 | .align 5 |
| 150 | ENTRY(AES_encrypt) | 150 | ENTRY(AES_encrypt) |
| 151 | sub r3,pc,#8 @ AES_encrypt | 151 | adr r3,AES_encrypt |
| 152 | stmdb sp!,{r1,r4-r12,lr} | 152 | stmdb sp!,{r1,r4-r12,lr} |
| 153 | mov r12,r0 @ inp | 153 | mov r12,r0 @ inp |
| 154 | mov r11,r2 | 154 | mov r11,r2 |
| @@ -381,7 +381,7 @@ _armv4_AES_encrypt: | |||
| 381 | .align 5 | 381 | .align 5 |
| 382 | ENTRY(private_AES_set_encrypt_key) | 382 | ENTRY(private_AES_set_encrypt_key) |
| 383 | _armv4_AES_set_encrypt_key: | 383 | _armv4_AES_set_encrypt_key: |
| 384 | sub r3,pc,#8 @ AES_set_encrypt_key | 384 | adr r3,_armv4_AES_set_encrypt_key |
| 385 | teq r0,#0 | 385 | teq r0,#0 |
| 386 | moveq r0,#-1 | 386 | moveq r0,#-1 |
| 387 | beq .Labrt | 387 | beq .Labrt |
| @@ -843,7 +843,7 @@ AES_Td: | |||
| 843 | @ const AES_KEY *key) { | 843 | @ const AES_KEY *key) { |
| 844 | .align 5 | 844 | .align 5 |
| 845 | ENTRY(AES_decrypt) | 845 | ENTRY(AES_decrypt) |
| 846 | sub r3,pc,#8 @ AES_decrypt | 846 | adr r3,AES_decrypt |
| 847 | stmdb sp!,{r1,r4-r12,lr} | 847 | stmdb sp!,{r1,r4-r12,lr} |
| 848 | mov r12,r0 @ inp | 848 | mov r12,r0 @ inp |
| 849 | mov r11,r2 | 849 | mov r11,r2 |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 7e1f76027f66..72abdc541f38 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
| @@ -19,6 +19,13 @@ | |||
| 19 | #include <asm/unified.h> | 19 | #include <asm/unified.h> |
| 20 | #include <asm/compiler.h> | 20 | #include <asm/compiler.h> |
| 21 | 21 | ||
| 22 | #if __LINUX_ARM_ARCH__ < 6 | ||
| 23 | #include <asm-generic/uaccess-unaligned.h> | ||
| 24 | #else | ||
| 25 | #define __get_user_unaligned __get_user | ||
| 26 | #define __put_user_unaligned __put_user | ||
| 27 | #endif | ||
| 28 | |||
| 22 | #define VERIFY_READ 0 | 29 | #define VERIFY_READ 0 |
| 23 | #define VERIFY_WRITE 1 | 30 | #define VERIFY_WRITE 1 |
| 24 | 31 | ||
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 74ad15d1a065..bc6bd9683ba4 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -442,10 +442,10 @@ local_restart: | |||
| 442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 442 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
| 443 | 443 | ||
| 444 | add r1, sp, #S_OFF | 444 | add r1, sp, #S_OFF |
| 445 | cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) | 445 | 2: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) |
| 446 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back | 446 | eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back |
| 447 | bcs arm_syscall | 447 | bcs arm_syscall |
| 448 | 2: mov why, #0 @ no longer a real syscall | 448 | mov why, #0 @ no longer a real syscall |
| 449 | b sys_ni_syscall @ not private func | 449 | b sys_ni_syscall @ not private func |
| 450 | 450 | ||
| 451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) | 451 | #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index de23a9beed13..39f89fbd5111 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
| @@ -329,10 +329,10 @@ | |||
| 329 | #ifdef CONFIG_CONTEXT_TRACKING | 329 | #ifdef CONFIG_CONTEXT_TRACKING |
| 330 | .if \save | 330 | .if \save |
| 331 | stmdb sp!, {r0-r3, ip, lr} | 331 | stmdb sp!, {r0-r3, ip, lr} |
| 332 | bl user_exit | 332 | bl context_tracking_user_exit |
| 333 | ldmia sp!, {r0-r3, ip, lr} | 333 | ldmia sp!, {r0-r3, ip, lr} |
| 334 | .else | 334 | .else |
| 335 | bl user_exit | 335 | bl context_tracking_user_exit |
| 336 | .endif | 336 | .endif |
| 337 | #endif | 337 | #endif |
| 338 | .endm | 338 | .endm |
| @@ -341,10 +341,10 @@ | |||
| 341 | #ifdef CONFIG_CONTEXT_TRACKING | 341 | #ifdef CONFIG_CONTEXT_TRACKING |
| 342 | .if \save | 342 | .if \save |
| 343 | stmdb sp!, {r0-r3, ip, lr} | 343 | stmdb sp!, {r0-r3, ip, lr} |
| 344 | bl user_enter | 344 | bl context_tracking_user_enter |
| 345 | ldmia sp!, {r0-r3, ip, lr} | 345 | ldmia sp!, {r0-r3, ip, lr} |
| 346 | .else | 346 | .else |
| 347 | bl user_enter | 347 | bl context_tracking_user_enter |
| 348 | .endif | 348 | .endif |
| 349 | #endif | 349 | #endif |
| 350 | .endm | 350 | .endm |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 51680d15ca8e..d445d060e346 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
| @@ -187,7 +187,7 @@ | |||
| 187 | 187 | ||
| 188 | /* | 188 | /* |
| 189 | * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other | 189 | * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other |
| 190 | * pre-MIPS32/MIPS53 processors have CLO, CLZ. The IDT RC64574 is 64-bit and | 190 | * pre-MIPS32/MIPS64 processors have CLO, CLZ. The IDT RC64574 is 64-bit and |
| 191 | * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels | 191 | * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels |
| 192 | * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ. | 192 | * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ. |
| 193 | */ | 193 | */ |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f25a7e9f8cbc..5f8b95512580 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
| @@ -308,12 +308,10 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, | |||
| 308 | { | 308 | { |
| 309 | int i; | 309 | int i; |
| 310 | 310 | ||
| 311 | /* Make sure that gcc doesn't leave the empty loop body. */ | 311 | if (cpu_needs_post_dma_flush(dev)) |
| 312 | for (i = 0; i < nelems; i++, sg++) { | 312 | for (i = 0; i < nelems; i++, sg++) |
| 313 | if (cpu_needs_post_dma_flush(dev)) | ||
| 314 | __dma_sync(sg_page(sg), sg->offset, sg->length, | 313 | __dma_sync(sg_page(sg), sg->offset, sg->length, |
| 315 | direction); | 314 | direction); |
| 316 | } | ||
| 317 | } | 315 | } |
| 318 | 316 | ||
| 319 | static void mips_dma_sync_sg_for_device(struct device *dev, | 317 | static void mips_dma_sync_sg_for_device(struct device *dev, |
| @@ -321,12 +319,10 @@ static void mips_dma_sync_sg_for_device(struct device *dev, | |||
| 321 | { | 319 | { |
| 322 | int i; | 320 | int i; |
| 323 | 321 | ||
| 324 | /* Make sure that gcc doesn't leave the empty loop body. */ | 322 | if (!plat_device_is_coherent(dev)) |
| 325 | for (i = 0; i < nelems; i++, sg++) { | 323 | for (i = 0; i < nelems; i++, sg++) |
| 326 | if (!plat_device_is_coherent(dev)) | ||
| 327 | __dma_sync(sg_page(sg), sg->offset, sg->length, | 324 | __dma_sync(sg_page(sg), sg->offset, sg->length, |
| 328 | direction); | 325 | direction); |
| 329 | } | ||
| 330 | } | 326 | } |
| 331 | 327 | ||
| 332 | int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 328 | int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h index eb59bfe23e85..93c9980e1b6b 100644 --- a/arch/openrisc/include/asm/prom.h +++ b/arch/openrisc/include/asm/prom.h | |||
| @@ -14,53 +14,9 @@ | |||
| 14 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
| 15 | * (at your option) any later version. | 15 | * (at your option) any later version. |
| 16 | */ | 16 | */ |
| 17 | |||
| 18 | #include <linux/of.h> /* linux/of.h gets to determine #include ordering */ | ||
| 19 | |||
| 20 | #ifndef _ASM_OPENRISC_PROM_H | 17 | #ifndef _ASM_OPENRISC_PROM_H |
| 21 | #define _ASM_OPENRISC_PROM_H | 18 | #define _ASM_OPENRISC_PROM_H |
| 22 | #ifdef __KERNEL__ | ||
| 23 | #ifndef __ASSEMBLY__ | ||
| 24 | 19 | ||
| 25 | #include <linux/types.h> | ||
| 26 | #include <asm/irq.h> | ||
| 27 | #include <linux/irqdomain.h> | ||
| 28 | #include <linux/atomic.h> | ||
| 29 | #include <linux/of_irq.h> | ||
| 30 | #include <linux/of_fdt.h> | ||
| 31 | #include <linux/of_address.h> | ||
| 32 | #include <linux/proc_fs.h> | ||
| 33 | #include <linux/platform_device.h> | ||
| 34 | #define HAVE_ARCH_DEVTREE_FIXUPS | 20 | #define HAVE_ARCH_DEVTREE_FIXUPS |
| 35 | 21 | ||
| 36 | /* Other Prototypes */ | ||
| 37 | extern int early_uartlite_console(void); | ||
| 38 | |||
| 39 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and | ||
| 40 | * size parameters. | ||
| 41 | */ | ||
| 42 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | ||
| 43 | unsigned long *busno, unsigned long *phys, unsigned long *size); | ||
| 44 | |||
| 45 | extern void kdump_move_device_tree(void); | ||
| 46 | |||
| 47 | /* Get the MAC address */ | ||
| 48 | extern const void *of_get_mac_address(struct device_node *np); | ||
| 49 | |||
| 50 | /** | ||
| 51 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
| 52 | * @pdev: the device whose interrupt is to be resolved | ||
| 53 | * @out_irq: structure of_irq filled by this function | ||
| 54 | * | ||
| 55 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
| 56 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
| 57 | * walking. If not, it will implement standard swizzling and walk up the | ||
| 58 | * PCI tree until an device-node is found, at which point it will finish | ||
| 59 | * resolving using the OF tree walking. | ||
| 60 | */ | ||
| 61 | struct pci_dev; | ||
| 62 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | ||
| 63 | |||
| 64 | #endif /* __ASSEMBLY__ */ | ||
| 65 | #endif /* __KERNEL__ */ | ||
| 66 | #endif /* _ASM_OPENRISC_PROM_H */ | 22 | #endif /* _ASM_OPENRISC_PROM_H */ |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 6a15c968d214..15ca2255f438 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
| @@ -74,7 +74,7 @@ src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c | |||
| 74 | src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c | 74 | src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c |
| 75 | src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c | 75 | src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c |
| 76 | 76 | ||
| 77 | src-plat-y := of.c | 77 | src-plat-y := of.c epapr.c |
| 78 | src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ | 78 | src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ |
| 79 | treeboot-walnut.c cuboot-acadia.c \ | 79 | treeboot-walnut.c cuboot-acadia.c \ |
| 80 | cuboot-kilauea.c simpleboot.c \ | 80 | cuboot-kilauea.c simpleboot.c \ |
| @@ -97,7 +97,7 @@ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \ | |||
| 97 | prpmc2800.c | 97 | prpmc2800.c |
| 98 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c | 98 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c |
| 99 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c | 99 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c |
| 100 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c | 100 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c |
| 101 | 101 | ||
| 102 | src-wlib := $(sort $(src-wlib-y)) | 102 | src-wlib := $(sort $(src-wlib-y)) |
| 103 | src-plat := $(sort $(src-plat-y)) | 103 | src-plat := $(sort $(src-plat-y)) |
diff --git a/arch/powerpc/boot/epapr-wrapper.c b/arch/powerpc/boot/epapr-wrapper.c new file mode 100644 index 000000000000..c10191006673 --- /dev/null +++ b/arch/powerpc/boot/epapr-wrapper.c | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | extern void epapr_platform_init(unsigned long r3, unsigned long r4, | ||
| 2 | unsigned long r5, unsigned long r6, | ||
| 3 | unsigned long r7); | ||
| 4 | |||
| 5 | void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | ||
| 6 | unsigned long r6, unsigned long r7) | ||
| 7 | { | ||
| 8 | epapr_platform_init(r3, r4, r5, r6, r7); | ||
| 9 | } | ||
diff --git a/arch/powerpc/boot/epapr.c b/arch/powerpc/boot/epapr.c index 06c1961bd124..02e91aa2194a 100644 --- a/arch/powerpc/boot/epapr.c +++ b/arch/powerpc/boot/epapr.c | |||
| @@ -48,8 +48,8 @@ static void platform_fixups(void) | |||
| 48 | fdt_addr, fdt_totalsize((void *)fdt_addr), ima_size); | 48 | fdt_addr, fdt_totalsize((void *)fdt_addr), ima_size); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 51 | void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
| 52 | unsigned long r6, unsigned long r7) | 52 | unsigned long r6, unsigned long r7) |
| 53 | { | 53 | { |
| 54 | epapr_magic = r6; | 54 | epapr_magic = r6; |
| 55 | ima_size = r7; | 55 | ima_size = r7; |
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c index 61d9899aa0d0..62e2f43ec1df 100644 --- a/arch/powerpc/boot/of.c +++ b/arch/powerpc/boot/of.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | 26 | ||
| 27 | static unsigned long claim_base; | 27 | static unsigned long claim_base; |
| 28 | 28 | ||
| 29 | void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | ||
| 30 | unsigned long r6, unsigned long r7); | ||
| 31 | |||
| 29 | static void *of_try_claim(unsigned long size) | 32 | static void *of_try_claim(unsigned long size) |
| 30 | { | 33 | { |
| 31 | unsigned long addr = 0; | 34 | unsigned long addr = 0; |
| @@ -61,7 +64,7 @@ static void of_image_hdr(const void *hdr) | |||
| 61 | } | 64 | } |
| 62 | } | 65 | } |
| 63 | 66 | ||
| 64 | void platform_init(unsigned long a1, unsigned long a2, void *promptr) | 67 | static void of_platform_init(unsigned long a1, unsigned long a2, void *promptr) |
| 65 | { | 68 | { |
| 66 | platform_ops.image_hdr = of_image_hdr; | 69 | platform_ops.image_hdr = of_image_hdr; |
| 67 | platform_ops.malloc = of_try_claim; | 70 | platform_ops.malloc = of_try_claim; |
| @@ -81,3 +84,14 @@ void platform_init(unsigned long a1, unsigned long a2, void *promptr) | |||
| 81 | loader_info.initrd_size = a2; | 84 | loader_info.initrd_size = a2; |
| 82 | } | 85 | } |
| 83 | } | 86 | } |
| 87 | |||
| 88 | void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | ||
| 89 | unsigned long r6, unsigned long r7) | ||
| 90 | { | ||
| 91 | /* Detect OF vs. ePAPR boot */ | ||
| 92 | if (r5) | ||
| 93 | of_platform_init(r3, r4, (void *)r5); | ||
| 94 | else | ||
| 95 | epapr_platform_init(r3, r4, r5, r6, r7); | ||
| 96 | } | ||
| 97 | |||
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 6761c746048d..cd7af841ba05 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
| @@ -148,18 +148,18 @@ make_space=y | |||
| 148 | 148 | ||
| 149 | case "$platform" in | 149 | case "$platform" in |
| 150 | pseries) | 150 | pseries) |
| 151 | platformo=$object/of.o | 151 | platformo="$object/of.o $object/epapr.o" |
| 152 | link_address='0x4000000' | 152 | link_address='0x4000000' |
| 153 | ;; | 153 | ;; |
| 154 | maple) | 154 | maple) |
| 155 | platformo=$object/of.o | 155 | platformo="$object/of.o $object/epapr.o" |
| 156 | link_address='0x400000' | 156 | link_address='0x400000' |
| 157 | ;; | 157 | ;; |
| 158 | pmac|chrp) | 158 | pmac|chrp) |
| 159 | platformo=$object/of.o | 159 | platformo="$object/of.o $object/epapr.o" |
| 160 | ;; | 160 | ;; |
| 161 | coff) | 161 | coff) |
| 162 | platformo="$object/crt0.o $object/of.o" | 162 | platformo="$object/crt0.o $object/of.o $object/epapr.o" |
| 163 | lds=$object/zImage.coff.lds | 163 | lds=$object/zImage.coff.lds |
| 164 | link_address='0x500000' | 164 | link_address='0x500000' |
| 165 | pie= | 165 | pie= |
| @@ -253,6 +253,7 @@ treeboot-iss4xx-mpic) | |||
| 253 | platformo="$object/treeboot-iss4xx.o" | 253 | platformo="$object/treeboot-iss4xx.o" |
| 254 | ;; | 254 | ;; |
| 255 | epapr) | 255 | epapr) |
| 256 | platformo="$object/epapr.o $object/epapr-wrapper.o" | ||
| 256 | link_address='0x20000000' | 257 | link_address='0x20000000' |
| 257 | pie=-pie | 258 | pie=-pie |
| 258 | ;; | 259 | ;; |
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index 0e40843a1c6e..41f13cec8a8f 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
| @@ -69,9 +69,9 @@ extern struct thread_info *softirq_ctx[NR_CPUS]; | |||
| 69 | 69 | ||
| 70 | extern void irq_ctx_init(void); | 70 | extern void irq_ctx_init(void); |
| 71 | extern void call_do_softirq(struct thread_info *tp); | 71 | extern void call_do_softirq(struct thread_info *tp); |
| 72 | extern int call_handle_irq(int irq, void *p1, | 72 | extern void call_do_irq(struct pt_regs *regs, struct thread_info *tp); |
| 73 | struct thread_info *tp, void *func); | ||
| 74 | extern void do_IRQ(struct pt_regs *regs); | 73 | extern void do_IRQ(struct pt_regs *regs); |
| 74 | extern void __do_irq(struct pt_regs *regs); | ||
| 75 | 75 | ||
| 76 | int irq_choose_cpu(const struct cpumask *mask); | 76 | int irq_choose_cpu(const struct cpumask *mask); |
| 77 | 77 | ||
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index e378cccfca55..ce4de5aed7b5 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
| @@ -149,8 +149,6 @@ typedef struct { | |||
| 149 | 149 | ||
| 150 | struct thread_struct { | 150 | struct thread_struct { |
| 151 | unsigned long ksp; /* Kernel stack pointer */ | 151 | unsigned long ksp; /* Kernel stack pointer */ |
| 152 | unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ | ||
| 153 | |||
| 154 | #ifdef CONFIG_PPC64 | 152 | #ifdef CONFIG_PPC64 |
| 155 | unsigned long ksp_vsid; | 153 | unsigned long ksp_vsid; |
| 156 | #endif | 154 | #endif |
| @@ -162,6 +160,7 @@ struct thread_struct { | |||
| 162 | #endif | 160 | #endif |
| 163 | #ifdef CONFIG_PPC32 | 161 | #ifdef CONFIG_PPC32 |
| 164 | void *pgdir; /* root of page-table tree */ | 162 | void *pgdir; /* root of page-table tree */ |
| 163 | unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ | ||
| 165 | #endif | 164 | #endif |
| 166 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 165 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
| 167 | /* | 166 | /* |
| @@ -321,7 +320,6 @@ struct thread_struct { | |||
| 321 | #else | 320 | #else |
| 322 | #define INIT_THREAD { \ | 321 | #define INIT_THREAD { \ |
| 323 | .ksp = INIT_SP, \ | 322 | .ksp = INIT_SP, \ |
| 324 | .ksp_limit = INIT_SP_LIMIT, \ | ||
| 325 | .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ | 323 | .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ |
| 326 | .fs = KERNEL_DS, \ | 324 | .fs = KERNEL_DS, \ |
| 327 | .fpr = {{0}}, \ | 325 | .fpr = {{0}}, \ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d8958be5f31a..502c7a4e73f7 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -80,10 +80,11 @@ int main(void) | |||
| 80 | DEFINE(TASKTHREADPPR, offsetof(struct task_struct, thread.ppr)); | 80 | DEFINE(TASKTHREADPPR, offsetof(struct task_struct, thread.ppr)); |
| 81 | #else | 81 | #else |
| 82 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); | 82 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); |
| 83 | DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16)); | ||
| 84 | DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit)); | ||
| 83 | #endif /* CONFIG_PPC64 */ | 85 | #endif /* CONFIG_PPC64 */ |
| 84 | 86 | ||
| 85 | DEFINE(KSP, offsetof(struct thread_struct, ksp)); | 87 | DEFINE(KSP, offsetof(struct thread_struct, ksp)); |
| 86 | DEFINE(KSP_LIMIT, offsetof(struct thread_struct, ksp_limit)); | ||
| 87 | DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); | 88 | DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); |
| 88 | #ifdef CONFIG_BOOKE | 89 | #ifdef CONFIG_BOOKE |
| 89 | DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); | 90 | DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0])); |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index c69440cef7af..57d286a78f86 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -441,50 +441,6 @@ void migrate_irqs(void) | |||
| 441 | } | 441 | } |
| 442 | #endif | 442 | #endif |
| 443 | 443 | ||
| 444 | static inline void handle_one_irq(unsigned int irq) | ||
| 445 | { | ||
| 446 | struct thread_info *curtp, *irqtp; | ||
| 447 | unsigned long saved_sp_limit; | ||
| 448 | struct irq_desc *desc; | ||
| 449 | |||
| 450 | desc = irq_to_desc(irq); | ||
| 451 | if (!desc) | ||
| 452 | return; | ||
| 453 | |||
| 454 | /* Switch to the irq stack to handle this */ | ||
| 455 | curtp = current_thread_info(); | ||
| 456 | irqtp = hardirq_ctx[smp_processor_id()]; | ||
| 457 | |||
| 458 | if (curtp == irqtp) { | ||
| 459 | /* We're already on the irq stack, just handle it */ | ||
| 460 | desc->handle_irq(irq, desc); | ||
| 461 | return; | ||
| 462 | } | ||
| 463 | |||
| 464 | saved_sp_limit = current->thread.ksp_limit; | ||
| 465 | |||
| 466 | irqtp->task = curtp->task; | ||
| 467 | irqtp->flags = 0; | ||
| 468 | |||
| 469 | /* Copy the softirq bits in preempt_count so that the | ||
| 470 | * softirq checks work in the hardirq context. */ | ||
| 471 | irqtp->preempt_count = (irqtp->preempt_count & ~SOFTIRQ_MASK) | | ||
| 472 | (curtp->preempt_count & SOFTIRQ_MASK); | ||
| 473 | |||
| 474 | current->thread.ksp_limit = (unsigned long)irqtp + | ||
| 475 | _ALIGN_UP(sizeof(struct thread_info), 16); | ||
| 476 | |||
| 477 | call_handle_irq(irq, desc, irqtp, desc->handle_irq); | ||
| 478 | current->thread.ksp_limit = saved_sp_limit; | ||
| 479 | irqtp->task = NULL; | ||
| 480 | |||
| 481 | /* Set any flag that may have been set on the | ||
| 482 | * alternate stack | ||
| 483 | */ | ||
| 484 | if (irqtp->flags) | ||
| 485 | set_bits(irqtp->flags, &curtp->flags); | ||
| 486 | } | ||
| 487 | |||
| 488 | static inline void check_stack_overflow(void) | 444 | static inline void check_stack_overflow(void) |
| 489 | { | 445 | { |
| 490 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 446 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
| @@ -501,9 +457,9 @@ static inline void check_stack_overflow(void) | |||
| 501 | #endif | 457 | #endif |
| 502 | } | 458 | } |
| 503 | 459 | ||
| 504 | void do_IRQ(struct pt_regs *regs) | 460 | void __do_irq(struct pt_regs *regs) |
| 505 | { | 461 | { |
| 506 | struct pt_regs *old_regs = set_irq_regs(regs); | 462 | struct irq_desc *desc; |
| 507 | unsigned int irq; | 463 | unsigned int irq; |
| 508 | 464 | ||
| 509 | irq_enter(); | 465 | irq_enter(); |
| @@ -519,18 +475,56 @@ void do_IRQ(struct pt_regs *regs) | |||
| 519 | */ | 475 | */ |
| 520 | irq = ppc_md.get_irq(); | 476 | irq = ppc_md.get_irq(); |
| 521 | 477 | ||
| 522 | /* We can hard enable interrupts now */ | 478 | /* We can hard enable interrupts now to allow perf interrupts */ |
| 523 | may_hard_irq_enable(); | 479 | may_hard_irq_enable(); |
| 524 | 480 | ||
| 525 | /* And finally process it */ | 481 | /* And finally process it */ |
| 526 | if (irq != NO_IRQ) | 482 | if (unlikely(irq == NO_IRQ)) |
| 527 | handle_one_irq(irq); | ||
| 528 | else | ||
| 529 | __get_cpu_var(irq_stat).spurious_irqs++; | 483 | __get_cpu_var(irq_stat).spurious_irqs++; |
| 484 | else { | ||
| 485 | desc = irq_to_desc(irq); | ||
| 486 | if (likely(desc)) | ||
| 487 | desc->handle_irq(irq, desc); | ||
| 488 | } | ||
| 530 | 489 | ||
| 531 | trace_irq_exit(regs); | 490 | trace_irq_exit(regs); |
| 532 | 491 | ||
| 533 | irq_exit(); | 492 | irq_exit(); |
| 493 | } | ||
| 494 | |||
| 495 | void do_IRQ(struct pt_regs *regs) | ||
| 496 | { | ||
| 497 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 498 | struct thread_info *curtp, *irqtp; | ||
| 499 | |||
| 500 | /* Switch to the irq stack to handle this */ | ||
| 501 | curtp = current_thread_info(); | ||
| 502 | irqtp = hardirq_ctx[raw_smp_processor_id()]; | ||
| 503 | |||
| 504 | /* Already there ? */ | ||
| 505 | if (unlikely(curtp == irqtp)) { | ||
| 506 | __do_irq(regs); | ||
| 507 | set_irq_regs(old_regs); | ||
| 508 | return; | ||
| 509 | } | ||
| 510 | |||
| 511 | /* Prepare the thread_info in the irq stack */ | ||
| 512 | irqtp->task = curtp->task; | ||
| 513 | irqtp->flags = 0; | ||
| 514 | |||
| 515 | /* Copy the preempt_count so that the [soft]irq checks work. */ | ||
| 516 | irqtp->preempt_count = curtp->preempt_count; | ||
| 517 | |||
| 518 | /* Switch stack and call */ | ||
| 519 | call_do_irq(regs, irqtp); | ||
| 520 | |||
| 521 | /* Restore stack limit */ | ||
| 522 | irqtp->task = NULL; | ||
| 523 | |||
| 524 | /* Copy back updates to the thread_info */ | ||
| 525 | if (irqtp->flags) | ||
| 526 | set_bits(irqtp->flags, &curtp->flags); | ||
| 527 | |||
| 534 | set_irq_regs(old_regs); | 528 | set_irq_regs(old_regs); |
| 535 | } | 529 | } |
| 536 | 530 | ||
| @@ -592,28 +586,22 @@ void irq_ctx_init(void) | |||
| 592 | memset((void *)softirq_ctx[i], 0, THREAD_SIZE); | 586 | memset((void *)softirq_ctx[i], 0, THREAD_SIZE); |
| 593 | tp = softirq_ctx[i]; | 587 | tp = softirq_ctx[i]; |
| 594 | tp->cpu = i; | 588 | tp->cpu = i; |
| 595 | tp->preempt_count = 0; | ||
| 596 | 589 | ||
| 597 | memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); | 590 | memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); |
| 598 | tp = hardirq_ctx[i]; | 591 | tp = hardirq_ctx[i]; |
| 599 | tp->cpu = i; | 592 | tp->cpu = i; |
| 600 | tp->preempt_count = HARDIRQ_OFFSET; | ||
| 601 | } | 593 | } |
| 602 | } | 594 | } |
| 603 | 595 | ||
| 604 | static inline void do_softirq_onstack(void) | 596 | static inline void do_softirq_onstack(void) |
| 605 | { | 597 | { |
| 606 | struct thread_info *curtp, *irqtp; | 598 | struct thread_info *curtp, *irqtp; |
| 607 | unsigned long saved_sp_limit = current->thread.ksp_limit; | ||
| 608 | 599 | ||
| 609 | curtp = current_thread_info(); | 600 | curtp = current_thread_info(); |
| 610 | irqtp = softirq_ctx[smp_processor_id()]; | 601 | irqtp = softirq_ctx[smp_processor_id()]; |
| 611 | irqtp->task = curtp->task; | 602 | irqtp->task = curtp->task; |
| 612 | irqtp->flags = 0; | 603 | irqtp->flags = 0; |
| 613 | current->thread.ksp_limit = (unsigned long)irqtp + | ||
| 614 | _ALIGN_UP(sizeof(struct thread_info), 16); | ||
| 615 | call_do_softirq(irqtp); | 604 | call_do_softirq(irqtp); |
| 616 | current->thread.ksp_limit = saved_sp_limit; | ||
| 617 | irqtp->task = NULL; | 605 | irqtp->task = NULL; |
| 618 | 606 | ||
| 619 | /* Set any flag that may have been set on the | 607 | /* Set any flag that may have been set on the |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 777d999f563b..2b0ad9845363 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -36,26 +36,41 @@ | |||
| 36 | 36 | ||
| 37 | .text | 37 | .text |
| 38 | 38 | ||
| 39 | /* | ||
| 40 | * We store the saved ksp_limit in the unused part | ||
| 41 | * of the STACK_FRAME_OVERHEAD | ||
| 42 | */ | ||
| 39 | _GLOBAL(call_do_softirq) | 43 | _GLOBAL(call_do_softirq) |
| 40 | mflr r0 | 44 | mflr r0 |
| 41 | stw r0,4(r1) | 45 | stw r0,4(r1) |
| 46 | lwz r10,THREAD+KSP_LIMIT(r2) | ||
| 47 | addi r11,r3,THREAD_INFO_GAP | ||
| 42 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) | 48 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r3) |
| 43 | mr r1,r3 | 49 | mr r1,r3 |
| 50 | stw r10,8(r1) | ||
| 51 | stw r11,THREAD+KSP_LIMIT(r2) | ||
| 44 | bl __do_softirq | 52 | bl __do_softirq |
| 53 | lwz r10,8(r1) | ||
| 45 | lwz r1,0(r1) | 54 | lwz r1,0(r1) |
| 46 | lwz r0,4(r1) | 55 | lwz r0,4(r1) |
| 56 | stw r10,THREAD+KSP_LIMIT(r2) | ||
| 47 | mtlr r0 | 57 | mtlr r0 |
| 48 | blr | 58 | blr |
| 49 | 59 | ||
| 50 | _GLOBAL(call_handle_irq) | 60 | _GLOBAL(call_do_irq) |
| 51 | mflr r0 | 61 | mflr r0 |
| 52 | stw r0,4(r1) | 62 | stw r0,4(r1) |
| 53 | mtctr r6 | 63 | lwz r10,THREAD+KSP_LIMIT(r2) |
| 54 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5) | 64 | addi r11,r3,THREAD_INFO_GAP |
| 55 | mr r1,r5 | 65 | stwu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) |
| 56 | bctrl | 66 | mr r1,r4 |
| 67 | stw r10,8(r1) | ||
| 68 | stw r11,THREAD+KSP_LIMIT(r2) | ||
| 69 | bl __do_irq | ||
| 70 | lwz r10,8(r1) | ||
| 57 | lwz r1,0(r1) | 71 | lwz r1,0(r1) |
| 58 | lwz r0,4(r1) | 72 | lwz r0,4(r1) |
| 73 | stw r10,THREAD+KSP_LIMIT(r2) | ||
| 59 | mtlr r0 | 74 | mtlr r0 |
| 60 | blr | 75 | blr |
| 61 | 76 | ||
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 971d7e78aff2..e59caf874d05 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
| @@ -40,14 +40,12 @@ _GLOBAL(call_do_softirq) | |||
| 40 | mtlr r0 | 40 | mtlr r0 |
| 41 | blr | 41 | blr |
| 42 | 42 | ||
| 43 | _GLOBAL(call_handle_irq) | 43 | _GLOBAL(call_do_irq) |
| 44 | ld r8,0(r6) | ||
| 45 | mflr r0 | 44 | mflr r0 |
| 46 | std r0,16(r1) | 45 | std r0,16(r1) |
| 47 | mtctr r8 | 46 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r4) |
| 48 | stdu r1,THREAD_SIZE-STACK_FRAME_OVERHEAD(r5) | 47 | mr r1,r4 |
| 49 | mr r1,r5 | 48 | bl .__do_irq |
| 50 | bctrl | ||
| 51 | ld r1,0(r1) | 49 | ld r1,0(r1) |
| 52 | ld r0,16(r1) | 50 | ld r0,16(r1) |
| 53 | mtlr r0 | 51 | mtlr r0 |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 6f428da53e20..96d2fdf3aa9e 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -1000,9 +1000,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
| 1000 | kregs = (struct pt_regs *) sp; | 1000 | kregs = (struct pt_regs *) sp; |
| 1001 | sp -= STACK_FRAME_OVERHEAD; | 1001 | sp -= STACK_FRAME_OVERHEAD; |
| 1002 | p->thread.ksp = sp; | 1002 | p->thread.ksp = sp; |
| 1003 | #ifdef CONFIG_PPC32 | ||
| 1003 | p->thread.ksp_limit = (unsigned long)task_stack_page(p) + | 1004 | p->thread.ksp_limit = (unsigned long)task_stack_page(p) + |
| 1004 | _ALIGN_UP(sizeof(struct thread_info), 16); | 1005 | _ALIGN_UP(sizeof(struct thread_info), 16); |
| 1005 | 1006 | #endif | |
| 1006 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 1007 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
| 1007 | p->thread.ptrace_bps[0] = NULL; | 1008 | p->thread.ptrace_bps[0] = NULL; |
| 1008 | #endif | 1009 | #endif |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 12e656ffe60e..5fe2842e8bab 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -196,6 +196,8 @@ static int __initdata mem_reserve_cnt; | |||
| 196 | 196 | ||
| 197 | static cell_t __initdata regbuf[1024]; | 197 | static cell_t __initdata regbuf[1024]; |
| 198 | 198 | ||
| 199 | static bool rtas_has_query_cpu_stopped; | ||
| 200 | |||
| 199 | 201 | ||
| 200 | /* | 202 | /* |
| 201 | * Error results ... some OF calls will return "-1" on error, some | 203 | * Error results ... some OF calls will return "-1" on error, some |
| @@ -1574,6 +1576,11 @@ static void __init prom_instantiate_rtas(void) | |||
| 1574 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", | 1576 | prom_setprop(rtas_node, "/rtas", "linux,rtas-entry", |
| 1575 | &val, sizeof(val)); | 1577 | &val, sizeof(val)); |
| 1576 | 1578 | ||
| 1579 | /* Check if it supports "query-cpu-stopped-state" */ | ||
| 1580 | if (prom_getprop(rtas_node, "query-cpu-stopped-state", | ||
| 1581 | &val, sizeof(val)) != PROM_ERROR) | ||
| 1582 | rtas_has_query_cpu_stopped = true; | ||
| 1583 | |||
| 1577 | #if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__) | 1584 | #if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__) |
| 1578 | /* PowerVN takeover hack */ | 1585 | /* PowerVN takeover hack */ |
| 1579 | prom_rtas_data = base; | 1586 | prom_rtas_data = base; |
| @@ -1815,6 +1822,18 @@ static void __init prom_hold_cpus(void) | |||
| 1815 | = (void *) LOW_ADDR(__secondary_hold_acknowledge); | 1822 | = (void *) LOW_ADDR(__secondary_hold_acknowledge); |
| 1816 | unsigned long secondary_hold = LOW_ADDR(__secondary_hold); | 1823 | unsigned long secondary_hold = LOW_ADDR(__secondary_hold); |
| 1817 | 1824 | ||
| 1825 | /* | ||
| 1826 | * On pseries, if RTAS supports "query-cpu-stopped-state", | ||
| 1827 | * we skip this stage, the CPUs will be started by the | ||
| 1828 | * kernel using RTAS. | ||
| 1829 | */ | ||
| 1830 | if ((of_platform == PLATFORM_PSERIES || | ||
| 1831 | of_platform == PLATFORM_PSERIES_LPAR) && | ||
| 1832 | rtas_has_query_cpu_stopped) { | ||
| 1833 | prom_printf("prom_hold_cpus: skipped\n"); | ||
| 1834 | return; | ||
| 1835 | } | ||
| 1836 | |||
| 1818 | prom_debug("prom_hold_cpus: start...\n"); | 1837 | prom_debug("prom_hold_cpus: start...\n"); |
| 1819 | prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); | 1838 | prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); |
| 1820 | prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); | 1839 | prom_debug(" 1) *spinloop = 0x%x\n", *spinloop); |
| @@ -3011,6 +3030,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 3011 | * On non-powermacs, put all CPUs in spin-loops. | 3030 | * On non-powermacs, put all CPUs in spin-loops. |
| 3012 | * | 3031 | * |
| 3013 | * PowerMacs use a different mechanism to spin CPUs | 3032 | * PowerMacs use a different mechanism to spin CPUs |
| 3033 | * | ||
| 3034 | * (This must be done after instanciating RTAS) | ||
| 3014 | */ | 3035 | */ |
| 3015 | if (of_platform != PLATFORM_POWERMAC && | 3036 | if (of_platform != PLATFORM_POWERMAC && |
| 3016 | of_platform != PLATFORM_OPAL) | 3037 | of_platform != PLATFORM_OPAL) |
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index a7ee978fb860..b1faa1593c90 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c | |||
| @@ -1505,6 +1505,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 1505 | */ | 1505 | */ |
| 1506 | if ((ra == 1) && !(regs->msr & MSR_PR) \ | 1506 | if ((ra == 1) && !(regs->msr & MSR_PR) \ |
| 1507 | && (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) { | 1507 | && (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) { |
| 1508 | #ifdef CONFIG_PPC32 | ||
| 1508 | /* | 1509 | /* |
| 1509 | * Check if we will touch kernel sack overflow | 1510 | * Check if we will touch kernel sack overflow |
| 1510 | */ | 1511 | */ |
| @@ -1513,7 +1514,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) | |||
| 1513 | err = -EINVAL; | 1514 | err = -EINVAL; |
| 1514 | break; | 1515 | break; |
| 1515 | } | 1516 | } |
| 1516 | 1517 | #endif /* CONFIG_PPC32 */ | |
| 1517 | /* | 1518 | /* |
| 1518 | * Check if we already set since that means we'll | 1519 | * Check if we already set since that means we'll |
| 1519 | * lose the previous value. | 1520 | * lose the previous value. |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 1c1771a40250..24f58cb0a543 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -233,18 +233,24 @@ static void __init smp_init_pseries(void) | |||
| 233 | 233 | ||
| 234 | alloc_bootmem_cpumask_var(&of_spin_mask); | 234 | alloc_bootmem_cpumask_var(&of_spin_mask); |
| 235 | 235 | ||
| 236 | /* Mark threads which are still spinning in hold loops. */ | 236 | /* |
| 237 | if (cpu_has_feature(CPU_FTR_SMT)) { | 237 | * Mark threads which are still spinning in hold loops |
| 238 | for_each_present_cpu(i) { | 238 | * |
| 239 | if (cpu_thread_in_core(i) == 0) | 239 | * We know prom_init will not have started them if RTAS supports |
| 240 | cpumask_set_cpu(i, of_spin_mask); | 240 | * query-cpu-stopped-state. |
| 241 | } | 241 | */ |
| 242 | } else { | 242 | if (rtas_token("query-cpu-stopped-state") == RTAS_UNKNOWN_SERVICE) { |
| 243 | cpumask_copy(of_spin_mask, cpu_present_mask); | 243 | if (cpu_has_feature(CPU_FTR_SMT)) { |
| 244 | for_each_present_cpu(i) { | ||
| 245 | if (cpu_thread_in_core(i) == 0) | ||
| 246 | cpumask_set_cpu(i, of_spin_mask); | ||
| 247 | } | ||
| 248 | } else | ||
| 249 | cpumask_copy(of_spin_mask, cpu_present_mask); | ||
| 250 | |||
| 251 | cpumask_clear_cpu(boot_cpuid, of_spin_mask); | ||
| 244 | } | 252 | } |
| 245 | 253 | ||
| 246 | cpumask_clear_cpu(boot_cpuid, of_spin_mask); | ||
| 247 | |||
| 248 | /* Non-lpar has additional take/give timebase */ | 254 | /* Non-lpar has additional take/give timebase */ |
| 249 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | 255 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { |
| 250 | smp_ops->give_timebase = rtas_give_timebase; | 256 | smp_ops->give_timebase = rtas_give_timebase; |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index dcc6ac2d8026..7143793859fa 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -93,6 +93,7 @@ config S390 | |||
| 93 | select ARCH_INLINE_WRITE_UNLOCK_IRQ | 93 | select ARCH_INLINE_WRITE_UNLOCK_IRQ |
| 94 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE | 94 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE |
| 95 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION | 95 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION |
| 96 | select ARCH_USE_CMPXCHG_LOCKREF | ||
| 96 | select ARCH_WANT_IPC_PARSE_VERSION | 97 | select ARCH_WANT_IPC_PARSE_VERSION |
| 97 | select BUILDTIME_EXTABLE_SORT | 98 | select BUILDTIME_EXTABLE_SORT |
| 98 | select CLONE_BACKWARDS2 | 99 | select CLONE_BACKWARDS2 |
| @@ -102,7 +103,6 @@ config S390 | |||
| 102 | select GENERIC_TIME_VSYSCALL_OLD | 103 | select GENERIC_TIME_VSYSCALL_OLD |
| 103 | select HAVE_ALIGNED_STRUCT_PAGE if SLUB | 104 | select HAVE_ALIGNED_STRUCT_PAGE if SLUB |
| 104 | select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 | 105 | select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 |
| 105 | select HAVE_ARCH_MUTEX_CPU_RELAX | ||
| 106 | select HAVE_ARCH_SECCOMP_FILTER | 106 | select HAVE_ARCH_SECCOMP_FILTER |
| 107 | select HAVE_ARCH_TRACEHOOK | 107 | select HAVE_ARCH_TRACEHOOK |
| 108 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT | 108 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT |
diff --git a/arch/s390/include/asm/mutex.h b/arch/s390/include/asm/mutex.h index 688271f5f2e4..458c1f7fbc18 100644 --- a/arch/s390/include/asm/mutex.h +++ b/arch/s390/include/asm/mutex.h | |||
| @@ -7,5 +7,3 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <asm-generic/mutex-dec.h> | 9 | #include <asm-generic/mutex-dec.h> |
| 10 | |||
| 11 | #define arch_mutex_cpu_relax() barrier() | ||
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 0eb37505cab1..ca7821f07260 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -198,6 +198,8 @@ static inline void cpu_relax(void) | |||
| 198 | barrier(); | 198 | barrier(); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | #define arch_mutex_cpu_relax() barrier() | ||
| 202 | |||
| 201 | static inline void psw_set_key(unsigned int key) | 203 | static inline void psw_set_key(unsigned int key) |
| 202 | { | 204 | { |
| 203 | asm volatile("spka 0(%0)" : : "d" (key)); | 205 | asm volatile("spka 0(%0)" : : "d" (key)); |
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index 701fe8c59e1f..83e5d216105e 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h | |||
| @@ -44,6 +44,11 @@ extern void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); | |||
| 44 | extern int arch_spin_trylock_retry(arch_spinlock_t *); | 44 | extern int arch_spin_trylock_retry(arch_spinlock_t *); |
| 45 | extern void arch_spin_relax(arch_spinlock_t *lock); | 45 | extern void arch_spin_relax(arch_spinlock_t *lock); |
| 46 | 46 | ||
| 47 | static inline int arch_spin_value_unlocked(arch_spinlock_t lock) | ||
| 48 | { | ||
| 49 | return lock.owner_cpu == 0; | ||
| 50 | } | ||
| 51 | |||
| 47 | static inline void arch_spin_lock(arch_spinlock_t *lp) | 52 | static inline void arch_spin_lock(arch_spinlock_t *lp) |
| 48 | { | 53 | { |
| 49 | int old; | 54 | int old; |
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 6aef9fbc09b7..b913915e8e63 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h | |||
| @@ -79,30 +79,38 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn) | |||
| 79 | return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY; | 79 | return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static inline unsigned long mfn_to_pfn(unsigned long mfn) | 82 | static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn) |
| 83 | { | 83 | { |
| 84 | unsigned long pfn; | 84 | unsigned long pfn; |
| 85 | int ret = 0; | 85 | int ret; |
| 86 | 86 | ||
| 87 | if (xen_feature(XENFEAT_auto_translated_physmap)) | 87 | if (xen_feature(XENFEAT_auto_translated_physmap)) |
| 88 | return mfn; | 88 | return mfn; |
| 89 | 89 | ||
| 90 | if (unlikely(mfn >= machine_to_phys_nr)) { | 90 | if (unlikely(mfn >= machine_to_phys_nr)) |
| 91 | pfn = ~0; | 91 | return ~0; |
| 92 | goto try_override; | 92 | |
| 93 | } | ||
| 94 | pfn = 0; | ||
| 95 | /* | 93 | /* |
| 96 | * The array access can fail (e.g., device space beyond end of RAM). | 94 | * The array access can fail (e.g., device space beyond end of RAM). |
| 97 | * In such cases it doesn't matter what we return (we return garbage), | 95 | * In such cases it doesn't matter what we return (we return garbage), |
| 98 | * but we must handle the fault without crashing! | 96 | * but we must handle the fault without crashing! |
| 99 | */ | 97 | */ |
| 100 | ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); | 98 | ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); |
| 101 | try_override: | ||
| 102 | /* ret might be < 0 if there are no entries in the m2p for mfn */ | ||
| 103 | if (ret < 0) | 99 | if (ret < 0) |
| 104 | pfn = ~0; | 100 | return ~0; |
| 105 | else if (get_phys_to_machine(pfn) != mfn) | 101 | |
| 102 | return pfn; | ||
| 103 | } | ||
| 104 | |||
| 105 | static inline unsigned long mfn_to_pfn(unsigned long mfn) | ||
| 106 | { | ||
| 107 | unsigned long pfn; | ||
| 108 | |||
| 109 | if (xen_feature(XENFEAT_auto_translated_physmap)) | ||
| 110 | return mfn; | ||
| 111 | |||
| 112 | pfn = mfn_to_pfn_no_overrides(mfn); | ||
| 113 | if (get_phys_to_machine(pfn) != mfn) { | ||
| 106 | /* | 114 | /* |
| 107 | * If this appears to be a foreign mfn (because the pfn | 115 | * If this appears to be a foreign mfn (because the pfn |
| 108 | * doesn't map back to the mfn), then check the local override | 116 | * doesn't map back to the mfn), then check the local override |
| @@ -111,6 +119,7 @@ try_override: | |||
| 111 | * m2p_find_override_pfn returns ~0 if it doesn't find anything. | 119 | * m2p_find_override_pfn returns ~0 if it doesn't find anything. |
| 112 | */ | 120 | */ |
| 113 | pfn = m2p_find_override_pfn(mfn, ~0); | 121 | pfn = m2p_find_override_pfn(mfn, ~0); |
| 122 | } | ||
| 114 | 123 | ||
| 115 | /* | 124 | /* |
| 116 | * pfn is ~0 if there are no entries in the m2p for mfn or if the | 125 | * pfn is ~0 if there are no entries in the m2p for mfn or if the |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index a9c606bb4945..897783b3302a 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1506,7 +1506,7 @@ static int __init init_hw_perf_events(void) | |||
| 1506 | err = amd_pmu_init(); | 1506 | err = amd_pmu_init(); |
| 1507 | break; | 1507 | break; |
| 1508 | default: | 1508 | default: |
| 1509 | return 0; | 1509 | err = -ENOTSUPP; |
| 1510 | } | 1510 | } |
| 1511 | if (err != 0) { | 1511 | if (err != 0) { |
| 1512 | pr_cont("no PMU driver, software events only.\n"); | 1512 | pr_cont("no PMU driver, software events only.\n"); |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 8b901e8d782d..a61c7d5811be 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
| @@ -879,7 +879,6 @@ int m2p_add_override(unsigned long mfn, struct page *page, | |||
| 879 | unsigned long uninitialized_var(address); | 879 | unsigned long uninitialized_var(address); |
| 880 | unsigned level; | 880 | unsigned level; |
| 881 | pte_t *ptep = NULL; | 881 | pte_t *ptep = NULL; |
| 882 | int ret = 0; | ||
| 883 | 882 | ||
| 884 | pfn = page_to_pfn(page); | 883 | pfn = page_to_pfn(page); |
| 885 | if (!PageHighMem(page)) { | 884 | if (!PageHighMem(page)) { |
| @@ -926,8 +925,8 @@ int m2p_add_override(unsigned long mfn, struct page *page, | |||
| 926 | * frontend pages while they are being shared with the backend, | 925 | * frontend pages while they are being shared with the backend, |
| 927 | * because mfn_to_pfn (that ends up being called by GUPF) will | 926 | * because mfn_to_pfn (that ends up being called by GUPF) will |
| 928 | * return the backend pfn rather than the frontend pfn. */ | 927 | * return the backend pfn rather than the frontend pfn. */ |
| 929 | ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); | 928 | pfn = mfn_to_pfn_no_overrides(mfn); |
| 930 | if (ret == 0 && get_phys_to_machine(pfn) == mfn) | 929 | if (get_phys_to_machine(pfn) == mfn) |
| 931 | set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); | 930 | set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); |
| 932 | 931 | ||
| 933 | return 0; | 932 | return 0; |
| @@ -942,7 +941,6 @@ int m2p_remove_override(struct page *page, | |||
| 942 | unsigned long uninitialized_var(address); | 941 | unsigned long uninitialized_var(address); |
| 943 | unsigned level; | 942 | unsigned level; |
| 944 | pte_t *ptep = NULL; | 943 | pte_t *ptep = NULL; |
| 945 | int ret = 0; | ||
| 946 | 944 | ||
| 947 | pfn = page_to_pfn(page); | 945 | pfn = page_to_pfn(page); |
| 948 | mfn = get_phys_to_machine(pfn); | 946 | mfn = get_phys_to_machine(pfn); |
| @@ -1029,8 +1027,8 @@ int m2p_remove_override(struct page *page, | |||
| 1029 | * the original pfn causes mfn_to_pfn(mfn) to return the frontend | 1027 | * the original pfn causes mfn_to_pfn(mfn) to return the frontend |
| 1030 | * pfn again. */ | 1028 | * pfn again. */ |
| 1031 | mfn &= ~FOREIGN_FRAME_BIT; | 1029 | mfn &= ~FOREIGN_FRAME_BIT; |
| 1032 | ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); | 1030 | pfn = mfn_to_pfn_no_overrides(mfn); |
| 1033 | if (ret == 0 && get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) && | 1031 | if (get_phys_to_machine(pfn) == FOREIGN_FRAME(mfn) && |
| 1034 | m2p_find_override(mfn) == NULL) | 1032 | m2p_find_override(mfn) == NULL) |
| 1035 | set_phys_to_machine(pfn, mfn); | 1033 | set_phys_to_machine(pfn, mfn); |
| 1036 | 1034 | ||
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 253f63fceea1..be6b86078957 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
| @@ -259,6 +259,14 @@ void xen_uninit_lock_cpu(int cpu) | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | 261 | ||
| 262 | /* | ||
| 263 | * Our init of PV spinlocks is split in two init functions due to us | ||
| 264 | * using paravirt patching and jump labels patching and having to do | ||
| 265 | * all of this before SMP code is invoked. | ||
| 266 | * | ||
| 267 | * The paravirt patching needs to be done _before_ the alternative asm code | ||
| 268 | * is started, otherwise we would not patch the core kernel code. | ||
| 269 | */ | ||
| 262 | void __init xen_init_spinlocks(void) | 270 | void __init xen_init_spinlocks(void) |
| 263 | { | 271 | { |
| 264 | 272 | ||
| @@ -267,12 +275,26 @@ void __init xen_init_spinlocks(void) | |||
| 267 | return; | 275 | return; |
| 268 | } | 276 | } |
| 269 | 277 | ||
| 270 | static_key_slow_inc(¶virt_ticketlocks_enabled); | ||
| 271 | |||
| 272 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); | 278 | pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); |
| 273 | pv_lock_ops.unlock_kick = xen_unlock_kick; | 279 | pv_lock_ops.unlock_kick = xen_unlock_kick; |
| 274 | } | 280 | } |
| 275 | 281 | ||
| 282 | /* | ||
| 283 | * While the jump_label init code needs to happend _after_ the jump labels are | ||
| 284 | * enabled and before SMP is started. Hence we use pre-SMP initcall level | ||
| 285 | * init. We cannot do it in xen_init_spinlocks as that is done before | ||
| 286 | * jump labels are activated. | ||
| 287 | */ | ||
| 288 | static __init int xen_init_spinlocks_jump(void) | ||
| 289 | { | ||
| 290 | if (!xen_pvspin) | ||
| 291 | return 0; | ||
| 292 | |||
| 293 | static_key_slow_inc(¶virt_ticketlocks_enabled); | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | early_initcall(xen_init_spinlocks_jump); | ||
| 297 | |||
| 276 | static __init int xen_parse_nopvspin(char *arg) | 298 | static __init int xen_parse_nopvspin(char *arg) |
| 277 | { | 299 | { |
| 278 | xen_pvspin = false; | 300 | xen_pvspin = false; |
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index f40acef80269..a6977e12d574 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/ipmi.h> | 39 | #include <linux/ipmi.h> |
| 40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
| 41 | #include <linux/pnp.h> | 41 | #include <linux/pnp.h> |
| 42 | #include <linux/spinlock.h> | ||
| 42 | 43 | ||
| 43 | MODULE_AUTHOR("Zhao Yakui"); | 44 | MODULE_AUTHOR("Zhao Yakui"); |
| 44 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); | 45 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); |
| @@ -57,7 +58,7 @@ struct acpi_ipmi_device { | |||
| 57 | struct list_head head; | 58 | struct list_head head; |
| 58 | /* the IPMI request message list */ | 59 | /* the IPMI request message list */ |
| 59 | struct list_head tx_msg_list; | 60 | struct list_head tx_msg_list; |
| 60 | struct mutex tx_msg_lock; | 61 | spinlock_t tx_msg_lock; |
| 61 | acpi_handle handle; | 62 | acpi_handle handle; |
| 62 | struct pnp_dev *pnp_dev; | 63 | struct pnp_dev *pnp_dev; |
| 63 | ipmi_user_t user_interface; | 64 | ipmi_user_t user_interface; |
| @@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
| 147 | struct kernel_ipmi_msg *msg; | 148 | struct kernel_ipmi_msg *msg; |
| 148 | struct acpi_ipmi_buffer *buffer; | 149 | struct acpi_ipmi_buffer *buffer; |
| 149 | struct acpi_ipmi_device *device; | 150 | struct acpi_ipmi_device *device; |
| 151 | unsigned long flags; | ||
| 150 | 152 | ||
| 151 | msg = &tx_msg->tx_message; | 153 | msg = &tx_msg->tx_message; |
| 152 | /* | 154 | /* |
| @@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
| 177 | 179 | ||
| 178 | /* Get the msgid */ | 180 | /* Get the msgid */ |
| 179 | device = tx_msg->device; | 181 | device = tx_msg->device; |
| 180 | mutex_lock(&device->tx_msg_lock); | 182 | spin_lock_irqsave(&device->tx_msg_lock, flags); |
| 181 | device->curr_msgid++; | 183 | device->curr_msgid++; |
| 182 | tx_msg->tx_msgid = device->curr_msgid; | 184 | tx_msg->tx_msgid = device->curr_msgid; |
| 183 | mutex_unlock(&device->tx_msg_lock); | 185 | spin_unlock_irqrestore(&device->tx_msg_lock, flags); |
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, | 188 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, |
| @@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
| 242 | int msg_found = 0; | 244 | int msg_found = 0; |
| 243 | struct acpi_ipmi_msg *tx_msg; | 245 | struct acpi_ipmi_msg *tx_msg; |
| 244 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; | 246 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; |
| 247 | unsigned long flags; | ||
| 245 | 248 | ||
| 246 | if (msg->user != ipmi_device->user_interface) { | 249 | if (msg->user != ipmi_device->user_interface) { |
| 247 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " | 250 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " |
| @@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
| 250 | ipmi_free_recv_msg(msg); | 253 | ipmi_free_recv_msg(msg); |
| 251 | return; | 254 | return; |
| 252 | } | 255 | } |
| 253 | mutex_lock(&ipmi_device->tx_msg_lock); | 256 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
| 254 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { | 257 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { |
| 255 | if (msg->msgid == tx_msg->tx_msgid) { | 258 | if (msg->msgid == tx_msg->tx_msgid) { |
| 256 | msg_found = 1; | 259 | msg_found = 1; |
| @@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
| 258 | } | 261 | } |
| 259 | } | 262 | } |
| 260 | 263 | ||
| 261 | mutex_unlock(&ipmi_device->tx_msg_lock); | 264 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
| 262 | if (!msg_found) { | 265 | if (!msg_found) { |
| 263 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " | 266 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " |
| 264 | "returned.\n", msg->msgid); | 267 | "returned.\n", msg->msgid); |
| @@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
| 378 | struct acpi_ipmi_device *ipmi_device = handler_context; | 381 | struct acpi_ipmi_device *ipmi_device = handler_context; |
| 379 | int err, rem_time; | 382 | int err, rem_time; |
| 380 | acpi_status status; | 383 | acpi_status status; |
| 384 | unsigned long flags; | ||
| 381 | /* | 385 | /* |
| 382 | * IPMI opregion message. | 386 | * IPMI opregion message. |
| 383 | * IPMI message is firstly written to the BMC and system software | 387 | * IPMI message is firstly written to the BMC and system software |
| @@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
| 395 | return AE_NO_MEMORY; | 399 | return AE_NO_MEMORY; |
| 396 | 400 | ||
| 397 | acpi_format_ipmi_msg(tx_msg, address, value); | 401 | acpi_format_ipmi_msg(tx_msg, address, value); |
| 398 | mutex_lock(&ipmi_device->tx_msg_lock); | 402 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
| 399 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); | 403 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); |
| 400 | mutex_unlock(&ipmi_device->tx_msg_lock); | 404 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
| 401 | err = ipmi_request_settime(ipmi_device->user_interface, | 405 | err = ipmi_request_settime(ipmi_device->user_interface, |
| 402 | &tx_msg->addr, | 406 | &tx_msg->addr, |
| 403 | tx_msg->tx_msgid, | 407 | tx_msg->tx_msgid, |
| @@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
| 413 | status = AE_OK; | 417 | status = AE_OK; |
| 414 | 418 | ||
| 415 | end_label: | 419 | end_label: |
| 416 | mutex_lock(&ipmi_device->tx_msg_lock); | 420 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
| 417 | list_del(&tx_msg->head); | 421 | list_del(&tx_msg->head); |
| 418 | mutex_unlock(&ipmi_device->tx_msg_lock); | 422 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
| 419 | kfree(tx_msg); | 423 | kfree(tx_msg); |
| 420 | return status; | 424 | return status; |
| 421 | } | 425 | } |
| @@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) | |||
| 457 | 461 | ||
| 458 | INIT_LIST_HEAD(&ipmi_device->head); | 462 | INIT_LIST_HEAD(&ipmi_device->head); |
| 459 | 463 | ||
| 460 | mutex_init(&ipmi_device->tx_msg_lock); | 464 | spin_lock_init(&ipmi_device->tx_msg_lock); |
| 461 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); | 465 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); |
| 462 | ipmi_install_space_handler(ipmi_device); | 466 | ipmi_install_space_handler(ipmi_device); |
| 463 | 467 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fbdb82e70d10..611ce9061dc5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -1121,7 +1121,7 @@ int acpi_bus_register_driver(struct acpi_driver *driver) | |||
| 1121 | EXPORT_SYMBOL(acpi_bus_register_driver); | 1121 | EXPORT_SYMBOL(acpi_bus_register_driver); |
| 1122 | 1122 | ||
| 1123 | /** | 1123 | /** |
| 1124 | * acpi_bus_unregister_driver - unregisters a driver with the APIC bus | 1124 | * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus |
| 1125 | * @driver: driver to unregister | 1125 | * @driver: driver to unregister |
| 1126 | * | 1126 | * |
| 1127 | * Unregisters a driver with the ACPI bus. Searches the namespace for all | 1127 | * Unregisters a driver with the ACPI bus. Searches the namespace for all |
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 7a7929ba2658..06189e55b4e5 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c | |||
| @@ -142,32 +142,6 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
| 142 | return length; | 142 | return length; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | ssize_t tpm_show_locality(struct device *dev, struct device_attribute *attr, | ||
| 146 | char *buf) | ||
| 147 | { | ||
| 148 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
| 149 | struct tpm_private *priv = TPM_VPRIV(chip); | ||
| 150 | u8 locality = priv->shr->locality; | ||
| 151 | |||
| 152 | return sprintf(buf, "%d\n", locality); | ||
| 153 | } | ||
| 154 | |||
| 155 | ssize_t tpm_store_locality(struct device *dev, struct device_attribute *attr, | ||
| 156 | const char *buf, size_t len) | ||
| 157 | { | ||
| 158 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
| 159 | struct tpm_private *priv = TPM_VPRIV(chip); | ||
| 160 | u8 val; | ||
| 161 | |||
| 162 | int rv = kstrtou8(buf, 0, &val); | ||
| 163 | if (rv) | ||
| 164 | return rv; | ||
| 165 | |||
| 166 | priv->shr->locality = val; | ||
| 167 | |||
| 168 | return len; | ||
| 169 | } | ||
| 170 | |||
| 171 | static const struct file_operations vtpm_ops = { | 145 | static const struct file_operations vtpm_ops = { |
| 172 | .owner = THIS_MODULE, | 146 | .owner = THIS_MODULE, |
| 173 | .llseek = no_llseek, | 147 | .llseek = no_llseek, |
| @@ -188,8 +162,6 @@ static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | |||
| 188 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 162 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
| 189 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | 163 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); |
| 190 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | 164 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); |
| 191 | static DEVICE_ATTR(locality, S_IRUGO | S_IWUSR, tpm_show_locality, | ||
| 192 | tpm_store_locality); | ||
| 193 | 165 | ||
| 194 | static struct attribute *vtpm_attrs[] = { | 166 | static struct attribute *vtpm_attrs[] = { |
| 195 | &dev_attr_pubek.attr, | 167 | &dev_attr_pubek.attr, |
| @@ -202,7 +174,6 @@ static struct attribute *vtpm_attrs[] = { | |||
| 202 | &dev_attr_cancel.attr, | 174 | &dev_attr_cancel.attr, |
| 203 | &dev_attr_durations.attr, | 175 | &dev_attr_durations.attr, |
| 204 | &dev_attr_timeouts.attr, | 176 | &dev_attr_timeouts.attr, |
| 205 | &dev_attr_locality.attr, | ||
| 206 | NULL, | 177 | NULL, |
| 207 | }; | 178 | }; |
| 208 | 179 | ||
| @@ -210,8 +181,6 @@ static struct attribute_group vtpm_attr_grp = { | |||
| 210 | .attrs = vtpm_attrs, | 181 | .attrs = vtpm_attrs, |
| 211 | }; | 182 | }; |
| 212 | 183 | ||
| 213 | #define TPM_LONG_TIMEOUT (10 * 60 * HZ) | ||
| 214 | |||
| 215 | static const struct tpm_vendor_specific tpm_vtpm = { | 184 | static const struct tpm_vendor_specific tpm_vtpm = { |
| 216 | .status = vtpm_status, | 185 | .status = vtpm_status, |
| 217 | .recv = vtpm_recv, | 186 | .recv = vtpm_recv, |
| @@ -224,11 +193,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { | |||
| 224 | .miscdev = { | 193 | .miscdev = { |
| 225 | .fops = &vtpm_ops, | 194 | .fops = &vtpm_ops, |
| 226 | }, | 195 | }, |
| 227 | .duration = { | ||
| 228 | TPM_LONG_TIMEOUT, | ||
| 229 | TPM_LONG_TIMEOUT, | ||
| 230 | TPM_LONG_TIMEOUT, | ||
| 231 | }, | ||
| 232 | }; | 196 | }; |
| 233 | 197 | ||
| 234 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) | 198 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 41c69469ce20..971d796e071d 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
| @@ -26,6 +26,7 @@ config DW_APB_TIMER_OF | |||
| 26 | 26 | ||
| 27 | config ARMADA_370_XP_TIMER | 27 | config ARMADA_370_XP_TIMER |
| 28 | bool | 28 | bool |
| 29 | select CLKSRC_OF | ||
| 29 | 30 | ||
| 30 | config ORION_TIMER | 31 | config ORION_TIMER |
| 31 | select CLKSRC_OF | 32 | select CLKSRC_OF |
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 37f5325bec95..b9ddd9e3a2f5 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c | |||
| @@ -30,6 +30,9 @@ void __init clocksource_of_init(void) | |||
| 30 | clocksource_of_init_fn init_func; | 30 | clocksource_of_init_fn init_func; |
| 31 | 31 | ||
| 32 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { | 32 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { |
| 33 | if (!of_device_is_available(np)) | ||
| 34 | continue; | ||
| 35 | |||
| 33 | init_func = match->data; | 36 | init_func = match->data; |
| 34 | init_func(np); | 37 | init_func(np); |
| 35 | } | 38 | } |
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index b9c81b7c3a3b..3a5909c12d42 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c | |||
| @@ -301,7 +301,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p) | |||
| 301 | ced->name = dev_name(&p->pdev->dev); | 301 | ced->name = dev_name(&p->pdev->dev); |
| 302 | ced->features = CLOCK_EVT_FEAT_ONESHOT; | 302 | ced->features = CLOCK_EVT_FEAT_ONESHOT; |
| 303 | ced->rating = 200; | 303 | ced->rating = 200; |
| 304 | ced->cpumask = cpumask_of(0); | 304 | ced->cpumask = cpu_possible_mask; |
| 305 | ced->set_next_event = em_sti_clock_event_next; | 305 | ced->set_next_event = em_sti_clock_event_next; |
| 306 | ced->set_mode = em_sti_clock_event_mode; | 306 | ced->set_mode = em_sti_clock_event_mode; |
| 307 | 307 | ||
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 5b34768f4d7c..62b0de6a1837 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
| @@ -428,7 +428,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) | |||
| 428 | evt->irq); | 428 | evt->irq); |
| 429 | return -EIO; | 429 | return -EIO; |
| 430 | } | 430 | } |
| 431 | irq_set_affinity(evt->irq, cpumask_of(cpu)); | ||
| 432 | } else { | 431 | } else { |
| 433 | enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); | 432 | enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); |
| 434 | } | 433 | } |
| @@ -449,6 +448,7 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, | |||
| 449 | unsigned long action, void *hcpu) | 448 | unsigned long action, void *hcpu) |
| 450 | { | 449 | { |
| 451 | struct mct_clock_event_device *mevt; | 450 | struct mct_clock_event_device *mevt; |
| 451 | unsigned int cpu; | ||
| 452 | 452 | ||
| 453 | /* | 453 | /* |
| 454 | * Grab cpu pointer in each case to avoid spurious | 454 | * Grab cpu pointer in each case to avoid spurious |
| @@ -459,6 +459,12 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, | |||
| 459 | mevt = this_cpu_ptr(&percpu_mct_tick); | 459 | mevt = this_cpu_ptr(&percpu_mct_tick); |
| 460 | exynos4_local_timer_setup(&mevt->evt); | 460 | exynos4_local_timer_setup(&mevt->evt); |
| 461 | break; | 461 | break; |
| 462 | case CPU_ONLINE: | ||
| 463 | cpu = (unsigned long)hcpu; | ||
| 464 | if (mct_int_type == MCT_INT_SPI) | ||
| 465 | irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], | ||
| 466 | cpumask_of(cpu)); | ||
| 467 | break; | ||
| 462 | case CPU_DYING: | 468 | case CPU_DYING: |
| 463 | mevt = this_cpu_ptr(&percpu_mct_tick); | 469 | mevt = this_cpu_ptr(&percpu_mct_tick); |
| 464 | exynos4_local_timer_stop(&mevt->evt); | 470 | exynos4_local_timer_stop(&mevt->evt); |
| @@ -500,6 +506,8 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem | |||
| 500 | &percpu_mct_tick); | 506 | &percpu_mct_tick); |
| 501 | WARN(err, "MCT: can't request IRQ %d (%d)\n", | 507 | WARN(err, "MCT: can't request IRQ %d (%d)\n", |
| 502 | mct_irqs[MCT_L0_IRQ], err); | 508 | mct_irqs[MCT_L0_IRQ], err); |
| 509 | } else { | ||
| 510 | irq_set_affinity(mct_irqs[MCT_L0_IRQ], cpumask_of(0)); | ||
| 503 | } | 511 | } |
| 504 | 512 | ||
| 505 | err = register_cpu_notifier(&exynos4_mct_cpu_nb); | 513 | err = register_cpu_notifier(&exynos4_mct_cpu_nb); |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index a1260b4549db..d2c3253e015e 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -986,6 +986,10 @@ static int __init acpi_cpufreq_init(void) | |||
| 986 | { | 986 | { |
| 987 | int ret; | 987 | int ret; |
| 988 | 988 | ||
| 989 | /* don't keep reloading if cpufreq_driver exists */ | ||
| 990 | if (cpufreq_get_current_driver()) | ||
| 991 | return 0; | ||
| 992 | |||
| 989 | if (acpi_disabled) | 993 | if (acpi_disabled) |
| 990 | return 0; | 994 | return 0; |
| 991 | 995 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 89b3c52cd5c3..04548f7023af 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -1460,6 +1460,9 @@ unsigned int cpufreq_get(unsigned int cpu) | |||
| 1460 | { | 1460 | { |
| 1461 | unsigned int ret_freq = 0; | 1461 | unsigned int ret_freq = 0; |
| 1462 | 1462 | ||
| 1463 | if (cpufreq_disabled() || !cpufreq_driver) | ||
| 1464 | return -ENOENT; | ||
| 1465 | |||
| 1463 | if (!down_read_trylock(&cpufreq_rwsem)) | 1466 | if (!down_read_trylock(&cpufreq_rwsem)) |
| 1464 | return 0; | 1467 | return 0; |
| 1465 | 1468 | ||
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index d514c152fd1a..be5380ecdcd4 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
| @@ -457,7 +457,7 @@ err_free_table: | |||
| 457 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 457 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); |
| 458 | err_put_node: | 458 | err_put_node: |
| 459 | of_node_put(np); | 459 | of_node_put(np); |
| 460 | dev_err(dvfs_info->dev, "%s: failed initialization\n", __func__); | 460 | dev_err(&pdev->dev, "%s: failed initialization\n", __func__); |
| 461 | return ret; | 461 | return ret; |
| 462 | } | 462 | } |
| 463 | 463 | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 62c2e32e25ef..98814d12a604 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
| @@ -525,16 +525,25 @@ static int applesmc_init_smcreg_try(void) | |||
| 525 | { | 525 | { |
| 526 | struct applesmc_registers *s = &smcreg; | 526 | struct applesmc_registers *s = &smcreg; |
| 527 | bool left_light_sensor, right_light_sensor; | 527 | bool left_light_sensor, right_light_sensor; |
| 528 | unsigned int count; | ||
| 528 | u8 tmp[1]; | 529 | u8 tmp[1]; |
| 529 | int ret; | 530 | int ret; |
| 530 | 531 | ||
| 531 | if (s->init_complete) | 532 | if (s->init_complete) |
| 532 | return 0; | 533 | return 0; |
| 533 | 534 | ||
| 534 | ret = read_register_count(&s->key_count); | 535 | ret = read_register_count(&count); |
| 535 | if (ret) | 536 | if (ret) |
| 536 | return ret; | 537 | return ret; |
| 537 | 538 | ||
| 539 | if (s->cache && s->key_count != count) { | ||
| 540 | pr_warn("key count changed from %d to %d\n", | ||
| 541 | s->key_count, count); | ||
| 542 | kfree(s->cache); | ||
| 543 | s->cache = NULL; | ||
| 544 | } | ||
| 545 | s->key_count = count; | ||
| 546 | |||
| 538 | if (!s->cache) | 547 | if (!s->cache) |
| 539 | s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); | 548 | s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); |
| 540 | if (!s->cache) | 549 | if (!s->cache) |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index dbecf08399f8..5888feef1ac5 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
| @@ -98,6 +98,8 @@ | |||
| 98 | 98 | ||
| 99 | #define DW_IC_ERR_TX_ABRT 0x1 | 99 | #define DW_IC_ERR_TX_ABRT 0x1 |
| 100 | 100 | ||
| 101 | #define DW_IC_TAR_10BITADDR_MASTER BIT(12) | ||
| 102 | |||
| 101 | /* | 103 | /* |
| 102 | * status codes | 104 | * status codes |
| 103 | */ | 105 | */ |
| @@ -388,22 +390,34 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | |||
| 388 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | 390 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) |
| 389 | { | 391 | { |
| 390 | struct i2c_msg *msgs = dev->msgs; | 392 | struct i2c_msg *msgs = dev->msgs; |
| 391 | u32 ic_con; | 393 | u32 ic_con, ic_tar = 0; |
| 392 | 394 | ||
| 393 | /* Disable the adapter */ | 395 | /* Disable the adapter */ |
| 394 | __i2c_dw_enable(dev, false); | 396 | __i2c_dw_enable(dev, false); |
| 395 | 397 | ||
| 396 | /* set the slave (target) address */ | ||
| 397 | dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); | ||
| 398 | |||
| 399 | /* if the slave address is ten bit address, enable 10BITADDR */ | 398 | /* if the slave address is ten bit address, enable 10BITADDR */ |
| 400 | ic_con = dw_readl(dev, DW_IC_CON); | 399 | ic_con = dw_readl(dev, DW_IC_CON); |
| 401 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) | 400 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { |
| 402 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | 401 | ic_con |= DW_IC_CON_10BITADDR_MASTER; |
| 403 | else | 402 | /* |
| 403 | * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing | ||
| 404 | * mode has to be enabled via bit 12 of IC_TAR register. | ||
| 405 | * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be | ||
| 406 | * detected from registers. | ||
| 407 | */ | ||
| 408 | ic_tar = DW_IC_TAR_10BITADDR_MASTER; | ||
| 409 | } else { | ||
| 404 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; | 410 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; |
| 411 | } | ||
| 412 | |||
| 405 | dw_writel(dev, ic_con, DW_IC_CON); | 413 | dw_writel(dev, ic_con, DW_IC_CON); |
| 406 | 414 | ||
| 415 | /* | ||
| 416 | * Set the slave (target) address and enable 10-bit addressing mode | ||
| 417 | * if applicable. | ||
| 418 | */ | ||
| 419 | dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); | ||
| 420 | |||
| 407 | /* Enable the adapter */ | 421 | /* Enable the adapter */ |
| 408 | __i2c_dw_enable(dev, true); | 422 | __i2c_dw_enable(dev, true); |
| 409 | 423 | ||
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 8ed79a086f85..1672effbcebb 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c | |||
| @@ -393,6 +393,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr, | |||
| 393 | 393 | ||
| 394 | desc = &priv->hw[priv->head]; | 394 | desc = &priv->hw[priv->head]; |
| 395 | 395 | ||
| 396 | /* Initialize the DMA buffer */ | ||
| 397 | memset(priv->dma_buffer, 0, sizeof(priv->dma_buffer)); | ||
| 398 | |||
| 396 | /* Initialize the descriptor */ | 399 | /* Initialize the descriptor */ |
| 397 | memset(desc, 0, sizeof(struct ismt_desc)); | 400 | memset(desc, 0, sizeof(struct ismt_desc)); |
| 398 | desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); | 401 | desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 7f3a47443494..d3e9cc3153a9 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
| @@ -234,9 +234,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) | |||
| 234 | ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | | 234 | ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | |
| 235 | (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; | 235 | (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; |
| 236 | 236 | ||
| 237 | writel_relaxed(data_reg_lo, | 237 | writel(data_reg_lo, |
| 238 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); | 238 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); |
| 239 | writel_relaxed(data_reg_hi, | 239 | writel(data_reg_hi, |
| 240 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); | 240 | drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); |
| 241 | 241 | ||
| 242 | } else { | 242 | } else { |
| @@ -697,6 +697,7 @@ static const struct of_device_id mv64xxx_i2c_of_match_table[] = { | |||
| 697 | MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); | 697 | MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); |
| 698 | 698 | ||
| 699 | #ifdef CONFIG_OF | 699 | #ifdef CONFIG_OF |
| 700 | #ifdef CONFIG_HAVE_CLK | ||
| 700 | static int | 701 | static int |
| 701 | mv64xxx_calc_freq(const int tclk, const int n, const int m) | 702 | mv64xxx_calc_freq(const int tclk, const int n, const int m) |
| 702 | { | 703 | { |
| @@ -726,16 +727,12 @@ mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n, | |||
| 726 | return false; | 727 | return false; |
| 727 | return true; | 728 | return true; |
| 728 | } | 729 | } |
| 730 | #endif /* CONFIG_HAVE_CLK */ | ||
| 729 | 731 | ||
| 730 | static int | 732 | static int |
| 731 | mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, | 733 | mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, |
| 732 | struct device *dev) | 734 | struct device *dev) |
| 733 | { | 735 | { |
| 734 | const struct of_device_id *device; | ||
| 735 | struct device_node *np = dev->of_node; | ||
| 736 | u32 bus_freq, tclk; | ||
| 737 | int rc = 0; | ||
| 738 | |||
| 739 | /* CLK is mandatory when using DT to describe the i2c bus. We | 736 | /* CLK is mandatory when using DT to describe the i2c bus. We |
| 740 | * need to know tclk in order to calculate bus clock | 737 | * need to know tclk in order to calculate bus clock |
| 741 | * factors. | 738 | * factors. |
| @@ -744,6 +741,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, | |||
| 744 | /* Have OF but no CLK */ | 741 | /* Have OF but no CLK */ |
| 745 | return -ENODEV; | 742 | return -ENODEV; |
| 746 | #else | 743 | #else |
| 744 | const struct of_device_id *device; | ||
| 745 | struct device_node *np = dev->of_node; | ||
| 746 | u32 bus_freq, tclk; | ||
| 747 | int rc = 0; | ||
| 748 | |||
| 747 | if (IS_ERR(drv_data->clk)) { | 749 | if (IS_ERR(drv_data->clk)) { |
| 748 | rc = -ENODEV; | 750 | rc = -ENODEV; |
| 749 | goto out; | 751 | goto out; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3535f3c0f7b4..3747b9bf67d6 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
| @@ -1178,8 +1178,6 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) | |||
| 1178 | 1178 | ||
| 1179 | i2c_del_adapter(&i2c->adap); | 1179 | i2c_del_adapter(&i2c->adap); |
| 1180 | 1180 | ||
| 1181 | clk_disable_unprepare(i2c->clk); | ||
| 1182 | |||
| 1183 | if (pdev->dev.of_node && IS_ERR(i2c->pctrl)) | 1181 | if (pdev->dev.of_node && IS_ERR(i2c->pctrl)) |
| 1184 | s3c24xx_i2c_dt_gpio_free(i2c); | 1182 | s3c24xx_i2c_dt_gpio_free(i2c); |
| 1185 | 1183 | ||
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ea49834377c8..2a20986a2fec 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | #define DM_MSG_PREFIX "io" | 19 | #define DM_MSG_PREFIX "io" |
| 20 | 20 | ||
| 21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG | 21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG |
| 22 | #define MIN_IOS 16 | ||
| 23 | #define MIN_BIOS 16 | ||
| 24 | 22 | ||
| 25 | struct dm_io_client { | 23 | struct dm_io_client { |
| 26 | mempool_t *pool; | 24 | mempool_t *pool; |
| @@ -50,16 +48,17 @@ static struct kmem_cache *_dm_io_cache; | |||
| 50 | struct dm_io_client *dm_io_client_create(void) | 48 | struct dm_io_client *dm_io_client_create(void) |
| 51 | { | 49 | { |
| 52 | struct dm_io_client *client; | 50 | struct dm_io_client *client; |
| 51 | unsigned min_ios = dm_get_reserved_bio_based_ios(); | ||
| 53 | 52 | ||
| 54 | client = kmalloc(sizeof(*client), GFP_KERNEL); | 53 | client = kmalloc(sizeof(*client), GFP_KERNEL); |
| 55 | if (!client) | 54 | if (!client) |
| 56 | return ERR_PTR(-ENOMEM); | 55 | return ERR_PTR(-ENOMEM); |
| 57 | 56 | ||
| 58 | client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); | 57 | client->pool = mempool_create_slab_pool(min_ios, _dm_io_cache); |
| 59 | if (!client->pool) | 58 | if (!client->pool) |
| 60 | goto bad; | 59 | goto bad; |
| 61 | 60 | ||
| 62 | client->bios = bioset_create(MIN_BIOS, 0); | 61 | client->bios = bioset_create(min_ios, 0); |
| 63 | if (!client->bios) | 62 | if (!client->bios) |
| 64 | goto bad; | 63 | goto bad; |
| 65 | 64 | ||
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index b759a127f9c3..de570a558764 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/device-mapper.h> | 8 | #include <linux/device-mapper.h> |
| 9 | 9 | ||
| 10 | #include "dm.h" | ||
| 10 | #include "dm-path-selector.h" | 11 | #include "dm-path-selector.h" |
| 11 | #include "dm-uevent.h" | 12 | #include "dm-uevent.h" |
| 12 | 13 | ||
| @@ -116,8 +117,6 @@ struct dm_mpath_io { | |||
| 116 | 117 | ||
| 117 | typedef int (*action_fn) (struct pgpath *pgpath); | 118 | typedef int (*action_fn) (struct pgpath *pgpath); |
| 118 | 119 | ||
| 119 | #define MIN_IOS 256 /* Mempool size */ | ||
| 120 | |||
| 121 | static struct kmem_cache *_mpio_cache; | 120 | static struct kmem_cache *_mpio_cache; |
| 122 | 121 | ||
| 123 | static struct workqueue_struct *kmultipathd, *kmpath_handlerd; | 122 | static struct workqueue_struct *kmultipathd, *kmpath_handlerd; |
| @@ -190,6 +189,7 @@ static void free_priority_group(struct priority_group *pg, | |||
| 190 | static struct multipath *alloc_multipath(struct dm_target *ti) | 189 | static struct multipath *alloc_multipath(struct dm_target *ti) |
| 191 | { | 190 | { |
| 192 | struct multipath *m; | 191 | struct multipath *m; |
| 192 | unsigned min_ios = dm_get_reserved_rq_based_ios(); | ||
| 193 | 193 | ||
| 194 | m = kzalloc(sizeof(*m), GFP_KERNEL); | 194 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
| 195 | if (m) { | 195 | if (m) { |
| @@ -202,7 +202,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) | |||
| 202 | INIT_WORK(&m->trigger_event, trigger_event); | 202 | INIT_WORK(&m->trigger_event, trigger_event); |
| 203 | init_waitqueue_head(&m->pg_init_wait); | 203 | init_waitqueue_head(&m->pg_init_wait); |
| 204 | mutex_init(&m->work_mutex); | 204 | mutex_init(&m->work_mutex); |
| 205 | m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); | 205 | m->mpio_pool = mempool_create_slab_pool(min_ios, _mpio_cache); |
| 206 | if (!m->mpio_pool) { | 206 | if (!m->mpio_pool) { |
| 207 | kfree(m); | 207 | kfree(m); |
| 208 | return NULL; | 208 | return NULL; |
| @@ -1268,6 +1268,7 @@ static int noretry_error(int error) | |||
| 1268 | case -EREMOTEIO: | 1268 | case -EREMOTEIO: |
| 1269 | case -EILSEQ: | 1269 | case -EILSEQ: |
| 1270 | case -ENODATA: | 1270 | case -ENODATA: |
| 1271 | case -ENOSPC: | ||
| 1271 | return 1; | 1272 | return 1; |
| 1272 | } | 1273 | } |
| 1273 | 1274 | ||
| @@ -1298,8 +1299,17 @@ static int do_end_io(struct multipath *m, struct request *clone, | |||
| 1298 | if (!error && !clone->errors) | 1299 | if (!error && !clone->errors) |
| 1299 | return 0; /* I/O complete */ | 1300 | return 0; /* I/O complete */ |
| 1300 | 1301 | ||
| 1301 | if (noretry_error(error)) | 1302 | if (noretry_error(error)) { |
| 1303 | if ((clone->cmd_flags & REQ_WRITE_SAME) && | ||
| 1304 | !clone->q->limits.max_write_same_sectors) { | ||
| 1305 | struct queue_limits *limits; | ||
| 1306 | |||
| 1307 | /* device doesn't really support WRITE SAME, disable it */ | ||
| 1308 | limits = dm_get_queue_limits(dm_table_get_md(m->ti->table)); | ||
| 1309 | limits->max_write_same_sectors = 0; | ||
| 1310 | } | ||
| 1302 | return error; | 1311 | return error; |
| 1312 | } | ||
| 1303 | 1313 | ||
| 1304 | if (mpio->pgpath) | 1314 | if (mpio->pgpath) |
| 1305 | fail_path(mpio->pgpath); | 1315 | fail_path(mpio->pgpath); |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 3ac415675b6c..4caa8e6d59d7 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
| @@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, | |||
| 256 | */ | 256 | */ |
| 257 | INIT_WORK_ONSTACK(&req.work, do_metadata); | 257 | INIT_WORK_ONSTACK(&req.work, do_metadata); |
| 258 | queue_work(ps->metadata_wq, &req.work); | 258 | queue_work(ps->metadata_wq, &req.work); |
| 259 | flush_work(&req.work); | 259 | flush_workqueue(ps->metadata_wq); |
| 260 | 260 | ||
| 261 | return req.result; | 261 | return req.result; |
| 262 | } | 262 | } |
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c434e5aab2df..aec57d76db5d 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
| @@ -725,17 +725,16 @@ static int calc_max_buckets(void) | |||
| 725 | */ | 725 | */ |
| 726 | static int init_hash_tables(struct dm_snapshot *s) | 726 | static int init_hash_tables(struct dm_snapshot *s) |
| 727 | { | 727 | { |
| 728 | sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; | 728 | sector_t hash_size, cow_dev_size, max_buckets; |
| 729 | 729 | ||
| 730 | /* | 730 | /* |
| 731 | * Calculate based on the size of the original volume or | 731 | * Calculate based on the size of the original volume or |
| 732 | * the COW volume... | 732 | * the COW volume... |
| 733 | */ | 733 | */ |
| 734 | cow_dev_size = get_dev_size(s->cow->bdev); | 734 | cow_dev_size = get_dev_size(s->cow->bdev); |
| 735 | origin_dev_size = get_dev_size(s->origin->bdev); | ||
| 736 | max_buckets = calc_max_buckets(); | 735 | max_buckets = calc_max_buckets(); |
| 737 | 736 | ||
| 738 | hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; | 737 | hash_size = cow_dev_size >> s->store->chunk_shift; |
| 739 | hash_size = min(hash_size, max_buckets); | 738 | hash_size = min(hash_size, max_buckets); |
| 740 | 739 | ||
| 741 | if (hash_size < 64) | 740 | if (hash_size < 64) |
diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 8ae31e8d3d64..3d404c1371ed 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c | |||
| @@ -451,19 +451,26 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, | |||
| 451 | struct dm_stat_percpu *p; | 451 | struct dm_stat_percpu *p; |
| 452 | 452 | ||
| 453 | /* | 453 | /* |
| 454 | * For strict correctness we should use local_irq_disable/enable | 454 | * For strict correctness we should use local_irq_save/restore |
| 455 | * instead of preempt_disable/enable. | 455 | * instead of preempt_disable/enable. |
| 456 | * | 456 | * |
| 457 | * This is racy if the driver finishes bios from non-interrupt | 457 | * preempt_disable/enable is racy if the driver finishes bios |
| 458 | * context as well as from interrupt context or from more different | 458 | * from non-interrupt context as well as from interrupt context |
| 459 | * interrupts. | 459 | * or from more different interrupts. |
| 460 | * | 460 | * |
| 461 | * However, the race only results in not counting some events, | 461 | * On 64-bit architectures the race only results in not counting some |
| 462 | * so it is acceptable. | 462 | * events, so it is acceptable. On 32-bit architectures the race could |
| 463 | * cause the counter going off by 2^32, so we need to do proper locking | ||
| 464 | * there. | ||
| 463 | * | 465 | * |
| 464 | * part_stat_lock()/part_stat_unlock() have this race too. | 466 | * part_stat_lock()/part_stat_unlock() have this race too. |
| 465 | */ | 467 | */ |
| 468 | #if BITS_PER_LONG == 32 | ||
| 469 | unsigned long flags; | ||
| 470 | local_irq_save(flags); | ||
| 471 | #else | ||
| 466 | preempt_disable(); | 472 | preempt_disable(); |
| 473 | #endif | ||
| 467 | p = &s->stat_percpu[smp_processor_id()][entry]; | 474 | p = &s->stat_percpu[smp_processor_id()][entry]; |
| 468 | 475 | ||
| 469 | if (!end) { | 476 | if (!end) { |
| @@ -478,7 +485,11 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, | |||
| 478 | p->ticks[idx] += duration; | 485 | p->ticks[idx] += duration; |
| 479 | } | 486 | } |
| 480 | 487 | ||
| 488 | #if BITS_PER_LONG == 32 | ||
| 489 | local_irq_restore(flags); | ||
| 490 | #else | ||
| 481 | preempt_enable(); | 491 | preempt_enable(); |
| 492 | #endif | ||
| 482 | } | 493 | } |
| 483 | 494 | ||
| 484 | static void __dm_stat_bio(struct dm_stat *s, unsigned long bi_rw, | 495 | static void __dm_stat_bio(struct dm_stat *s, unsigned long bi_rw, |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ed063427d676..2c0cf511ec23 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -2095,6 +2095,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
| 2095 | * them down to the data device. The thin device's discard | 2095 | * them down to the data device. The thin device's discard |
| 2096 | * processing will cause mappings to be removed from the btree. | 2096 | * processing will cause mappings to be removed from the btree. |
| 2097 | */ | 2097 | */ |
| 2098 | ti->discard_zeroes_data_unsupported = true; | ||
| 2098 | if (pf.discard_enabled && pf.discard_passdown) { | 2099 | if (pf.discard_enabled && pf.discard_passdown) { |
| 2099 | ti->num_discard_bios = 1; | 2100 | ti->num_discard_bios = 1; |
| 2100 | 2101 | ||
| @@ -2104,7 +2105,6 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
| 2104 | * thin devices' discard limits consistent). | 2105 | * thin devices' discard limits consistent). |
| 2105 | */ | 2106 | */ |
| 2106 | ti->discards_supported = true; | 2107 | ti->discards_supported = true; |
| 2107 | ti->discard_zeroes_data_unsupported = true; | ||
| 2108 | } | 2108 | } |
| 2109 | ti->private = pt; | 2109 | ti->private = pt; |
| 2110 | 2110 | ||
| @@ -2689,8 +2689,16 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
| 2689 | * They get transferred to the live pool in bind_control_target() | 2689 | * They get transferred to the live pool in bind_control_target() |
| 2690 | * called from pool_preresume(). | 2690 | * called from pool_preresume(). |
| 2691 | */ | 2691 | */ |
| 2692 | if (!pt->adjusted_pf.discard_enabled) | 2692 | if (!pt->adjusted_pf.discard_enabled) { |
| 2693 | /* | ||
| 2694 | * Must explicitly disallow stacking discard limits otherwise the | ||
| 2695 | * block layer will stack them if pool's data device has support. | ||
| 2696 | * QUEUE_FLAG_DISCARD wouldn't be set but there is no way for the | ||
| 2697 | * user to see that, so make sure to set all discard limits to 0. | ||
| 2698 | */ | ||
| 2699 | limits->discard_granularity = 0; | ||
| 2693 | return; | 2700 | return; |
| 2701 | } | ||
| 2694 | 2702 | ||
| 2695 | disable_passdown_if_not_supported(pt); | 2703 | disable_passdown_if_not_supported(pt); |
| 2696 | 2704 | ||
| @@ -2826,10 +2834,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
| 2826 | ti->per_bio_data_size = sizeof(struct dm_thin_endio_hook); | 2834 | ti->per_bio_data_size = sizeof(struct dm_thin_endio_hook); |
| 2827 | 2835 | ||
| 2828 | /* In case the pool supports discards, pass them on. */ | 2836 | /* In case the pool supports discards, pass them on. */ |
| 2837 | ti->discard_zeroes_data_unsupported = true; | ||
| 2829 | if (tc->pool->pf.discard_enabled) { | 2838 | if (tc->pool->pf.discard_enabled) { |
| 2830 | ti->discards_supported = true; | 2839 | ti->discards_supported = true; |
| 2831 | ti->num_discard_bios = 1; | 2840 | ti->num_discard_bios = 1; |
| 2832 | ti->discard_zeroes_data_unsupported = true; | ||
| 2833 | /* Discard bios must be split on a block boundary */ | 2841 | /* Discard bios must be split on a block boundary */ |
| 2834 | ti->split_discard_bios = true; | 2842 | ti->split_discard_bios = true; |
| 2835 | } | 2843 | } |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 6a5e9ed2fcc3..b3e26c7d1417 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -211,10 +211,55 @@ struct dm_md_mempools { | |||
| 211 | struct bio_set *bs; | 211 | struct bio_set *bs; |
| 212 | }; | 212 | }; |
| 213 | 213 | ||
| 214 | #define MIN_IOS 256 | 214 | #define RESERVED_BIO_BASED_IOS 16 |
| 215 | #define RESERVED_REQUEST_BASED_IOS 256 | ||
| 216 | #define RESERVED_MAX_IOS 1024 | ||
| 215 | static struct kmem_cache *_io_cache; | 217 | static struct kmem_cache *_io_cache; |
| 216 | static struct kmem_cache *_rq_tio_cache; | 218 | static struct kmem_cache *_rq_tio_cache; |
| 217 | 219 | ||
| 220 | /* | ||
| 221 | * Bio-based DM's mempools' reserved IOs set by the user. | ||
| 222 | */ | ||
| 223 | static unsigned reserved_bio_based_ios = RESERVED_BIO_BASED_IOS; | ||
| 224 | |||
| 225 | /* | ||
| 226 | * Request-based DM's mempools' reserved IOs set by the user. | ||
| 227 | */ | ||
| 228 | static unsigned reserved_rq_based_ios = RESERVED_REQUEST_BASED_IOS; | ||
| 229 | |||
| 230 | static unsigned __dm_get_reserved_ios(unsigned *reserved_ios, | ||
| 231 | unsigned def, unsigned max) | ||
| 232 | { | ||
| 233 | unsigned ios = ACCESS_ONCE(*reserved_ios); | ||
| 234 | unsigned modified_ios = 0; | ||
| 235 | |||
| 236 | if (!ios) | ||
| 237 | modified_ios = def; | ||
| 238 | else if (ios > max) | ||
| 239 | modified_ios = max; | ||
| 240 | |||
| 241 | if (modified_ios) { | ||
| 242 | (void)cmpxchg(reserved_ios, ios, modified_ios); | ||
| 243 | ios = modified_ios; | ||
| 244 | } | ||
| 245 | |||
| 246 | return ios; | ||
| 247 | } | ||
| 248 | |||
| 249 | unsigned dm_get_reserved_bio_based_ios(void) | ||
| 250 | { | ||
| 251 | return __dm_get_reserved_ios(&reserved_bio_based_ios, | ||
| 252 | RESERVED_BIO_BASED_IOS, RESERVED_MAX_IOS); | ||
| 253 | } | ||
| 254 | EXPORT_SYMBOL_GPL(dm_get_reserved_bio_based_ios); | ||
| 255 | |||
| 256 | unsigned dm_get_reserved_rq_based_ios(void) | ||
| 257 | { | ||
| 258 | return __dm_get_reserved_ios(&reserved_rq_based_ios, | ||
| 259 | RESERVED_REQUEST_BASED_IOS, RESERVED_MAX_IOS); | ||
| 260 | } | ||
| 261 | EXPORT_SYMBOL_GPL(dm_get_reserved_rq_based_ios); | ||
| 262 | |||
| 218 | static int __init local_init(void) | 263 | static int __init local_init(void) |
| 219 | { | 264 | { |
| 220 | int r = -ENOMEM; | 265 | int r = -ENOMEM; |
| @@ -2278,6 +2323,17 @@ struct target_type *dm_get_immutable_target_type(struct mapped_device *md) | |||
| 2278 | } | 2323 | } |
| 2279 | 2324 | ||
| 2280 | /* | 2325 | /* |
| 2326 | * The queue_limits are only valid as long as you have a reference | ||
| 2327 | * count on 'md'. | ||
| 2328 | */ | ||
| 2329 | struct queue_limits *dm_get_queue_limits(struct mapped_device *md) | ||
| 2330 | { | ||
| 2331 | BUG_ON(!atomic_read(&md->holders)); | ||
| 2332 | return &md->queue->limits; | ||
| 2333 | } | ||
| 2334 | EXPORT_SYMBOL_GPL(dm_get_queue_limits); | ||
| 2335 | |||
| 2336 | /* | ||
| 2281 | * Fully initialize a request-based queue (->elevator, ->request_fn, etc). | 2337 | * Fully initialize a request-based queue (->elevator, ->request_fn, etc). |
| 2282 | */ | 2338 | */ |
| 2283 | static int dm_init_request_based_queue(struct mapped_device *md) | 2339 | static int dm_init_request_based_queue(struct mapped_device *md) |
| @@ -2862,18 +2918,18 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u | |||
| 2862 | 2918 | ||
| 2863 | if (type == DM_TYPE_BIO_BASED) { | 2919 | if (type == DM_TYPE_BIO_BASED) { |
| 2864 | cachep = _io_cache; | 2920 | cachep = _io_cache; |
| 2865 | pool_size = 16; | 2921 | pool_size = dm_get_reserved_bio_based_ios(); |
| 2866 | front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); | 2922 | front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); |
| 2867 | } else if (type == DM_TYPE_REQUEST_BASED) { | 2923 | } else if (type == DM_TYPE_REQUEST_BASED) { |
| 2868 | cachep = _rq_tio_cache; | 2924 | cachep = _rq_tio_cache; |
| 2869 | pool_size = MIN_IOS; | 2925 | pool_size = dm_get_reserved_rq_based_ios(); |
| 2870 | front_pad = offsetof(struct dm_rq_clone_bio_info, clone); | 2926 | front_pad = offsetof(struct dm_rq_clone_bio_info, clone); |
| 2871 | /* per_bio_data_size is not used. See __bind_mempools(). */ | 2927 | /* per_bio_data_size is not used. See __bind_mempools(). */ |
| 2872 | WARN_ON(per_bio_data_size != 0); | 2928 | WARN_ON(per_bio_data_size != 0); |
| 2873 | } else | 2929 | } else |
| 2874 | goto out; | 2930 | goto out; |
| 2875 | 2931 | ||
| 2876 | pools->io_pool = mempool_create_slab_pool(MIN_IOS, cachep); | 2932 | pools->io_pool = mempool_create_slab_pool(pool_size, cachep); |
| 2877 | if (!pools->io_pool) | 2933 | if (!pools->io_pool) |
| 2878 | goto out; | 2934 | goto out; |
| 2879 | 2935 | ||
| @@ -2924,6 +2980,13 @@ module_exit(dm_exit); | |||
| 2924 | 2980 | ||
| 2925 | module_param(major, uint, 0); | 2981 | module_param(major, uint, 0); |
| 2926 | MODULE_PARM_DESC(major, "The major number of the device mapper"); | 2982 | MODULE_PARM_DESC(major, "The major number of the device mapper"); |
| 2983 | |||
| 2984 | module_param(reserved_bio_based_ios, uint, S_IRUGO | S_IWUSR); | ||
| 2985 | MODULE_PARM_DESC(reserved_bio_based_ios, "Reserved IOs in bio-based mempools"); | ||
| 2986 | |||
| 2987 | module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR); | ||
| 2988 | MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools"); | ||
| 2989 | |||
| 2927 | MODULE_DESCRIPTION(DM_NAME " driver"); | 2990 | MODULE_DESCRIPTION(DM_NAME " driver"); |
| 2928 | MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); | 2991 | MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); |
| 2929 | MODULE_LICENSE("GPL"); | 2992 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 5e604cc7b4aa..1d1ad7b7e527 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
| @@ -184,6 +184,9 @@ void dm_free_md_mempools(struct dm_md_mempools *pools); | |||
| 184 | /* | 184 | /* |
| 185 | * Helpers that are used by DM core | 185 | * Helpers that are used by DM core |
| 186 | */ | 186 | */ |
| 187 | unsigned dm_get_reserved_bio_based_ios(void); | ||
| 188 | unsigned dm_get_reserved_rq_based_ios(void); | ||
| 189 | |||
| 187 | static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen) | 190 | static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen) |
| 188 | { | 191 | { |
| 189 | return !maxlen || strlen(result) + 1 >= maxlen; | 192 | return !maxlen || strlen(result) + 1 >= maxlen; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e8ccf6c0f08a..bdd64b1b4817 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev) | |||
| 1155 | 1155 | ||
| 1156 | pci_enable_bridge(dev->bus->self); | 1156 | pci_enable_bridge(dev->bus->self); |
| 1157 | 1157 | ||
| 1158 | if (pci_is_enabled(dev)) | 1158 | if (pci_is_enabled(dev)) { |
| 1159 | if (!dev->is_busmaster) { | ||
| 1160 | dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n"); | ||
| 1161 | pci_set_master(dev); | ||
| 1162 | } | ||
| 1159 | return; | 1163 | return; |
| 1164 | } | ||
| 1165 | |||
| 1160 | retval = pci_enable_device(dev); | 1166 | retval = pci_enable_device(dev); |
| 1161 | if (retval) | 1167 | if (retval) |
| 1162 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", | 1168 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", |
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c index 75dca19bf214..6ac755270ab4 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.c +++ b/drivers/video/mmp/hw/mmp_ctrl.c | |||
| @@ -514,7 +514,7 @@ static int mmphw_probe(struct platform_device *pdev) | |||
| 514 | if (IS_ERR(ctrl->clk)) { | 514 | if (IS_ERR(ctrl->clk)) { |
| 515 | dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name); | 515 | dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name); |
| 516 | ret = -ENOENT; | 516 | ret = -ENOENT; |
| 517 | goto failed_get_clk; | 517 | goto failed; |
| 518 | } | 518 | } |
| 519 | clk_prepare_enable(ctrl->clk); | 519 | clk_prepare_enable(ctrl->clk); |
| 520 | 520 | ||
| @@ -551,21 +551,8 @@ failed_path_init: | |||
| 551 | path_deinit(path_plat); | 551 | path_deinit(path_plat); |
| 552 | } | 552 | } |
| 553 | 553 | ||
| 554 | if (ctrl->clk) { | 554 | clk_disable_unprepare(ctrl->clk); |
| 555 | devm_clk_put(ctrl->dev, ctrl->clk); | ||
| 556 | clk_disable_unprepare(ctrl->clk); | ||
| 557 | } | ||
| 558 | failed_get_clk: | ||
| 559 | devm_free_irq(ctrl->dev, ctrl->irq, ctrl); | ||
| 560 | failed: | 555 | failed: |
| 561 | if (ctrl) { | ||
| 562 | if (ctrl->reg_base) | ||
| 563 | devm_iounmap(ctrl->dev, ctrl->reg_base); | ||
| 564 | devm_release_mem_region(ctrl->dev, res->start, | ||
| 565 | resource_size(res)); | ||
| 566 | devm_kfree(ctrl->dev, ctrl); | ||
| 567 | } | ||
| 568 | |||
| 569 | dev_err(&pdev->dev, "device init failed\n"); | 556 | dev_err(&pdev->dev, "device init failed\n"); |
| 570 | 557 | ||
| 571 | return ret; | 558 | return ret; |
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index d250ed0f806d..27197a8048c0 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
| @@ -620,6 +620,7 @@ static int mxsfb_restore_mode(struct mxsfb_info *host) | |||
| 620 | break; | 620 | break; |
| 621 | case 3: | 621 | case 3: |
| 622 | bits_per_pixel = 32; | 622 | bits_per_pixel = 32; |
| 623 | break; | ||
| 623 | case 1: | 624 | case 1: |
| 624 | default: | 625 | default: |
| 625 | return -EINVAL; | 626 | return -EINVAL; |
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 7ef079c146e7..c172a5281f9e 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
| @@ -2075,6 +2075,7 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 2075 | if (!fb_find_mode(&info->var, info, mode_option, NULL, 0, | 2075 | if (!fb_find_mode(&info->var, info, mode_option, NULL, 0, |
| 2076 | info->monspecs.modedb, 16)) { | 2076 | info->monspecs.modedb, 16)) { |
| 2077 | printk(KERN_ERR "neofb: Unable to find usable video mode.\n"); | 2077 | printk(KERN_ERR "neofb: Unable to find usable video mode.\n"); |
| 2078 | err = -EINVAL; | ||
| 2078 | goto err_map_video; | 2079 | goto err_map_video; |
| 2079 | } | 2080 | } |
| 2080 | 2081 | ||
| @@ -2097,7 +2098,8 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 2097 | info->fix.smem_len >> 10, info->var.xres, | 2098 | info->fix.smem_len >> 10, info->var.xres, |
| 2098 | info->var.yres, h_sync / 1000, h_sync % 1000, v_sync); | 2099 | info->var.yres, h_sync / 1000, h_sync % 1000, v_sync); |
| 2099 | 2100 | ||
| 2100 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) | 2101 | err = fb_alloc_cmap(&info->cmap, 256, 0); |
| 2102 | if (err < 0) | ||
| 2101 | goto err_map_video; | 2103 | goto err_map_video; |
| 2102 | 2104 | ||
| 2103 | err = register_framebuffer(info); | 2105 | err = register_framebuffer(info); |
diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 171821ddd78d..ba5b40f581f6 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c | |||
| @@ -120,7 +120,7 @@ int of_get_display_timing(struct device_node *np, const char *name, | |||
| 120 | return -EINVAL; | 120 | return -EINVAL; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | timing_np = of_find_node_by_name(np, name); | 123 | timing_np = of_get_child_by_name(np, name); |
| 124 | if (!timing_np) { | 124 | if (!timing_np) { |
| 125 | pr_err("%s: could not find node '%s'\n", | 125 | pr_err("%s: could not find node '%s'\n", |
| 126 | of_node_full_name(np), name); | 126 | of_node_full_name(np), name); |
| @@ -143,11 +143,11 @@ struct display_timings *of_get_display_timings(struct device_node *np) | |||
| 143 | struct display_timings *disp; | 143 | struct display_timings *disp; |
| 144 | 144 | ||
| 145 | if (!np) { | 145 | if (!np) { |
| 146 | pr_err("%s: no devicenode given\n", of_node_full_name(np)); | 146 | pr_err("%s: no device node given\n", of_node_full_name(np)); |
| 147 | return NULL; | 147 | return NULL; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | timings_np = of_find_node_by_name(np, "display-timings"); | 150 | timings_np = of_get_child_by_name(np, "display-timings"); |
| 151 | if (!timings_np) { | 151 | if (!timings_np) { |
| 152 | pr_err("%s: could not find display-timings node\n", | 152 | pr_err("%s: could not find display-timings node\n", |
| 153 | of_node_full_name(np)); | 153 | of_node_full_name(np)); |
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig index 6c90885b0940..10b25e7cd878 100644 --- a/drivers/video/omap2/displays-new/Kconfig +++ b/drivers/video/omap2/displays-new/Kconfig | |||
| @@ -35,6 +35,7 @@ config DISPLAY_PANEL_DPI | |||
| 35 | 35 | ||
| 36 | config DISPLAY_PANEL_DSI_CM | 36 | config DISPLAY_PANEL_DSI_CM |
| 37 | tristate "Generic DSI Command Mode Panel" | 37 | tristate "Generic DSI Command Mode Panel" |
| 38 | depends on BACKLIGHT_CLASS_DEVICE | ||
| 38 | help | 39 | help |
| 39 | Driver for generic DSI command mode panels. | 40 | Driver for generic DSI command mode panels. |
| 40 | 41 | ||
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c index 1b60698f141e..ccd9073f706f 100644 --- a/drivers/video/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/omap2/displays-new/connector-analog-tv.c | |||
| @@ -191,7 +191,7 @@ static int tvc_probe_pdata(struct platform_device *pdev) | |||
| 191 | in = omap_dss_find_output(pdata->source); | 191 | in = omap_dss_find_output(pdata->source); |
| 192 | if (in == NULL) { | 192 | if (in == NULL) { |
| 193 | dev_err(&pdev->dev, "Failed to find video source\n"); | 193 | dev_err(&pdev->dev, "Failed to find video source\n"); |
| 194 | return -ENODEV; | 194 | return -EPROBE_DEFER; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | ddata->in = in; | 197 | ddata->in = in; |
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/omap2/displays-new/connector-dvi.c index bc5f8ceda371..63d88ee6dfe4 100644 --- a/drivers/video/omap2/displays-new/connector-dvi.c +++ b/drivers/video/omap2/displays-new/connector-dvi.c | |||
| @@ -263,7 +263,7 @@ static int dvic_probe_pdata(struct platform_device *pdev) | |||
| 263 | in = omap_dss_find_output(pdata->source); | 263 | in = omap_dss_find_output(pdata->source); |
| 264 | if (in == NULL) { | 264 | if (in == NULL) { |
| 265 | dev_err(&pdev->dev, "Failed to find video source\n"); | 265 | dev_err(&pdev->dev, "Failed to find video source\n"); |
| 266 | return -ENODEV; | 266 | return -EPROBE_DEFER; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | ddata->in = in; | 269 | ddata->in = in; |
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/omap2/displays-new/connector-hdmi.c index c5826716d6ab..9abe2c039ae9 100644 --- a/drivers/video/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/omap2/displays-new/connector-hdmi.c | |||
| @@ -290,7 +290,7 @@ static int hdmic_probe_pdata(struct platform_device *pdev) | |||
| 290 | in = omap_dss_find_output(pdata->source); | 290 | in = omap_dss_find_output(pdata->source); |
| 291 | if (in == NULL) { | 291 | if (in == NULL) { |
| 292 | dev_err(&pdev->dev, "Failed to find video source\n"); | 292 | dev_err(&pdev->dev, "Failed to find video source\n"); |
| 293 | return -ENODEV; | 293 | return -EPROBE_DEFER; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | ddata->in = in; | 296 | ddata->in = in; |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 02a7340111df..477975009eee 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
| @@ -3691,6 +3691,7 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) | |||
| 3691 | } | 3691 | } |
| 3692 | 3692 | ||
| 3693 | pm_runtime_enable(&pdev->dev); | 3693 | pm_runtime_enable(&pdev->dev); |
| 3694 | pm_runtime_irq_safe(&pdev->dev); | ||
| 3694 | 3695 | ||
| 3695 | r = dispc_runtime_get(); | 3696 | r = dispc_runtime_get(); |
| 3696 | if (r) | 3697 | if (r) |
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 47ca86c5c6c0..d838ba829459 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c | |||
| @@ -1336,14 +1336,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1336 | (info->var.bits_per_pixel * info->var.xres_virtual); | 1336 | (info->var.bits_per_pixel * info->var.xres_virtual); |
| 1337 | if (info->var.yres_virtual < info->var.yres) { | 1337 | if (info->var.yres_virtual < info->var.yres) { |
| 1338 | dev_err(info->device, "virtual vertical size smaller than real\n"); | 1338 | dev_err(info->device, "virtual vertical size smaller than real\n"); |
| 1339 | goto err_find_mode; | 1339 | rc = -EINVAL; |
| 1340 | } | ||
| 1341 | |||
| 1342 | /* maximize virtual vertical size for fast scrolling */ | ||
| 1343 | info->var.yres_virtual = info->fix.smem_len * 8 / | ||
| 1344 | (info->var.bits_per_pixel * info->var.xres_virtual); | ||
| 1345 | if (info->var.yres_virtual < info->var.yres) { | ||
| 1346 | dev_err(info->device, "virtual vertical size smaller than real\n"); | ||
| 1347 | goto err_find_mode; | 1340 | goto err_find_mode; |
| 1348 | } | 1341 | } |
| 1349 | 1342 | ||
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index a50c6e3a7cc4..b232908a6192 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -398,8 +398,6 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
| 398 | if (nr_pages > ARRAY_SIZE(frame_list)) | 398 | if (nr_pages > ARRAY_SIZE(frame_list)) |
| 399 | nr_pages = ARRAY_SIZE(frame_list); | 399 | nr_pages = ARRAY_SIZE(frame_list); |
| 400 | 400 | ||
| 401 | scratch_page = get_balloon_scratch_page(); | ||
| 402 | |||
| 403 | for (i = 0; i < nr_pages; i++) { | 401 | for (i = 0; i < nr_pages; i++) { |
| 404 | page = alloc_page(gfp); | 402 | page = alloc_page(gfp); |
| 405 | if (page == NULL) { | 403 | if (page == NULL) { |
| @@ -413,6 +411,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
| 413 | 411 | ||
| 414 | scrub_page(page); | 412 | scrub_page(page); |
| 415 | 413 | ||
| 414 | /* | ||
| 415 | * Ballooned out frames are effectively replaced with | ||
| 416 | * a scratch frame. Ensure direct mappings and the | ||
| 417 | * p2m are consistent. | ||
| 418 | */ | ||
| 419 | scratch_page = get_balloon_scratch_page(); | ||
| 416 | #ifdef CONFIG_XEN_HAVE_PVMMU | 420 | #ifdef CONFIG_XEN_HAVE_PVMMU |
| 417 | if (xen_pv_domain() && !PageHighMem(page)) { | 421 | if (xen_pv_domain() && !PageHighMem(page)) { |
| 418 | ret = HYPERVISOR_update_va_mapping( | 422 | ret = HYPERVISOR_update_va_mapping( |
| @@ -422,24 +426,19 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) | |||
| 422 | BUG_ON(ret); | 426 | BUG_ON(ret); |
| 423 | } | 427 | } |
| 424 | #endif | 428 | #endif |
| 425 | } | ||
| 426 | |||
| 427 | /* Ensure that ballooned highmem pages don't have kmaps. */ | ||
| 428 | kmap_flush_unused(); | ||
| 429 | flush_tlb_all(); | ||
| 430 | |||
| 431 | /* No more mappings: invalidate P2M and add to balloon. */ | ||
| 432 | for (i = 0; i < nr_pages; i++) { | ||
| 433 | pfn = mfn_to_pfn(frame_list[i]); | ||
| 434 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | 429 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
| 435 | unsigned long p; | 430 | unsigned long p; |
| 436 | p = page_to_pfn(scratch_page); | 431 | p = page_to_pfn(scratch_page); |
| 437 | __set_phys_to_machine(pfn, pfn_to_mfn(p)); | 432 | __set_phys_to_machine(pfn, pfn_to_mfn(p)); |
| 438 | } | 433 | } |
| 434 | put_balloon_scratch_page(); | ||
| 435 | |||
| 439 | balloon_append(pfn_to_page(pfn)); | 436 | balloon_append(pfn_to_page(pfn)); |
| 440 | } | 437 | } |
| 441 | 438 | ||
| 442 | put_balloon_scratch_page(); | 439 | /* Ensure that ballooned highmem pages don't have kmaps. */ |
| 440 | kmap_flush_unused(); | ||
| 441 | flush_tlb_all(); | ||
| 443 | 442 | ||
| 444 | set_xen_guest_handle(reservation.extent_start, frame_list); | 443 | set_xen_guest_handle(reservation.extent_start, frame_list); |
| 445 | reservation.nr_extents = nr_pages; | 444 | reservation.nr_extents = nr_pages; |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 73feacc49b2e..fd777032c2ba 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
| @@ -1163,21 +1163,6 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct | |||
| 1163 | return NULL; | 1163 | return NULL; |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | static int newer_jl_done(struct reiserfs_journal_cnode *cn) | ||
| 1167 | { | ||
| 1168 | struct super_block *sb = cn->sb; | ||
| 1169 | b_blocknr_t blocknr = cn->blocknr; | ||
| 1170 | |||
| 1171 | cn = cn->hprev; | ||
| 1172 | while (cn) { | ||
| 1173 | if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist && | ||
| 1174 | atomic_read(&cn->jlist->j_commit_left) != 0) | ||
| 1175 | return 0; | ||
| 1176 | cn = cn->hprev; | ||
| 1177 | } | ||
| 1178 | return 1; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | static void remove_journal_hash(struct super_block *, | 1166 | static void remove_journal_hash(struct super_block *, |
| 1182 | struct reiserfs_journal_cnode **, | 1167 | struct reiserfs_journal_cnode **, |
| 1183 | struct reiserfs_journal_list *, unsigned long, | 1168 | struct reiserfs_journal_list *, unsigned long, |
| @@ -1353,7 +1338,6 @@ static int flush_journal_list(struct super_block *s, | |||
| 1353 | reiserfs_warning(s, "clm-2048", "called with wcount %d", | 1338 | reiserfs_warning(s, "clm-2048", "called with wcount %d", |
| 1354 | atomic_read(&journal->j_wcount)); | 1339 | atomic_read(&journal->j_wcount)); |
| 1355 | } | 1340 | } |
| 1356 | BUG_ON(jl->j_trans_id == 0); | ||
| 1357 | 1341 | ||
| 1358 | /* if flushall == 0, the lock is already held */ | 1342 | /* if flushall == 0, the lock is already held */ |
| 1359 | if (flushall) { | 1343 | if (flushall) { |
| @@ -1593,31 +1577,6 @@ static int flush_journal_list(struct super_block *s, | |||
| 1593 | return err; | 1577 | return err; |
| 1594 | } | 1578 | } |
| 1595 | 1579 | ||
| 1596 | static int test_transaction(struct super_block *s, | ||
| 1597 | struct reiserfs_journal_list *jl) | ||
| 1598 | { | ||
| 1599 | struct reiserfs_journal_cnode *cn; | ||
| 1600 | |||
| 1601 | if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) | ||
| 1602 | return 1; | ||
| 1603 | |||
| 1604 | cn = jl->j_realblock; | ||
| 1605 | while (cn) { | ||
| 1606 | /* if the blocknr == 0, this has been cleared from the hash, | ||
| 1607 | ** skip it | ||
| 1608 | */ | ||
| 1609 | if (cn->blocknr == 0) { | ||
| 1610 | goto next; | ||
| 1611 | } | ||
| 1612 | if (cn->bh && !newer_jl_done(cn)) | ||
| 1613 | return 0; | ||
| 1614 | next: | ||
| 1615 | cn = cn->next; | ||
| 1616 | cond_resched(); | ||
| 1617 | } | ||
| 1618 | return 0; | ||
| 1619 | } | ||
| 1620 | |||
| 1621 | static int write_one_transaction(struct super_block *s, | 1580 | static int write_one_transaction(struct super_block *s, |
| 1622 | struct reiserfs_journal_list *jl, | 1581 | struct reiserfs_journal_list *jl, |
| 1623 | struct buffer_chunk *chunk) | 1582 | struct buffer_chunk *chunk) |
| @@ -1805,6 +1764,8 @@ static int flush_used_journal_lists(struct super_block *s, | |||
| 1805 | break; | 1764 | break; |
| 1806 | tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next); | 1765 | tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next); |
| 1807 | } | 1766 | } |
| 1767 | get_journal_list(jl); | ||
| 1768 | get_journal_list(flush_jl); | ||
| 1808 | /* try to find a group of blocks we can flush across all the | 1769 | /* try to find a group of blocks we can flush across all the |
| 1809 | ** transactions, but only bother if we've actually spanned | 1770 | ** transactions, but only bother if we've actually spanned |
| 1810 | ** across multiple lists | 1771 | ** across multiple lists |
| @@ -1813,6 +1774,8 @@ static int flush_used_journal_lists(struct super_block *s, | |||
| 1813 | ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i); | 1774 | ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i); |
| 1814 | } | 1775 | } |
| 1815 | flush_journal_list(s, flush_jl, 1); | 1776 | flush_journal_list(s, flush_jl, 1); |
| 1777 | put_journal_list(s, flush_jl); | ||
| 1778 | put_journal_list(s, jl); | ||
| 1816 | return 0; | 1779 | return 0; |
| 1817 | } | 1780 | } |
| 1818 | 1781 | ||
| @@ -3868,27 +3831,6 @@ int reiserfs_prepare_for_journal(struct super_block *sb, | |||
| 3868 | return 1; | 3831 | return 1; |
| 3869 | } | 3832 | } |
| 3870 | 3833 | ||
| 3871 | static void flush_old_journal_lists(struct super_block *s) | ||
| 3872 | { | ||
| 3873 | struct reiserfs_journal *journal = SB_JOURNAL(s); | ||
| 3874 | struct reiserfs_journal_list *jl; | ||
| 3875 | struct list_head *entry; | ||
| 3876 | time_t now = get_seconds(); | ||
| 3877 | |||
| 3878 | while (!list_empty(&journal->j_journal_list)) { | ||
| 3879 | entry = journal->j_journal_list.next; | ||
| 3880 | jl = JOURNAL_LIST_ENTRY(entry); | ||
| 3881 | /* this check should always be run, to send old lists to disk */ | ||
| 3882 | if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) && | ||
| 3883 | atomic_read(&jl->j_commit_left) == 0 && | ||
| 3884 | test_transaction(s, jl)) { | ||
| 3885 | flush_used_journal_lists(s, jl); | ||
| 3886 | } else { | ||
| 3887 | break; | ||
| 3888 | } | ||
| 3889 | } | ||
| 3890 | } | ||
| 3891 | |||
| 3892 | /* | 3834 | /* |
| 3893 | ** long and ugly. If flush, will not return until all commit | 3835 | ** long and ugly. If flush, will not return until all commit |
| 3894 | ** blocks and all real buffers in the trans are on disk. | 3836 | ** blocks and all real buffers in the trans are on disk. |
| @@ -4232,7 +4174,6 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
| 4232 | } | 4174 | } |
| 4233 | } | 4175 | } |
| 4234 | } | 4176 | } |
| 4235 | flush_old_journal_lists(sb); | ||
| 4236 | 4177 | ||
| 4237 | journal->j_current_jl->j_list_bitmap = | 4178 | journal->j_current_jl->j_list_bitmap = |
| 4238 | get_list_bitmap(sb, journal->j_current_jl); | 4179 | get_list_bitmap(sb, journal->j_current_jl); |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 7e5aae4bf46f..6eaf5edf1ea1 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
| @@ -30,18 +30,17 @@ void udf_free_inode(struct inode *inode) | |||
| 30 | { | 30 | { |
| 31 | struct super_block *sb = inode->i_sb; | 31 | struct super_block *sb = inode->i_sb; |
| 32 | struct udf_sb_info *sbi = UDF_SB(sb); | 32 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 33 | struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); | ||
| 33 | 34 | ||
| 34 | mutex_lock(&sbi->s_alloc_mutex); | 35 | if (lvidiu) { |
| 35 | if (sbi->s_lvid_bh) { | 36 | mutex_lock(&sbi->s_alloc_mutex); |
| 36 | struct logicalVolIntegrityDescImpUse *lvidiu = | ||
| 37 | udf_sb_lvidiu(sbi); | ||
| 38 | if (S_ISDIR(inode->i_mode)) | 37 | if (S_ISDIR(inode->i_mode)) |
| 39 | le32_add_cpu(&lvidiu->numDirs, -1); | 38 | le32_add_cpu(&lvidiu->numDirs, -1); |
| 40 | else | 39 | else |
| 41 | le32_add_cpu(&lvidiu->numFiles, -1); | 40 | le32_add_cpu(&lvidiu->numFiles, -1); |
| 42 | udf_updated_lvid(sb); | 41 | udf_updated_lvid(sb); |
| 42 | mutex_unlock(&sbi->s_alloc_mutex); | ||
| 43 | } | 43 | } |
| 44 | mutex_unlock(&sbi->s_alloc_mutex); | ||
| 45 | 44 | ||
| 46 | udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); | 45 | udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1); |
| 47 | } | 46 | } |
| @@ -55,6 +54,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) | |||
| 55 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; | 54 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; |
| 56 | struct udf_inode_info *iinfo; | 55 | struct udf_inode_info *iinfo; |
| 57 | struct udf_inode_info *dinfo = UDF_I(dir); | 56 | struct udf_inode_info *dinfo = UDF_I(dir); |
| 57 | struct logicalVolIntegrityDescImpUse *lvidiu; | ||
| 58 | 58 | ||
| 59 | inode = new_inode(sb); | 59 | inode = new_inode(sb); |
| 60 | 60 | ||
| @@ -92,12 +92,10 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) | |||
| 92 | return NULL; | 92 | return NULL; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | if (sbi->s_lvid_bh) { | 95 | lvidiu = udf_sb_lvidiu(sb); |
| 96 | struct logicalVolIntegrityDescImpUse *lvidiu; | 96 | if (lvidiu) { |
| 97 | |||
| 98 | iinfo->i_unique = lvid_get_unique_id(sb); | 97 | iinfo->i_unique = lvid_get_unique_id(sb); |
| 99 | mutex_lock(&sbi->s_alloc_mutex); | 98 | mutex_lock(&sbi->s_alloc_mutex); |
| 100 | lvidiu = udf_sb_lvidiu(sbi); | ||
| 101 | if (S_ISDIR(mode)) | 99 | if (S_ISDIR(mode)) |
| 102 | le32_add_cpu(&lvidiu->numDirs, 1); | 100 | le32_add_cpu(&lvidiu->numDirs, 1); |
| 103 | else | 101 | else |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 839a2bad7f45..91219385691d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -94,13 +94,25 @@ static unsigned int udf_count_free(struct super_block *); | |||
| 94 | static int udf_statfs(struct dentry *, struct kstatfs *); | 94 | static int udf_statfs(struct dentry *, struct kstatfs *); |
| 95 | static int udf_show_options(struct seq_file *, struct dentry *); | 95 | static int udf_show_options(struct seq_file *, struct dentry *); |
| 96 | 96 | ||
| 97 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) | 97 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb) |
| 98 | { | 98 | { |
| 99 | struct logicalVolIntegrityDesc *lvid = | 99 | struct logicalVolIntegrityDesc *lvid; |
| 100 | (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; | 100 | unsigned int partnum; |
| 101 | __u32 number_of_partitions = le32_to_cpu(lvid->numOfPartitions); | 101 | unsigned int offset; |
| 102 | __u32 offset = number_of_partitions * 2 * | 102 | |
| 103 | sizeof(uint32_t)/sizeof(uint8_t); | 103 | if (!UDF_SB(sb)->s_lvid_bh) |
| 104 | return NULL; | ||
| 105 | lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data; | ||
| 106 | partnum = le32_to_cpu(lvid->numOfPartitions); | ||
| 107 | if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) - | ||
| 108 | offsetof(struct logicalVolIntegrityDesc, impUse)) / | ||
| 109 | (2 * sizeof(uint32_t)) < partnum) { | ||
| 110 | udf_err(sb, "Logical volume integrity descriptor corrupted " | ||
| 111 | "(numOfPartitions = %u)!\n", partnum); | ||
| 112 | return NULL; | ||
| 113 | } | ||
| 114 | /* The offset is to skip freeSpaceTable and sizeTable arrays */ | ||
| 115 | offset = partnum * 2 * sizeof(uint32_t); | ||
| 104 | return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); | 116 | return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); |
| 105 | } | 117 | } |
| 106 | 118 | ||
| @@ -629,9 +641,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
| 629 | struct udf_options uopt; | 641 | struct udf_options uopt; |
| 630 | struct udf_sb_info *sbi = UDF_SB(sb); | 642 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 631 | int error = 0; | 643 | int error = 0; |
| 644 | struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); | ||
| 632 | 645 | ||
| 633 | if (sbi->s_lvid_bh) { | 646 | if (lvidiu) { |
| 634 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); | 647 | int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev); |
| 635 | if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) | 648 | if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) |
| 636 | return -EACCES; | 649 | return -EACCES; |
| 637 | } | 650 | } |
| @@ -1905,11 +1918,12 @@ static void udf_open_lvid(struct super_block *sb) | |||
| 1905 | 1918 | ||
| 1906 | if (!bh) | 1919 | if (!bh) |
| 1907 | return; | 1920 | return; |
| 1908 | |||
| 1909 | mutex_lock(&sbi->s_alloc_mutex); | ||
| 1910 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | 1921 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
| 1911 | lvidiu = udf_sb_lvidiu(sbi); | 1922 | lvidiu = udf_sb_lvidiu(sb); |
| 1923 | if (!lvidiu) | ||
| 1924 | return; | ||
| 1912 | 1925 | ||
| 1926 | mutex_lock(&sbi->s_alloc_mutex); | ||
| 1913 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1927 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
| 1914 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1928 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
| 1915 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, | 1929 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, |
| @@ -1937,10 +1951,12 @@ static void udf_close_lvid(struct super_block *sb) | |||
| 1937 | 1951 | ||
| 1938 | if (!bh) | 1952 | if (!bh) |
| 1939 | return; | 1953 | return; |
| 1954 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
| 1955 | lvidiu = udf_sb_lvidiu(sb); | ||
| 1956 | if (!lvidiu) | ||
| 1957 | return; | ||
| 1940 | 1958 | ||
| 1941 | mutex_lock(&sbi->s_alloc_mutex); | 1959 | mutex_lock(&sbi->s_alloc_mutex); |
| 1942 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
| 1943 | lvidiu = udf_sb_lvidiu(sbi); | ||
| 1944 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1960 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
| 1945 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1961 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
| 1946 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); | 1962 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME); |
| @@ -2093,15 +2109,19 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
| 2093 | 2109 | ||
| 2094 | if (sbi->s_lvid_bh) { | 2110 | if (sbi->s_lvid_bh) { |
| 2095 | struct logicalVolIntegrityDescImpUse *lvidiu = | 2111 | struct logicalVolIntegrityDescImpUse *lvidiu = |
| 2096 | udf_sb_lvidiu(sbi); | 2112 | udf_sb_lvidiu(sb); |
| 2097 | uint16_t minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); | 2113 | uint16_t minUDFReadRev; |
| 2098 | uint16_t minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); | 2114 | uint16_t minUDFWriteRev; |
| 2099 | /* uint16_t maxUDFWriteRev = | ||
| 2100 | le16_to_cpu(lvidiu->maxUDFWriteRev); */ | ||
| 2101 | 2115 | ||
| 2116 | if (!lvidiu) { | ||
| 2117 | ret = -EINVAL; | ||
| 2118 | goto error_out; | ||
| 2119 | } | ||
| 2120 | minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); | ||
| 2121 | minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); | ||
| 2102 | if (minUDFReadRev > UDF_MAX_READ_VERSION) { | 2122 | if (minUDFReadRev > UDF_MAX_READ_VERSION) { |
| 2103 | udf_err(sb, "minUDFReadRev=%x (max is %x)\n", | 2123 | udf_err(sb, "minUDFReadRev=%x (max is %x)\n", |
| 2104 | le16_to_cpu(lvidiu->minUDFReadRev), | 2124 | minUDFReadRev, |
| 2105 | UDF_MAX_READ_VERSION); | 2125 | UDF_MAX_READ_VERSION); |
| 2106 | ret = -EINVAL; | 2126 | ret = -EINVAL; |
| 2107 | goto error_out; | 2127 | goto error_out; |
| @@ -2265,11 +2285,7 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 2265 | struct logicalVolIntegrityDescImpUse *lvidiu; | 2285 | struct logicalVolIntegrityDescImpUse *lvidiu; |
| 2266 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); | 2286 | u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
| 2267 | 2287 | ||
| 2268 | if (sbi->s_lvid_bh != NULL) | 2288 | lvidiu = udf_sb_lvidiu(sb); |
| 2269 | lvidiu = udf_sb_lvidiu(sbi); | ||
| 2270 | else | ||
| 2271 | lvidiu = NULL; | ||
| 2272 | |||
| 2273 | buf->f_type = UDF_SUPER_MAGIC; | 2289 | buf->f_type = UDF_SUPER_MAGIC; |
| 2274 | buf->f_bsize = sb->s_blocksize; | 2290 | buf->f_bsize = sb->s_blocksize; |
| 2275 | buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; | 2291 | buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index ed401e94aa8c..1f32c7bd9f57 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
| @@ -162,7 +162,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb) | |||
| 162 | return sb->s_fs_info; | 162 | return sb->s_fs_info; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi); | 165 | struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb); |
| 166 | 166 | ||
| 167 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); | 167 | int udf_compute_nr_groups(struct super_block *sb, u32 partition); |
| 168 | 168 | ||
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 88c5ea75ebf6..f1d85cfc0a54 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -628,6 +628,7 @@ xfs_buf_item_unlock( | |||
| 628 | else if (aborted) { | 628 | else if (aborted) { |
| 629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); | 629 | ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); |
| 630 | if (lip->li_flags & XFS_LI_IN_AIL) { | 630 | if (lip->li_flags & XFS_LI_IN_AIL) { |
| 631 | spin_lock(&lip->li_ailp->xa_lock); | ||
| 631 | xfs_trans_ail_delete(lip->li_ailp, lip, | 632 | xfs_trans_ail_delete(lip->li_ailp, lip, |
| 632 | SHUTDOWN_LOG_IO_ERROR); | 633 | SHUTDOWN_LOG_IO_ERROR); |
| 633 | } | 634 | } |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 069537c845e5..20bf8e8002d6 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
| @@ -1224,6 +1224,7 @@ xfs_da3_node_toosmall( | |||
| 1224 | /* start with smaller blk num */ | 1224 | /* start with smaller blk num */ |
| 1225 | forward = nodehdr.forw < nodehdr.back; | 1225 | forward = nodehdr.forw < nodehdr.back; |
| 1226 | for (i = 0; i < 2; forward = !forward, i++) { | 1226 | for (i = 0; i < 2; forward = !forward, i++) { |
| 1227 | struct xfs_da3_icnode_hdr thdr; | ||
| 1227 | if (forward) | 1228 | if (forward) |
| 1228 | blkno = nodehdr.forw; | 1229 | blkno = nodehdr.forw; |
| 1229 | else | 1230 | else |
| @@ -1236,10 +1237,10 @@ xfs_da3_node_toosmall( | |||
| 1236 | return(error); | 1237 | return(error); |
| 1237 | 1238 | ||
| 1238 | node = bp->b_addr; | 1239 | node = bp->b_addr; |
| 1239 | xfs_da3_node_hdr_from_disk(&nodehdr, node); | 1240 | xfs_da3_node_hdr_from_disk(&thdr, node); |
| 1240 | xfs_trans_brelse(state->args->trans, bp); | 1241 | xfs_trans_brelse(state->args->trans, bp); |
| 1241 | 1242 | ||
| 1242 | if (count - nodehdr.count >= 0) | 1243 | if (count - thdr.count >= 0) |
| 1243 | break; /* fits with at least 25% to spare */ | 1244 | break; /* fits with at least 25% to spare */ |
| 1244 | } | 1245 | } |
| 1245 | if (i >= 2) { | 1246 | if (i >= 2) { |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 1edb5cc3e5f4..18272c766a50 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
| @@ -515,7 +515,7 @@ typedef struct xfs_swapext | |||
| 515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ | 515 | /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ |
| 516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) | 516 | #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) |
| 517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) | 517 | #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64) |
| 518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks) | 518 | #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) |
| 519 | 519 | ||
| 520 | /* | 520 | /* |
| 521 | * ioctl commands that replace IRIX syssgi()'s | 521 | * ioctl commands that replace IRIX syssgi()'s |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 193206ba4358..474807a401c8 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
| @@ -119,11 +119,6 @@ xfs_inode_free( | |||
| 119 | ip->i_itemp = NULL; | 119 | ip->i_itemp = NULL; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | /* asserts to verify all state is correct here */ | ||
| 123 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
| 124 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | ||
| 125 | ASSERT(!xfs_isiflocked(ip)); | ||
| 126 | |||
| 127 | /* | 122 | /* |
| 128 | * Because we use RCU freeing we need to ensure the inode always | 123 | * Because we use RCU freeing we need to ensure the inode always |
| 129 | * appears to be reclaimed with an invalid inode number when in the | 124 | * appears to be reclaimed with an invalid inode number when in the |
| @@ -135,6 +130,10 @@ xfs_inode_free( | |||
| 135 | ip->i_ino = 0; | 130 | ip->i_ino = 0; |
| 136 | spin_unlock(&ip->i_flags_lock); | 131 | spin_unlock(&ip->i_flags_lock); |
| 137 | 132 | ||
| 133 | /* asserts to verify all state is correct here */ | ||
| 134 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
| 135 | ASSERT(!xfs_isiflocked(ip)); | ||
| 136 | |||
| 138 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); | 137 | call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); |
| 139 | } | 138 | } |
| 140 | 139 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index dabda9521b4b..cc179878fe41 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -1970,6 +1970,13 @@ xlog_recover_do_inode_buffer( | |||
| 1970 | * magic number. If we don't recognise the magic number in the buffer, then | 1970 | * magic number. If we don't recognise the magic number in the buffer, then |
| 1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and | 1971 | * return a LSN of -1 so that the caller knows it was an unrecognised block and |
| 1972 | * so can recover the buffer. | 1972 | * so can recover the buffer. |
| 1973 | * | ||
| 1974 | * Note: we cannot rely solely on magic number matches to determine that the | ||
| 1975 | * buffer has a valid LSN - we also need to verify that it belongs to this | ||
| 1976 | * filesystem, so we need to extract the object's LSN and compare it to that | ||
| 1977 | * which we read from the superblock. If the UUIDs don't match, then we've got a | ||
| 1978 | * stale metadata block from an old filesystem instance that we need to recover | ||
| 1979 | * over the top of. | ||
| 1973 | */ | 1980 | */ |
| 1974 | static xfs_lsn_t | 1981 | static xfs_lsn_t |
| 1975 | xlog_recover_get_buf_lsn( | 1982 | xlog_recover_get_buf_lsn( |
| @@ -1980,6 +1987,8 @@ xlog_recover_get_buf_lsn( | |||
| 1980 | __uint16_t magic16; | 1987 | __uint16_t magic16; |
| 1981 | __uint16_t magicda; | 1988 | __uint16_t magicda; |
| 1982 | void *blk = bp->b_addr; | 1989 | void *blk = bp->b_addr; |
| 1990 | uuid_t *uuid; | ||
| 1991 | xfs_lsn_t lsn = -1; | ||
| 1983 | 1992 | ||
| 1984 | /* v4 filesystems always recover immediately */ | 1993 | /* v4 filesystems always recover immediately */ |
| 1985 | if (!xfs_sb_version_hascrc(&mp->m_sb)) | 1994 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
| @@ -1992,43 +2001,79 @@ xlog_recover_get_buf_lsn( | |||
| 1992 | case XFS_ABTB_MAGIC: | 2001 | case XFS_ABTB_MAGIC: |
| 1993 | case XFS_ABTC_MAGIC: | 2002 | case XFS_ABTC_MAGIC: |
| 1994 | case XFS_IBT_CRC_MAGIC: | 2003 | case XFS_IBT_CRC_MAGIC: |
| 1995 | case XFS_IBT_MAGIC: | 2004 | case XFS_IBT_MAGIC: { |
| 1996 | return be64_to_cpu( | 2005 | struct xfs_btree_block *btb = blk; |
| 1997 | ((struct xfs_btree_block *)blk)->bb_u.s.bb_lsn); | 2006 | |
| 2007 | lsn = be64_to_cpu(btb->bb_u.s.bb_lsn); | ||
| 2008 | uuid = &btb->bb_u.s.bb_uuid; | ||
| 2009 | break; | ||
| 2010 | } | ||
| 1998 | case XFS_BMAP_CRC_MAGIC: | 2011 | case XFS_BMAP_CRC_MAGIC: |
| 1999 | case XFS_BMAP_MAGIC: | 2012 | case XFS_BMAP_MAGIC: { |
| 2000 | return be64_to_cpu( | 2013 | struct xfs_btree_block *btb = blk; |
| 2001 | ((struct xfs_btree_block *)blk)->bb_u.l.bb_lsn); | 2014 | |
| 2015 | lsn = be64_to_cpu(btb->bb_u.l.bb_lsn); | ||
| 2016 | uuid = &btb->bb_u.l.bb_uuid; | ||
| 2017 | break; | ||
| 2018 | } | ||
| 2002 | case XFS_AGF_MAGIC: | 2019 | case XFS_AGF_MAGIC: |
| 2003 | return be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); | 2020 | lsn = be64_to_cpu(((struct xfs_agf *)blk)->agf_lsn); |
| 2021 | uuid = &((struct xfs_agf *)blk)->agf_uuid; | ||
| 2022 | break; | ||
| 2004 | case XFS_AGFL_MAGIC: | 2023 | case XFS_AGFL_MAGIC: |
| 2005 | return be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); | 2024 | lsn = be64_to_cpu(((struct xfs_agfl *)blk)->agfl_lsn); |
| 2025 | uuid = &((struct xfs_agfl *)blk)->agfl_uuid; | ||
| 2026 | break; | ||
| 2006 | case XFS_AGI_MAGIC: | 2027 | case XFS_AGI_MAGIC: |
| 2007 | return be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); | 2028 | lsn = be64_to_cpu(((struct xfs_agi *)blk)->agi_lsn); |
| 2029 | uuid = &((struct xfs_agi *)blk)->agi_uuid; | ||
| 2030 | break; | ||
| 2008 | case XFS_SYMLINK_MAGIC: | 2031 | case XFS_SYMLINK_MAGIC: |
| 2009 | return be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); | 2032 | lsn = be64_to_cpu(((struct xfs_dsymlink_hdr *)blk)->sl_lsn); |
| 2033 | uuid = &((struct xfs_dsymlink_hdr *)blk)->sl_uuid; | ||
| 2034 | break; | ||
| 2010 | case XFS_DIR3_BLOCK_MAGIC: | 2035 | case XFS_DIR3_BLOCK_MAGIC: |
| 2011 | case XFS_DIR3_DATA_MAGIC: | 2036 | case XFS_DIR3_DATA_MAGIC: |
| 2012 | case XFS_DIR3_FREE_MAGIC: | 2037 | case XFS_DIR3_FREE_MAGIC: |
| 2013 | return be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); | 2038 | lsn = be64_to_cpu(((struct xfs_dir3_blk_hdr *)blk)->lsn); |
| 2039 | uuid = &((struct xfs_dir3_blk_hdr *)blk)->uuid; | ||
| 2040 | break; | ||
| 2014 | case XFS_ATTR3_RMT_MAGIC: | 2041 | case XFS_ATTR3_RMT_MAGIC: |
| 2015 | return be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); | 2042 | lsn = be64_to_cpu(((struct xfs_attr3_rmt_hdr *)blk)->rm_lsn); |
| 2043 | uuid = &((struct xfs_attr3_rmt_hdr *)blk)->rm_uuid; | ||
| 2044 | break; | ||
| 2016 | case XFS_SB_MAGIC: | 2045 | case XFS_SB_MAGIC: |
| 2017 | return be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); | 2046 | lsn = be64_to_cpu(((struct xfs_dsb *)blk)->sb_lsn); |
| 2047 | uuid = &((struct xfs_dsb *)blk)->sb_uuid; | ||
| 2048 | break; | ||
| 2018 | default: | 2049 | default: |
| 2019 | break; | 2050 | break; |
| 2020 | } | 2051 | } |
| 2021 | 2052 | ||
| 2053 | if (lsn != (xfs_lsn_t)-1) { | ||
| 2054 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
| 2055 | goto recover_immediately; | ||
| 2056 | return lsn; | ||
| 2057 | } | ||
| 2058 | |||
| 2022 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); | 2059 | magicda = be16_to_cpu(((struct xfs_da_blkinfo *)blk)->magic); |
| 2023 | switch (magicda) { | 2060 | switch (magicda) { |
| 2024 | case XFS_DIR3_LEAF1_MAGIC: | 2061 | case XFS_DIR3_LEAF1_MAGIC: |
| 2025 | case XFS_DIR3_LEAFN_MAGIC: | 2062 | case XFS_DIR3_LEAFN_MAGIC: |
| 2026 | case XFS_DA3_NODE_MAGIC: | 2063 | case XFS_DA3_NODE_MAGIC: |
| 2027 | return be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); | 2064 | lsn = be64_to_cpu(((struct xfs_da3_blkinfo *)blk)->lsn); |
| 2065 | uuid = &((struct xfs_da3_blkinfo *)blk)->uuid; | ||
| 2066 | break; | ||
| 2028 | default: | 2067 | default: |
| 2029 | break; | 2068 | break; |
| 2030 | } | 2069 | } |
| 2031 | 2070 | ||
| 2071 | if (lsn != (xfs_lsn_t)-1) { | ||
| 2072 | if (!uuid_equal(&mp->m_sb.sb_uuid, uuid)) | ||
| 2073 | goto recover_immediately; | ||
| 2074 | return lsn; | ||
| 2075 | } | ||
| 2076 | |||
| 2032 | /* | 2077 | /* |
| 2033 | * We do individual object checks on dquot and inode buffers as they | 2078 | * We do individual object checks on dquot and inode buffers as they |
| 2034 | * have their own individual LSN records. Also, we could have a stale | 2079 | * have their own individual LSN records. Also, we could have a stale |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 653073de09e3..ed419c62dde1 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
| @@ -406,13 +406,14 @@ int dm_noflush_suspending(struct dm_target *ti); | |||
| 406 | union map_info *dm_get_mapinfo(struct bio *bio); | 406 | union map_info *dm_get_mapinfo(struct bio *bio); |
| 407 | union map_info *dm_get_rq_mapinfo(struct request *rq); | 407 | union map_info *dm_get_rq_mapinfo(struct request *rq); |
| 408 | 408 | ||
| 409 | struct queue_limits *dm_get_queue_limits(struct mapped_device *md); | ||
| 410 | |||
| 409 | /* | 411 | /* |
| 410 | * Geometry functions. | 412 | * Geometry functions. |
| 411 | */ | 413 | */ |
| 412 | int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); | 414 | int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); |
| 413 | int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); | 415 | int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); |
| 414 | 416 | ||
| 415 | |||
| 416 | /*----------------------------------------------------------------- | 417 | /*----------------------------------------------------------------- |
| 417 | * Functions for manipulating device-mapper tables. | 418 | * Functions for manipulating device-mapper tables. |
| 418 | *---------------------------------------------------------------*/ | 419 | *---------------------------------------------------------------*/ |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index ccd4260834c5..bab49da8a0f0 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
| @@ -15,8 +15,8 @@ | |||
| 15 | #include <linux/spinlock_types.h> | 15 | #include <linux/spinlock_types.h> |
| 16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
| 17 | #include <linux/lockdep.h> | 17 | #include <linux/lockdep.h> |
| 18 | |||
| 19 | #include <linux/atomic.h> | 18 | #include <linux/atomic.h> |
| 19 | #include <asm/processor.h> | ||
| 20 | 20 | ||
| 21 | /* | 21 | /* |
| 22 | * Simple, straightforward mutexes with strict semantics: | 22 | * Simple, straightforward mutexes with strict semantics: |
| @@ -175,8 +175,8 @@ extern void mutex_unlock(struct mutex *lock); | |||
| 175 | 175 | ||
| 176 | extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); | 176 | extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); |
| 177 | 177 | ||
| 178 | #ifndef CONFIG_HAVE_ARCH_MUTEX_CPU_RELAX | 178 | #ifndef arch_mutex_cpu_relax |
| 179 | #define arch_mutex_cpu_relax() cpu_relax() | 179 | # define arch_mutex_cpu_relax() cpu_relax() |
| 180 | #endif | 180 | #endif |
| 181 | 181 | ||
| 182 | #endif | 182 | #endif |
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 535cecf1e02f..fcd63baee5f2 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #ifndef __OF_IRQ_H | 1 | #ifndef __OF_IRQ_H |
| 2 | #define __OF_IRQ_H | 2 | #define __OF_IRQ_H |
| 3 | 3 | ||
| 4 | #if defined(CONFIG_OF) | ||
| 5 | struct of_irq; | ||
| 6 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 7 | #include <linux/errno.h> | 5 | #include <linux/errno.h> |
| 8 | #include <linux/irq.h> | 6 | #include <linux/irq.h> |
| @@ -10,14 +8,6 @@ struct of_irq; | |||
| 10 | #include <linux/ioport.h> | 8 | #include <linux/ioport.h> |
| 11 | #include <linux/of.h> | 9 | #include <linux/of.h> |
| 12 | 10 | ||
| 13 | /* | ||
| 14 | * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC | ||
| 15 | * implements it differently. However, the prototype is the same for all, | ||
| 16 | * so declare it here regardless of the CONFIG_OF_IRQ setting. | ||
| 17 | */ | ||
| 18 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); | ||
| 19 | |||
| 20 | #if defined(CONFIG_OF_IRQ) | ||
| 21 | /** | 11 | /** |
| 22 | * of_irq - container for device_node/irq_specifier pair for an irq controller | 12 | * of_irq - container for device_node/irq_specifier pair for an irq controller |
| 23 | * @controller: pointer to interrupt controller device tree node | 13 | * @controller: pointer to interrupt controller device tree node |
| @@ -71,11 +61,17 @@ extern int of_irq_to_resource(struct device_node *dev, int index, | |||
| 71 | extern int of_irq_count(struct device_node *dev); | 61 | extern int of_irq_count(struct device_node *dev); |
| 72 | extern int of_irq_to_resource_table(struct device_node *dev, | 62 | extern int of_irq_to_resource_table(struct device_node *dev, |
| 73 | struct resource *res, int nr_irqs); | 63 | struct resource *res, int nr_irqs); |
| 74 | extern struct device_node *of_irq_find_parent(struct device_node *child); | ||
| 75 | 64 | ||
| 76 | extern void of_irq_init(const struct of_device_id *matches); | 65 | extern void of_irq_init(const struct of_device_id *matches); |
| 77 | 66 | ||
| 78 | #endif /* CONFIG_OF_IRQ */ | 67 | #if defined(CONFIG_OF) |
| 68 | /* | ||
| 69 | * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC | ||
| 70 | * implements it differently. However, the prototype is the same for all, | ||
| 71 | * so declare it here regardless of the CONFIG_OF_IRQ setting. | ||
| 72 | */ | ||
| 73 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); | ||
| 74 | extern struct device_node *of_irq_find_parent(struct device_node *child); | ||
| 79 | 75 | ||
| 80 | #else /* !CONFIG_OF */ | 76 | #else /* !CONFIG_OF */ |
| 81 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, | 77 | static inline unsigned int irq_of_parse_and_map(struct device_node *dev, |
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 247091bf0587..859c8dfd78a1 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
| @@ -51,6 +51,15 @@ void context_tracking_user_enter(void) | |||
| 51 | unsigned long flags; | 51 | unsigned long flags; |
| 52 | 52 | ||
| 53 | /* | 53 | /* |
| 54 | * Repeat the user_enter() check here because some archs may be calling | ||
| 55 | * this from asm and if no CPU needs context tracking, they shouldn't | ||
| 56 | * go further. Repeat the check here until they support the static key | ||
| 57 | * check. | ||
| 58 | */ | ||
| 59 | if (!static_key_false(&context_tracking_enabled)) | ||
| 60 | return; | ||
| 61 | |||
| 62 | /* | ||
| 54 | * Some contexts may involve an exception occuring in an irq, | 63 | * Some contexts may involve an exception occuring in an irq, |
| 55 | * leading to that nesting: | 64 | * leading to that nesting: |
| 56 | * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit() | 65 | * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit() |
| @@ -151,6 +160,9 @@ void context_tracking_user_exit(void) | |||
| 151 | { | 160 | { |
| 152 | unsigned long flags; | 161 | unsigned long flags; |
| 153 | 162 | ||
| 163 | if (!static_key_false(&context_tracking_enabled)) | ||
| 164 | return; | ||
| 165 | |||
| 154 | if (in_interrupt()) | 166 | if (in_interrupt()) |
| 155 | return; | 167 | return; |
| 156 | 168 | ||
diff --git a/kernel/params.c b/kernel/params.c index 81c4e78c8f4c..c00d5b502aa4 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
| @@ -254,11 +254,11 @@ int parse_args(const char *doing, | |||
| 254 | 254 | ||
| 255 | 255 | ||
| 256 | STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", unsigned long, kstrtoul); | 256 | STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", unsigned long, kstrtoul); |
| 257 | STANDARD_PARAM_DEF(short, short, "%hi", long, kstrtoul); | 257 | STANDARD_PARAM_DEF(short, short, "%hi", long, kstrtol); |
| 258 | STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, kstrtoul); | 258 | STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, kstrtoul); |
| 259 | STANDARD_PARAM_DEF(int, int, "%i", long, kstrtoul); | 259 | STANDARD_PARAM_DEF(int, int, "%i", long, kstrtol); |
| 260 | STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, kstrtoul); | 260 | STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, kstrtoul); |
| 261 | STANDARD_PARAM_DEF(long, long, "%li", long, kstrtoul); | 261 | STANDARD_PARAM_DEF(long, long, "%li", long, kstrtol); |
| 262 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, kstrtoul); | 262 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, kstrtoul); |
| 263 | 263 | ||
| 264 | int param_set_charp(const char *val, const struct kernel_param *kp) | 264 | int param_set_charp(const char *val, const struct kernel_param *kp) |
diff --git a/lib/kobject.c b/lib/kobject.c index 962175134702..669bf190d4fb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
| @@ -933,10 +933,7 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj) | |||
| 933 | 933 | ||
| 934 | bool kobj_ns_current_may_mount(enum kobj_ns_type type) | 934 | bool kobj_ns_current_may_mount(enum kobj_ns_type type) |
| 935 | { | 935 | { |
| 936 | bool may_mount = false; | 936 | bool may_mount = true; |
| 937 | |||
| 938 | if (type == KOBJ_NS_TYPE_NONE) | ||
| 939 | return true; | ||
| 940 | 937 | ||
| 941 | spin_lock(&kobj_ns_type_lock); | 938 | spin_lock(&kobj_ns_type_lock); |
| 942 | if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && | 939 | if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && |
diff --git a/lib/lockref.c b/lib/lockref.c index 677d036cf3c7..6f9d434c1521 100644 --- a/lib/lockref.c +++ b/lib/lockref.c | |||
| @@ -4,6 +4,22 @@ | |||
| 4 | #ifdef CONFIG_CMPXCHG_LOCKREF | 4 | #ifdef CONFIG_CMPXCHG_LOCKREF |
| 5 | 5 | ||
| 6 | /* | 6 | /* |
| 7 | * Allow weakly-ordered memory architectures to provide barrier-less | ||
| 8 | * cmpxchg semantics for lockref updates. | ||
| 9 | */ | ||
| 10 | #ifndef cmpxchg64_relaxed | ||
| 11 | # define cmpxchg64_relaxed cmpxchg64 | ||
| 12 | #endif | ||
| 13 | |||
| 14 | /* | ||
| 15 | * Allow architectures to override the default cpu_relax() within CMPXCHG_LOOP. | ||
| 16 | * This is useful for architectures with an expensive cpu_relax(). | ||
| 17 | */ | ||
| 18 | #ifndef arch_mutex_cpu_relax | ||
| 19 | # define arch_mutex_cpu_relax() cpu_relax() | ||
| 20 | #endif | ||
| 21 | |||
| 22 | /* | ||
| 7 | * Note that the "cmpxchg()" reloads the "old" value for the | 23 | * Note that the "cmpxchg()" reloads the "old" value for the |
| 8 | * failure case. | 24 | * failure case. |
| 9 | */ | 25 | */ |
| @@ -14,12 +30,13 @@ | |||
| 14 | while (likely(arch_spin_value_unlocked(old.lock.rlock.raw_lock))) { \ | 30 | while (likely(arch_spin_value_unlocked(old.lock.rlock.raw_lock))) { \ |
| 15 | struct lockref new = old, prev = old; \ | 31 | struct lockref new = old, prev = old; \ |
| 16 | CODE \ | 32 | CODE \ |
| 17 | old.lock_count = cmpxchg64(&lockref->lock_count, \ | 33 | old.lock_count = cmpxchg64_relaxed(&lockref->lock_count, \ |
| 18 | old.lock_count, new.lock_count); \ | 34 | old.lock_count, \ |
| 35 | new.lock_count); \ | ||
| 19 | if (likely(old.lock_count == prev.lock_count)) { \ | 36 | if (likely(old.lock_count == prev.lock_count)) { \ |
| 20 | SUCCESS; \ | 37 | SUCCESS; \ |
| 21 | } \ | 38 | } \ |
| 22 | cpu_relax(); \ | 39 | arch_mutex_cpu_relax(); \ |
| 23 | } \ | 40 | } \ |
| 24 | } while (0) | 41 | } while (0) |
| 25 | 42 | ||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 98969541cbcc..bea523a5d852 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
| @@ -139,6 +139,18 @@ static int snd_compr_open(struct inode *inode, struct file *f) | |||
| 139 | static int snd_compr_free(struct inode *inode, struct file *f) | 139 | static int snd_compr_free(struct inode *inode, struct file *f) |
| 140 | { | 140 | { |
| 141 | struct snd_compr_file *data = f->private_data; | 141 | struct snd_compr_file *data = f->private_data; |
| 142 | struct snd_compr_runtime *runtime = data->stream.runtime; | ||
| 143 | |||
| 144 | switch (runtime->state) { | ||
| 145 | case SNDRV_PCM_STATE_RUNNING: | ||
| 146 | case SNDRV_PCM_STATE_DRAINING: | ||
| 147 | case SNDRV_PCM_STATE_PAUSED: | ||
| 148 | data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP); | ||
| 149 | break; | ||
| 150 | default: | ||
| 151 | break; | ||
| 152 | } | ||
| 153 | |||
| 142 | data->stream.ops->free(&data->stream); | 154 | data->stream.ops->free(&data->stream); |
| 143 | kfree(data->stream.runtime->buffer); | 155 | kfree(data->stream.runtime->buffer); |
| 144 | kfree(data->stream.runtime); | 156 | kfree(data->stream.runtime); |
| @@ -837,7 +849,8 @@ static int snd_compress_dev_disconnect(struct snd_device *device) | |||
| 837 | struct snd_compr *compr; | 849 | struct snd_compr *compr; |
| 838 | 850 | ||
| 839 | compr = device->device_data; | 851 | compr = device->device_data; |
| 840 | snd_unregister_device(compr->direction, compr->card, compr->device); | 852 | snd_unregister_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, |
| 853 | compr->device); | ||
| 841 | return 0; | 854 | return 0; |
| 842 | } | 855 | } |
| 843 | 856 | ||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index b524f89a1f13..18d972501585 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
| @@ -111,6 +111,9 @@ enum { | |||
| 111 | /* 0x0009 - 0x0014 -> 12 test regs */ | 111 | /* 0x0009 - 0x0014 -> 12 test regs */ |
| 112 | /* 0x0015 - visibility reg */ | 112 | /* 0x0015 - visibility reg */ |
| 113 | 113 | ||
| 114 | /* Cirrus Logic CS4208 */ | ||
| 115 | #define CS4208_VENDOR_NID 0x24 | ||
| 116 | |||
| 114 | /* | 117 | /* |
| 115 | * Cirrus Logic CS4210 | 118 | * Cirrus Logic CS4210 |
| 116 | * | 119 | * |
| @@ -223,6 +226,16 @@ static const struct hda_verb cs_coef_init_verbs[] = { | |||
| 223 | {} /* terminator */ | 226 | {} /* terminator */ |
| 224 | }; | 227 | }; |
| 225 | 228 | ||
| 229 | static const struct hda_verb cs4208_coef_init_verbs[] = { | ||
| 230 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | ||
| 231 | {0x24, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | ||
| 232 | {0x24, AC_VERB_SET_COEF_INDEX, 0x0033}, | ||
| 233 | {0x24, AC_VERB_SET_PROC_COEF, 0x0001}, /* A1 ICS */ | ||
| 234 | {0x24, AC_VERB_SET_COEF_INDEX, 0x0034}, | ||
| 235 | {0x24, AC_VERB_SET_PROC_COEF, 0x1C01}, /* A1 Enable, A Thresh = 300mV */ | ||
| 236 | {} /* terminator */ | ||
| 237 | }; | ||
| 238 | |||
| 226 | /* Errata: CS4207 rev C0/C1/C2 Silicon | 239 | /* Errata: CS4207 rev C0/C1/C2 Silicon |
| 227 | * | 240 | * |
| 228 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf | 241 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf |
| @@ -295,6 +308,8 @@ static int cs_init(struct hda_codec *codec) | |||
| 295 | /* init_verb sequence for C0/C1/C2 errata*/ | 308 | /* init_verb sequence for C0/C1/C2 errata*/ |
| 296 | snd_hda_sequence_write(codec, cs_errata_init_verbs); | 309 | snd_hda_sequence_write(codec, cs_errata_init_verbs); |
| 297 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 310 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
| 311 | } else if (spec->vendor_nid == CS4208_VENDOR_NID) { | ||
| 312 | snd_hda_sequence_write(codec, cs4208_coef_init_verbs); | ||
| 298 | } | 313 | } |
| 299 | 314 | ||
| 300 | snd_hda_gen_init(codec); | 315 | snd_hda_gen_init(codec); |
| @@ -434,6 +449,29 @@ static const struct hda_pintbl mba42_pincfgs[] = { | |||
| 434 | {} /* terminator */ | 449 | {} /* terminator */ |
| 435 | }; | 450 | }; |
| 436 | 451 | ||
| 452 | static const struct hda_pintbl mba6_pincfgs[] = { | ||
| 453 | { 0x10, 0x032120f0 }, /* HP */ | ||
| 454 | { 0x11, 0x500000f0 }, | ||
| 455 | { 0x12, 0x90100010 }, /* Speaker */ | ||
| 456 | { 0x13, 0x500000f0 }, | ||
| 457 | { 0x14, 0x500000f0 }, | ||
| 458 | { 0x15, 0x770000f0 }, | ||
| 459 | { 0x16, 0x770000f0 }, | ||
| 460 | { 0x17, 0x430000f0 }, | ||
| 461 | { 0x18, 0x43ab9030 }, /* Mic */ | ||
| 462 | { 0x19, 0x770000f0 }, | ||
| 463 | { 0x1a, 0x770000f0 }, | ||
| 464 | { 0x1b, 0x770000f0 }, | ||
| 465 | { 0x1c, 0x90a00090 }, | ||
| 466 | { 0x1d, 0x500000f0 }, | ||
| 467 | { 0x1e, 0x500000f0 }, | ||
| 468 | { 0x1f, 0x500000f0 }, | ||
| 469 | { 0x20, 0x500000f0 }, | ||
| 470 | { 0x21, 0x430000f0 }, | ||
| 471 | { 0x22, 0x430000f0 }, | ||
| 472 | {} /* terminator */ | ||
| 473 | }; | ||
| 474 | |||
| 437 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, | 475 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, |
| 438 | const struct hda_fixup *fix, int action) | 476 | const struct hda_fixup *fix, int action) |
| 439 | { | 477 | { |
| @@ -556,22 +594,23 @@ static int patch_cs420x(struct hda_codec *codec) | |||
| 556 | 594 | ||
| 557 | /* | 595 | /* |
| 558 | * CS4208 support: | 596 | * CS4208 support: |
| 559 | * Its layout is no longer compatible with CS4206/CS4207, and the generic | 597 | * Its layout is no longer compatible with CS4206/CS4207 |
| 560 | * parser seems working fairly well, except for trivial fixups. | ||
| 561 | */ | 598 | */ |
| 562 | enum { | 599 | enum { |
| 600 | CS4208_MBA6, | ||
| 563 | CS4208_GPIO0, | 601 | CS4208_GPIO0, |
| 564 | }; | 602 | }; |
| 565 | 603 | ||
| 566 | static const struct hda_model_fixup cs4208_models[] = { | 604 | static const struct hda_model_fixup cs4208_models[] = { |
| 567 | { .id = CS4208_GPIO0, .name = "gpio0" }, | 605 | { .id = CS4208_GPIO0, .name = "gpio0" }, |
| 606 | { .id = CS4208_MBA6, .name = "mba6" }, | ||
| 568 | {} | 607 | {} |
| 569 | }; | 608 | }; |
| 570 | 609 | ||
| 571 | static const struct snd_pci_quirk cs4208_fixup_tbl[] = { | 610 | static const struct snd_pci_quirk cs4208_fixup_tbl[] = { |
| 572 | /* codec SSID */ | 611 | /* codec SSID */ |
| 573 | SND_PCI_QUIRK(0x106b, 0x7100, "MacBookPro 6,1", CS4208_GPIO0), | 612 | SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), |
| 574 | SND_PCI_QUIRK(0x106b, 0x7200, "MacBookPro 6,2", CS4208_GPIO0), | 613 | SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), |
| 575 | {} /* terminator */ | 614 | {} /* terminator */ |
| 576 | }; | 615 | }; |
| 577 | 616 | ||
| @@ -588,18 +627,35 @@ static void cs4208_fixup_gpio0(struct hda_codec *codec, | |||
| 588 | } | 627 | } |
| 589 | 628 | ||
| 590 | static const struct hda_fixup cs4208_fixups[] = { | 629 | static const struct hda_fixup cs4208_fixups[] = { |
| 630 | [CS4208_MBA6] = { | ||
| 631 | .type = HDA_FIXUP_PINS, | ||
| 632 | .v.pins = mba6_pincfgs, | ||
| 633 | .chained = true, | ||
| 634 | .chain_id = CS4208_GPIO0, | ||
| 635 | }, | ||
| 591 | [CS4208_GPIO0] = { | 636 | [CS4208_GPIO0] = { |
| 592 | .type = HDA_FIXUP_FUNC, | 637 | .type = HDA_FIXUP_FUNC, |
| 593 | .v.func = cs4208_fixup_gpio0, | 638 | .v.func = cs4208_fixup_gpio0, |
| 594 | }, | 639 | }, |
| 595 | }; | 640 | }; |
| 596 | 641 | ||
| 642 | /* correct the 0dB offset of input pins */ | ||
| 643 | static void cs4208_fix_amp_caps(struct hda_codec *codec, hda_nid_t adc) | ||
| 644 | { | ||
| 645 | unsigned int caps; | ||
| 646 | |||
| 647 | caps = query_amp_caps(codec, adc, HDA_INPUT); | ||
| 648 | caps &= ~(AC_AMPCAP_OFFSET); | ||
| 649 | caps |= 0x02; | ||
| 650 | snd_hda_override_amp_caps(codec, adc, HDA_INPUT, caps); | ||
| 651 | } | ||
| 652 | |||
| 597 | static int patch_cs4208(struct hda_codec *codec) | 653 | static int patch_cs4208(struct hda_codec *codec) |
| 598 | { | 654 | { |
| 599 | struct cs_spec *spec; | 655 | struct cs_spec *spec; |
| 600 | int err; | 656 | int err; |
| 601 | 657 | ||
| 602 | spec = cs_alloc_spec(codec, 0); /* no specific w/a */ | 658 | spec = cs_alloc_spec(codec, CS4208_VENDOR_NID); |
| 603 | if (!spec) | 659 | if (!spec) |
| 604 | return -ENOMEM; | 660 | return -ENOMEM; |
| 605 | 661 | ||
| @@ -609,6 +665,12 @@ static int patch_cs4208(struct hda_codec *codec) | |||
| 609 | cs4208_fixups); | 665 | cs4208_fixups); |
| 610 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 666 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
| 611 | 667 | ||
| 668 | snd_hda_override_wcaps(codec, 0x18, | ||
| 669 | get_wcaps(codec, 0x18) | AC_WCAP_STEREO); | ||
| 670 | cs4208_fix_amp_caps(codec, 0x18); | ||
| 671 | cs4208_fix_amp_caps(codec, 0x1b); | ||
| 672 | cs4208_fix_amp_caps(codec, 0x1c); | ||
| 673 | |||
| 612 | err = cs_parse_auto_config(codec); | 674 | err = cs_parse_auto_config(codec); |
| 613 | if (err < 0) | 675 | if (err < 0) |
| 614 | goto error; | 676 | goto error; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 3d8cd04455a6..7ea0245fc6bd 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -1149,32 +1149,43 @@ static int hdmi_choose_cvt(struct hda_codec *codec, | |||
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | static void haswell_config_cvts(struct hda_codec *codec, | 1151 | static void haswell_config_cvts(struct hda_codec *codec, |
| 1152 | int pin_id, int mux_id) | 1152 | hda_nid_t pin_nid, int mux_idx) |
| 1153 | { | 1153 | { |
| 1154 | struct hdmi_spec *spec = codec->spec; | 1154 | struct hdmi_spec *spec = codec->spec; |
| 1155 | struct hdmi_spec_per_pin *per_pin; | 1155 | hda_nid_t nid, end_nid; |
| 1156 | int pin_idx, mux_idx; | 1156 | int cvt_idx, curr; |
| 1157 | int curr; | 1157 | struct hdmi_spec_per_cvt *per_cvt; |
| 1158 | int err; | ||
| 1159 | 1158 | ||
| 1160 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1159 | /* configure all pins, including "no physical connection" ones */ |
| 1161 | per_pin = get_pin(spec, pin_idx); | 1160 | end_nid = codec->start_nid + codec->num_nodes; |
| 1161 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
| 1162 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
| 1163 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
| 1162 | 1164 | ||
| 1163 | if (pin_idx == pin_id) | 1165 | if (wid_type != AC_WID_PIN) |
| 1164 | continue; | 1166 | continue; |
| 1165 | 1167 | ||
| 1166 | curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | 1168 | if (nid == pin_nid) |
| 1169 | continue; | ||
| 1170 | |||
| 1171 | curr = snd_hda_codec_read(codec, nid, 0, | ||
| 1167 | AC_VERB_GET_CONNECT_SEL, 0); | 1172 | AC_VERB_GET_CONNECT_SEL, 0); |
| 1173 | if (curr != mux_idx) | ||
| 1174 | continue; | ||
| 1168 | 1175 | ||
| 1169 | /* Choose another unused converter */ | 1176 | /* choose an unassigned converter. The conveters in the |
| 1170 | if (curr == mux_id) { | 1177 | * connection list are in the same order as in the codec. |
| 1171 | err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx); | 1178 | */ |
| 1172 | if (err < 0) | 1179 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { |
| 1173 | return; | 1180 | per_cvt = get_cvt(spec, cvt_idx); |
| 1174 | snd_printdd("HDMI: choose converter %d for pin %d\n", mux_idx, pin_idx); | 1181 | if (!per_cvt->assigned) { |
| 1175 | snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, | 1182 | snd_printdd("choose cvt %d for pin nid %d\n", |
| 1183 | cvt_idx, nid); | ||
| 1184 | snd_hda_codec_write_cache(codec, nid, 0, | ||
| 1176 | AC_VERB_SET_CONNECT_SEL, | 1185 | AC_VERB_SET_CONNECT_SEL, |
| 1177 | mux_idx); | 1186 | cvt_idx); |
| 1187 | break; | ||
| 1188 | } | ||
| 1178 | } | 1189 | } |
| 1179 | } | 1190 | } |
| 1180 | } | 1191 | } |
| @@ -1216,7 +1227,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
| 1216 | 1227 | ||
| 1217 | /* configure unused pins to choose other converters */ | 1228 | /* configure unused pins to choose other converters */ |
| 1218 | if (is_haswell(codec)) | 1229 | if (is_haswell(codec)) |
| 1219 | haswell_config_cvts(codec, pin_idx, mux_idx); | 1230 | haswell_config_cvts(codec, per_pin->pin_nid, mux_idx); |
| 1220 | 1231 | ||
| 1221 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); | 1232 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); |
| 1222 | 1233 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bc07d369fac4..0e303b99a47c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -3439,6 +3439,9 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, | |||
| 3439 | /* Set to manual mode */ | 3439 | /* Set to manual mode */ |
| 3440 | val = alc_read_coef_idx(codec, 0x06); | 3440 | val = alc_read_coef_idx(codec, 0x06); |
| 3441 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 3441 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
| 3442 | /* Enable Line1 input control by verb */ | ||
| 3443 | val = alc_read_coef_idx(codec, 0x1a); | ||
| 3444 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); | ||
| 3442 | break; | 3445 | break; |
| 3443 | } | 3446 | } |
| 3444 | } | 3447 | } |
| @@ -3531,6 +3534,7 @@ enum { | |||
| 3531 | ALC269VB_FIXUP_ORDISSIMO_EVE2, | 3534 | ALC269VB_FIXUP_ORDISSIMO_EVE2, |
| 3532 | ALC283_FIXUP_CHROME_BOOK, | 3535 | ALC283_FIXUP_CHROME_BOOK, |
| 3533 | ALC282_FIXUP_ASUS_TX300, | 3536 | ALC282_FIXUP_ASUS_TX300, |
| 3537 | ALC283_FIXUP_INT_MIC, | ||
| 3534 | }; | 3538 | }; |
| 3535 | 3539 | ||
| 3536 | static const struct hda_fixup alc269_fixups[] = { | 3540 | static const struct hda_fixup alc269_fixups[] = { |
| @@ -3790,6 +3794,16 @@ static const struct hda_fixup alc269_fixups[] = { | |||
| 3790 | .type = HDA_FIXUP_FUNC, | 3794 | .type = HDA_FIXUP_FUNC, |
| 3791 | .v.func = alc282_fixup_asus_tx300, | 3795 | .v.func = alc282_fixup_asus_tx300, |
| 3792 | }, | 3796 | }, |
| 3797 | [ALC283_FIXUP_INT_MIC] = { | ||
| 3798 | .type = HDA_FIXUP_VERBS, | ||
| 3799 | .v.verbs = (const struct hda_verb[]) { | ||
| 3800 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, | ||
| 3801 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, | ||
| 3802 | { } | ||
| 3803 | }, | ||
| 3804 | .chained = true, | ||
| 3805 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | ||
| 3806 | }, | ||
| 3793 | }; | 3807 | }; |
| 3794 | 3808 | ||
| 3795 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 3809 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -3874,7 +3888,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 3874 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3888 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 3875 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3889 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 3876 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3890 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 3877 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3891 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), |
| 3878 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3892 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 3879 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 3893 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 3880 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), | 3894 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index c2dff9cb1f2c..9b5f077fee5b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -101,7 +101,7 @@ static int setup_cpunode_map(void) | |||
| 101 | 101 | ||
| 102 | dir1 = opendir(PATH_SYS_NODE); | 102 | dir1 = opendir(PATH_SYS_NODE); |
| 103 | if (!dir1) | 103 | if (!dir1) |
| 104 | return -1; | 104 | return 0; |
| 105 | 105 | ||
| 106 | while ((dent1 = readdir(dir1)) != NULL) { | 106 | while ((dent1 = readdir(dir1)) != NULL) { |
| 107 | if (dent1->d_type != DT_DIR || | 107 | if (dent1->d_type != DT_DIR || |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fd4853404727..71aa3e35406b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -1055,6 +1055,7 @@ static int trace__replay(struct trace *trace) | |||
| 1055 | 1055 | ||
| 1056 | trace->tool.sample = trace__process_sample; | 1056 | trace->tool.sample = trace__process_sample; |
| 1057 | trace->tool.mmap = perf_event__process_mmap; | 1057 | trace->tool.mmap = perf_event__process_mmap; |
| 1058 | trace->tool.mmap2 = perf_event__process_mmap2; | ||
| 1058 | trace->tool.comm = perf_event__process_comm; | 1059 | trace->tool.comm = perf_event__process_comm; |
| 1059 | trace->tool.exit = perf_event__process_exit; | 1060 | trace->tool.exit = perf_event__process_exit; |
| 1060 | trace->tool.fork = perf_event__process_fork; | 1061 | trace->tool.fork = perf_event__process_fork; |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 346ee929d250..5f6f9b3271bb 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
| @@ -87,7 +87,7 @@ CFLAGS += -Wall | |||
| 87 | CFLAGS += -Wextra | 87 | CFLAGS += -Wextra |
| 88 | CFLAGS += -std=gnu99 | 88 | CFLAGS += -std=gnu99 |
| 89 | 89 | ||
| 90 | EXTLIBS = -lelf -lpthread -lrt -lm | 90 | EXTLIBS = -lelf -lpthread -lrt -lm -ldl |
| 91 | 91 | ||
| 92 | ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) | 92 | ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) |
| 93 | CFLAGS += -fstack-protector-all | 93 | CFLAGS += -fstack-protector-all |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 933d14f287ca..6188d2876a71 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -792,7 +792,7 @@ static int machine__create_modules(struct machine *machine) | |||
| 792 | modules = path; | 792 | modules = path; |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | if (symbol__restricted_filename(path, "/proc/modules")) | 795 | if (symbol__restricted_filename(modules, "/proc/modules")) |
| 796 | return -1; | 796 | return -1; |
| 797 | 797 | ||
| 798 | file = fopen(modules, "r"); | 798 | file = fopen(modules, "r"); |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 20c7299a9d4e..371476cb8ddc 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
| @@ -118,7 +118,6 @@ static const Dwfl_Callbacks offline_callbacks = { | |||
| 118 | static int debuginfo__init_offline_dwarf(struct debuginfo *self, | 118 | static int debuginfo__init_offline_dwarf(struct debuginfo *self, |
| 119 | const char *path) | 119 | const char *path) |
| 120 | { | 120 | { |
| 121 | Dwfl_Module *mod; | ||
| 122 | int fd; | 121 | int fd; |
| 123 | 122 | ||
| 124 | fd = open(path, O_RDONLY); | 123 | fd = open(path, O_RDONLY); |
| @@ -129,11 +128,11 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self, | |||
| 129 | if (!self->dwfl) | 128 | if (!self->dwfl) |
| 130 | goto error; | 129 | goto error; |
| 131 | 130 | ||
| 132 | mod = dwfl_report_offline(self->dwfl, "", "", fd); | 131 | self->mod = dwfl_report_offline(self->dwfl, "", "", fd); |
| 133 | if (!mod) | 132 | if (!self->mod) |
| 134 | goto error; | 133 | goto error; |
| 135 | 134 | ||
| 136 | self->dbg = dwfl_module_getdwarf(mod, &self->bias); | 135 | self->dbg = dwfl_module_getdwarf(self->mod, &self->bias); |
| 137 | if (!self->dbg) | 136 | if (!self->dbg) |
| 138 | goto error; | 137 | goto error; |
| 139 | 138 | ||
| @@ -676,37 +675,42 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
| 676 | } | 675 | } |
| 677 | 676 | ||
| 678 | /* Convert subprogram DIE to trace point */ | 677 | /* Convert subprogram DIE to trace point */ |
| 679 | static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, | 678 | static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, |
| 680 | bool retprobe, struct probe_trace_point *tp) | 679 | Dwarf_Addr paddr, bool retprobe, |
| 680 | struct probe_trace_point *tp) | ||
| 681 | { | 681 | { |
| 682 | Dwarf_Addr eaddr, highaddr; | 682 | Dwarf_Addr eaddr, highaddr; |
| 683 | const char *name; | 683 | GElf_Sym sym; |
| 684 | 684 | const char *symbol; | |
| 685 | /* Copy the name of probe point */ | 685 | |
| 686 | name = dwarf_diename(sp_die); | 686 | /* Verify the address is correct */ |
| 687 | if (name) { | 687 | if (dwarf_entrypc(sp_die, &eaddr) != 0) { |
| 688 | if (dwarf_entrypc(sp_die, &eaddr) != 0) { | 688 | pr_warning("Failed to get entry address of %s\n", |
| 689 | pr_warning("Failed to get entry address of %s\n", | 689 | dwarf_diename(sp_die)); |
| 690 | dwarf_diename(sp_die)); | 690 | return -ENOENT; |
| 691 | return -ENOENT; | 691 | } |
| 692 | } | 692 | if (dwarf_highpc(sp_die, &highaddr) != 0) { |
| 693 | if (dwarf_highpc(sp_die, &highaddr) != 0) { | 693 | pr_warning("Failed to get end address of %s\n", |
| 694 | pr_warning("Failed to get end address of %s\n", | 694 | dwarf_diename(sp_die)); |
| 695 | dwarf_diename(sp_die)); | 695 | return -ENOENT; |
| 696 | return -ENOENT; | 696 | } |
| 697 | } | 697 | if (paddr > highaddr) { |
| 698 | if (paddr > highaddr) { | 698 | pr_warning("Offset specified is greater than size of %s\n", |
| 699 | pr_warning("Offset specified is greater than size of %s\n", | 699 | dwarf_diename(sp_die)); |
| 700 | dwarf_diename(sp_die)); | 700 | return -EINVAL; |
| 701 | return -EINVAL; | 701 | } |
| 702 | } | 702 | |
| 703 | tp->symbol = strdup(name); | 703 | /* Get an appropriate symbol from symtab */ |
| 704 | if (tp->symbol == NULL) | 704 | symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); |
| 705 | return -ENOMEM; | 705 | if (!symbol) { |
| 706 | tp->offset = (unsigned long)(paddr - eaddr); | 706 | pr_warning("Failed to find symbol at 0x%lx\n", |
| 707 | } else | 707 | (unsigned long)paddr); |
| 708 | /* This function has no name. */ | 708 | return -ENOENT; |
| 709 | tp->offset = (unsigned long)paddr; | 709 | } |
| 710 | tp->offset = (unsigned long)(paddr - sym.st_value); | ||
| 711 | tp->symbol = strdup(symbol); | ||
| 712 | if (!tp->symbol) | ||
| 713 | return -ENOMEM; | ||
| 710 | 714 | ||
| 711 | /* Return probe must be on the head of a subprogram */ | 715 | /* Return probe must be on the head of a subprogram */ |
| 712 | if (retprobe) { | 716 | if (retprobe) { |
| @@ -1149,7 +1153,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
| 1149 | tev = &tf->tevs[tf->ntevs++]; | 1153 | tev = &tf->tevs[tf->ntevs++]; |
| 1150 | 1154 | ||
| 1151 | /* Trace point should be converted from subprogram DIE */ | 1155 | /* Trace point should be converted from subprogram DIE */ |
| 1152 | ret = convert_to_trace_point(&pf->sp_die, pf->addr, | 1156 | ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, |
| 1153 | pf->pev->point.retprobe, &tev->point); | 1157 | pf->pev->point.retprobe, &tev->point); |
| 1154 | if (ret < 0) | 1158 | if (ret < 0) |
| 1155 | return ret; | 1159 | return ret; |
| @@ -1181,7 +1185,7 @@ int debuginfo__find_trace_events(struct debuginfo *self, | |||
| 1181 | { | 1185 | { |
| 1182 | struct trace_event_finder tf = { | 1186 | struct trace_event_finder tf = { |
| 1183 | .pf = {.pev = pev, .callback = add_probe_trace_event}, | 1187 | .pf = {.pev = pev, .callback = add_probe_trace_event}, |
| 1184 | .max_tevs = max_tevs}; | 1188 | .mod = self->mod, .max_tevs = max_tevs}; |
| 1185 | int ret; | 1189 | int ret; |
| 1186 | 1190 | ||
| 1187 | /* Allocate result tevs array */ | 1191 | /* Allocate result tevs array */ |
| @@ -1250,7 +1254,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
| 1250 | vl = &af->vls[af->nvls++]; | 1254 | vl = &af->vls[af->nvls++]; |
| 1251 | 1255 | ||
| 1252 | /* Trace point should be converted from subprogram DIE */ | 1256 | /* Trace point should be converted from subprogram DIE */ |
| 1253 | ret = convert_to_trace_point(&pf->sp_die, pf->addr, | 1257 | ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, |
| 1254 | pf->pev->point.retprobe, &vl->point); | 1258 | pf->pev->point.retprobe, &vl->point); |
| 1255 | if (ret < 0) | 1259 | if (ret < 0) |
| 1256 | return ret; | 1260 | return ret; |
| @@ -1289,6 +1293,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self, | |||
| 1289 | { | 1293 | { |
| 1290 | struct available_var_finder af = { | 1294 | struct available_var_finder af = { |
| 1291 | .pf = {.pev = pev, .callback = add_available_vars}, | 1295 | .pf = {.pev = pev, .callback = add_available_vars}, |
| 1296 | .mod = self->mod, | ||
| 1292 | .max_vls = max_vls, .externs = externs}; | 1297 | .max_vls = max_vls, .externs = externs}; |
| 1293 | int ret; | 1298 | int ret; |
| 1294 | 1299 | ||
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 17e94d0c36f9..3b7d63018960 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
| @@ -23,6 +23,7 @@ static inline int is_c_varname(const char *name) | |||
| 23 | /* debug information structure */ | 23 | /* debug information structure */ |
| 24 | struct debuginfo { | 24 | struct debuginfo { |
| 25 | Dwarf *dbg; | 25 | Dwarf *dbg; |
| 26 | Dwfl_Module *mod; | ||
| 26 | Dwfl *dwfl; | 27 | Dwfl *dwfl; |
| 27 | Dwarf_Addr bias; | 28 | Dwarf_Addr bias; |
| 28 | }; | 29 | }; |
| @@ -77,6 +78,7 @@ struct probe_finder { | |||
| 77 | 78 | ||
| 78 | struct trace_event_finder { | 79 | struct trace_event_finder { |
| 79 | struct probe_finder pf; | 80 | struct probe_finder pf; |
| 81 | Dwfl_Module *mod; /* For solving symbols */ | ||
| 80 | struct probe_trace_event *tevs; /* Found trace events */ | 82 | struct probe_trace_event *tevs; /* Found trace events */ |
| 81 | int ntevs; /* Number of trace events */ | 83 | int ntevs; /* Number of trace events */ |
| 82 | int max_tevs; /* Max number of trace events */ | 84 | int max_tevs; /* Max number of trace events */ |
| @@ -84,6 +86,7 @@ struct trace_event_finder { | |||
| 84 | 86 | ||
| 85 | struct available_var_finder { | 87 | struct available_var_finder { |
| 86 | struct probe_finder pf; | 88 | struct probe_finder pf; |
| 89 | Dwfl_Module *mod; /* For solving symbols */ | ||
| 87 | struct variable_list *vls; /* Found variable lists */ | 90 | struct variable_list *vls; /* Found variable lists */ |
| 88 | int nvls; /* Number of variable lists */ | 91 | int nvls; /* Number of variable lists */ |
| 89 | int max_vls; /* Max no. of variable lists */ | 92 | int max_vls; /* Max no. of variable lists */ |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index a9c829be5216..d2a888e2e058 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
| @@ -928,8 +928,33 @@ int dso__load_sym(struct dso *dso, struct map *map, | |||
| 928 | * to it... | 928 | * to it... |
| 929 | */ | 929 | */ |
| 930 | if (symbol_conf.demangle) { | 930 | if (symbol_conf.demangle) { |
| 931 | demangled = bfd_demangle(NULL, elf_name, | 931 | /* |
| 932 | * The demangler doesn't deal with cloned functions. | ||
| 933 | * XXXX.clone.NUM or similar | ||
| 934 | * Strip the dot part and readd it later. | ||
| 935 | */ | ||
| 936 | char *p = (char *)elf_name, *dot; | ||
| 937 | dot = strchr(elf_name, '.'); | ||
| 938 | if (dot) { | ||
| 939 | p = strdup(elf_name); | ||
| 940 | if (!p) | ||
| 941 | goto new_symbol; | ||
| 942 | dot = strchr(p, '.'); | ||
| 943 | *dot = 0; | ||
| 944 | } | ||
| 945 | |||
| 946 | demangled = bfd_demangle(NULL, p, | ||
| 932 | DMGL_PARAMS | DMGL_ANSI); | 947 | DMGL_PARAMS | DMGL_ANSI); |
| 948 | if (dot) | ||
| 949 | *dot = '.'; | ||
| 950 | if (demangled && dot) { | ||
| 951 | demangled = realloc(demangled, strlen(demangled) + strlen(dot) + 1); | ||
| 952 | if (!demangled) | ||
| 953 | goto new_symbol; | ||
| 954 | strcpy(demangled + (dot - p), dot); | ||
| 955 | } | ||
| 956 | if (p != elf_name) | ||
| 957 | free(p); | ||
| 933 | if (demangled != NULL) | 958 | if (demangled != NULL) |
| 934 | elf_name = demangled; | 959 | elf_name = demangled; |
| 935 | } | 960 | } |
