diff options
57 files changed, 969 insertions, 377 deletions
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index 18dc52c4f2a0..e8cf9cf873b3 100644 --- a/Documentation/DMA-attributes.txt +++ b/Documentation/DMA-attributes.txt | |||
@@ -100,3 +100,29 @@ allocated by dma_alloc_attrs() function from individual pages if it can | |||
100 | be mapped as contiguous chunk into device dma address space. By | 100 | be mapped as contiguous chunk into device dma address space. By |
101 | specifying this attribute the allocated buffer is forced to be contiguous | 101 | specifying this attribute the allocated buffer is forced to be contiguous |
102 | also in physical memory. | 102 | also in physical memory. |
103 | |||
104 | DMA_ATTR_ALLOC_SINGLE_PAGES | ||
105 | --------------------------- | ||
106 | |||
107 | This is a hint to the DMA-mapping subsystem that it's probably not worth | ||
108 | the time to try to allocate memory to in a way that gives better TLB | ||
109 | efficiency (AKA it's not worth trying to build the mapping out of larger | ||
110 | pages). You might want to specify this if: | ||
111 | - You know that the accesses to this memory won't thrash the TLB. | ||
112 | You might know that the accesses are likely to be sequential or | ||
113 | that they aren't sequential but it's unlikely you'll ping-pong | ||
114 | between many addresses that are likely to be in different physical | ||
115 | pages. | ||
116 | - You know that the penalty of TLB misses while accessing the | ||
117 | memory will be small enough to be inconsequential. If you are | ||
118 | doing a heavy operation like decryption or decompression this | ||
119 | might be the case. | ||
120 | - You know that the DMA mapping is fairly transitory. If you expect | ||
121 | the mapping to have a short lifetime then it may be worth it to | ||
122 | optimize allocation (avoid coming up with large pages) instead of | ||
123 | getting the slight performance win of larger pages. | ||
124 | Setting this hint doesn't guarantee that you won't get huge pages, but it | ||
125 | means that we won't try quite as hard to get them. | ||
126 | |||
127 | NOTE: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM, | ||
128 | though ARM64 patches will likely be posted soon. | ||
diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt index 92d86f7271b4..453053f1661f 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.txt | |||
@@ -340,8 +340,10 @@ comparison: | |||
340 | 340 | ||
341 | int (*match)(struct device * dev, struct device_driver * drv); | 341 | int (*match)(struct device * dev, struct device_driver * drv); |
342 | 342 | ||
343 | match should return '1' if the driver supports the device, and '0' | 343 | match should return positive value if the driver supports the device, |
344 | otherwise. | 344 | and zero otherwise. It may also return error code (for example |
345 | -EPROBE_DEFER) if determining that given driver supports the device is | ||
346 | not possible. | ||
345 | 347 | ||
346 | When a device is registered, the bus's list of drivers is iterated | 348 | When a device is registered, the bus's list of drivers is iterated |
347 | over. bus->match() is called for each one until a match is found. | 349 | over. bus->match() is called for each one until a match is found. |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1d00da16d980..f6c185f2d8b0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -572,7 +572,6 @@ config ARCH_RPC | |||
572 | select NEED_MACH_IO_H | 572 | select NEED_MACH_IO_H |
573 | select NEED_MACH_MEMORY_H | 573 | select NEED_MACH_MEMORY_H |
574 | select NO_IOPORT_MAP | 574 | select NO_IOPORT_MAP |
575 | select VIRT_TO_BUS | ||
576 | help | 575 | help |
577 | On the Acorn Risc-PC, Linux can support the internal IDE disk and | 576 | On the Acorn Risc-PC, Linux can support the internal IDE disk and |
578 | CD-ROM interface, serial and parallel port, and the floppy drive. | 577 | CD-ROM interface, serial and parallel port, and the floppy drive. |
@@ -1336,7 +1335,6 @@ config BIG_LITTLE | |||
1336 | config BL_SWITCHER | 1335 | config BL_SWITCHER |
1337 | bool "big.LITTLE switcher support" | 1336 | bool "big.LITTLE switcher support" |
1338 | depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC | 1337 | depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC |
1339 | select ARM_CPU_SUSPEND | ||
1340 | select CPU_PM | 1338 | select CPU_PM |
1341 | help | 1339 | help |
1342 | The big.LITTLE "switcher" provides the core functionality to | 1340 | The big.LITTLE "switcher" provides the core functionality to |
@@ -2110,7 +2108,8 @@ config ARCH_SUSPEND_POSSIBLE | |||
2110 | def_bool y | 2108 | def_bool y |
2111 | 2109 | ||
2112 | config ARM_CPU_SUSPEND | 2110 | config ARM_CPU_SUSPEND |
2113 | def_bool PM_SLEEP | 2111 | def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW |
2112 | depends on ARCH_SUSPEND_POSSIBLE | ||
2114 | 2113 | ||
2115 | config ARCH_HIBERNATION_POSSIBLE | 2114 | config ARCH_HIBERNATION_POSSIBLE |
2116 | bool | 2115 | bool |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fe254108d1d9..46fb1cac2698 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -352,7 +352,6 @@ archclean: | |||
352 | 352 | ||
353 | # My testing targets (bypasses dependencies) | 353 | # My testing targets (bypasses dependencies) |
354 | bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage | 354 | bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage |
355 | i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ | ||
356 | 355 | ||
357 | 356 | ||
358 | define archhelp | 357 | define archhelp |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 9eca7aee927f..48fab15cfc02 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
@@ -88,7 +88,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE | |||
88 | $(call if_changed,objcopy) | 88 | $(call if_changed,objcopy) |
89 | @$(kecho) ' Kernel: $@ is ready' | 89 | @$(kecho) ' Kernel: $@ is ready' |
90 | 90 | ||
91 | PHONY += initrd FORCE | 91 | PHONY += initrd |
92 | initrd: | 92 | initrd: |
93 | @test "$(INITRD_PHYS)" != "" || \ | 93 | @test "$(INITRD_PHYS)" != "" || \ |
94 | (echo This machine does not support INITRD; exit -1) | 94 | (echo This machine does not support INITRD; exit -1) |
@@ -107,12 +107,4 @@ uinstall: | |||
107 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ | 107 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ |
108 | $(obj)/uImage System.map "$(INSTALL_PATH)" | 108 | $(obj)/uImage System.map "$(INSTALL_PATH)" |
109 | 109 | ||
110 | zi: | ||
111 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ | ||
112 | $(obj)/zImage System.map "$(INSTALL_PATH)" | ||
113 | |||
114 | i: | ||
115 | $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ | ||
116 | $(obj)/Image System.map "$(INSTALL_PATH)" | ||
117 | |||
118 | subdir- := bootp compressed dts | 110 | subdir- := bootp compressed dts |
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index 0714e0334e33..86b2f5d28240 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore | |||
@@ -3,11 +3,7 @@ bswapsdi2.S | |||
3 | font.c | 3 | font.c |
4 | lib1funcs.S | 4 | lib1funcs.S |
5 | hyp-stub.S | 5 | hyp-stub.S |
6 | piggy.gzip | 6 | piggy_data |
7 | piggy.lzo | ||
8 | piggy.lzma | ||
9 | piggy.xzkern | ||
10 | piggy.lz4 | ||
11 | vmlinux | 7 | vmlinux |
12 | vmlinux.lds | 8 | vmlinux.lds |
13 | 9 | ||
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 43788b1a1ac5..d50430c40045 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -66,11 +66,11 @@ endif | |||
66 | 66 | ||
67 | CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)" | 67 | CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)" |
68 | 68 | ||
69 | suffix_$(CONFIG_KERNEL_GZIP) = gzip | 69 | compress-$(CONFIG_KERNEL_GZIP) = gzip |
70 | suffix_$(CONFIG_KERNEL_LZO) = lzo | 70 | compress-$(CONFIG_KERNEL_LZO) = lzo |
71 | suffix_$(CONFIG_KERNEL_LZMA) = lzma | 71 | compress-$(CONFIG_KERNEL_LZMA) = lzma |
72 | suffix_$(CONFIG_KERNEL_XZ) = xzkern | 72 | compress-$(CONFIG_KERNEL_XZ) = xzkern |
73 | suffix_$(CONFIG_KERNEL_LZ4) = lz4 | 73 | compress-$(CONFIG_KERNEL_LZ4) = lz4 |
74 | 74 | ||
75 | # Borrowed libfdt files for the ATAG compatibility mode | 75 | # Borrowed libfdt files for the ATAG compatibility mode |
76 | 76 | ||
@@ -89,15 +89,12 @@ ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) | |||
89 | OBJS += $(libfdt_objs) atags_to_fdt.o | 89 | OBJS += $(libfdt_objs) atags_to_fdt.o |
90 | endif | 90 | endif |
91 | 91 | ||
92 | targets := vmlinux vmlinux.lds \ | 92 | targets := vmlinux vmlinux.lds piggy_data piggy.o \ |
93 | piggy.$(suffix_y) piggy.$(suffix_y).o \ | 93 | lib1funcs.o ashldi3.o bswapsdi2.o \ |
94 | lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \ | 94 | head.o $(OBJS) |
95 | bswapsdi2.S font.o font.c head.o misc.o $(OBJS) | ||
96 | 95 | ||
97 | # Make sure files are removed during clean | 96 | clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ |
98 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \ | 97 | $(libfdt) $(libfdt_hdrs) hyp-stub.S |
99 | lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \ | ||
100 | hyp-stub.S | ||
101 | 98 | ||
102 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | 99 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
103 | 100 | ||
@@ -178,17 +175,17 @@ fi | |||
178 | 175 | ||
179 | efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a | 176 | efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a |
180 | 177 | ||
181 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ | 178 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ |
182 | $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \ | 179 | $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \ |
183 | $(bswapsdi2) $(efi-obj-y) FORCE | 180 | $(bswapsdi2) $(efi-obj-y) FORCE |
184 | @$(check_for_multiple_zreladdr) | 181 | @$(check_for_multiple_zreladdr) |
185 | $(call if_changed,ld) | 182 | $(call if_changed,ld) |
186 | @$(check_for_bad_syms) | 183 | @$(check_for_bad_syms) |
187 | 184 | ||
188 | $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE | 185 | $(obj)/piggy_data: $(obj)/../Image FORCE |
189 | $(call if_changed,$(suffix_y)) | 186 | $(call if_changed,$(compress-y)) |
190 | 187 | ||
191 | $(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE | 188 | $(obj)/piggy.o: $(obj)/piggy_data |
192 | 189 | ||
193 | CFLAGS_font.o := -Dstatic= | 190 | CFLAGS_font.o := -Dstatic= |
194 | 191 | ||
diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.S index a68adf91a165..f72088495f43 100644 --- a/arch/arm/boot/compressed/piggy.gzip.S +++ b/arch/arm/boot/compressed/piggy.S | |||
@@ -1,6 +1,6 @@ | |||
1 | .section .piggydata,#alloc | 1 | .section .piggydata,#alloc |
2 | .globl input_data | 2 | .globl input_data |
3 | input_data: | 3 | input_data: |
4 | .incbin "arch/arm/boot/compressed/piggy.gzip" | 4 | .incbin "arch/arm/boot/compressed/piggy_data" |
5 | .globl input_data_end | 5 | .globl input_data_end |
6 | input_data_end: | 6 | input_data_end: |
diff --git a/arch/arm/boot/compressed/piggy.lz4.S b/arch/arm/boot/compressed/piggy.lz4.S deleted file mode 100644 index 3d9a575618a3..000000000000 --- a/arch/arm/boot/compressed/piggy.lz4.S +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | .section .piggydata,#alloc | ||
2 | .globl input_data | ||
3 | input_data: | ||
4 | .incbin "arch/arm/boot/compressed/piggy.lz4" | ||
5 | .globl input_data_end | ||
6 | input_data_end: | ||
diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S deleted file mode 100644 index d7e69cffbc0a..000000000000 --- a/arch/arm/boot/compressed/piggy.lzma.S +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | .section .piggydata,#alloc | ||
2 | .globl input_data | ||
3 | input_data: | ||
4 | .incbin "arch/arm/boot/compressed/piggy.lzma" | ||
5 | .globl input_data_end | ||
6 | input_data_end: | ||
diff --git a/arch/arm/boot/compressed/piggy.lzo.S b/arch/arm/boot/compressed/piggy.lzo.S deleted file mode 100644 index a425ad95959a..000000000000 --- a/arch/arm/boot/compressed/piggy.lzo.S +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | .section .piggydata,#alloc | ||
2 | .globl input_data | ||
3 | input_data: | ||
4 | .incbin "arch/arm/boot/compressed/piggy.lzo" | ||
5 | .globl input_data_end | ||
6 | input_data_end: | ||
diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S deleted file mode 100644 index 5703f300d027..000000000000 --- a/arch/arm/boot/compressed/piggy.xzkern.S +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | .section .piggydata,#alloc | ||
2 | .globl input_data | ||
3 | input_data: | ||
4 | .incbin "arch/arm/boot/compressed/piggy.xzkern" | ||
5 | .globl input_data_end | ||
6 | input_data_end: | ||
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 3d224941b541..fb0a0a4dfea4 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -1290,7 +1290,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) | |||
1290 | struct sa1111_dev *dev = SA1111_DEV(_dev); | 1290 | struct sa1111_dev *dev = SA1111_DEV(_dev); |
1291 | struct sa1111_driver *drv = SA1111_DRV(_drv); | 1291 | struct sa1111_driver *drv = SA1111_DRV(_drv); |
1292 | 1292 | ||
1293 | return dev->devid & drv->devid; | 1293 | return !!(dev->devid & drv->devid); |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | static int sa1111_bus_suspend(struct device *dev, pm_message_t state) | 1296 | static int sa1111_bus_suspend(struct device *dev, pm_message_t state) |
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 16da6380eb85..3f6616b472af 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild | |||
@@ -23,7 +23,6 @@ generic-y += preempt.h | |||
23 | generic-y += resource.h | 23 | generic-y += resource.h |
24 | generic-y += rwsem.h | 24 | generic-y += rwsem.h |
25 | generic-y += seccomp.h | 25 | generic-y += seccomp.h |
26 | generic-y += sections.h | ||
27 | generic-y += segment.h | 26 | generic-y += segment.h |
28 | generic-y += sembuf.h | 27 | generic-y += sembuf.h |
29 | generic-y += serial.h | 28 | generic-y += serial.h |
diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index e1f07764b0d6..7d919a9b32e5 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h | |||
@@ -74,7 +74,7 @@ static inline uint32_t __div64_32(uint64_t *n, uint32_t base) | |||
74 | static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) | 74 | static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) |
75 | { | 75 | { |
76 | unsigned long long res; | 76 | unsigned long long res; |
77 | unsigned int tmp = 0; | 77 | register unsigned int tmp asm("ip") = 0; |
78 | 78 | ||
79 | if (!bias) { | 79 | if (!bias) { |
80 | asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" | 80 | asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" |
@@ -90,12 +90,12 @@ static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) | |||
90 | : "r" (m), "r" (n) | 90 | : "r" (m), "r" (n) |
91 | : "cc"); | 91 | : "cc"); |
92 | } else { | 92 | } else { |
93 | asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" | 93 | asm ( "umull %Q0, %R0, %Q2, %Q3\n\t" |
94 | "cmn %Q0, %Q1\n\t" | 94 | "cmn %Q0, %Q2\n\t" |
95 | "adcs %R0, %R0, %R1\n\t" | 95 | "adcs %R0, %R0, %R2\n\t" |
96 | "adc %Q0, %3, #0" | 96 | "adc %Q0, %1, #0" |
97 | : "=&r" (res) | 97 | : "=&r" (res), "+&r" (tmp) |
98 | : "r" (m), "r" (n), "r" (tmp) | 98 | : "r" (m), "r" (n) |
99 | : "cc"); | 99 | : "cc"); |
100 | } | 100 | } |
101 | 101 | ||
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index c79b57bf71c4..9427fd632552 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
@@ -134,6 +134,21 @@ | |||
134 | */ | 134 | */ |
135 | #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) | 135 | #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) |
136 | 136 | ||
137 | #ifdef CONFIG_XIP_KERNEL | ||
138 | /* | ||
139 | * When referencing data in RAM from the XIP region in a relative manner | ||
140 | * with the MMU off, we need the relative offset between the two physical | ||
141 | * addresses. The macro below achieves this, which is: | ||
142 | * __pa(v_data) - __xip_pa(v_text) | ||
143 | */ | ||
144 | #define PHYS_RELATIVE(v_data, v_text) \ | ||
145 | (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \ | ||
146 | ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \ | ||
147 | CONFIG_XIP_PHYS_ADDR)) | ||
148 | #else | ||
149 | #define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text)) | ||
150 | #endif | ||
151 | |||
137 | #ifndef __ASSEMBLY__ | 152 | #ifndef __ASSEMBLY__ |
138 | 153 | ||
139 | /* | 154 | /* |
@@ -273,14 +288,14 @@ static inline void *phys_to_virt(phys_addr_t x) | |||
273 | #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) | 288 | #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) |
274 | #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) | 289 | #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) |
275 | 290 | ||
276 | extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); | 291 | extern unsigned long (*arch_virt_to_idmap)(unsigned long x); |
277 | 292 | ||
278 | /* | 293 | /* |
279 | * These are for systems that have a hardware interconnect supported alias of | 294 | * These are for systems that have a hardware interconnect supported alias of |
280 | * physical memory for idmap purposes. Most cases should leave these | 295 | * physical memory for idmap purposes. Most cases should leave these |
281 | * untouched. | 296 | * untouched. Note: this can only return addresses less than 4GiB. |
282 | */ | 297 | */ |
283 | static inline phys_addr_t __virt_to_idmap(unsigned long x) | 298 | static inline unsigned long __virt_to_idmap(unsigned long x) |
284 | { | 299 | { |
285 | if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) | 300 | if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) |
286 | return arch_virt_to_idmap(x); | 301 | return arch_virt_to_idmap(x); |
@@ -303,20 +318,6 @@ static inline phys_addr_t __virt_to_idmap(unsigned long x) | |||
303 | #define __bus_to_pfn(x) __phys_to_pfn(x) | 318 | #define __bus_to_pfn(x) __phys_to_pfn(x) |
304 | #endif | 319 | #endif |
305 | 320 | ||
306 | #ifdef CONFIG_VIRT_TO_BUS | ||
307 | #define virt_to_bus virt_to_bus | ||
308 | static inline __deprecated unsigned long virt_to_bus(void *x) | ||
309 | { | ||
310 | return __virt_to_bus((unsigned long)x); | ||
311 | } | ||
312 | |||
313 | #define bus_to_virt bus_to_virt | ||
314 | static inline __deprecated void *bus_to_virt(unsigned long x) | ||
315 | { | ||
316 | return (void *)__bus_to_virt(x); | ||
317 | } | ||
318 | #endif | ||
319 | |||
320 | /* | 321 | /* |
321 | * Conversion between a struct page and a physical address. | 322 | * Conversion between a struct page and a physical address. |
322 | * | 323 | * |
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 432ce8176498..fa5b42d44985 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h | |||
@@ -26,7 +26,12 @@ void __check_vmalloc_seq(struct mm_struct *mm); | |||
26 | #ifdef CONFIG_CPU_HAS_ASID | 26 | #ifdef CONFIG_CPU_HAS_ASID |
27 | 27 | ||
28 | void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); | 28 | void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); |
29 | #define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) | 29 | static inline int |
30 | init_new_context(struct task_struct *tsk, struct mm_struct *mm) | ||
31 | { | ||
32 | atomic64_set(&mm->context.id, 0); | ||
33 | return 0; | ||
34 | } | ||
30 | 35 | ||
31 | #ifdef CONFIG_ARM_ERRATA_798181 | 36 | #ifdef CONFIG_ARM_ERRATA_798181 |
32 | void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, | 37 | void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, |
@@ -85,7 +90,12 @@ static inline void finish_arch_post_lock_switch(void) | |||
85 | 90 | ||
86 | #endif /* CONFIG_MMU */ | 91 | #endif /* CONFIG_MMU */ |
87 | 92 | ||
88 | #define init_new_context(tsk,mm) 0 | 93 | static inline int |
94 | init_new_context(struct task_struct *tsk, struct mm_struct *mm) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
89 | 99 | ||
90 | #endif /* CONFIG_CPU_HAS_ASID */ | 100 | #endif /* CONFIG_CPU_HAS_ASID */ |
91 | 101 | ||
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h new file mode 100644 index 000000000000..803bbf2b20b8 --- /dev/null +++ b/arch/arm/include/asm/sections.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _ASM_ARM_SECTIONS_H | ||
2 | #define _ASM_ARM_SECTIONS_H | ||
3 | |||
4 | #include <asm-generic/sections.h> | ||
5 | |||
6 | extern char _exiprom[]; | ||
7 | |||
8 | #endif /* _ASM_ARM_SECTIONS_H */ | ||
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h index 00098615c6f0..73e5e8513751 100644 --- a/arch/arm/include/asm/sparsemem.h +++ b/arch/arm/include/asm/sparsemem.h | |||
@@ -15,10 +15,11 @@ | |||
15 | * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000, | 15 | * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000, |
16 | * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26. | 16 | * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26. |
17 | * | 17 | * |
18 | * Define these in your mach/memory.h. | 18 | * These can be overridden in your mach/memory.h. |
19 | */ | 19 | */ |
20 | #if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS) | 20 | #if !defined(MAX_PHYSMEM_BITS) || !defined(SECTION_SIZE_BITS) |
21 | #error Sparsemem is not supported on this platform | 21 | #define MAX_PHYSMEM_BITS 36 |
22 | #define SECTION_SIZE_BITS 28 | ||
22 | #endif | 23 | #endif |
23 | 24 | ||
24 | #endif | 25 | #endif |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3ce377f7251f..e2550500486d 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -1064,7 +1064,6 @@ ENDPROC(vector_\name) | |||
1064 | .endm | 1064 | .endm |
1065 | 1065 | ||
1066 | .section .stubs, "ax", %progbits | 1066 | .section .stubs, "ax", %progbits |
1067 | __stubs_start: | ||
1068 | @ This must be the first word | 1067 | @ This must be the first word |
1069 | .word vector_swi | 1068 | .word vector_swi |
1070 | 1069 | ||
@@ -1202,14 +1201,13 @@ vector_addrexcptn: | |||
1202 | .long __fiq_svc @ e | 1201 | .long __fiq_svc @ e |
1203 | .long __fiq_svc @ f | 1202 | .long __fiq_svc @ f |
1204 | 1203 | ||
1205 | .globl vector_fiq_offset | 1204 | .globl vector_fiq |
1206 | .equ vector_fiq_offset, vector_fiq | ||
1207 | 1205 | ||
1208 | .section .vectors, "ax", %progbits | 1206 | .section .vectors, "ax", %progbits |
1209 | __vectors_start: | 1207 | .L__vectors_start: |
1210 | W(b) vector_rst | 1208 | W(b) vector_rst |
1211 | W(b) vector_und | 1209 | W(b) vector_und |
1212 | W(ldr) pc, __vectors_start + 0x1000 | 1210 | W(ldr) pc, .L__vectors_start + 0x1000 |
1213 | W(b) vector_pabt | 1211 | W(b) vector_pabt |
1214 | W(b) vector_dabt | 1212 | W(b) vector_dabt |
1215 | W(b) vector_addrexcptn | 1213 | W(b) vector_addrexcptn |
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c index a71501ff6f18..b09561a6d06a 100644 --- a/arch/arm/kernel/hibernate.c +++ b/arch/arm/kernel/hibernate.c | |||
@@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused) | |||
62 | 62 | ||
63 | ret = swsusp_save(); | 63 | ret = swsusp_save(); |
64 | if (ret == 0) | 64 | if (ret == 0) |
65 | _soft_restart(virt_to_phys(cpu_resume), false); | 65 | _soft_restart(virt_to_idmap(cpu_resume), false); |
66 | return ret; | 66 | return ret; |
67 | } | 67 | } |
68 | 68 | ||
@@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused) | |||
87 | for (pbe = restore_pblist; pbe; pbe = pbe->next) | 87 | for (pbe = restore_pblist; pbe; pbe = pbe->next) |
88 | copy_page(pbe->orig_address, pbe->address); | 88 | copy_page(pbe->orig_address, pbe->address); |
89 | 89 | ||
90 | _soft_restart(virt_to_phys(cpu_resume), false); | 90 | _soft_restart(virt_to_idmap(cpu_resume), false); |
91 | } | 91 | } |
92 | 92 | ||
93 | static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; | 93 | static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; |
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 2a55373f49bf..0b1e4a93d67e 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/irqchip/arm-gic-v3.h> | ||
20 | #include <linux/linkage.h> | 21 | #include <linux/linkage.h> |
21 | #include <asm/assembler.h> | 22 | #include <asm/assembler.h> |
22 | #include <asm/virt.h> | 23 | #include <asm/virt.h> |
@@ -161,6 +162,29 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE | |||
161 | 1: | 162 | 1: |
162 | #endif | 163 | #endif |
163 | 164 | ||
165 | #ifdef CONFIG_ARM_GIC_V3 | ||
166 | @ Check whether GICv3 system registers are available | ||
167 | mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 | ||
168 | ubfx r7, r7, #28, #4 | ||
169 | cmp r7, #1 | ||
170 | bne 2f | ||
171 | |||
172 | @ Enable system register accesses | ||
173 | mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE | ||
174 | orr r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) | ||
175 | mcr p15, 4, r7, c12, c9, 5 @ ICC_HSRE | ||
176 | isb | ||
177 | |||
178 | @ SRE bit could be forced to 0 by firmware. | ||
179 | @ Check whether it sticks before accessing any other sysreg | ||
180 | mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE | ||
181 | tst r7, #ICC_SRE_EL2_SRE | ||
182 | beq 2f | ||
183 | mov r7, #0 | ||
184 | mcr p15, 4, r7, c12, c11, 0 @ ICH_HCR | ||
185 | 2: | ||
186 | #endif | ||
187 | |||
164 | bx lr @ The boot CPU mode is left in r4. | 188 | bx lr @ The boot CPU mode is left in r4. |
165 | ENDPROC(__hyp_stub_install_secondary) | 189 | ENDPROC(__hyp_stub_install_secondary) |
166 | 190 | ||
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 1d45320ee125..ece04a457486 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -95,7 +95,7 @@ void __init init_IRQ(void) | |||
95 | outer_cache.write_sec = machine_desc->l2c_write_sec; | 95 | outer_cache.write_sec = machine_desc->l2c_write_sec; |
96 | ret = l2x0_of_init(machine_desc->l2c_aux_val, | 96 | ret = l2x0_of_init(machine_desc->l2c_aux_val, |
97 | machine_desc->l2c_aux_mask); | 97 | machine_desc->l2c_aux_mask); |
98 | if (ret) | 98 | if (ret && ret != -ENODEV) |
99 | pr_err("L2C: failed to init: %d\n", ret); | 99 | pr_err("L2C: failed to init: %d\n", ret); |
100 | } | 100 | } |
101 | 101 | ||
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8bf3b7c09888..59fd0e24c56b 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
@@ -143,10 +143,8 @@ void (*kexec_reinit)(void); | |||
143 | 143 | ||
144 | void machine_kexec(struct kimage *image) | 144 | void machine_kexec(struct kimage *image) |
145 | { | 145 | { |
146 | unsigned long page_list; | 146 | unsigned long page_list, reboot_entry_phys; |
147 | unsigned long reboot_code_buffer_phys; | 147 | void (*reboot_entry)(void); |
148 | unsigned long reboot_entry = (unsigned long)relocate_new_kernel; | ||
149 | unsigned long reboot_entry_phys; | ||
150 | void *reboot_code_buffer; | 148 | void *reboot_code_buffer; |
151 | 149 | ||
152 | /* | 150 | /* |
@@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image) | |||
159 | 157 | ||
160 | page_list = image->head & PAGE_MASK; | 158 | page_list = image->head & PAGE_MASK; |
161 | 159 | ||
162 | /* we need both effective and real address here */ | ||
163 | reboot_code_buffer_phys = | ||
164 | page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
165 | reboot_code_buffer = page_address(image->control_code_page); | 160 | reboot_code_buffer = page_address(image->control_code_page); |
166 | 161 | ||
167 | /* Prepare parameters for reboot_code_buffer*/ | 162 | /* Prepare parameters for reboot_code_buffer*/ |
@@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image) | |||
174 | 169 | ||
175 | /* copy our kernel relocation code to the control code page */ | 170 | /* copy our kernel relocation code to the control code page */ |
176 | reboot_entry = fncpy(reboot_code_buffer, | 171 | reboot_entry = fncpy(reboot_code_buffer, |
177 | reboot_entry, | 172 | &relocate_new_kernel, |
178 | relocate_new_kernel_size); | 173 | relocate_new_kernel_size); |
179 | reboot_entry_phys = (unsigned long)reboot_entry + | 174 | |
180 | (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); | 175 | /* get the identity mapping physical address for the reboot code */ |
176 | reboot_entry_phys = virt_to_idmap(reboot_entry); | ||
181 | 177 | ||
182 | pr_info("Bye!\n"); | 178 | pr_info("Bye!\n"); |
183 | 179 | ||
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index efdddcb97dd1..4f14b5ce6535 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -34,7 +34,7 @@ | |||
34 | * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. | 34 | * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. |
35 | */ | 35 | */ |
36 | #undef MODULES_VADDR | 36 | #undef MODULES_VADDR |
37 | #define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK) | 37 | #define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK) |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifdef CONFIG_MMU | 40 | #ifdef CONFIG_MMU |
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c index 38269358fd25..71a2ff9ec490 100644 --- a/arch/arm/kernel/reboot.c +++ b/arch/arm/kernel/reboot.c | |||
@@ -50,7 +50,7 @@ static void __soft_restart(void *addr) | |||
50 | flush_cache_all(); | 50 | flush_cache_all(); |
51 | 51 | ||
52 | /* Switch to the identity mapping. */ | 52 | /* Switch to the identity mapping. */ |
53 | phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset); | 53 | phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset); |
54 | phys_reset((unsigned long)addr); | 54 | phys_reset((unsigned long)addr); |
55 | 55 | ||
56 | /* Should never get here. */ | 56 | /* Should never get here. */ |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 08b7847bf912..ec279d161b32 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * to run the rebalance_domains for all idle cores and the cpu_capacity can be | 40 | * to run the rebalance_domains for all idle cores and the cpu_capacity can be |
41 | * updated during this sequence. | 41 | * updated during this sequence. |
42 | */ | 42 | */ |
43 | static DEFINE_PER_CPU(unsigned long, cpu_scale); | 43 | static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; |
44 | 44 | ||
45 | unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) | 45 | unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) |
46 | { | 46 | { |
@@ -306,8 +306,6 @@ void __init init_cpu_topology(void) | |||
306 | cpu_topo->socket_id = -1; | 306 | cpu_topo->socket_id = -1; |
307 | cpumask_clear(&cpu_topo->core_sibling); | 307 | cpumask_clear(&cpu_topo->core_sibling); |
308 | cpumask_clear(&cpu_topo->thread_sibling); | 308 | cpumask_clear(&cpu_topo->thread_sibling); |
309 | |||
310 | set_capacity_scale(cpu, SCHED_CAPACITY_SCALE); | ||
311 | } | 309 | } |
312 | smp_wmb(); | 310 | smp_wmb(); |
313 | 311 | ||
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S new file mode 100644 index 000000000000..cba1ec899a69 --- /dev/null +++ b/arch/arm/kernel/vmlinux-xip.lds.S | |||
@@ -0,0 +1,316 @@ | |||
1 | /* ld script to make ARM Linux kernel | ||
2 | * taken from the i386 version by Russell King | ||
3 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
4 | */ | ||
5 | |||
6 | #include <asm-generic/vmlinux.lds.h> | ||
7 | #include <asm/cache.h> | ||
8 | #include <asm/thread_info.h> | ||
9 | #include <asm/memory.h> | ||
10 | #include <asm/page.h> | ||
11 | |||
12 | #define PROC_INFO \ | ||
13 | . = ALIGN(4); \ | ||
14 | VMLINUX_SYMBOL(__proc_info_begin) = .; \ | ||
15 | *(.proc.info.init) \ | ||
16 | VMLINUX_SYMBOL(__proc_info_end) = .; | ||
17 | |||
18 | #define IDMAP_TEXT \ | ||
19 | ALIGN_FUNCTION(); \ | ||
20 | VMLINUX_SYMBOL(__idmap_text_start) = .; \ | ||
21 | *(.idmap.text) \ | ||
22 | VMLINUX_SYMBOL(__idmap_text_end) = .; \ | ||
23 | . = ALIGN(PAGE_SIZE); \ | ||
24 | VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ | ||
25 | *(.hyp.idmap.text) \ | ||
26 | VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; | ||
27 | |||
28 | #ifdef CONFIG_HOTPLUG_CPU | ||
29 | #define ARM_CPU_DISCARD(x) | ||
30 | #define ARM_CPU_KEEP(x) x | ||
31 | #else | ||
32 | #define ARM_CPU_DISCARD(x) x | ||
33 | #define ARM_CPU_KEEP(x) | ||
34 | #endif | ||
35 | |||
36 | #if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ | ||
37 | defined(CONFIG_GENERIC_BUG) | ||
38 | #define ARM_EXIT_KEEP(x) x | ||
39 | #define ARM_EXIT_DISCARD(x) | ||
40 | #else | ||
41 | #define ARM_EXIT_KEEP(x) | ||
42 | #define ARM_EXIT_DISCARD(x) x | ||
43 | #endif | ||
44 | |||
45 | OUTPUT_ARCH(arm) | ||
46 | ENTRY(stext) | ||
47 | |||
48 | #ifndef __ARMEB__ | ||
49 | jiffies = jiffies_64; | ||
50 | #else | ||
51 | jiffies = jiffies_64 + 4; | ||
52 | #endif | ||
53 | |||
54 | SECTIONS | ||
55 | { | ||
56 | /* | ||
57 | * XXX: The linker does not define how output sections are | ||
58 | * assigned to input sections when there are multiple statements | ||
59 | * matching the same input section name. There is no documented | ||
60 | * order of matching. | ||
61 | * | ||
62 | * unwind exit sections must be discarded before the rest of the | ||
63 | * unwind sections get included. | ||
64 | */ | ||
65 | /DISCARD/ : { | ||
66 | *(.ARM.exidx.exit.text) | ||
67 | *(.ARM.extab.exit.text) | ||
68 | ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) | ||
69 | ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) | ||
70 | ARM_EXIT_DISCARD(EXIT_TEXT) | ||
71 | ARM_EXIT_DISCARD(EXIT_DATA) | ||
72 | EXIT_CALL | ||
73 | #ifndef CONFIG_MMU | ||
74 | *(.text.fixup) | ||
75 | *(__ex_table) | ||
76 | #endif | ||
77 | #ifndef CONFIG_SMP_ON_UP | ||
78 | *(.alt.smp.init) | ||
79 | #endif | ||
80 | *(.discard) | ||
81 | *(.discard.*) | ||
82 | } | ||
83 | |||
84 | . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); | ||
85 | _xiprom = .; /* XIP ROM area to be mapped */ | ||
86 | |||
87 | .head.text : { | ||
88 | _text = .; | ||
89 | HEAD_TEXT | ||
90 | } | ||
91 | |||
92 | .text : { /* Real text segment */ | ||
93 | _stext = .; /* Text and read-only data */ | ||
94 | IDMAP_TEXT | ||
95 | __exception_text_start = .; | ||
96 | *(.exception.text) | ||
97 | __exception_text_end = .; | ||
98 | IRQENTRY_TEXT | ||
99 | TEXT_TEXT | ||
100 | SCHED_TEXT | ||
101 | LOCK_TEXT | ||
102 | KPROBES_TEXT | ||
103 | *(.gnu.warning) | ||
104 | *(.glue_7) | ||
105 | *(.glue_7t) | ||
106 | . = ALIGN(4); | ||
107 | *(.got) /* Global offset table */ | ||
108 | ARM_CPU_KEEP(PROC_INFO) | ||
109 | } | ||
110 | |||
111 | RO_DATA(PAGE_SIZE) | ||
112 | |||
113 | . = ALIGN(4); | ||
114 | __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { | ||
115 | __start___ex_table = .; | ||
116 | #ifdef CONFIG_MMU | ||
117 | *(__ex_table) | ||
118 | #endif | ||
119 | __stop___ex_table = .; | ||
120 | } | ||
121 | |||
122 | #ifdef CONFIG_ARM_UNWIND | ||
123 | /* | ||
124 | * Stack unwinding tables | ||
125 | */ | ||
126 | . = ALIGN(8); | ||
127 | .ARM.unwind_idx : { | ||
128 | __start_unwind_idx = .; | ||
129 | *(.ARM.exidx*) | ||
130 | __stop_unwind_idx = .; | ||
131 | } | ||
132 | .ARM.unwind_tab : { | ||
133 | __start_unwind_tab = .; | ||
134 | *(.ARM.extab*) | ||
135 | __stop_unwind_tab = .; | ||
136 | } | ||
137 | #endif | ||
138 | |||
139 | NOTES | ||
140 | |||
141 | _etext = .; /* End of text and rodata section */ | ||
142 | |||
143 | /* | ||
144 | * The vectors and stubs are relocatable code, and the | ||
145 | * only thing that matters is their relative offsets | ||
146 | */ | ||
147 | __vectors_start = .; | ||
148 | .vectors 0xffff0000 : AT(__vectors_start) { | ||
149 | *(.vectors) | ||
150 | } | ||
151 | . = __vectors_start + SIZEOF(.vectors); | ||
152 | __vectors_end = .; | ||
153 | |||
154 | __stubs_start = .; | ||
155 | .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { | ||
156 | *(.stubs) | ||
157 | } | ||
158 | . = __stubs_start + SIZEOF(.stubs); | ||
159 | __stubs_end = .; | ||
160 | |||
161 | PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); | ||
162 | |||
163 | INIT_TEXT_SECTION(8) | ||
164 | .exit.text : { | ||
165 | ARM_EXIT_KEEP(EXIT_TEXT) | ||
166 | } | ||
167 | .init.proc.info : { | ||
168 | ARM_CPU_DISCARD(PROC_INFO) | ||
169 | } | ||
170 | .init.arch.info : { | ||
171 | __arch_info_begin = .; | ||
172 | *(.arch.info.init) | ||
173 | __arch_info_end = .; | ||
174 | } | ||
175 | .init.tagtable : { | ||
176 | __tagtable_begin = .; | ||
177 | *(.taglist.init) | ||
178 | __tagtable_end = .; | ||
179 | } | ||
180 | #ifdef CONFIG_SMP_ON_UP | ||
181 | .init.smpalt : { | ||
182 | __smpalt_begin = .; | ||
183 | *(.alt.smp.init) | ||
184 | __smpalt_end = .; | ||
185 | } | ||
186 | #endif | ||
187 | .init.pv_table : { | ||
188 | __pv_table_begin = .; | ||
189 | *(.pv_table) | ||
190 | __pv_table_end = .; | ||
191 | } | ||
192 | .init.data : { | ||
193 | INIT_SETUP(16) | ||
194 | INIT_CALLS | ||
195 | CON_INITCALL | ||
196 | SECURITY_INITCALL | ||
197 | INIT_RAM_FS | ||
198 | } | ||
199 | |||
200 | #ifdef CONFIG_SMP | ||
201 | PERCPU_SECTION(L1_CACHE_BYTES) | ||
202 | #endif | ||
203 | |||
204 | _exiprom = .; /* End of XIP ROM area */ | ||
205 | __data_loc = ALIGN(4); /* location in binary */ | ||
206 | . = PAGE_OFFSET + TEXT_OFFSET; | ||
207 | |||
208 | .data : AT(__data_loc) { | ||
209 | _data = .; /* address in memory */ | ||
210 | _sdata = .; | ||
211 | |||
212 | /* | ||
213 | * first, the init task union, aligned | ||
214 | * to an 8192 byte boundary. | ||
215 | */ | ||
216 | INIT_TASK_DATA(THREAD_SIZE) | ||
217 | |||
218 | . = ALIGN(PAGE_SIZE); | ||
219 | __init_begin = .; | ||
220 | INIT_DATA | ||
221 | ARM_EXIT_KEEP(EXIT_DATA) | ||
222 | . = ALIGN(PAGE_SIZE); | ||
223 | __init_end = .; | ||
224 | |||
225 | NOSAVE_DATA | ||
226 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) | ||
227 | READ_MOSTLY_DATA(L1_CACHE_BYTES) | ||
228 | |||
229 | /* | ||
230 | * and the usual data section | ||
231 | */ | ||
232 | DATA_DATA | ||
233 | CONSTRUCTORS | ||
234 | |||
235 | _edata = .; | ||
236 | } | ||
237 | _edata_loc = __data_loc + SIZEOF(.data); | ||
238 | |||
239 | #ifdef CONFIG_HAVE_TCM | ||
240 | /* | ||
241 | * We align everything to a page boundary so we can | ||
242 | * free it after init has commenced and TCM contents have | ||
243 | * been copied to its destination. | ||
244 | */ | ||
245 | .tcm_start : { | ||
246 | . = ALIGN(PAGE_SIZE); | ||
247 | __tcm_start = .; | ||
248 | __itcm_start = .; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Link these to the ITCM RAM | ||
253 | * Put VMA to the TCM address and LMA to the common RAM | ||
254 | * and we'll upload the contents from RAM to TCM and free | ||
255 | * the used RAM after that. | ||
256 | */ | ||
257 | .text_itcm ITCM_OFFSET : AT(__itcm_start) | ||
258 | { | ||
259 | __sitcm_text = .; | ||
260 | *(.tcm.text) | ||
261 | *(.tcm.rodata) | ||
262 | . = ALIGN(4); | ||
263 | __eitcm_text = .; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Reset the dot pointer, this is needed to create the | ||
268 | * relative __dtcm_start below (to be used as extern in code). | ||
269 | */ | ||
270 | . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm); | ||
271 | |||
272 | .dtcm_start : { | ||
273 | __dtcm_start = .; | ||
274 | } | ||
275 | |||
276 | /* TODO: add remainder of ITCM as well, that can be used for data! */ | ||
277 | .data_dtcm DTCM_OFFSET : AT(__dtcm_start) | ||
278 | { | ||
279 | . = ALIGN(4); | ||
280 | __sdtcm_data = .; | ||
281 | *(.tcm.data) | ||
282 | . = ALIGN(4); | ||
283 | __edtcm_data = .; | ||
284 | } | ||
285 | |||
286 | /* Reset the dot pointer or the linker gets confused */ | ||
287 | . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm); | ||
288 | |||
289 | /* End marker for freeing TCM copy in linked object */ | ||
290 | .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){ | ||
291 | . = ALIGN(PAGE_SIZE); | ||
292 | __tcm_end = .; | ||
293 | } | ||
294 | #endif | ||
295 | |||
296 | BSS_SECTION(0, 0, 0) | ||
297 | _end = .; | ||
298 | |||
299 | STABS_DEBUG | ||
300 | } | ||
301 | |||
302 | /* | ||
303 | * These must never be empty | ||
304 | * If you have to comment these two assert statements out, your | ||
305 | * binutils is too old (for other reasons as well) | ||
306 | */ | ||
307 | ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") | ||
308 | ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") | ||
309 | |||
310 | /* | ||
311 | * The HYP init code can't be more than a page long, | ||
312 | * and should not cross a page boundary. | ||
313 | * The above comment applies as well. | ||
314 | */ | ||
315 | ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, | ||
316 | "HYP init code too big or misaligned") | ||
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b4139cbbbdd9..1fab979daeaf 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -3,14 +3,16 @@ | |||
3 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> | 3 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifdef CONFIG_XIP_KERNEL | ||
7 | #include "vmlinux-xip.lds.S" | ||
8 | #else | ||
9 | |||
6 | #include <asm-generic/vmlinux.lds.h> | 10 | #include <asm-generic/vmlinux.lds.h> |
7 | #include <asm/cache.h> | 11 | #include <asm/cache.h> |
8 | #include <asm/thread_info.h> | 12 | #include <asm/thread_info.h> |
9 | #include <asm/memory.h> | 13 | #include <asm/memory.h> |
10 | #include <asm/page.h> | 14 | #include <asm/page.h> |
11 | #ifdef CONFIG_ARM_KERNMEM_PERMS | ||
12 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
13 | #endif | ||
14 | 16 | ||
15 | #define PROC_INFO \ | 17 | #define PROC_INFO \ |
16 | . = ALIGN(4); \ | 18 | . = ALIGN(4); \ |
@@ -89,17 +91,13 @@ SECTIONS | |||
89 | *(.discard.*) | 91 | *(.discard.*) |
90 | } | 92 | } |
91 | 93 | ||
92 | #ifdef CONFIG_XIP_KERNEL | ||
93 | . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); | ||
94 | #else | ||
95 | . = PAGE_OFFSET + TEXT_OFFSET; | 94 | . = PAGE_OFFSET + TEXT_OFFSET; |
96 | #endif | ||
97 | .head.text : { | 95 | .head.text : { |
98 | _text = .; | 96 | _text = .; |
99 | HEAD_TEXT | 97 | HEAD_TEXT |
100 | } | 98 | } |
101 | 99 | ||
102 | #ifdef CONFIG_ARM_KERNMEM_PERMS | 100 | #ifdef CONFIG_DEBUG_RODATA |
103 | . = ALIGN(1<<SECTION_SHIFT); | 101 | . = ALIGN(1<<SECTION_SHIFT); |
104 | #endif | 102 | #endif |
105 | 103 | ||
@@ -123,7 +121,7 @@ SECTIONS | |||
123 | ARM_CPU_KEEP(PROC_INFO) | 121 | ARM_CPU_KEEP(PROC_INFO) |
124 | } | 122 | } |
125 | 123 | ||
126 | #ifdef CONFIG_DEBUG_RODATA | 124 | #ifdef CONFIG_DEBUG_ALIGN_RODATA |
127 | . = ALIGN(1<<SECTION_SHIFT); | 125 | . = ALIGN(1<<SECTION_SHIFT); |
128 | #endif | 126 | #endif |
129 | RO_DATA(PAGE_SIZE) | 127 | RO_DATA(PAGE_SIZE) |
@@ -158,32 +156,33 @@ SECTIONS | |||
158 | 156 | ||
159 | _etext = .; /* End of text and rodata section */ | 157 | _etext = .; /* End of text and rodata section */ |
160 | 158 | ||
161 | #ifndef CONFIG_XIP_KERNEL | 159 | #ifdef CONFIG_DEBUG_RODATA |
162 | # ifdef CONFIG_ARM_KERNMEM_PERMS | ||
163 | . = ALIGN(1<<SECTION_SHIFT); | 160 | . = ALIGN(1<<SECTION_SHIFT); |
164 | # else | 161 | #else |
165 | . = ALIGN(PAGE_SIZE); | 162 | . = ALIGN(PAGE_SIZE); |
166 | # endif | ||
167 | __init_begin = .; | ||
168 | #endif | 163 | #endif |
164 | __init_begin = .; | ||
165 | |||
169 | /* | 166 | /* |
170 | * The vectors and stubs are relocatable code, and the | 167 | * The vectors and stubs are relocatable code, and the |
171 | * only thing that matters is their relative offsets | 168 | * only thing that matters is their relative offsets |
172 | */ | 169 | */ |
173 | __vectors_start = .; | 170 | __vectors_start = .; |
174 | .vectors 0 : AT(__vectors_start) { | 171 | .vectors 0xffff0000 : AT(__vectors_start) { |
175 | *(.vectors) | 172 | *(.vectors) |
176 | } | 173 | } |
177 | . = __vectors_start + SIZEOF(.vectors); | 174 | . = __vectors_start + SIZEOF(.vectors); |
178 | __vectors_end = .; | 175 | __vectors_end = .; |
179 | 176 | ||
180 | __stubs_start = .; | 177 | __stubs_start = .; |
181 | .stubs 0x1000 : AT(__stubs_start) { | 178 | .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { |
182 | *(.stubs) | 179 | *(.stubs) |
183 | } | 180 | } |
184 | . = __stubs_start + SIZEOF(.stubs); | 181 | . = __stubs_start + SIZEOF(.stubs); |
185 | __stubs_end = .; | 182 | __stubs_end = .; |
186 | 183 | ||
184 | PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); | ||
185 | |||
187 | INIT_TEXT_SECTION(8) | 186 | INIT_TEXT_SECTION(8) |
188 | .exit.text : { | 187 | .exit.text : { |
189 | ARM_EXIT_KEEP(EXIT_TEXT) | 188 | ARM_EXIT_KEEP(EXIT_TEXT) |
@@ -214,37 +213,28 @@ SECTIONS | |||
214 | __pv_table_end = .; | 213 | __pv_table_end = .; |
215 | } | 214 | } |
216 | .init.data : { | 215 | .init.data : { |
217 | #ifndef CONFIG_XIP_KERNEL | ||
218 | INIT_DATA | 216 | INIT_DATA |
219 | #endif | ||
220 | INIT_SETUP(16) | 217 | INIT_SETUP(16) |
221 | INIT_CALLS | 218 | INIT_CALLS |
222 | CON_INITCALL | 219 | CON_INITCALL |
223 | SECURITY_INITCALL | 220 | SECURITY_INITCALL |
224 | INIT_RAM_FS | 221 | INIT_RAM_FS |
225 | } | 222 | } |
226 | #ifndef CONFIG_XIP_KERNEL | ||
227 | .exit.data : { | 223 | .exit.data : { |
228 | ARM_EXIT_KEEP(EXIT_DATA) | 224 | ARM_EXIT_KEEP(EXIT_DATA) |
229 | } | 225 | } |
230 | #endif | ||
231 | 226 | ||
232 | #ifdef CONFIG_SMP | 227 | #ifdef CONFIG_SMP |
233 | PERCPU_SECTION(L1_CACHE_BYTES) | 228 | PERCPU_SECTION(L1_CACHE_BYTES) |
234 | #endif | 229 | #endif |
235 | 230 | ||
236 | #ifdef CONFIG_XIP_KERNEL | 231 | #ifdef CONFIG_DEBUG_RODATA |
237 | __data_loc = ALIGN(4); /* location in binary */ | ||
238 | . = PAGE_OFFSET + TEXT_OFFSET; | ||
239 | #else | ||
240 | #ifdef CONFIG_ARM_KERNMEM_PERMS | ||
241 | . = ALIGN(1<<SECTION_SHIFT); | 232 | . = ALIGN(1<<SECTION_SHIFT); |
242 | #else | 233 | #else |
243 | . = ALIGN(THREAD_SIZE); | 234 | . = ALIGN(THREAD_SIZE); |
244 | #endif | 235 | #endif |
245 | __init_end = .; | 236 | __init_end = .; |
246 | __data_loc = .; | 237 | __data_loc = .; |
247 | #endif | ||
248 | 238 | ||
249 | .data : AT(__data_loc) { | 239 | .data : AT(__data_loc) { |
250 | _data = .; /* address in memory */ | 240 | _data = .; /* address in memory */ |
@@ -256,15 +246,6 @@ SECTIONS | |||
256 | */ | 246 | */ |
257 | INIT_TASK_DATA(THREAD_SIZE) | 247 | INIT_TASK_DATA(THREAD_SIZE) |
258 | 248 | ||
259 | #ifdef CONFIG_XIP_KERNEL | ||
260 | . = ALIGN(PAGE_SIZE); | ||
261 | __init_begin = .; | ||
262 | INIT_DATA | ||
263 | ARM_EXIT_KEEP(EXIT_DATA) | ||
264 | . = ALIGN(PAGE_SIZE); | ||
265 | __init_end = .; | ||
266 | #endif | ||
267 | |||
268 | NOSAVE_DATA | 249 | NOSAVE_DATA |
269 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) | 250 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) |
270 | READ_MOSTLY_DATA(L1_CACHE_BYTES) | 251 | READ_MOSTLY_DATA(L1_CACHE_BYTES) |
@@ -342,6 +323,15 @@ SECTIONS | |||
342 | STABS_DEBUG | 323 | STABS_DEBUG |
343 | } | 324 | } |
344 | 325 | ||
326 | #ifdef CONFIG_DEBUG_RODATA | ||
327 | /* | ||
328 | * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will | ||
329 | * be the first section-aligned location after __start_rodata. Otherwise, | ||
330 | * it will be equal to __start_rodata. | ||
331 | */ | ||
332 | __start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT); | ||
333 | #endif | ||
334 | |||
345 | /* | 335 | /* |
346 | * These must never be empty | 336 | * These must never be empty |
347 | * If you have to comment these two assert statements out, your | 337 | * If you have to comment these two assert statements out, your |
@@ -357,3 +347,5 @@ ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") | |||
357 | */ | 347 | */ |
358 | ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, | 348 | ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, |
359 | "HYP init code too big or misaligned") | 349 | "HYP init code too big or misaligned") |
350 | |||
351 | #endif /* CONFIG_XIP_KERNEL */ | ||
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 8fb97b93b6bb..53b456a5bbe0 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h | |||
@@ -30,7 +30,7 @@ | |||
30 | u32 *uart; | 30 | u32 *uart; |
31 | 31 | ||
32 | /* PORT_16C550A, in polled non-fifo mode */ | 32 | /* PORT_16C550A, in polled non-fifo mode */ |
33 | static void putc(char c) | 33 | static inline void putc(char c) |
34 | { | 34 | { |
35 | if (!uart) | 35 | if (!uart) |
36 | return; | 36 | return; |
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index 07152d00fc50..cbbdd84cf49a 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig | |||
@@ -68,7 +68,6 @@ config ARCH_NETWINDER | |||
68 | select ISA | 68 | select ISA |
69 | select ISA_DMA | 69 | select ISA_DMA |
70 | select PCI | 70 | select PCI |
71 | select VIRT_TO_BUS | ||
72 | help | 71 | help |
73 | Say Y here if you intend to run this kernel on the Rebel.COM | 72 | Say Y here if you intend to run this kernel on the Rebel.COM |
74 | NetWinder. Information about this machine can be found at: | 73 | NetWinder. Information about this machine can be found at: |
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index c279293f084c..d80879ce4963 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c | |||
@@ -63,7 +63,7 @@ static void __init keystone_init(void) | |||
63 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 63 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
64 | } | 64 | } |
65 | 65 | ||
66 | static phys_addr_t keystone_virt_to_idmap(unsigned long x) | 66 | static unsigned long keystone_virt_to_idmap(unsigned long x) |
67 | { | 67 | { |
68 | return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; | 68 | return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; |
69 | } | 69 | } |
diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h index c089a1aea674..a001c7c34df2 100644 --- a/arch/arm/mach-ks8695/include/mach/uncompress.h +++ b/arch/arm/mach-ks8695/include/mach/uncompress.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <mach/regs-uart.h> | 18 | #include <mach/regs-uart.h> |
19 | 19 | ||
20 | static void putc(char c) | 20 | static inline void putc(char c) |
21 | { | 21 | { |
22 | while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE)) | 22 | while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE)) |
23 | barrier(); | 23 | barrier(); |
diff --git a/arch/arm/mach-netx/include/mach/uncompress.h b/arch/arm/mach-netx/include/mach/uncompress.h index 5cb1051b5831..033875dbc32b 100644 --- a/arch/arm/mach-netx/include/mach/uncompress.h +++ b/arch/arm/mach-netx/include/mach/uncompress.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define FR_BUSY (1<<3) | 40 | #define FR_BUSY (1<<3) |
41 | #define FR_TXFF (1<<5) | 41 | #define FR_TXFF (1<<5) |
42 | 42 | ||
43 | static void putc(char c) | 43 | static inline void putc(char c) |
44 | { | 44 | { |
45 | unsigned long base; | 45 | unsigned long base; |
46 | 46 | ||
diff --git a/arch/arm/mach-omap1/include/mach/uncompress.h b/arch/arm/mach-omap1/include/mach/uncompress.h index 4869633de8cd..9cca6a56788f 100644 --- a/arch/arm/mach-omap1/include/mach/uncompress.h +++ b/arch/arm/mach-omap1/include/mach/uncompress.h | |||
@@ -45,7 +45,7 @@ static void set_omap_uart_info(unsigned char port) | |||
45 | *uart_info = port; | 45 | *uart_info = port; |
46 | } | 46 | } |
47 | 47 | ||
48 | static void putc(int c) | 48 | static inline void putc(int c) |
49 | { | 49 | { |
50 | if (!uart_base) | 50 | if (!uart_base) |
51 | return; | 51 | return; |
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h index 0fd4b0b8ef22..654a6f3f2547 100644 --- a/arch/arm/mach-rpc/include/mach/uncompress.h +++ b/arch/arm/mach-rpc/include/mach/uncompress.h | |||
@@ -76,7 +76,7 @@ int white; | |||
76 | /* | 76 | /* |
77 | * This does not append a newline | 77 | * This does not append a newline |
78 | */ | 78 | */ |
79 | static void putc(int c) | 79 | static inline void putc(int c) |
80 | { | 80 | { |
81 | extern void ll_write_char(char *, char c, char white); | 81 | extern void ll_write_char(char *, char c, char white); |
82 | int x,y; | 82 | int x,y; |
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h index 73093dc89829..a1a041b9740b 100644 --- a/arch/arm/mach-sa1100/include/mach/uncompress.h +++ b/arch/arm/mach-sa1100/include/mach/uncompress.h | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) | 20 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) |
21 | 21 | ||
22 | static void putc(int c) | 22 | static inline void putc(int c) |
23 | { | 23 | { |
24 | unsigned long serial_port; | 24 | unsigned long serial_port; |
25 | 25 | ||
diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h index 4b7c324ff664..3855ecebda6e 100644 --- a/arch/arm/mach-w90x900/include/mach/uncompress.h +++ b/arch/arm/mach-w90x900/include/mach/uncompress.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) | 27 | #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) |
28 | static volatile u32 * const uart_base = (u32 *)UART0_PA; | 28 | static volatile u32 * const uart_base = (u32 *)UART0_PA; |
29 | 29 | ||
30 | static void putc(int ch) | 30 | static inline void putc(int ch) |
31 | { | 31 | { |
32 | /* Check THRE and TEMT bits before we transmit the character. | 32 | /* Check THRE and TEMT bits before we transmit the character. |
33 | */ | 33 | */ |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 549f6d3aec5b..55347662e5ed 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -1037,24 +1037,26 @@ config ARCH_SUPPORTS_BIG_ENDIAN | |||
1037 | This option specifies the architecture can support big endian | 1037 | This option specifies the architecture can support big endian |
1038 | operation. | 1038 | operation. |
1039 | 1039 | ||
1040 | config ARM_KERNMEM_PERMS | ||
1041 | bool "Restrict kernel memory permissions" | ||
1042 | depends on MMU | ||
1043 | help | ||
1044 | If this is set, kernel memory other than kernel text (and rodata) | ||
1045 | will be made non-executable. The tradeoff is that each region is | ||
1046 | padded to section-size (1MiB) boundaries (because their permissions | ||
1047 | are different and splitting the 1M pages into 4K ones causes TLB | ||
1048 | performance problems), wasting memory. | ||
1049 | |||
1050 | config DEBUG_RODATA | 1040 | config DEBUG_RODATA |
1051 | bool "Make kernel text and rodata read-only" | 1041 | bool "Make kernel text and rodata read-only" |
1052 | depends on ARM_KERNMEM_PERMS | 1042 | depends on MMU && !XIP_KERNEL |
1043 | default y if CPU_V7 | ||
1044 | help | ||
1045 | If this is set, kernel text and rodata memory will be made | ||
1046 | read-only, and non-text kernel memory will be made non-executable. | ||
1047 | The tradeoff is that each region is padded to section-size (1MiB) | ||
1048 | boundaries (because their permissions are different and splitting | ||
1049 | the 1M pages into 4K ones causes TLB performance problems), which | ||
1050 | can waste memory. | ||
1051 | |||
1052 | config DEBUG_ALIGN_RODATA | ||
1053 | bool "Make rodata strictly non-executable" | ||
1054 | depends on DEBUG_RODATA | ||
1053 | default y | 1055 | default y |
1054 | help | 1056 | help |
1055 | If this is set, kernel text and rodata will be made read-only. This | 1057 | If this is set, rodata will be made explicitly non-executable. This |
1056 | is to help catch accidental or malicious attempts to change the | 1058 | provides protection on the rare chance that attackers might find and |
1057 | kernel's executable code. Additionally splits rodata from kernel | 1059 | use ROP gadgets that exist in the rodata section. This adds an |
1058 | text so it can be made explicitly non-executable. This creates | 1060 | additional section-aligned split of rodata from kernel text so it |
1059 | another section-size padded region, so it can waste more memory | 1061 | can be made explicitly non-executable. This padding may waste memory |
1060 | space while gaining the read-only protections. | 1062 | space to gain the additional protection. |
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 1e373d268c04..88255bea65e4 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <asm/cputype.h> | 22 | #include <asm/cputype.h> |
23 | #include <asm/hardware/cache-tauros2.h> | 23 | #include <asm/hardware/cache-tauros2.h> |
24 | 24 | ||
25 | /* CP15 PJ4 Control configuration register */ | ||
26 | #define CCR_L2C_PREFETCH_DISABLE BIT(24) | ||
27 | #define CCR_L2C_ECC_ENABLE BIT(23) | ||
28 | #define CCR_L2C_WAY7_4_DISABLE BIT(21) | ||
29 | #define CCR_L2C_BURST8_ENABLE BIT(20) | ||
25 | 30 | ||
26 | /* | 31 | /* |
27 | * When Tauros2 is used on a CPU that supports the v7 hierarchical | 32 | * When Tauros2 is used on a CPU that supports the v7 hierarchical |
@@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features) | |||
182 | u = read_extra_features(); | 187 | u = read_extra_features(); |
183 | 188 | ||
184 | if (features & CACHE_TAUROS2_PREFETCH_ON) | 189 | if (features & CACHE_TAUROS2_PREFETCH_ON) |
185 | u &= ~0x01000000; | 190 | u &= ~CCR_L2C_PREFETCH_DISABLE; |
186 | else | 191 | else |
187 | u |= 0x01000000; | 192 | u |= CCR_L2C_PREFETCH_DISABLE; |
188 | pr_info("Tauros2: %s L2 prefetch.\n", | 193 | pr_info("Tauros2: %s L2 prefetch.\n", |
189 | (features & CACHE_TAUROS2_PREFETCH_ON) | 194 | (features & CACHE_TAUROS2_PREFETCH_ON) |
190 | ? "Enabling" : "Disabling"); | 195 | ? "Enabling" : "Disabling"); |
191 | 196 | ||
192 | if (features & CACHE_TAUROS2_LINEFILL_BURST8) | 197 | if (features & CACHE_TAUROS2_LINEFILL_BURST8) |
193 | u |= 0x00100000; | 198 | u |= CCR_L2C_BURST8_ENABLE; |
194 | else | 199 | else |
195 | u &= ~0x00100000; | 200 | u &= ~CCR_L2C_BURST8_ENABLE; |
196 | pr_info("Tauros2: %s line fill burt8.\n", | 201 | pr_info("Tauros2: %s burst8 line fill.\n", |
197 | (features & CACHE_TAUROS2_LINEFILL_BURST8) | 202 | (features & CACHE_TAUROS2_LINEFILL_BURST8) |
198 | ? "Enabling" : "Disabling"); | 203 | ? "Enabling" : "Disabling"); |
199 | 204 | ||
@@ -287,16 +292,15 @@ void __init tauros2_init(unsigned int features) | |||
287 | node = of_find_matching_node(NULL, tauros2_ids); | 292 | node = of_find_matching_node(NULL, tauros2_ids); |
288 | if (!node) { | 293 | if (!node) { |
289 | pr_info("Not found marvell,tauros2-cache, disable it\n"); | 294 | pr_info("Not found marvell,tauros2-cache, disable it\n"); |
290 | return; | 295 | } else { |
296 | ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); | ||
297 | if (ret) { | ||
298 | pr_info("Not found marvell,tauros-cache-features property, " | ||
299 | "disable extra features\n"); | ||
300 | features = 0; | ||
301 | } else | ||
302 | features = f; | ||
291 | } | 303 | } |
292 | |||
293 | ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); | ||
294 | if (ret) { | ||
295 | pr_info("Not found marvell,tauros-cache-features property, " | ||
296 | "disable extra features\n"); | ||
297 | features = 0; | ||
298 | } else | ||
299 | features = f; | ||
300 | #endif | 304 | #endif |
301 | tauros2_internal_init(features); | 305 | tauros2_internal_init(features); |
302 | } | 306 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0eca3812527e..deac58d5f1f7 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -42,6 +42,55 @@ | |||
42 | #include "dma.h" | 42 | #include "dma.h" |
43 | #include "mm.h" | 43 | #include "mm.h" |
44 | 44 | ||
45 | struct arm_dma_alloc_args { | ||
46 | struct device *dev; | ||
47 | size_t size; | ||
48 | gfp_t gfp; | ||
49 | pgprot_t prot; | ||
50 | const void *caller; | ||
51 | bool want_vaddr; | ||
52 | }; | ||
53 | |||
54 | struct arm_dma_free_args { | ||
55 | struct device *dev; | ||
56 | size_t size; | ||
57 | void *cpu_addr; | ||
58 | struct page *page; | ||
59 | bool want_vaddr; | ||
60 | }; | ||
61 | |||
62 | struct arm_dma_allocator { | ||
63 | void *(*alloc)(struct arm_dma_alloc_args *args, | ||
64 | struct page **ret_page); | ||
65 | void (*free)(struct arm_dma_free_args *args); | ||
66 | }; | ||
67 | |||
68 | struct arm_dma_buffer { | ||
69 | struct list_head list; | ||
70 | void *virt; | ||
71 | struct arm_dma_allocator *allocator; | ||
72 | }; | ||
73 | |||
74 | static LIST_HEAD(arm_dma_bufs); | ||
75 | static DEFINE_SPINLOCK(arm_dma_bufs_lock); | ||
76 | |||
77 | static struct arm_dma_buffer *arm_dma_buffer_find(void *virt) | ||
78 | { | ||
79 | struct arm_dma_buffer *buf, *found = NULL; | ||
80 | unsigned long flags; | ||
81 | |||
82 | spin_lock_irqsave(&arm_dma_bufs_lock, flags); | ||
83 | list_for_each_entry(buf, &arm_dma_bufs, list) { | ||
84 | if (buf->virt == virt) { | ||
85 | list_del(&buf->list); | ||
86 | found = buf; | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | spin_unlock_irqrestore(&arm_dma_bufs_lock, flags); | ||
91 | return found; | ||
92 | } | ||
93 | |||
45 | /* | 94 | /* |
46 | * The DMA API is built upon the notion of "buffer ownership". A buffer | 95 | * The DMA API is built upon the notion of "buffer ownership". A buffer |
47 | * is either exclusively owned by the CPU (and therefore may be accessed | 96 | * is either exclusively owned by the CPU (and therefore may be accessed |
@@ -592,7 +641,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot) | |||
592 | #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL | 641 | #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL |
593 | #define __alloc_from_pool(size, ret_page) NULL | 642 | #define __alloc_from_pool(size, ret_page) NULL |
594 | #define __alloc_from_contiguous(dev, size, prot, ret, c, wv) NULL | 643 | #define __alloc_from_contiguous(dev, size, prot, ret, c, wv) NULL |
595 | #define __free_from_pool(cpu_addr, size) 0 | 644 | #define __free_from_pool(cpu_addr, size) do { } while (0) |
596 | #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) | 645 | #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) |
597 | #define __dma_free_remap(cpu_addr, size) do { } while (0) | 646 | #define __dma_free_remap(cpu_addr, size) do { } while (0) |
598 | 647 | ||
@@ -610,7 +659,78 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp, | |||
610 | return page_address(page); | 659 | return page_address(page); |
611 | } | 660 | } |
612 | 661 | ||
662 | static void *simple_allocator_alloc(struct arm_dma_alloc_args *args, | ||
663 | struct page **ret_page) | ||
664 | { | ||
665 | return __alloc_simple_buffer(args->dev, args->size, args->gfp, | ||
666 | ret_page); | ||
667 | } | ||
668 | |||
669 | static void simple_allocator_free(struct arm_dma_free_args *args) | ||
670 | { | ||
671 | __dma_free_buffer(args->page, args->size); | ||
672 | } | ||
613 | 673 | ||
674 | static struct arm_dma_allocator simple_allocator = { | ||
675 | .alloc = simple_allocator_alloc, | ||
676 | .free = simple_allocator_free, | ||
677 | }; | ||
678 | |||
679 | static void *cma_allocator_alloc(struct arm_dma_alloc_args *args, | ||
680 | struct page **ret_page) | ||
681 | { | ||
682 | return __alloc_from_contiguous(args->dev, args->size, args->prot, | ||
683 | ret_page, args->caller, | ||
684 | args->want_vaddr); | ||
685 | } | ||
686 | |||
687 | static void cma_allocator_free(struct arm_dma_free_args *args) | ||
688 | { | ||
689 | __free_from_contiguous(args->dev, args->page, args->cpu_addr, | ||
690 | args->size, args->want_vaddr); | ||
691 | } | ||
692 | |||
693 | static struct arm_dma_allocator cma_allocator = { | ||
694 | .alloc = cma_allocator_alloc, | ||
695 | .free = cma_allocator_free, | ||
696 | }; | ||
697 | |||
698 | static void *pool_allocator_alloc(struct arm_dma_alloc_args *args, | ||
699 | struct page **ret_page) | ||
700 | { | ||
701 | return __alloc_from_pool(args->size, ret_page); | ||
702 | } | ||
703 | |||
704 | static void pool_allocator_free(struct arm_dma_free_args *args) | ||
705 | { | ||
706 | __free_from_pool(args->cpu_addr, args->size); | ||
707 | } | ||
708 | |||
709 | static struct arm_dma_allocator pool_allocator = { | ||
710 | .alloc = pool_allocator_alloc, | ||
711 | .free = pool_allocator_free, | ||
712 | }; | ||
713 | |||
714 | static void *remap_allocator_alloc(struct arm_dma_alloc_args *args, | ||
715 | struct page **ret_page) | ||
716 | { | ||
717 | return __alloc_remap_buffer(args->dev, args->size, args->gfp, | ||
718 | args->prot, ret_page, args->caller, | ||
719 | args->want_vaddr); | ||
720 | } | ||
721 | |||
722 | static void remap_allocator_free(struct arm_dma_free_args *args) | ||
723 | { | ||
724 | if (args->want_vaddr) | ||
725 | __dma_free_remap(args->cpu_addr, args->size); | ||
726 | |||
727 | __dma_free_buffer(args->page, args->size); | ||
728 | } | ||
729 | |||
730 | static struct arm_dma_allocator remap_allocator = { | ||
731 | .alloc = remap_allocator_alloc, | ||
732 | .free = remap_allocator_free, | ||
733 | }; | ||
614 | 734 | ||
615 | static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | 735 | static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, |
616 | gfp_t gfp, pgprot_t prot, bool is_coherent, | 736 | gfp_t gfp, pgprot_t prot, bool is_coherent, |
@@ -619,7 +739,16 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
619 | u64 mask = get_coherent_dma_mask(dev); | 739 | u64 mask = get_coherent_dma_mask(dev); |
620 | struct page *page = NULL; | 740 | struct page *page = NULL; |
621 | void *addr; | 741 | void *addr; |
622 | bool want_vaddr; | 742 | bool allowblock, cma; |
743 | struct arm_dma_buffer *buf; | ||
744 | struct arm_dma_alloc_args args = { | ||
745 | .dev = dev, | ||
746 | .size = PAGE_ALIGN(size), | ||
747 | .gfp = gfp, | ||
748 | .prot = prot, | ||
749 | .caller = caller, | ||
750 | .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), | ||
751 | }; | ||
623 | 752 | ||
624 | #ifdef CONFIG_DMA_API_DEBUG | 753 | #ifdef CONFIG_DMA_API_DEBUG |
625 | u64 limit = (mask + 1) & ~mask; | 754 | u64 limit = (mask + 1) & ~mask; |
@@ -633,6 +762,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
633 | if (!mask) | 762 | if (!mask) |
634 | return NULL; | 763 | return NULL; |
635 | 764 | ||
765 | buf = kzalloc(sizeof(*buf), gfp); | ||
766 | if (!buf) | ||
767 | return NULL; | ||
768 | |||
636 | if (mask < 0xffffffffULL) | 769 | if (mask < 0xffffffffULL) |
637 | gfp |= GFP_DMA; | 770 | gfp |= GFP_DMA; |
638 | 771 | ||
@@ -644,28 +777,37 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
644 | * platform; see CONFIG_HUGETLBFS. | 777 | * platform; see CONFIG_HUGETLBFS. |
645 | */ | 778 | */ |
646 | gfp &= ~(__GFP_COMP); | 779 | gfp &= ~(__GFP_COMP); |
780 | args.gfp = gfp; | ||
647 | 781 | ||
648 | *handle = DMA_ERROR_CODE; | 782 | *handle = DMA_ERROR_CODE; |
649 | size = PAGE_ALIGN(size); | 783 | allowblock = gfpflags_allow_blocking(gfp); |
650 | want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); | 784 | cma = allowblock ? dev_get_cma_area(dev) : false; |
651 | 785 | ||
652 | if (nommu()) | 786 | if (cma) |
653 | addr = __alloc_simple_buffer(dev, size, gfp, &page); | 787 | buf->allocator = &cma_allocator; |
654 | else if (dev_get_cma_area(dev) && (gfp & __GFP_DIRECT_RECLAIM)) | 788 | else if (nommu() || is_coherent) |
655 | addr = __alloc_from_contiguous(dev, size, prot, &page, | 789 | buf->allocator = &simple_allocator; |
656 | caller, want_vaddr); | 790 | else if (allowblock) |
657 | else if (is_coherent) | 791 | buf->allocator = &remap_allocator; |
658 | addr = __alloc_simple_buffer(dev, size, gfp, &page); | ||
659 | else if (!gfpflags_allow_blocking(gfp)) | ||
660 | addr = __alloc_from_pool(size, &page); | ||
661 | else | 792 | else |
662 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, | 793 | buf->allocator = &pool_allocator; |
663 | caller, want_vaddr); | 794 | |
795 | addr = buf->allocator->alloc(&args, &page); | ||
796 | |||
797 | if (page) { | ||
798 | unsigned long flags; | ||
664 | 799 | ||
665 | if (page) | ||
666 | *handle = pfn_to_dma(dev, page_to_pfn(page)); | 800 | *handle = pfn_to_dma(dev, page_to_pfn(page)); |
801 | buf->virt = args.want_vaddr ? addr : page; | ||
802 | |||
803 | spin_lock_irqsave(&arm_dma_bufs_lock, flags); | ||
804 | list_add(&buf->list, &arm_dma_bufs); | ||
805 | spin_unlock_irqrestore(&arm_dma_bufs_lock, flags); | ||
806 | } else { | ||
807 | kfree(buf); | ||
808 | } | ||
667 | 809 | ||
668 | return want_vaddr ? addr : page; | 810 | return args.want_vaddr ? addr : page; |
669 | } | 811 | } |
670 | 812 | ||
671 | /* | 813 | /* |
@@ -741,25 +883,21 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, | |||
741 | bool is_coherent) | 883 | bool is_coherent) |
742 | { | 884 | { |
743 | struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); | 885 | struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); |
744 | bool want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); | 886 | struct arm_dma_buffer *buf; |
745 | 887 | struct arm_dma_free_args args = { | |
746 | size = PAGE_ALIGN(size); | 888 | .dev = dev, |
747 | 889 | .size = PAGE_ALIGN(size), | |
748 | if (nommu()) { | 890 | .cpu_addr = cpu_addr, |
749 | __dma_free_buffer(page, size); | 891 | .page = page, |
750 | } else if (!is_coherent && __free_from_pool(cpu_addr, size)) { | 892 | .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), |
893 | }; | ||
894 | |||
895 | buf = arm_dma_buffer_find(cpu_addr); | ||
896 | if (WARN(!buf, "Freeing invalid buffer %p\n", cpu_addr)) | ||
751 | return; | 897 | return; |
752 | } else if (!dev_get_cma_area(dev)) { | 898 | |
753 | if (want_vaddr && !is_coherent) | 899 | buf->allocator->free(&args); |
754 | __dma_free_remap(cpu_addr, size); | 900 | kfree(buf); |
755 | __dma_free_buffer(page, size); | ||
756 | } else { | ||
757 | /* | ||
758 | * Non-atomic allocations cannot be freed with IRQs disabled | ||
759 | */ | ||
760 | WARN_ON(irqs_disabled()); | ||
761 | __free_from_contiguous(dev, page, cpu_addr, size, want_vaddr); | ||
762 | } | ||
763 | } | 901 | } |
764 | 902 | ||
765 | void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, | 903 | void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, |
@@ -1122,6 +1260,9 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping, | |||
1122 | spin_unlock_irqrestore(&mapping->lock, flags); | 1260 | spin_unlock_irqrestore(&mapping->lock, flags); |
1123 | } | 1261 | } |
1124 | 1262 | ||
1263 | /* We'll try 2M, 1M, 64K, and finally 4K; array must end with 0! */ | ||
1264 | static const int iommu_order_array[] = { 9, 8, 4, 0 }; | ||
1265 | |||
1125 | static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, | 1266 | static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, |
1126 | gfp_t gfp, struct dma_attrs *attrs) | 1267 | gfp_t gfp, struct dma_attrs *attrs) |
1127 | { | 1268 | { |
@@ -1129,6 +1270,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, | |||
1129 | int count = size >> PAGE_SHIFT; | 1270 | int count = size >> PAGE_SHIFT; |
1130 | int array_size = count * sizeof(struct page *); | 1271 | int array_size = count * sizeof(struct page *); |
1131 | int i = 0; | 1272 | int i = 0; |
1273 | int order_idx = 0; | ||
1132 | 1274 | ||
1133 | if (array_size <= PAGE_SIZE) | 1275 | if (array_size <= PAGE_SIZE) |
1134 | pages = kzalloc(array_size, GFP_KERNEL); | 1276 | pages = kzalloc(array_size, GFP_KERNEL); |
@@ -1154,6 +1296,10 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, | |||
1154 | return pages; | 1296 | return pages; |
1155 | } | 1297 | } |
1156 | 1298 | ||
1299 | /* Go straight to 4K chunks if caller says it's OK. */ | ||
1300 | if (dma_get_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, attrs)) | ||
1301 | order_idx = ARRAY_SIZE(iommu_order_array) - 1; | ||
1302 | |||
1157 | /* | 1303 | /* |
1158 | * IOMMU can map any pages, so himem can also be used here | 1304 | * IOMMU can map any pages, so himem can also be used here |
1159 | */ | 1305 | */ |
@@ -1162,22 +1308,24 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, | |||
1162 | while (count) { | 1308 | while (count) { |
1163 | int j, order; | 1309 | int j, order; |
1164 | 1310 | ||
1165 | for (order = __fls(count); order > 0; --order) { | 1311 | order = iommu_order_array[order_idx]; |
1166 | /* | 1312 | |
1167 | * We do not want OOM killer to be invoked as long | 1313 | /* Drop down when we get small */ |
1168 | * as we can fall back to single pages, so we force | 1314 | if (__fls(count) < order) { |
1169 | * __GFP_NORETRY for orders higher than zero. | 1315 | order_idx++; |
1170 | */ | 1316 | continue; |
1171 | pages[i] = alloc_pages(gfp | __GFP_NORETRY, order); | ||
1172 | if (pages[i]) | ||
1173 | break; | ||
1174 | } | 1317 | } |
1175 | 1318 | ||
1176 | if (!pages[i]) { | 1319 | if (order) { |
1177 | /* | 1320 | /* See if it's easy to allocate a high-order chunk */ |
1178 | * Fall back to single page allocation. | 1321 | pages[i] = alloc_pages(gfp | __GFP_NORETRY, order); |
1179 | * Might invoke OOM killer as last resort. | 1322 | |
1180 | */ | 1323 | /* Go down a notch at first sign of pressure */ |
1324 | if (!pages[i]) { | ||
1325 | order_idx++; | ||
1326 | continue; | ||
1327 | } | ||
1328 | } else { | ||
1181 | pages[i] = alloc_pages(gfp, 0); | 1329 | pages[i] = alloc_pages(gfp, 0); |
1182 | if (!pages[i]) | 1330 | if (!pages[i]) |
1183 | goto error; | 1331 | goto error; |
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index d65909697165..bd274a05b8ff 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * page tables. | 15 | * page tables. |
16 | */ | 16 | */ |
17 | pgd_t *idmap_pgd; | 17 | pgd_t *idmap_pgd; |
18 | phys_addr_t (*arch_virt_to_idmap) (unsigned long x); | 18 | unsigned long (*arch_virt_to_idmap)(unsigned long x); |
19 | 19 | ||
20 | #ifdef CONFIG_ARM_LPAE | 20 | #ifdef CONFIG_ARM_LPAE |
21 | static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, | 21 | static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 49bd08178008..370581aeb871 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -572,8 +572,9 @@ void __init mem_init(void) | |||
572 | } | 572 | } |
573 | } | 573 | } |
574 | 574 | ||
575 | #ifdef CONFIG_ARM_KERNMEM_PERMS | 575 | #ifdef CONFIG_DEBUG_RODATA |
576 | struct section_perm { | 576 | struct section_perm { |
577 | const char *name; | ||
577 | unsigned long start; | 578 | unsigned long start; |
578 | unsigned long end; | 579 | unsigned long end; |
579 | pmdval_t mask; | 580 | pmdval_t mask; |
@@ -581,9 +582,13 @@ struct section_perm { | |||
581 | pmdval_t clear; | 582 | pmdval_t clear; |
582 | }; | 583 | }; |
583 | 584 | ||
585 | /* First section-aligned location at or after __start_rodata. */ | ||
586 | extern char __start_rodata_section_aligned[]; | ||
587 | |||
584 | static struct section_perm nx_perms[] = { | 588 | static struct section_perm nx_perms[] = { |
585 | /* Make pages tables, etc before _stext RW (set NX). */ | 589 | /* Make pages tables, etc before _stext RW (set NX). */ |
586 | { | 590 | { |
591 | .name = "pre-text NX", | ||
587 | .start = PAGE_OFFSET, | 592 | .start = PAGE_OFFSET, |
588 | .end = (unsigned long)_stext, | 593 | .end = (unsigned long)_stext, |
589 | .mask = ~PMD_SECT_XN, | 594 | .mask = ~PMD_SECT_XN, |
@@ -591,26 +596,26 @@ static struct section_perm nx_perms[] = { | |||
591 | }, | 596 | }, |
592 | /* Make init RW (set NX). */ | 597 | /* Make init RW (set NX). */ |
593 | { | 598 | { |
599 | .name = "init NX", | ||
594 | .start = (unsigned long)__init_begin, | 600 | .start = (unsigned long)__init_begin, |
595 | .end = (unsigned long)_sdata, | 601 | .end = (unsigned long)_sdata, |
596 | .mask = ~PMD_SECT_XN, | 602 | .mask = ~PMD_SECT_XN, |
597 | .prot = PMD_SECT_XN, | 603 | .prot = PMD_SECT_XN, |
598 | }, | 604 | }, |
599 | #ifdef CONFIG_DEBUG_RODATA | ||
600 | /* Make rodata NX (set RO in ro_perms below). */ | 605 | /* Make rodata NX (set RO in ro_perms below). */ |
601 | { | 606 | { |
602 | .start = (unsigned long)__start_rodata, | 607 | .name = "rodata NX", |
608 | .start = (unsigned long)__start_rodata_section_aligned, | ||
603 | .end = (unsigned long)__init_begin, | 609 | .end = (unsigned long)__init_begin, |
604 | .mask = ~PMD_SECT_XN, | 610 | .mask = ~PMD_SECT_XN, |
605 | .prot = PMD_SECT_XN, | 611 | .prot = PMD_SECT_XN, |
606 | }, | 612 | }, |
607 | #endif | ||
608 | }; | 613 | }; |
609 | 614 | ||
610 | #ifdef CONFIG_DEBUG_RODATA | ||
611 | static struct section_perm ro_perms[] = { | 615 | static struct section_perm ro_perms[] = { |
612 | /* Make kernel code and rodata RX (set RO). */ | 616 | /* Make kernel code and rodata RX (set RO). */ |
613 | { | 617 | { |
618 | .name = "text/rodata RO", | ||
614 | .start = (unsigned long)_stext, | 619 | .start = (unsigned long)_stext, |
615 | .end = (unsigned long)__init_begin, | 620 | .end = (unsigned long)__init_begin, |
616 | #ifdef CONFIG_ARM_LPAE | 621 | #ifdef CONFIG_ARM_LPAE |
@@ -623,7 +628,6 @@ static struct section_perm ro_perms[] = { | |||
623 | #endif | 628 | #endif |
624 | }, | 629 | }, |
625 | }; | 630 | }; |
626 | #endif | ||
627 | 631 | ||
628 | /* | 632 | /* |
629 | * Updates section permissions only for the current mm (sections are | 633 | * Updates section permissions only for the current mm (sections are |
@@ -670,8 +674,8 @@ void set_section_perms(struct section_perm *perms, int n, bool set, | |||
670 | for (i = 0; i < n; i++) { | 674 | for (i = 0; i < n; i++) { |
671 | if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || | 675 | if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || |
672 | !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { | 676 | !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { |
673 | pr_err("BUG: section %lx-%lx not aligned to %lx\n", | 677 | pr_err("BUG: %s section %lx-%lx not aligned to %lx\n", |
674 | perms[i].start, perms[i].end, | 678 | perms[i].name, perms[i].start, perms[i].end, |
675 | SECTION_SIZE); | 679 | SECTION_SIZE); |
676 | continue; | 680 | continue; |
677 | } | 681 | } |
@@ -712,7 +716,6 @@ void fix_kernmem_perms(void) | |||
712 | stop_machine(__fix_kernmem_perms, NULL, NULL); | 716 | stop_machine(__fix_kernmem_perms, NULL, NULL); |
713 | } | 717 | } |
714 | 718 | ||
715 | #ifdef CONFIG_DEBUG_RODATA | ||
716 | int __mark_rodata_ro(void *unused) | 719 | int __mark_rodata_ro(void *unused) |
717 | { | 720 | { |
718 | update_sections_early(ro_perms, ARRAY_SIZE(ro_perms)); | 721 | update_sections_early(ro_perms, ARRAY_SIZE(ro_perms)); |
@@ -735,11 +738,10 @@ void set_kernel_text_ro(void) | |||
735 | set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true, | 738 | set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true, |
736 | current->active_mm); | 739 | current->active_mm); |
737 | } | 740 | } |
738 | #endif /* CONFIG_DEBUG_RODATA */ | ||
739 | 741 | ||
740 | #else | 742 | #else |
741 | static inline void fix_kernmem_perms(void) { } | 743 | static inline void fix_kernmem_perms(void) { } |
742 | #endif /* CONFIG_ARM_KERNMEM_PERMS */ | 744 | #endif /* CONFIG_DEBUG_RODATA */ |
743 | 745 | ||
744 | void free_tcmmem(void) | 746 | void free_tcmmem(void) |
745 | { | 747 | { |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 88fbe0d23ca6..62f4d01941f7 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -1253,7 +1253,7 @@ static inline void prepare_page_table(void) | |||
1253 | 1253 | ||
1254 | #ifdef CONFIG_XIP_KERNEL | 1254 | #ifdef CONFIG_XIP_KERNEL |
1255 | /* The XIP kernel is mapped in the module area -- skip over it */ | 1255 | /* The XIP kernel is mapped in the module area -- skip over it */ |
1256 | addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK; | 1256 | addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK; |
1257 | #endif | 1257 | #endif |
1258 | for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE) | 1258 | for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE) |
1259 | pmd_clear(pmd_off_k(addr)); | 1259 | pmd_clear(pmd_off_k(addr)); |
@@ -1335,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc) | |||
1335 | #ifdef CONFIG_XIP_KERNEL | 1335 | #ifdef CONFIG_XIP_KERNEL |
1336 | map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); | 1336 | map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); |
1337 | map.virtual = MODULES_VADDR; | 1337 | map.virtual = MODULES_VADDR; |
1338 | map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; | 1338 | map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK; |
1339 | map.type = MT_ROM; | 1339 | map.type = MT_ROM; |
1340 | create_mapping(&map); | 1340 | create_mapping(&map); |
1341 | #endif | 1341 | #endif |
@@ -1426,7 +1426,11 @@ static void __init kmap_init(void) | |||
1426 | static void __init map_lowmem(void) | 1426 | static void __init map_lowmem(void) |
1427 | { | 1427 | { |
1428 | struct memblock_region *reg; | 1428 | struct memblock_region *reg; |
1429 | #ifdef CONFIG_XIP_KERNEL | ||
1430 | phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE); | ||
1431 | #else | ||
1429 | phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); | 1432 | phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); |
1433 | #endif | ||
1430 | phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); | 1434 | phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); |
1431 | 1435 | ||
1432 | /* Map all the lowmem memory banks. */ | 1436 | /* Map all the lowmem memory banks. */ |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 0f92d575a304..0f8963a7e7d9 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -487,7 +487,7 @@ __errata_finish: | |||
487 | 487 | ||
488 | .align 2 | 488 | .align 2 |
489 | __v7_setup_stack_ptr: | 489 | __v7_setup_stack_ptr: |
490 | .word __v7_setup_stack - . | 490 | .word PHYS_RELATIVE(__v7_setup_stack, .) |
491 | ENDPROC(__v7_setup) | 491 | ENDPROC(__v7_setup) |
492 | 492 | ||
493 | .bss | 493 | .bss |
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac812..ffb93db68e9c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/sched_clock.h> | 19 | #include <linux/sched_clock.h> |
20 | #include <plat/time.h> | 20 | #include <plat/time.h> |
21 | #include <asm/delay.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * MBus bridge block registers. | 24 | * MBus bridge block registers. |
@@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) | |||
188 | timer_base = _timer_base; | 189 | timer_base = _timer_base; |
189 | } | 190 | } |
190 | 191 | ||
192 | static unsigned long orion_delay_timer_read(void) | ||
193 | { | ||
194 | return ~readl(timer_base + TIMER0_VAL_OFF); | ||
195 | } | ||
196 | |||
197 | static struct delay_timer orion_delay_timer = { | ||
198 | .read_current_timer = orion_delay_timer_read, | ||
199 | }; | ||
200 | |||
191 | void __init | 201 | void __init |
192 | orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, | 202 | orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, |
193 | unsigned int irq, unsigned int tclk) | 203 | unsigned int irq, unsigned int tclk) |
@@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, | |||
202 | 212 | ||
203 | ticks_per_jiffy = (tclk + HZ/2) / HZ; | 213 | ticks_per_jiffy = (tclk + HZ/2) / HZ; |
204 | 214 | ||
215 | orion_delay_timer.freq = tclk; | ||
216 | register_current_timer_delay(&orion_delay_timer); | ||
217 | |||
205 | /* | 218 | /* |
206 | * Set scale and timer for sched_clock. | 219 | * Set scale and timer for sched_clock. |
207 | */ | 220 | */ |
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index f67f35b6edb1..42816bebb1e0 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/psci.h> | 22 | #include <linux/psci.h> |
23 | #include <linux/slab.h> | ||
24 | 23 | ||
25 | #include <uapi/linux/psci.h> | 24 | #include <uapi/linux/psci.h> |
26 | 25 | ||
@@ -28,73 +27,6 @@ | |||
28 | #include <asm/cpu_ops.h> | 27 | #include <asm/cpu_ops.h> |
29 | #include <asm/errno.h> | 28 | #include <asm/errno.h> |
30 | #include <asm/smp_plat.h> | 29 | #include <asm/smp_plat.h> |
31 | #include <asm/suspend.h> | ||
32 | |||
33 | static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); | ||
34 | |||
35 | static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu) | ||
36 | { | ||
37 | int i, ret, count = 0; | ||
38 | u32 *psci_states; | ||
39 | struct device_node *state_node, *cpu_node; | ||
40 | |||
41 | cpu_node = of_get_cpu_node(cpu, NULL); | ||
42 | if (!cpu_node) | ||
43 | return -ENODEV; | ||
44 | |||
45 | /* | ||
46 | * If the PSCI cpu_suspend function hook has not been initialized | ||
47 | * idle states must not be enabled, so bail out | ||
48 | */ | ||
49 | if (!psci_ops.cpu_suspend) | ||
50 | return -EOPNOTSUPP; | ||
51 | |||
52 | /* Count idle states */ | ||
53 | while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", | ||
54 | count))) { | ||
55 | count++; | ||
56 | of_node_put(state_node); | ||
57 | } | ||
58 | |||
59 | if (!count) | ||
60 | return -ENODEV; | ||
61 | |||
62 | psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); | ||
63 | if (!psci_states) | ||
64 | return -ENOMEM; | ||
65 | |||
66 | for (i = 0; i < count; i++) { | ||
67 | u32 state; | ||
68 | |||
69 | state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); | ||
70 | |||
71 | ret = of_property_read_u32(state_node, | ||
72 | "arm,psci-suspend-param", | ||
73 | &state); | ||
74 | if (ret) { | ||
75 | pr_warn(" * %s missing arm,psci-suspend-param property\n", | ||
76 | state_node->full_name); | ||
77 | of_node_put(state_node); | ||
78 | goto free_mem; | ||
79 | } | ||
80 | |||
81 | of_node_put(state_node); | ||
82 | pr_debug("psci-power-state %#x index %d\n", state, i); | ||
83 | if (!psci_power_state_is_valid(state)) { | ||
84 | pr_warn("Invalid PSCI power state %#x\n", state); | ||
85 | ret = -EINVAL; | ||
86 | goto free_mem; | ||
87 | } | ||
88 | psci_states[i] = state; | ||
89 | } | ||
90 | /* Idle states parsed correctly, initialize per-cpu pointer */ | ||
91 | per_cpu(psci_power_state, cpu) = psci_states; | ||
92 | return 0; | ||
93 | |||
94 | free_mem: | ||
95 | kfree(psci_states); | ||
96 | return ret; | ||
97 | } | ||
98 | 30 | ||
99 | static int __init cpu_psci_cpu_init(unsigned int cpu) | 31 | static int __init cpu_psci_cpu_init(unsigned int cpu) |
100 | { | 32 | { |
@@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu) | |||
178 | } | 110 | } |
179 | #endif | 111 | #endif |
180 | 112 | ||
181 | static int psci_suspend_finisher(unsigned long index) | ||
182 | { | ||
183 | u32 *state = __this_cpu_read(psci_power_state); | ||
184 | |||
185 | return psci_ops.cpu_suspend(state[index - 1], | ||
186 | virt_to_phys(cpu_resume)); | ||
187 | } | ||
188 | |||
189 | static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) | ||
190 | { | ||
191 | int ret; | ||
192 | u32 *state = __this_cpu_read(psci_power_state); | ||
193 | /* | ||
194 | * idle state index 0 corresponds to wfi, should never be called | ||
195 | * from the cpu_suspend operations | ||
196 | */ | ||
197 | if (WARN_ON_ONCE(!index)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | if (!psci_power_state_loses_context(state[index - 1])) | ||
201 | ret = psci_ops.cpu_suspend(state[index - 1], 0); | ||
202 | else | ||
203 | ret = cpu_suspend(index, psci_suspend_finisher); | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | const struct cpu_operations cpu_psci_ops = { | 113 | const struct cpu_operations cpu_psci_ops = { |
209 | .name = "psci", | 114 | .name = "psci", |
210 | #ifdef CONFIG_CPU_IDLE | 115 | #ifdef CONFIG_CPU_IDLE |
211 | .cpu_init_idle = cpu_psci_cpu_init_idle, | 116 | .cpu_init_idle = psci_cpu_init_idle, |
212 | .cpu_suspend = cpu_psci_cpu_suspend, | 117 | .cpu_suspend = psci_cpu_suspend_enter, |
213 | #endif | 118 | #endif |
214 | .cpu_init = cpu_psci_cpu_init, | 119 | .cpu_init = cpu_psci_cpu_init, |
215 | .cpu_prepare = cpu_psci_cpu_prepare, | 120 | .cpu_prepare = cpu_psci_cpu_prepare, |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c4da2df62e02..16688f50729c 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -560,6 +560,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) | |||
560 | struct device_attach_data *data = _data; | 560 | struct device_attach_data *data = _data; |
561 | struct device *dev = data->dev; | 561 | struct device *dev = data->dev; |
562 | bool async_allowed; | 562 | bool async_allowed; |
563 | int ret; | ||
563 | 564 | ||
564 | /* | 565 | /* |
565 | * Check if device has already been claimed. This may | 566 | * Check if device has already been claimed. This may |
@@ -570,8 +571,17 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) | |||
570 | if (dev->driver) | 571 | if (dev->driver) |
571 | return -EBUSY; | 572 | return -EBUSY; |
572 | 573 | ||
573 | if (!driver_match_device(drv, dev)) | 574 | ret = driver_match_device(drv, dev); |
575 | if (ret == 0) { | ||
576 | /* no match */ | ||
574 | return 0; | 577 | return 0; |
578 | } else if (ret == -EPROBE_DEFER) { | ||
579 | dev_dbg(dev, "Device match requests probe deferral\n"); | ||
580 | driver_deferred_probe_add(dev); | ||
581 | } else if (ret < 0) { | ||
582 | dev_dbg(dev, "Bus failed to match device: %d", ret); | ||
583 | return ret; | ||
584 | } /* ret > 0 means positive match */ | ||
575 | 585 | ||
576 | async_allowed = driver_allows_async_probing(drv); | 586 | async_allowed = driver_allows_async_probing(drv); |
577 | 587 | ||
@@ -691,6 +701,7 @@ void device_initial_probe(struct device *dev) | |||
691 | static int __driver_attach(struct device *dev, void *data) | 701 | static int __driver_attach(struct device *dev, void *data) |
692 | { | 702 | { |
693 | struct device_driver *drv = data; | 703 | struct device_driver *drv = data; |
704 | int ret; | ||
694 | 705 | ||
695 | /* | 706 | /* |
696 | * Lock device and try to bind to it. We drop the error | 707 | * Lock device and try to bind to it. We drop the error |
@@ -702,8 +713,17 @@ static int __driver_attach(struct device *dev, void *data) | |||
702 | * is an error. | 713 | * is an error. |
703 | */ | 714 | */ |
704 | 715 | ||
705 | if (!driver_match_device(drv, dev)) | 716 | ret = driver_match_device(drv, dev); |
717 | if (ret == 0) { | ||
718 | /* no match */ | ||
706 | return 0; | 719 | return 0; |
720 | } else if (ret == -EPROBE_DEFER) { | ||
721 | dev_dbg(dev, "Device match requests probe deferral\n"); | ||
722 | driver_deferred_probe_add(dev); | ||
723 | } else if (ret < 0) { | ||
724 | dev_dbg(dev, "Bus failed to match device: %d", ret); | ||
725 | return ret; | ||
726 | } /* ret > 0 means positive match */ | ||
707 | 727 | ||
708 | if (dev->parent) /* Needed for USB */ | 728 | if (dev->parent) /* Needed for USB */ |
709 | device_lock(dev->parent); | 729 | device_lock(dev->parent); |
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 779b6ff0c7ad..eb20b941154b 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -353,11 +353,25 @@ void clkdev_drop(struct clk_lookup *cl) | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL(clkdev_drop); | 354 | EXPORT_SYMBOL(clkdev_drop); |
355 | 355 | ||
356 | static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw, | ||
357 | const char *con_id, | ||
358 | const char *dev_id, ...) | ||
359 | { | ||
360 | struct clk_lookup *cl; | ||
361 | va_list ap; | ||
362 | |||
363 | va_start(ap, dev_id); | ||
364 | cl = vclkdev_create(hw, con_id, dev_id, ap); | ||
365 | va_end(ap); | ||
366 | |||
367 | return cl; | ||
368 | } | ||
369 | |||
356 | /** | 370 | /** |
357 | * clk_register_clkdev - register one clock lookup for a struct clk | 371 | * clk_register_clkdev - register one clock lookup for a struct clk |
358 | * @clk: struct clk to associate with all clk_lookups | 372 | * @clk: struct clk to associate with all clk_lookups |
359 | * @con_id: connection ID string on device | 373 | * @con_id: connection ID string on device |
360 | * @dev_id: format string describing device name | 374 | * @dev_id: string describing device name |
361 | * | 375 | * |
362 | * con_id or dev_id may be NULL as a wildcard, just as in the rest of | 376 | * con_id or dev_id may be NULL as a wildcard, just as in the rest of |
363 | * clkdev. | 377 | * clkdev. |
@@ -368,17 +382,22 @@ EXPORT_SYMBOL(clkdev_drop); | |||
368 | * after clk_register(). | 382 | * after clk_register(). |
369 | */ | 383 | */ |
370 | int clk_register_clkdev(struct clk *clk, const char *con_id, | 384 | int clk_register_clkdev(struct clk *clk, const char *con_id, |
371 | const char *dev_fmt, ...) | 385 | const char *dev_id) |
372 | { | 386 | { |
373 | struct clk_lookup *cl; | 387 | struct clk_lookup *cl; |
374 | va_list ap; | ||
375 | 388 | ||
376 | if (IS_ERR(clk)) | 389 | if (IS_ERR(clk)) |
377 | return PTR_ERR(clk); | 390 | return PTR_ERR(clk); |
378 | 391 | ||
379 | va_start(ap, dev_fmt); | 392 | /* |
380 | cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap); | 393 | * Since dev_id can be NULL, and NULL is handled specially, we must |
381 | va_end(ap); | 394 | * pass it as either a NULL format string, or with "%s". |
395 | */ | ||
396 | if (dev_id) | ||
397 | cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s", | ||
398 | dev_id); | ||
399 | else | ||
400 | cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL); | ||
382 | 401 | ||
383 | return cl ? 0 : -ENOMEM; | 402 | return cl ? 0 : -ENOMEM; |
384 | } | 403 | } |
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index f25cd79c8a79..11bfee8b79a9 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #define pr_fmt(fmt) "psci: " fmt | 14 | #define pr_fmt(fmt) "psci: " fmt |
15 | 15 | ||
16 | #include <linux/arm-smccc.h> | 16 | #include <linux/arm-smccc.h> |
17 | #include <linux/cpuidle.h> | ||
17 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
18 | #include <linux/linkage.h> | 19 | #include <linux/linkage.h> |
19 | #include <linux/of.h> | 20 | #include <linux/of.h> |
@@ -21,10 +22,12 @@ | |||
21 | #include <linux/printk.h> | 22 | #include <linux/printk.h> |
22 | #include <linux/psci.h> | 23 | #include <linux/psci.h> |
23 | #include <linux/reboot.h> | 24 | #include <linux/reboot.h> |
25 | #include <linux/slab.h> | ||
24 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
25 | 27 | ||
26 | #include <uapi/linux/psci.h> | 28 | #include <uapi/linux/psci.h> |
27 | 29 | ||
30 | #include <asm/cpuidle.h> | ||
28 | #include <asm/cputype.h> | 31 | #include <asm/cputype.h> |
29 | #include <asm/system_misc.h> | 32 | #include <asm/system_misc.h> |
30 | #include <asm/smp_plat.h> | 33 | #include <asm/smp_plat.h> |
@@ -244,6 +247,123 @@ static int __init psci_features(u32 psci_func_id) | |||
244 | psci_func_id, 0, 0); | 247 | psci_func_id, 0, 0); |
245 | } | 248 | } |
246 | 249 | ||
250 | #ifdef CONFIG_CPU_IDLE | ||
251 | static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); | ||
252 | |||
253 | static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu) | ||
254 | { | ||
255 | int i, ret, count = 0; | ||
256 | u32 *psci_states; | ||
257 | struct device_node *state_node; | ||
258 | |||
259 | /* | ||
260 | * If the PSCI cpu_suspend function hook has not been initialized | ||
261 | * idle states must not be enabled, so bail out | ||
262 | */ | ||
263 | if (!psci_ops.cpu_suspend) | ||
264 | return -EOPNOTSUPP; | ||
265 | |||
266 | /* Count idle states */ | ||
267 | while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", | ||
268 | count))) { | ||
269 | count++; | ||
270 | of_node_put(state_node); | ||
271 | } | ||
272 | |||
273 | if (!count) | ||
274 | return -ENODEV; | ||
275 | |||
276 | psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); | ||
277 | if (!psci_states) | ||
278 | return -ENOMEM; | ||
279 | |||
280 | for (i = 0; i < count; i++) { | ||
281 | u32 state; | ||
282 | |||
283 | state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); | ||
284 | |||
285 | ret = of_property_read_u32(state_node, | ||
286 | "arm,psci-suspend-param", | ||
287 | &state); | ||
288 | if (ret) { | ||
289 | pr_warn(" * %s missing arm,psci-suspend-param property\n", | ||
290 | state_node->full_name); | ||
291 | of_node_put(state_node); | ||
292 | goto free_mem; | ||
293 | } | ||
294 | |||
295 | of_node_put(state_node); | ||
296 | pr_debug("psci-power-state %#x index %d\n", state, i); | ||
297 | if (!psci_power_state_is_valid(state)) { | ||
298 | pr_warn("Invalid PSCI power state %#x\n", state); | ||
299 | ret = -EINVAL; | ||
300 | goto free_mem; | ||
301 | } | ||
302 | psci_states[i] = state; | ||
303 | } | ||
304 | /* Idle states parsed correctly, initialize per-cpu pointer */ | ||
305 | per_cpu(psci_power_state, cpu) = psci_states; | ||
306 | return 0; | ||
307 | |||
308 | free_mem: | ||
309 | kfree(psci_states); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | int psci_cpu_init_idle(unsigned int cpu) | ||
314 | { | ||
315 | struct device_node *cpu_node; | ||
316 | int ret; | ||
317 | |||
318 | cpu_node = of_get_cpu_node(cpu, NULL); | ||
319 | if (!cpu_node) | ||
320 | return -ENODEV; | ||
321 | |||
322 | ret = psci_dt_cpu_init_idle(cpu_node, cpu); | ||
323 | |||
324 | of_node_put(cpu_node); | ||
325 | |||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static int psci_suspend_finisher(unsigned long index) | ||
330 | { | ||
331 | u32 *state = __this_cpu_read(psci_power_state); | ||
332 | |||
333 | return psci_ops.cpu_suspend(state[index - 1], | ||
334 | virt_to_phys(cpu_resume)); | ||
335 | } | ||
336 | |||
337 | int psci_cpu_suspend_enter(unsigned long index) | ||
338 | { | ||
339 | int ret; | ||
340 | u32 *state = __this_cpu_read(psci_power_state); | ||
341 | /* | ||
342 | * idle state index 0 corresponds to wfi, should never be called | ||
343 | * from the cpu_suspend operations | ||
344 | */ | ||
345 | if (WARN_ON_ONCE(!index)) | ||
346 | return -EINVAL; | ||
347 | |||
348 | if (!psci_power_state_loses_context(state[index - 1])) | ||
349 | ret = psci_ops.cpu_suspend(state[index - 1], 0); | ||
350 | else | ||
351 | ret = cpu_suspend(index, psci_suspend_finisher); | ||
352 | |||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | /* ARM specific CPU idle operations */ | ||
357 | #ifdef CONFIG_ARM | ||
358 | static struct cpuidle_ops psci_cpuidle_ops __initdata = { | ||
359 | .suspend = psci_cpu_suspend_enter, | ||
360 | .init = psci_dt_cpu_init_idle, | ||
361 | }; | ||
362 | |||
363 | CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops); | ||
364 | #endif | ||
365 | #endif | ||
366 | |||
247 | static int psci_system_suspend(unsigned long unused) | 367 | static int psci_system_suspend(unsigned long unused) |
248 | { | 368 | { |
249 | return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), | 369 | return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), |
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index c33127284cfe..5361197f3e57 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c | |||
@@ -23,13 +23,16 @@ | |||
23 | 23 | ||
24 | struct vb2_dc_conf { | 24 | struct vb2_dc_conf { |
25 | struct device *dev; | 25 | struct device *dev; |
26 | struct dma_attrs attrs; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct vb2_dc_buf { | 29 | struct vb2_dc_buf { |
29 | struct device *dev; | 30 | struct device *dev; |
30 | void *vaddr; | 31 | void *vaddr; |
31 | unsigned long size; | 32 | unsigned long size; |
33 | void *cookie; | ||
32 | dma_addr_t dma_addr; | 34 | dma_addr_t dma_addr; |
35 | struct dma_attrs attrs; | ||
33 | enum dma_data_direction dma_dir; | 36 | enum dma_data_direction dma_dir; |
34 | struct sg_table *dma_sgt; | 37 | struct sg_table *dma_sgt; |
35 | struct frame_vector *vec; | 38 | struct frame_vector *vec; |
@@ -131,7 +134,8 @@ static void vb2_dc_put(void *buf_priv) | |||
131 | sg_free_table(buf->sgt_base); | 134 | sg_free_table(buf->sgt_base); |
132 | kfree(buf->sgt_base); | 135 | kfree(buf->sgt_base); |
133 | } | 136 | } |
134 | dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr); | 137 | dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr, |
138 | &buf->attrs); | ||
135 | put_device(buf->dev); | 139 | put_device(buf->dev); |
136 | kfree(buf); | 140 | kfree(buf); |
137 | } | 141 | } |
@@ -147,14 +151,18 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size, | |||
147 | if (!buf) | 151 | if (!buf) |
148 | return ERR_PTR(-ENOMEM); | 152 | return ERR_PTR(-ENOMEM); |
149 | 153 | ||
150 | buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, | 154 | buf->attrs = conf->attrs; |
151 | GFP_KERNEL | gfp_flags); | 155 | buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr, |
152 | if (!buf->vaddr) { | 156 | GFP_KERNEL | gfp_flags, &buf->attrs); |
157 | if (!buf->cookie) { | ||
153 | dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); | 158 | dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); |
154 | kfree(buf); | 159 | kfree(buf); |
155 | return ERR_PTR(-ENOMEM); | 160 | return ERR_PTR(-ENOMEM); |
156 | } | 161 | } |
157 | 162 | ||
163 | if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->attrs)) | ||
164 | buf->vaddr = buf->cookie; | ||
165 | |||
158 | /* Prevent the device from being released while the buffer is used */ | 166 | /* Prevent the device from being released while the buffer is used */ |
159 | buf->dev = get_device(dev); | 167 | buf->dev = get_device(dev); |
160 | buf->size = size; | 168 | buf->size = size; |
@@ -185,8 +193,8 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) | |||
185 | */ | 193 | */ |
186 | vma->vm_pgoff = 0; | 194 | vma->vm_pgoff = 0; |
187 | 195 | ||
188 | ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr, | 196 | ret = dma_mmap_attrs(buf->dev, vma, buf->cookie, |
189 | buf->dma_addr, buf->size); | 197 | buf->dma_addr, buf->size, &buf->attrs); |
190 | 198 | ||
191 | if (ret) { | 199 | if (ret) { |
192 | pr_err("Remapping memory failed, error: %d\n", ret); | 200 | pr_err("Remapping memory failed, error: %d\n", ret); |
@@ -329,7 +337,7 @@ static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum) | |||
329 | { | 337 | { |
330 | struct vb2_dc_buf *buf = dbuf->priv; | 338 | struct vb2_dc_buf *buf = dbuf->priv; |
331 | 339 | ||
332 | return buf->vaddr + pgnum * PAGE_SIZE; | 340 | return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL; |
333 | } | 341 | } |
334 | 342 | ||
335 | static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf) | 343 | static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf) |
@@ -368,8 +376,8 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) | |||
368 | return NULL; | 376 | return NULL; |
369 | } | 377 | } |
370 | 378 | ||
371 | ret = dma_get_sgtable(buf->dev, sgt, buf->vaddr, buf->dma_addr, | 379 | ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr, |
372 | buf->size); | 380 | buf->size, &buf->attrs); |
373 | if (ret < 0) { | 381 | if (ret < 0) { |
374 | dev_err(buf->dev, "failed to get scatterlist from DMA API\n"); | 382 | dev_err(buf->dev, "failed to get scatterlist from DMA API\n"); |
375 | kfree(sgt); | 383 | kfree(sgt); |
@@ -721,7 +729,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = { | |||
721 | }; | 729 | }; |
722 | EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); | 730 | EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); |
723 | 731 | ||
724 | void *vb2_dma_contig_init_ctx(struct device *dev) | 732 | void *vb2_dma_contig_init_ctx_attrs(struct device *dev, |
733 | struct dma_attrs *attrs) | ||
725 | { | 734 | { |
726 | struct vb2_dc_conf *conf; | 735 | struct vb2_dc_conf *conf; |
727 | 736 | ||
@@ -730,10 +739,12 @@ void *vb2_dma_contig_init_ctx(struct device *dev) | |||
730 | return ERR_PTR(-ENOMEM); | 739 | return ERR_PTR(-ENOMEM); |
731 | 740 | ||
732 | conf->dev = dev; | 741 | conf->dev = dev; |
742 | if (attrs) | ||
743 | conf->attrs = *attrs; | ||
733 | 744 | ||
734 | return conf; | 745 | return conf; |
735 | } | 746 | } |
736 | EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx); | 747 | EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx_attrs); |
737 | 748 | ||
738 | void vb2_dma_contig_cleanup_ctx(void *alloc_ctx) | 749 | void vb2_dma_contig_cleanup_ctx(void *alloc_ctx) |
739 | { | 750 | { |
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 33557481d452..fc82743aefb6 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c | |||
@@ -62,7 +62,7 @@ static int nvdimm_bus_match(struct device *dev, struct device_driver *drv) | |||
62 | { | 62 | { |
63 | struct nd_device_driver *nd_drv = to_nd_device_driver(drv); | 63 | struct nd_device_driver *nd_drv = to_nd_device_driver(drv); |
64 | 64 | ||
65 | return test_bit(to_nd_device_type(dev), &nd_drv->type); | 65 | return !!test_bit(to_nd_device_type(dev), &nd_drv->type); |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct module *to_bus_provider(struct device *dev) | 68 | static struct module *to_bus_provider(struct device *dev) |
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index 08bffcc466de..c2c04f7cbe8a 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h | |||
@@ -44,8 +44,7 @@ struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id, | |||
44 | void clkdev_add_table(struct clk_lookup *, size_t); | 44 | void clkdev_add_table(struct clk_lookup *, size_t); |
45 | int clk_add_alias(const char *, const char *, const char *, struct device *); | 45 | int clk_add_alias(const char *, const char *, const char *, struct device *); |
46 | 46 | ||
47 | int clk_register_clkdev(struct clk *, const char *, const char *, ...) | 47 | int clk_register_clkdev(struct clk *, const char *, const char *); |
48 | __printf(3, 4); | ||
49 | int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); | 48 | int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); |
50 | 49 | ||
51 | #ifdef CONFIG_COMMON_CLK | 50 | #ifdef CONFIG_COMMON_CLK |
diff --git a/include/linux/device.h b/include/linux/device.h index 2d0e6e541d52..88192d098aed 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -70,8 +70,11 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); | |||
70 | * @dev_groups: Default attributes of the devices on the bus. | 70 | * @dev_groups: Default attributes of the devices on the bus. |
71 | * @drv_groups: Default attributes of the device drivers on the bus. | 71 | * @drv_groups: Default attributes of the device drivers on the bus. |
72 | * @match: Called, perhaps multiple times, whenever a new device or driver | 72 | * @match: Called, perhaps multiple times, whenever a new device or driver |
73 | * is added for this bus. It should return a nonzero value if the | 73 | * is added for this bus. It should return a positive value if the |
74 | * given device can be handled by the given driver. | 74 | * given device can be handled by the given driver and zero |
75 | * otherwise. It may also return error code if determining that | ||
76 | * the driver supports the device is not possible. In case of | ||
77 | * -EPROBE_DEFER it will queue the device for deferred probing. | ||
75 | * @uevent: Called when a device is added, removed, or a few other things | 78 | * @uevent: Called when a device is added, removed, or a few other things |
76 | * that generate uevents to add the environment variables. | 79 | * that generate uevents to add the environment variables. |
77 | * @probe: Called when a new device or driver add to this bus, and callback | 80 | * @probe: Called when a new device or driver add to this bus, and callback |
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index 99c0be00b47c..5246239a4953 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h | |||
@@ -18,6 +18,7 @@ enum dma_attr { | |||
18 | DMA_ATTR_NO_KERNEL_MAPPING, | 18 | DMA_ATTR_NO_KERNEL_MAPPING, |
19 | DMA_ATTR_SKIP_CPU_SYNC, | 19 | DMA_ATTR_SKIP_CPU_SYNC, |
20 | DMA_ATTR_FORCE_CONTIGUOUS, | 20 | DMA_ATTR_FORCE_CONTIGUOUS, |
21 | DMA_ATTR_ALLOC_SINGLE_PAGES, | ||
21 | DMA_ATTR_MAX, | 22 | DMA_ATTR_MAX, |
22 | }; | 23 | }; |
23 | 24 | ||
diff --git a/include/linux/psci.h b/include/linux/psci.h index 12c4865457ad..393efe2edf9a 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h | |||
@@ -24,6 +24,9 @@ bool psci_tos_resident_on(int cpu); | |||
24 | bool psci_power_state_loses_context(u32 state); | 24 | bool psci_power_state_loses_context(u32 state); |
25 | bool psci_power_state_is_valid(u32 state); | 25 | bool psci_power_state_is_valid(u32 state); |
26 | 26 | ||
27 | int psci_cpu_init_idle(unsigned int cpu); | ||
28 | int psci_cpu_suspend_enter(unsigned long index); | ||
29 | |||
27 | struct psci_operations { | 30 | struct psci_operations { |
28 | int (*cpu_suspend)(u32 state, unsigned long entry_point); | 31 | int (*cpu_suspend)(u32 state, unsigned long entry_point); |
29 | int (*cpu_off)(u32 state); | 32 | int (*cpu_off)(u32 state); |
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h index c33dfa69d7ab..2087c9a68be3 100644 --- a/include/media/videobuf2-dma-contig.h +++ b/include/media/videobuf2-dma-contig.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <media/videobuf2-v4l2.h> | 16 | #include <media/videobuf2-v4l2.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | 18 | ||
19 | struct dma_attrs; | ||
20 | |||
19 | static inline dma_addr_t | 21 | static inline dma_addr_t |
20 | vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) | 22 | vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) |
21 | { | 23 | { |
@@ -24,7 +26,14 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no) | |||
24 | return *addr; | 26 | return *addr; |
25 | } | 27 | } |
26 | 28 | ||
27 | void *vb2_dma_contig_init_ctx(struct device *dev); | 29 | void *vb2_dma_contig_init_ctx_attrs(struct device *dev, |
30 | struct dma_attrs *attrs); | ||
31 | |||
32 | static inline void *vb2_dma_contig_init_ctx(struct device *dev) | ||
33 | { | ||
34 | return vb2_dma_contig_init_ctx_attrs(dev, NULL); | ||
35 | } | ||
36 | |||
28 | void vb2_dma_contig_cleanup_ctx(void *alloc_ctx); | 37 | void vb2_dma_contig_cleanup_ctx(void *alloc_ctx); |
29 | 38 | ||
30 | extern const struct vb2_mem_ops vb2_dma_contig_memops; | 39 | extern const struct vb2_mem_ops vb2_dma_contig_memops; |