Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Mar 2016 23:31:54 +0000 (16:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Mar 2016 23:31:54 +0000 (16:31 -0700)
Pull ARM updates from Russell King:
 "Another mixture of changes this time around:

   - Split XIP linker file from main linker file to make it more
     maintainable, and various XIP fixes, and clean up a resulting
     macro.

   - Decompressor cleanups from Masahiro Yamada

   - Avoid printing an error for a missing L2 cache

   - Remove some duplicated symbols in System.map, and move
     vectors/stubs back into kernel VMA

   - Various low priority fixes from Arnd

   - Updates to allow bus match functions to return negative errno
     values, touching some drivers and the driver core.  Greg has acked
     these changes.

   - Virtualisation platform udpates form Jean-Philippe Brucker.

   - Security enhancements from Kees Cook

   - Rework some Kconfig dependencies and move PSCI idle management code
     out of arch/arm into drivers/firmware/psci.c

   - ARM DMA mapping updates, touching media, acked by Mauro.

   - Fix places in ARM code which should be using virt_to_idmap() so
     that Keystone2 can work.

   - Fix Marvell Tauros2 to work again with non-DT boots.

   - Provide a delay timer for ARM Orion platforms"

* 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (45 commits)
  ARM: 8546/1: dma-mapping: refactor to fix coherent+cma+gfp=0
  ARM: 8547/1: dma-mapping: store buffer information
  ARM: 8543/1: decompressor: rename suffix_y to compress-y
  ARM: 8542/1: decompressor: merge piggy.*.S and simplify Makefile
  ARM: 8541/1: decompressor: drop redundant FORCE in Makefile
  ARM: 8540/1: decompressor: use clean-files instead of extra-y to clean files
  ARM: 8539/1: decompressor: drop more unneeded assignments to "targets"
  ARM: 8538/1: decompressor: drop unneeded assignments to "targets"
  ARM: 8532/1: uncompress: mark putc as inline
  ARM: 8531/1: turn init_new_context into an inline function
  ARM: 8530/1: remove VIRT_TO_BUS
  ARM: 8537/1: drop unused DEBUG_RODATA from XIP_KERNEL
  ARM: 8536/1: mm: hide __start_rodata_section_aligned for non-debug builds
  ARM: 8535/1: mm: DEBUG_RODATA makes no sense with XIP_KERNEL
  ARM: 8534/1: virt: fix hyp-stub build for pre-ARMv7 CPUs
  ARM: make the physical-relative calculation more obvious
  ARM: 8512/1: proc-v7.S: Adjust stack address when XIP_KERNEL
  ARM: 8411/1: Add default SPARSEMEM settings
  ARM: 8503/1: clk_register_clkdev: remove format string interface
  ARM: 8529/1: remove 'i' and 'zi' targets
  ...

58 files changed:
Documentation/DMA-attributes.txt
Documentation/driver-model/porting.txt
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/compressed/.gitignore
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/piggy.S [new file with mode: 0644]
arch/arm/boot/compressed/piggy.gzip.S [deleted file]
arch/arm/boot/compressed/piggy.lz4.S [deleted file]
arch/arm/boot/compressed/piggy.lzma.S [deleted file]
arch/arm/boot/compressed/piggy.lzo.S [deleted file]
arch/arm/boot/compressed/piggy.xzkern.S [deleted file]
arch/arm/common/sa1111.c
arch/arm/include/asm/Kbuild
arch/arm/include/asm/div64.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/sections.h [new file with mode: 0644]
arch/arm/include/asm/sparsemem.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/hibernate.c
arch/arm/kernel/hyp-stub.S
arch/arm/kernel/irq.c
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/module.c
arch/arm/kernel/reboot.c
arch/arm/kernel/topology.c
arch/arm/kernel/vmlinux-xip.lds.S [new file with mode: 0644]
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-davinci/include/mach/uncompress.h
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-keystone/keystone.c
arch/arm/mach-ks8695/include/mach/uncompress.h
arch/arm/mach-netx/include/mach/uncompress.h
arch/arm/mach-omap1/include/mach/uncompress.h
arch/arm/mach-rpc/include/mach/uncompress.h
arch/arm/mach-sa1100/include/mach/uncompress.h
arch/arm/mach-w90x900/include/mach/uncompress.h
arch/arm/mm/Kconfig
arch/arm/mm/cache-tauros2.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/idmap.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-v7.S
arch/arm/plat-orion/time.c
arch/arm64/kernel/psci.c
drivers/base/dd.c
drivers/clk/clkdev.c
drivers/firmware/psci.c
drivers/media/v4l2-core/videobuf2-dma-contig.c
drivers/nvdimm/bus.c
include/linux/clkdev.h
include/linux/device.h
include/linux/dma-attrs.h
include/linux/psci.h
include/media/videobuf2-dma-contig.h

index 18dc52c4f2a0b13a42d9867c36c94f4774bf58e2..e8cf9cf873b37577eeed325b4b7cc8dc0710ec9a 100644 (file)
@@ -100,3 +100,29 @@ allocated by dma_alloc_attrs() function from individual pages if it can
 be mapped as contiguous chunk into device dma address space. By
 specifying this attribute the allocated buffer is forced to be contiguous
 also in physical memory.
+
+DMA_ATTR_ALLOC_SINGLE_PAGES
+---------------------------
+
+This is a hint to the DMA-mapping subsystem that it's probably not worth
+the time to try to allocate memory to in a way that gives better TLB
+efficiency (AKA it's not worth trying to build the mapping out of larger
+pages).  You might want to specify this if:
+- You know that the accesses to this memory won't thrash the TLB.
+  You might know that the accesses are likely to be sequential or
+  that they aren't sequential but it's unlikely you'll ping-pong
+  between many addresses that are likely to be in different physical
+  pages.
+- You know that the penalty of TLB misses while accessing the
+  memory will be small enough to be inconsequential.  If you are
+  doing a heavy operation like decryption or decompression this
+  might be the case.
+- You know that the DMA mapping is fairly transitory.  If you expect
+  the mapping to have a short lifetime then it may be worth it to
+  optimize allocation (avoid coming up with large pages) instead of
+  getting the slight performance win of larger pages.
+Setting this hint doesn't guarantee that you won't get huge pages, but it
+means that we won't try quite as hard to get them.
+
+NOTE: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM,
+though ARM64 patches will likely be posted soon.
index 92d86f7271b4d960431e3333ce5d0de3b9f9889e..453053f1661f47e2dc3c75d0564b2105e8ddfb22 100644 (file)
@@ -340,8 +340,10 @@ comparison:
 
   int (*match)(struct device * dev, struct device_driver * drv);
 
-match should return '1' if the driver supports the device, and '0'
-otherwise. 
+match should return positive value if the driver supports the device,
+and zero otherwise. It may also return error code (for example
+-EPROBE_DEFER) if determining that given driver supports the device is
+not possible.
 
 When a device is registered, the bus's list of drivers is iterated
 over. bus->match() is called for each one until a match is found. 
index 1d00da16d980707e633a2391fac51381254276a7..f6c185f2d8b0940da84ed59808c0047de14c268e 100644 (file)
@@ -572,7 +572,6 @@ config ARCH_RPC
        select NEED_MACH_IO_H
        select NEED_MACH_MEMORY_H
        select NO_IOPORT_MAP
-       select VIRT_TO_BUS
        help
          On the Acorn Risc-PC, Linux can support the internal IDE disk and
          CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -1336,7 +1335,6 @@ config BIG_LITTLE
 config BL_SWITCHER
        bool "big.LITTLE switcher support"
        depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC
-       select ARM_CPU_SUSPEND
        select CPU_PM
        help
          The big.LITTLE "switcher" provides the core functionality to
@@ -2110,7 +2108,8 @@ config ARCH_SUSPEND_POSSIBLE
        def_bool y
 
 config ARM_CPU_SUSPEND
-       def_bool PM_SLEEP
+       def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW
+       depends on ARCH_SUSPEND_POSSIBLE
 
 config ARCH_HIBERNATION_POSSIBLE
        bool
index fe254108d1d92c88bb05b90221ca314edcaceedb..46fb1cac2698a06d4af77c0cd85fbc453761bc54 100644 (file)
@@ -352,7 +352,6 @@ archclean:
 
 # My testing targets (bypasses dependencies)
 bp:;   $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
-i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
 
 
 define archhelp
index 9eca7aee927f3081975d7372a66a358565c33c56..48fab15cfc0218e1a8e7a0bab389dc766d8ce3e7 100644 (file)
@@ -88,7 +88,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE
        $(call if_changed,objcopy)
        @$(kecho) '  Kernel: $@ is ready'
 
-PHONY += initrd FORCE
+PHONY += initrd
 initrd:
        @test "$(INITRD_PHYS)" != "" || \
        (echo This machine does not support INITRD; exit -1)
@@ -107,12 +107,4 @@ uinstall:
        $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
        $(obj)/uImage System.map "$(INSTALL_PATH)"
 
-zi:
-       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
-       $(obj)/zImage System.map "$(INSTALL_PATH)"
-
-i:
-       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
-       $(obj)/Image System.map "$(INSTALL_PATH)"
-
 subdir-            := bootp compressed dts
index 0714e0334e33c9790b221d03859574b2f4e774ad..86b2f5d28240bab4f27217daadbe7d44b64b2a1c 100644 (file)
@@ -3,11 +3,7 @@ bswapsdi2.S
 font.c
 lib1funcs.S
 hyp-stub.S
-piggy.gzip
-piggy.lzo
-piggy.lzma
-piggy.xzkern
-piggy.lz4
+piggy_data
 vmlinux
 vmlinux.lds
 
index 43788b1a1ac5e64372e1f3d3b012ba97a2e2d6ea..d50430c40045dd3e43fe37abf63f11a011e4c687 100644 (file)
@@ -66,11 +66,11 @@ endif
 
 CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
 
-suffix_$(CONFIG_KERNEL_GZIP) = gzip
-suffix_$(CONFIG_KERNEL_LZO)  = lzo
-suffix_$(CONFIG_KERNEL_LZMA) = lzma
-suffix_$(CONFIG_KERNEL_XZ)   = xzkern
-suffix_$(CONFIG_KERNEL_LZ4)  = lz4
+compress-$(CONFIG_KERNEL_GZIP) = gzip
+compress-$(CONFIG_KERNEL_LZO)  = lzo
+compress-$(CONFIG_KERNEL_LZMA) = lzma
+compress-$(CONFIG_KERNEL_XZ)   = xzkern
+compress-$(CONFIG_KERNEL_LZ4)  = lz4
 
 # Borrowed libfdt files for the ATAG compatibility mode
 
@@ -89,15 +89,12 @@ ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
 OBJS   += $(libfdt_objs) atags_to_fdt.o
 endif
 
-targets       := vmlinux vmlinux.lds \
-                piggy.$(suffix_y) piggy.$(suffix_y).o \
-                lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \
-                bswapsdi2.S font.o font.c head.o misc.o $(OBJS)
+targets       := vmlinux vmlinux.lds piggy_data piggy.o \
+                lib1funcs.o ashldi3.o bswapsdi2.o \
+                head.o $(OBJS)
 
-# Make sure files are removed during clean
-extra-y       += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \
-                lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \
-                hyp-stub.S
+clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \
+               $(libfdt) $(libfdt_hdrs) hyp-stub.S
 
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 
@@ -178,17 +175,17 @@ fi
 
 efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a
 
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
                $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
                $(bswapsdi2) $(efi-obj-y) FORCE
        @$(check_for_multiple_zreladdr)
        $(call if_changed,ld)
        @$(check_for_bad_syms)
 
-$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
-       $(call if_changed,$(suffix_y))
+$(obj)/piggy_data: $(obj)/../Image FORCE
+       $(call if_changed,$(compress-y))
 
-$(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE
+$(obj)/piggy.o: $(obj)/piggy_data
 
 CFLAGS_font.o := -Dstatic=
 
diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.S
new file mode 100644 (file)
index 0000000..f720884
--- /dev/null
@@ -0,0 +1,6 @@
+       .section .piggydata,#alloc
+       .globl  input_data
+input_data:
+       .incbin "arch/arm/boot/compressed/piggy_data"
+       .globl  input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S
deleted file mode 100644 (file)
index a68adf9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-       .section .piggydata,#alloc
-       .globl  input_data
-input_data:
-       .incbin "arch/arm/boot/compressed/piggy.gzip"
-       .globl  input_data_end
-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 (file)
index 3d9a575..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-       .section .piggydata,#alloc
-       .globl  input_data
-input_data:
-       .incbin "arch/arm/boot/compressed/piggy.lz4"
-       .globl  input_data_end
-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 (file)
index d7e69cf..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-       .section .piggydata,#alloc
-       .globl  input_data
-input_data:
-       .incbin "arch/arm/boot/compressed/piggy.lzma"
-       .globl  input_data_end
-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 (file)
index a425ad9..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-       .section .piggydata,#alloc
-       .globl  input_data
-input_data:
-       .incbin "arch/arm/boot/compressed/piggy.lzo"
-       .globl  input_data_end
-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 (file)
index 5703f30..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-       .section .piggydata,#alloc
-       .globl  input_data
-input_data:
-       .incbin "arch/arm/boot/compressed/piggy.xzkern"
-       .globl  input_data_end
-input_data_end:
index 3d224941b5419e88a25aae2ae70632dba047606c..fb0a0a4dfea4da26fd635ccbad4a06de0a72ce94 100644 (file)
@@ -1290,7 +1290,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
        struct sa1111_dev *dev = SA1111_DEV(_dev);
        struct sa1111_driver *drv = SA1111_DRV(_drv);
 
-       return dev->devid & drv->devid;
+       return !!(dev->devid & drv->devid);
 }
 
 static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
index 16da6380eb8505a9f9b87db77ac4b56c1febd8d9..3f6616b472af6919f4308870b66228cfc0b884fd 100644 (file)
@@ -23,7 +23,6 @@ generic-y += preempt.h
 generic-y += resource.h
 generic-y += rwsem.h
 generic-y += seccomp.h
-generic-y += sections.h
 generic-y += segment.h
 generic-y += sembuf.h
 generic-y += serial.h
index e1f07764b0d6bf99e8ed9386a24a086fa82be1e1..7d919a9b32e5f6e251e1a42d2ccd8f7d33d62483 100644 (file)
@@ -74,7 +74,7 @@ static inline uint32_t __div64_32(uint64_t *n, uint32_t base)
 static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias)
 {
        unsigned long long res;
-       unsigned int tmp = 0;
+       register unsigned int tmp asm("ip") = 0;
 
        if (!bias) {
                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)
                        : "r" (m), "r" (n)
                        : "cc");
        } else {
-               asm (   "umull  %Q0, %R0, %Q1, %Q2\n\t"
-                       "cmn    %Q0, %Q1\n\t"
-                       "adcs   %R0, %R0, %R1\n\t"
-                       "adc    %Q0, %3, #0"
-                       : "=&r" (res)
-                       : "r" (m), "r" (n), "r" (tmp)
+               asm (   "umull  %Q0, %R0, %Q2, %Q3\n\t"
+                       "cmn    %Q0, %Q2\n\t"
+                       "adcs   %R0, %R0, %R2\n\t"
+                       "adc    %Q0, %1, #0"
+                       : "=&r" (res), "+&r" (tmp)
+                       : "r" (m), "r" (n)
                        : "cc");
        }
 
index c79b57bf71c40d1fc2083f67b198377936e0002f..9427fd6325527e95ff9e5ad0a3f2bd973481e22a 100644 (file)
  */
 #define PLAT_PHYS_OFFSET       UL(CONFIG_PHYS_OFFSET)
 
+#ifdef CONFIG_XIP_KERNEL
+/*
+ * When referencing data in RAM from the XIP region in a relative manner
+ * with the MMU off, we need the relative offset between the two physical
+ * addresses.  The macro below achieves this, which is:
+ *    __pa(v_data) - __xip_pa(v_text)
+ */
+#define PHYS_RELATIVE(v_data, v_text) \
+       (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \
+        ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \
+          CONFIG_XIP_PHYS_ADDR))
+#else
+#define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text))
+#endif
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -273,14 +288,14 @@ static inline void *phys_to_virt(phys_addr_t x)
 #define __va(x)                        ((void *)__phys_to_virt((phys_addr_t)(x)))
 #define pfn_to_kaddr(pfn)      __va((phys_addr_t)(pfn) << PAGE_SHIFT)
 
-extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x);
+extern unsigned long (*arch_virt_to_idmap)(unsigned long x);
 
 /*
  * These are for systems that have a hardware interconnect supported alias of
  * physical memory for idmap purposes.  Most cases should leave these
- * untouched.
+ * untouched.  Note: this can only return addresses less than 4GiB.
  */
-static inline phys_addr_t __virt_to_idmap(unsigned long x)
+static inline unsigned long __virt_to_idmap(unsigned long x)
 {
        if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap)
                return arch_virt_to_idmap(x);
@@ -303,20 +318,6 @@ static inline phys_addr_t __virt_to_idmap(unsigned long x)
 #define __bus_to_pfn(x)        __phys_to_pfn(x)
 #endif
 
-#ifdef CONFIG_VIRT_TO_BUS
-#define virt_to_bus virt_to_bus
-static inline __deprecated unsigned long virt_to_bus(void *x)
-{
-       return __virt_to_bus((unsigned long)x);
-}
-
-#define bus_to_virt bus_to_virt
-static inline __deprecated void *bus_to_virt(unsigned long x)
-{
-       return (void *)__bus_to_virt(x);
-}
-#endif
-
 /*
  * Conversion between a struct page and a physical address.
  *
index 432ce8176498e0a014b26689716454150278056c..fa5b42d44985fbda00595f891450c6a60c8fd48b 100644 (file)
@@ -26,7 +26,12 @@ void __check_vmalloc_seq(struct mm_struct *mm);
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
-#define init_new_context(tsk,mm)       ({ atomic64_set(&(mm)->context.id, 0); 0; })
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+       atomic64_set(&mm->context.id, 0);
+       return 0;
+}
 
 #ifdef CONFIG_ARM_ERRATA_798181
 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)
 
 #endif /* CONFIG_MMU */
 
-#define init_new_context(tsk,mm)       0
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+       return 0;
+}
+
 
 #endif /* CONFIG_CPU_HAS_ASID */
 
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
new file mode 100644 (file)
index 0000000..803bbf2
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASM_ARM_SECTIONS_H
+#define _ASM_ARM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _exiprom[];
+
+#endif /* _ASM_ARM_SECTIONS_H */
index 00098615c6f0c35506f9628bb08dc81c39dca7a7..73e5e851375157513495e698a5d894617f7c86ce 100644 (file)
  * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000,
  * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26.
  *
- * Define these in your mach/memory.h.
+ * These can be overridden in your mach/memory.h.
  */
-#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS)
-#error Sparsemem is not supported on this platform
+#if !defined(MAX_PHYSMEM_BITS) || !defined(SECTION_SIZE_BITS)
+#define MAX_PHYSMEM_BITS       36
+#define SECTION_SIZE_BITS      28
 #endif
 
 #endif
index 3ce377f7251f3429668c2e2b563fcd8062c991ae..e2550500486d497c8455165b37916f2eb4974cd5 100644 (file)
@@ -1064,7 +1064,6 @@ ENDPROC(vector_\name)
        .endm
 
        .section .stubs, "ax", %progbits
-__stubs_start:
        @ This must be the first word
        .word   vector_swi
 
@@ -1202,14 +1201,13 @@ vector_addrexcptn:
        .long   __fiq_svc                       @  e
        .long   __fiq_svc                       @  f
 
-       .globl  vector_fiq_offset
-       .equ    vector_fiq_offset, vector_fiq
+       .globl  vector_fiq
 
        .section .vectors, "ax", %progbits
-__vectors_start:
+.L__vectors_start:
        W(b)    vector_rst
        W(b)    vector_und
-       W(ldr)  pc, __vectors_start + 0x1000
+       W(ldr)  pc, .L__vectors_start + 0x1000
        W(b)    vector_pabt
        W(b)    vector_dabt
        W(b)    vector_addrexcptn
index a71501ff6f1877fc9813fd4c3e10c51ae36f04e7..b09561a6d06a00eb9029fc9916ba1f654ca7e1c2 100644 (file)
@@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused)
 
        ret = swsusp_save();
        if (ret == 0)
-               _soft_restart(virt_to_phys(cpu_resume), false);
+               _soft_restart(virt_to_idmap(cpu_resume), false);
        return ret;
 }
 
@@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused)
        for (pbe = restore_pblist; pbe; pbe = pbe->next)
                copy_page(pbe->orig_address, pbe->address);
 
-       _soft_restart(virt_to_phys(cpu_resume), false);
+       _soft_restart(virt_to_idmap(cpu_resume), false);
 }
 
 static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata;
index 2a55373f49bfb621987ad2a548271fe51d7923b5..0b1e4a93d67edfe15899220087a4bdc53966f90c 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/irqchip/arm-gic-v3.h>
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/virt.h>
@@ -159,6 +160,29 @@ ARM_BE8(orr        r7, r7, #(1 << 25))     @ HSCTLR.EE
        bic     r7, #1                  @ Clear ENABLE
        mcr     p15, 0, r7, c14, c3, 1  @ CNTV_CTL
 1:
+#endif
+
+#ifdef CONFIG_ARM_GIC_V3
+       @ Check whether GICv3 system registers are available
+       mrc     p15, 0, r7, c0, c1, 1   @ ID_PFR1
+       ubfx    r7, r7, #28, #4
+       cmp     r7, #1
+       bne     2f
+
+       @ Enable system register accesses
+       mrc     p15, 4, r7, c12, c9, 5  @ ICC_HSRE
+       orr     r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE)
+       mcr     p15, 4, r7, c12, c9, 5  @ ICC_HSRE
+       isb
+
+       @ SRE bit could be forced to 0 by firmware.
+       @ Check whether it sticks before accessing any other sysreg
+       mrc     p15, 4, r7, c12, c9, 5  @ ICC_HSRE
+       tst     r7, #ICC_SRE_EL2_SRE
+       beq     2f
+       mov     r7, #0
+       mcr     p15, 4, r7, c12, c11, 0 @ ICH_HCR
+2:
 #endif
 
        bx      lr                      @ The boot CPU mode is left in r4.
index 1d45320ee125d572b108d8e40bb6e0150fea8b9a..ece04a457486c5998d312bce4f3c69b97e0e7b64 100644 (file)
@@ -95,7 +95,7 @@ void __init init_IRQ(void)
                        outer_cache.write_sec = machine_desc->l2c_write_sec;
                ret = l2x0_of_init(machine_desc->l2c_aux_val,
                                   machine_desc->l2c_aux_mask);
-               if (ret)
+               if (ret && ret != -ENODEV)
                        pr_err("L2C: failed to init: %d\n", ret);
        }
 
index 8bf3b7c098881b951df038575c6baf14e84df7b9..59fd0e24c56b150a1f22ab21983d72022fe52701 100644 (file)
@@ -143,10 +143,8 @@ void (*kexec_reinit)(void);
 
 void machine_kexec(struct kimage *image)
 {
-       unsigned long page_list;
-       unsigned long reboot_code_buffer_phys;
-       unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
-       unsigned long reboot_entry_phys;
+       unsigned long page_list, reboot_entry_phys;
+       void (*reboot_entry)(void);
        void *reboot_code_buffer;
 
        /*
@@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image)
 
        page_list = image->head & PAGE_MASK;
 
-       /* we need both effective and real address here */
-       reboot_code_buffer_phys =
-           page_to_pfn(image->control_code_page) << PAGE_SHIFT;
        reboot_code_buffer = page_address(image->control_code_page);
 
        /* Prepare parameters for reboot_code_buffer*/
@@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image)
 
        /* copy our kernel relocation code to the control code page */
        reboot_entry = fncpy(reboot_code_buffer,
-                            reboot_entry,
+                            &relocate_new_kernel,
                             relocate_new_kernel_size);
-       reboot_entry_phys = (unsigned long)reboot_entry +
-               (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
+
+       /* get the identity mapping physical address for the reboot code */
+       reboot_entry_phys = virt_to_idmap(reboot_entry);
 
        pr_info("Bye!\n");
 
index efdddcb97dd14df54b0f7307acb6a57367793f6b..4f14b5ce6535f7a19215660ebb4b3e62bd6ea5ed 100644 (file)
@@ -34,7 +34,7 @@
  * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
  */
 #undef MODULES_VADDR
-#define MODULES_VADDR  (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
+#define MODULES_VADDR  (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
 #endif
 
 #ifdef CONFIG_MMU
index 38269358fd252c6bb93fd58a0478319c436cdfd3..71a2ff9ec4900c58677f12114c85c82e8cfaa575 100644 (file)
@@ -50,7 +50,7 @@ static void __soft_restart(void *addr)
        flush_cache_all();
 
        /* Switch to the identity mapping. */
-       phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset);
+       phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
        phys_reset((unsigned long)addr);
 
        /* Should never get here. */
index 08b7847bf9124f004d7214c0e9c4dae23c0fffd2..ec279d161b3287e1df5b51702c499a2ac0187054 100644 (file)
@@ -40,7 +40,7 @@
  * to run the rebalance_domains for all idle cores and the cpu_capacity can be
  * updated during this sequence.
  */
-static DEFINE_PER_CPU(unsigned long, cpu_scale);
+static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
 
 unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu)
 {
@@ -306,8 +306,6 @@ void __init init_cpu_topology(void)
                cpu_topo->socket_id = -1;
                cpumask_clear(&cpu_topo->core_sibling);
                cpumask_clear(&cpu_topo->thread_sibling);
-
-               set_capacity_scale(cpu, SCHED_CAPACITY_SCALE);
        }
        smp_wmb();
 
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S
new file mode 100644 (file)
index 0000000..cba1ec8
--- /dev/null
@@ -0,0 +1,316 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+
+#define PROC_INFO                                                      \
+       . = ALIGN(4);                                                   \
+       VMLINUX_SYMBOL(__proc_info_begin) = .;                          \
+       *(.proc.info.init)                                              \
+       VMLINUX_SYMBOL(__proc_info_end) = .;
+
+#define IDMAP_TEXT                                                     \
+       ALIGN_FUNCTION();                                               \
+       VMLINUX_SYMBOL(__idmap_text_start) = .;                         \
+       *(.idmap.text)                                                  \
+       VMLINUX_SYMBOL(__idmap_text_end) = .;                           \
+       . = ALIGN(PAGE_SIZE);                                           \
+       VMLINUX_SYMBOL(__hyp_idmap_text_start) = .;                     \
+       *(.hyp.idmap.text)                                              \
+       VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define ARM_CPU_DISCARD(x)
+#define ARM_CPU_KEEP(x)                x
+#else
+#define ARM_CPU_DISCARD(x)     x
+#define ARM_CPU_KEEP(x)
+#endif
+
+#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
+       defined(CONFIG_GENERIC_BUG)
+#define ARM_EXIT_KEEP(x)       x
+#define ARM_EXIT_DISCARD(x)
+#else
+#define ARM_EXIT_KEEP(x)
+#define ARM_EXIT_DISCARD(x)    x
+#endif
+
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+
+#ifndef __ARMEB__
+jiffies = jiffies_64;
+#else
+jiffies = jiffies_64 + 4;
+#endif
+
+SECTIONS
+{
+       /*
+        * XXX: The linker does not define how output sections are
+        * assigned to input sections when there are multiple statements
+        * matching the same input section name.  There is no documented
+        * order of matching.
+        *
+        * unwind exit sections must be discarded before the rest of the
+        * unwind sections get included.
+        */
+       /DISCARD/ : {
+               *(.ARM.exidx.exit.text)
+               *(.ARM.extab.exit.text)
+               ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
+               ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
+               ARM_EXIT_DISCARD(EXIT_TEXT)
+               ARM_EXIT_DISCARD(EXIT_DATA)
+               EXIT_CALL
+#ifndef CONFIG_MMU
+               *(.text.fixup)
+               *(__ex_table)
+#endif
+#ifndef CONFIG_SMP_ON_UP
+               *(.alt.smp.init)
+#endif
+               *(.discard)
+               *(.discard.*)
+       }
+
+       . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+       _xiprom = .;                    /* XIP ROM area to be mapped */
+
+       .head.text : {
+               _text = .;
+               HEAD_TEXT
+       }
+
+       .text : {                       /* Real text segment            */
+               _stext = .;             /* Text and read-only data      */
+                       IDMAP_TEXT
+                       __exception_text_start = .;
+                       *(.exception.text)
+                       __exception_text_end = .;
+                       IRQENTRY_TEXT
+                       TEXT_TEXT
+                       SCHED_TEXT
+                       LOCK_TEXT
+                       KPROBES_TEXT
+                       *(.gnu.warning)
+                       *(.glue_7)
+                       *(.glue_7t)
+               . = ALIGN(4);
+               *(.got)                 /* Global offset table          */
+                       ARM_CPU_KEEP(PROC_INFO)
+       }
+
+       RO_DATA(PAGE_SIZE)
+
+       . = ALIGN(4);
+       __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
+               __start___ex_table = .;
+#ifdef CONFIG_MMU
+               *(__ex_table)
+#endif
+               __stop___ex_table = .;
+       }
+
+#ifdef CONFIG_ARM_UNWIND
+       /*
+        * Stack unwinding tables
+        */
+       . = ALIGN(8);
+       .ARM.unwind_idx : {
+               __start_unwind_idx = .;
+               *(.ARM.exidx*)
+               __stop_unwind_idx = .;
+       }
+       .ARM.unwind_tab : {
+               __start_unwind_tab = .;
+               *(.ARM.extab*)
+               __stop_unwind_tab = .;
+       }
+#endif
+
+       NOTES
+
+       _etext = .;                     /* End of text and rodata section */
+
+       /*
+        * The vectors and stubs are relocatable code, and the
+        * only thing that matters is their relative offsets
+        */
+       __vectors_start = .;
+       .vectors 0xffff0000 : AT(__vectors_start) {
+               *(.vectors)
+       }
+       . = __vectors_start + SIZEOF(.vectors);
+       __vectors_end = .;
+
+       __stubs_start = .;
+       .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {
+               *(.stubs)
+       }
+       . = __stubs_start + SIZEOF(.stubs);
+       __stubs_end = .;
+
+       PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
+
+       INIT_TEXT_SECTION(8)
+       .exit.text : {
+               ARM_EXIT_KEEP(EXIT_TEXT)
+       }
+       .init.proc.info : {
+               ARM_CPU_DISCARD(PROC_INFO)
+       }
+       .init.arch.info : {
+               __arch_info_begin = .;
+               *(.arch.info.init)
+               __arch_info_end = .;
+       }
+       .init.tagtable : {
+               __tagtable_begin = .;
+               *(.taglist.init)
+               __tagtable_end = .;
+       }
+#ifdef CONFIG_SMP_ON_UP
+       .init.smpalt : {
+               __smpalt_begin = .;
+               *(.alt.smp.init)
+               __smpalt_end = .;
+       }
+#endif
+       .init.pv_table : {
+               __pv_table_begin = .;
+               *(.pv_table)
+               __pv_table_end = .;
+       }
+       .init.data : {
+               INIT_SETUP(16)
+               INIT_CALLS
+               CON_INITCALL
+               SECURITY_INITCALL
+               INIT_RAM_FS
+       }
+
+#ifdef CONFIG_SMP
+       PERCPU_SECTION(L1_CACHE_BYTES)
+#endif
+
+       _exiprom = .;                   /* End of XIP ROM area */
+       __data_loc = ALIGN(4);          /* location in binary */
+       . = PAGE_OFFSET + TEXT_OFFSET;
+
+       .data : AT(__data_loc) {
+               _data = .;              /* address in memory */
+               _sdata = .;
+
+               /*
+                * first, the init task union, aligned
+                * to an 8192 byte boundary.
+                */
+               INIT_TASK_DATA(THREAD_SIZE)
+
+               . = ALIGN(PAGE_SIZE);
+               __init_begin = .;
+               INIT_DATA
+               ARM_EXIT_KEEP(EXIT_DATA)
+               . = ALIGN(PAGE_SIZE);
+               __init_end = .;
+
+               NOSAVE_DATA
+               CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
+               READ_MOSTLY_DATA(L1_CACHE_BYTES)
+
+               /*
+                * and the usual data section
+                */
+               DATA_DATA
+               CONSTRUCTORS
+
+               _edata = .;
+       }
+       _edata_loc = __data_loc + SIZEOF(.data);
+
+#ifdef CONFIG_HAVE_TCM
+        /*
+        * We align everything to a page boundary so we can
+        * free it after init has commenced and TCM contents have
+        * been copied to its destination.
+        */
+       .tcm_start : {
+               . = ALIGN(PAGE_SIZE);
+               __tcm_start = .;
+               __itcm_start = .;
+       }
+
+       /*
+        * Link these to the ITCM RAM
+        * Put VMA to the TCM address and LMA to the common RAM
+        * and we'll upload the contents from RAM to TCM and free
+        * the used RAM after that.
+        */
+       .text_itcm ITCM_OFFSET : AT(__itcm_start)
+       {
+               __sitcm_text = .;
+               *(.tcm.text)
+               *(.tcm.rodata)
+               . = ALIGN(4);
+               __eitcm_text = .;
+       }
+
+       /*
+        * Reset the dot pointer, this is needed to create the
+        * relative __dtcm_start below (to be used as extern in code).
+        */
+       . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm);
+
+       .dtcm_start : {
+               __dtcm_start = .;
+       }
+
+       /* TODO: add remainder of ITCM as well, that can be used for data! */
+       .data_dtcm DTCM_OFFSET : AT(__dtcm_start)
+       {
+               . = ALIGN(4);
+               __sdtcm_data = .;
+               *(.tcm.data)
+               . = ALIGN(4);
+               __edtcm_data = .;
+       }
+
+       /* Reset the dot pointer or the linker gets confused */
+       . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm);
+
+       /* End marker for freeing TCM copy in linked object */
+       .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){
+               . = ALIGN(PAGE_SIZE);
+               __tcm_end = .;
+       }
+#endif
+
+       BSS_SECTION(0, 0, 0)
+       _end = .;
+
+       STABS_DEBUG
+}
+
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
+ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
+ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
+
+/*
+ * The HYP init code can't be more than a page long,
+ * and should not cross a page boundary.
+ * The above comment applies as well.
+ */
+ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
+       "HYP init code too big or misaligned")
index b4139cbbbdd9830e7a4b74d9e306094bd1fe78b6..1fab979daeaf1c490b1215b44190bb498157124b 100644 (file)
@@ -3,14 +3,16 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
 
+#ifdef CONFIG_XIP_KERNEL
+#include "vmlinux-xip.lds.S"
+#else
+
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/cache.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
-#ifdef CONFIG_ARM_KERNMEM_PERMS
 #include <asm/pgtable.h>
-#endif
 
 #define PROC_INFO                                                      \
        . = ALIGN(4);                                                   \
@@ -89,17 +91,13 @@ SECTIONS
                *(.discard.*)
        }
 
-#ifdef CONFIG_XIP_KERNEL
-       . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
-#else
        . = PAGE_OFFSET + TEXT_OFFSET;
-#endif
        .head.text : {
                _text = .;
                HEAD_TEXT
        }
 
-#ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
        . = ALIGN(1<<SECTION_SHIFT);
 #endif
 
@@ -123,7 +121,7 @@ SECTIONS
                        ARM_CPU_KEEP(PROC_INFO)
        }
 
-#ifdef CONFIG_DEBUG_RODATA
+#ifdef CONFIG_DEBUG_ALIGN_RODATA
        . = ALIGN(1<<SECTION_SHIFT);
 #endif
        RO_DATA(PAGE_SIZE)
@@ -158,32 +156,33 @@ SECTIONS
 
        _etext = .;                     /* End of text and rodata section */
 
-#ifndef CONFIG_XIP_KERNEL
-# ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
        . = ALIGN(1<<SECTION_SHIFT);
-# else
+#else
        . = ALIGN(PAGE_SIZE);
-# endif
-       __init_begin = .;
 #endif
+       __init_begin = .;
+
        /*
         * The vectors and stubs are relocatable code, and the
         * only thing that matters is their relative offsets
         */
        __vectors_start = .;
-       .vectors 0 : AT(__vectors_start) {
+       .vectors 0xffff0000 : AT(__vectors_start) {
                *(.vectors)
        }
        . = __vectors_start + SIZEOF(.vectors);
        __vectors_end = .;
 
        __stubs_start = .;
-       .stubs 0x1000 : AT(__stubs_start) {
+       .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {
                *(.stubs)
        }
        . = __stubs_start + SIZEOF(.stubs);
        __stubs_end = .;
 
+       PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));
+
        INIT_TEXT_SECTION(8)
        .exit.text : {
                ARM_EXIT_KEEP(EXIT_TEXT)
@@ -214,37 +213,28 @@ SECTIONS
                __pv_table_end = .;
        }
        .init.data : {
-#ifndef CONFIG_XIP_KERNEL
                INIT_DATA
-#endif
                INIT_SETUP(16)
                INIT_CALLS
                CON_INITCALL
                SECURITY_INITCALL
                INIT_RAM_FS
        }
-#ifndef CONFIG_XIP_KERNEL
        .exit.data : {
                ARM_EXIT_KEEP(EXIT_DATA)
        }
-#endif
 
 #ifdef CONFIG_SMP
        PERCPU_SECTION(L1_CACHE_BYTES)
 #endif
 
-#ifdef CONFIG_XIP_KERNEL
-       __data_loc = ALIGN(4);          /* location in binary */
-       . = PAGE_OFFSET + TEXT_OFFSET;
-#else
-#ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
        . = ALIGN(1<<SECTION_SHIFT);
 #else
        . = ALIGN(THREAD_SIZE);
 #endif
        __init_end = .;
        __data_loc = .;
-#endif
 
        .data : AT(__data_loc) {
                _data = .;              /* address in memory */
@@ -256,15 +246,6 @@ SECTIONS
                 */
                INIT_TASK_DATA(THREAD_SIZE)
 
-#ifdef CONFIG_XIP_KERNEL
-               . = ALIGN(PAGE_SIZE);
-               __init_begin = .;
-               INIT_DATA
-               ARM_EXIT_KEEP(EXIT_DATA)
-               . = ALIGN(PAGE_SIZE);
-               __init_end = .;
-#endif
-
                NOSAVE_DATA
                CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
                READ_MOSTLY_DATA(L1_CACHE_BYTES)
@@ -342,6 +323,15 @@ SECTIONS
        STABS_DEBUG
 }
 
+#ifdef CONFIG_DEBUG_RODATA
+/*
+ * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will
+ * be the first section-aligned location after __start_rodata. Otherwise,
+ * it will be equal to __start_rodata.
+ */
+__start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT);
+#endif
+
 /*
  * These must never be empty
  * 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")
  */
 ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
        "HYP init code too big or misaligned")
+
+#endif /* CONFIG_XIP_KERNEL */
index 8fb97b93b6bb3d85ab0055c444b44f5fb9612a6e..53b456a5bbe03512275e674325a0533786a3fa6b 100644 (file)
@@ -30,7 +30,7 @@
 u32 *uart;
 
 /* PORT_16C550A, in polled non-fifo mode */
-static void putc(char c)
+static inline void putc(char c)
 {
        if (!uart)
                return;
index 07152d00fc505bc2aceac2cc9ebffae485175c8d..cbbdd84cf49ad0f70b464f79a336f07f24f5da82 100644 (file)
@@ -68,7 +68,6 @@ config ARCH_NETWINDER
        select ISA
        select ISA_DMA
        select PCI
-       select VIRT_TO_BUS
        help
          Say Y here if you intend to run this kernel on the Rebel.COM
          NetWinder.  Information about this machine can be found at:
index c279293f084cb87c2e0cc4cbf4ada1e2984e83f2..d80879ce4963b368a212747920982c268400dc1b 100644 (file)
@@ -63,7 +63,7 @@ static void __init keystone_init(void)
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
-static phys_addr_t keystone_virt_to_idmap(unsigned long x)
+static unsigned long keystone_virt_to_idmap(unsigned long x)
 {
        return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START;
 }
index c089a1aea674ee58a0e217ea3ee5034b08ed9a28..a001c7c34df22ea9badd1fdb71766946a904404a 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <mach/regs-uart.h>
 
-static void putc(char c)
+static inline void putc(char c)
 {
        while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE))
                barrier();
index 5cb1051b5831330beb681a78e2bc00450ff4f744..033875dbc32b8695dec4249a3494a799311b954f 100644 (file)
@@ -40,7 +40,7 @@
 #define FR_BUSY (1<<3)
 #define FR_TXFF (1<<5)
 
-static void putc(char c)
+static inline void putc(char c)
 {
        unsigned long base;
 
index 4869633de8cd36ab65c4ef7317cb97497013c3da..9cca6a56788fee71fa1a54a57a19610b276dbd96 100644 (file)
@@ -45,7 +45,7 @@ static void set_omap_uart_info(unsigned char port)
        *uart_info = port;
 }
 
-static void putc(int c)
+static inline void putc(int c)
 {
        if (!uart_base)
                return;
index 0fd4b0b8ef22ea91b2990588a5158bc226e0f170..654a6f3f2547d25bebeb628ab603c3d1cec4de68 100644 (file)
@@ -76,7 +76,7 @@ int white;
 /*
  * This does not append a newline
  */
-static void putc(int c)
+static inline void putc(int c)
 {
        extern void ll_write_char(char *, char c, char white);
        int x,y;
index 73093dc89829989f0cfb97a748632348b0253594..a1a041b9740bc58533b420cfc4ae7446b5a7dab5 100644 (file)
@@ -19,7 +19,7 @@
 
 #define UART(x)                (*(volatile unsigned long *)(serial_port + (x)))
 
-static void putc(int c)
+static inline void putc(int c)
 {
        unsigned long serial_port;
 
index 4b7c324ff664c64752ec3b5f1118a2145b7cae2f..3855ecebda6e6ed02c375707ddd0c6217eb19edc 100644 (file)
@@ -27,7 +27,7 @@
 #define TX_DONE        (UART_LSR_TEMT | UART_LSR_THRE)
 static volatile u32 * const uart_base = (u32 *)UART0_PA;
 
-static void putc(int ch)
+static inline void putc(int ch)
 {
        /* Check THRE and TEMT bits before we transmit the character.
         */
index 549f6d3aec5b66457a948f579f04b8b5dd1021cc..55347662e5edafa0900b54987b219a5fb83a6b5a 100644 (file)
@@ -1037,24 +1037,26 @@ config ARCH_SUPPORTS_BIG_ENDIAN
          This option specifies the architecture can support big endian
          operation.
 
-config ARM_KERNMEM_PERMS
-       bool "Restrict kernel memory permissions"
-       depends on MMU
-       help
-         If this is set, kernel memory other than kernel text (and rodata)
-         will be made non-executable. The tradeoff is that each region is
-         padded to section-size (1MiB) boundaries (because their permissions
-         are different and splitting the 1M pages into 4K ones causes TLB
-         performance problems), wasting memory.
-
 config DEBUG_RODATA
        bool "Make kernel text and rodata read-only"
-       depends on ARM_KERNMEM_PERMS
+       depends on MMU && !XIP_KERNEL
+       default y if CPU_V7
+       help
+         If this is set, kernel text and rodata memory will be made
+         read-only, and non-text kernel memory will be made non-executable.
+         The tradeoff is that each region is padded to section-size (1MiB)
+         boundaries (because their permissions are different and splitting
+         the 1M pages into 4K ones causes TLB performance problems), which
+         can waste memory.
+
+config DEBUG_ALIGN_RODATA
+       bool "Make rodata strictly non-executable"
+       depends on DEBUG_RODATA
        default y
        help
-         If this is set, kernel text and rodata will be made read-only. This
-         is to help catch accidental or malicious attempts to change the
-         kernel's executable code. Additionally splits rodata from kernel
-         text so it can be made explicitly non-executable. This creates
-         another section-size padded region, so it can waste more memory
-         space while gaining the read-only protections.
+         If this is set, rodata will be made explicitly non-executable. This
+         provides protection on the rare chance that attackers might find and
+         use ROP gadgets that exist in the rodata section. This adds an
+         additional section-aligned split of rodata from kernel text so it
+         can be made explicitly non-executable. This padding may waste memory
+         space to gain the additional protection.
index 1e373d268c04c3e3697ac40aaca1915f436a147b..88255bea65e41e61bd16ed2b12513ebcde7b04bd 100644 (file)
 #include <asm/cputype.h>
 #include <asm/hardware/cache-tauros2.h>
 
+/* CP15 PJ4 Control configuration register */
+#define CCR_L2C_PREFETCH_DISABLE       BIT(24)
+#define CCR_L2C_ECC_ENABLE             BIT(23)
+#define CCR_L2C_WAY7_4_DISABLE         BIT(21)
+#define CCR_L2C_BURST8_ENABLE          BIT(20)
 
 /*
  * When Tauros2 is used on a CPU that supports the v7 hierarchical
@@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features)
        u = read_extra_features();
 
        if (features & CACHE_TAUROS2_PREFETCH_ON)
-               u &= ~0x01000000;
+               u &= ~CCR_L2C_PREFETCH_DISABLE;
        else
-               u |= 0x01000000;
+               u |= CCR_L2C_PREFETCH_DISABLE;
        pr_info("Tauros2: %s L2 prefetch.\n",
                        (features & CACHE_TAUROS2_PREFETCH_ON)
                        ? "Enabling" : "Disabling");
 
        if (features & CACHE_TAUROS2_LINEFILL_BURST8)
-               u |= 0x00100000;
+               u |= CCR_L2C_BURST8_ENABLE;
        else
-               u &= ~0x00100000;
-       pr_info("Tauros2: %s line fill burt8.\n",
+               u &= ~CCR_L2C_BURST8_ENABLE;
+       pr_info("Tauros2: %s burst8 line fill.\n",
                        (features & CACHE_TAUROS2_LINEFILL_BURST8)
                        ? "Enabling" : "Disabling");
 
@@ -287,16 +292,15 @@ void __init tauros2_init(unsigned int features)
        node = of_find_matching_node(NULL, tauros2_ids);
        if (!node) {
                pr_info("Not found marvell,tauros2-cache, disable it\n");
-               return;
+       } else {
+               ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f);
+               if (ret) {
+                       pr_info("Not found marvell,tauros-cache-features property, "
+                               "disable extra features\n");
+                       features = 0;
+               } else
+                       features = f;
        }
-
-       ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f);
-       if (ret) {
-               pr_info("Not found marvell,tauros-cache-features property, "
-                       "disable extra features\n");
-               features = 0;
-       } else
-               features = f;
 #endif
        tauros2_internal_init(features);
 }
index 0eca3812527e614e891113839992b4e20cf3fb8d..deac58d5f1f7cf053ca215ec718c6902961a7908 100644 (file)
 #include "dma.h"
 #include "mm.h"
 
+struct arm_dma_alloc_args {
+       struct device *dev;
+       size_t size;
+       gfp_t gfp;
+       pgprot_t prot;
+       const void *caller;
+       bool want_vaddr;
+};
+
+struct arm_dma_free_args {
+       struct device *dev;
+       size_t size;
+       void *cpu_addr;
+       struct page *page;
+       bool want_vaddr;
+};
+
+struct arm_dma_allocator {
+       void *(*alloc)(struct arm_dma_alloc_args *args,
+                      struct page **ret_page);
+       void (*free)(struct arm_dma_free_args *args);
+};
+
+struct arm_dma_buffer {
+       struct list_head list;
+       void *virt;
+       struct arm_dma_allocator *allocator;
+};
+
+static LIST_HEAD(arm_dma_bufs);
+static DEFINE_SPINLOCK(arm_dma_bufs_lock);
+
+static struct arm_dma_buffer *arm_dma_buffer_find(void *virt)
+{
+       struct arm_dma_buffer *buf, *found = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&arm_dma_bufs_lock, flags);
+       list_for_each_entry(buf, &arm_dma_bufs, list) {
+               if (buf->virt == virt) {
+                       list_del(&buf->list);
+                       found = buf;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&arm_dma_bufs_lock, flags);
+       return found;
+}
+
 /*
  * The DMA API is built upon the notion of "buffer ownership".  A buffer
  * 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)
 #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL
 #define __alloc_from_pool(size, ret_page)                      NULL
 #define __alloc_from_contiguous(dev, size, prot, ret, c, wv)   NULL
-#define __free_from_pool(cpu_addr, size)                       0
+#define __free_from_pool(cpu_addr, size)                       do { } while (0)
 #define __free_from_contiguous(dev, page, cpu_addr, size, wv)  do { } while (0)
 #define __dma_free_remap(cpu_addr, size)                       do { } while (0)
 
@@ -610,7 +659,78 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
        return page_address(page);
 }
 
+static void *simple_allocator_alloc(struct arm_dma_alloc_args *args,
+                                   struct page **ret_page)
+{
+       return __alloc_simple_buffer(args->dev, args->size, args->gfp,
+                                    ret_page);
+}
+
+static void simple_allocator_free(struct arm_dma_free_args *args)
+{
+       __dma_free_buffer(args->page, args->size);
+}
 
+static struct arm_dma_allocator simple_allocator = {
+       .alloc = simple_allocator_alloc,
+       .free = simple_allocator_free,
+};
+
+static void *cma_allocator_alloc(struct arm_dma_alloc_args *args,
+                                struct page **ret_page)
+{
+       return __alloc_from_contiguous(args->dev, args->size, args->prot,
+                                      ret_page, args->caller,
+                                      args->want_vaddr);
+}
+
+static void cma_allocator_free(struct arm_dma_free_args *args)
+{
+       __free_from_contiguous(args->dev, args->page, args->cpu_addr,
+                              args->size, args->want_vaddr);
+}
+
+static struct arm_dma_allocator cma_allocator = {
+       .alloc = cma_allocator_alloc,
+       .free = cma_allocator_free,
+};
+
+static void *pool_allocator_alloc(struct arm_dma_alloc_args *args,
+                                 struct page **ret_page)
+{
+       return __alloc_from_pool(args->size, ret_page);
+}
+
+static void pool_allocator_free(struct arm_dma_free_args *args)
+{
+       __free_from_pool(args->cpu_addr, args->size);
+}
+
+static struct arm_dma_allocator pool_allocator = {
+       .alloc = pool_allocator_alloc,
+       .free = pool_allocator_free,
+};
+
+static void *remap_allocator_alloc(struct arm_dma_alloc_args *args,
+                                  struct page **ret_page)
+{
+       return __alloc_remap_buffer(args->dev, args->size, args->gfp,
+                                   args->prot, ret_page, args->caller,
+                                   args->want_vaddr);
+}
+
+static void remap_allocator_free(struct arm_dma_free_args *args)
+{
+       if (args->want_vaddr)
+               __dma_free_remap(args->cpu_addr, args->size);
+
+       __dma_free_buffer(args->page, args->size);
+}
+
+static struct arm_dma_allocator remap_allocator = {
+       .alloc = remap_allocator_alloc,
+       .free = remap_allocator_free,
+};
 
 static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
                         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,
        u64 mask = get_coherent_dma_mask(dev);
        struct page *page = NULL;
        void *addr;
-       bool want_vaddr;
+       bool allowblock, cma;
+       struct arm_dma_buffer *buf;
+       struct arm_dma_alloc_args args = {
+               .dev = dev,
+               .size = PAGE_ALIGN(size),
+               .gfp = gfp,
+               .prot = prot,
+               .caller = caller,
+               .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs),
+       };
 
 #ifdef CONFIG_DMA_API_DEBUG
        u64 limit = (mask + 1) & ~mask;
@@ -633,6 +762,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
        if (!mask)
                return NULL;
 
+       buf = kzalloc(sizeof(*buf), gfp);
+       if (!buf)
+               return NULL;
+
        if (mask < 0xffffffffULL)
                gfp |= GFP_DMA;
 
@@ -644,28 +777,37 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
         * platform; see CONFIG_HUGETLBFS.
         */
        gfp &= ~(__GFP_COMP);
+       args.gfp = gfp;
 
        *handle = DMA_ERROR_CODE;
-       size = PAGE_ALIGN(size);
-       want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
-
-       if (nommu())
-               addr = __alloc_simple_buffer(dev, size, gfp, &page);
-       else if (dev_get_cma_area(dev) && (gfp & __GFP_DIRECT_RECLAIM))
-               addr = __alloc_from_contiguous(dev, size, prot, &page,
-                                              caller, want_vaddr);
-       else if (is_coherent)
-               addr = __alloc_simple_buffer(dev, size, gfp, &page);
-       else if (!gfpflags_allow_blocking(gfp))
-               addr = __alloc_from_pool(size, &page);
+       allowblock = gfpflags_allow_blocking(gfp);
+       cma = allowblock ? dev_get_cma_area(dev) : false;
+
+       if (cma)
+               buf->allocator = &cma_allocator;
+       else if (nommu() || is_coherent)
+               buf->allocator = &simple_allocator;
+       else if (allowblock)
+               buf->allocator = &remap_allocator;
        else
-               addr = __alloc_remap_buffer(dev, size, gfp, prot, &page,
-                                           caller, want_vaddr);
+               buf->allocator = &pool_allocator;
+
+       addr = buf->allocator->alloc(&args, &page);
+
+       if (page) {
+               unsigned long flags;
 
-       if (page)
                *handle = pfn_to_dma(dev, page_to_pfn(page));
+               buf->virt = args.want_vaddr ? addr : page;
+
+               spin_lock_irqsave(&arm_dma_bufs_lock, flags);
+               list_add(&buf->list, &arm_dma_bufs);
+               spin_unlock_irqrestore(&arm_dma_bufs_lock, flags);
+       } else {
+               kfree(buf);
+       }
 
-       return want_vaddr ? addr : page;
+       return args.want_vaddr ? addr : page;
 }
 
 /*
@@ -741,25 +883,21 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
                           bool is_coherent)
 {
        struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
-       bool want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
-
-       size = PAGE_ALIGN(size);
-
-       if (nommu()) {
-               __dma_free_buffer(page, size);
-       } else if (!is_coherent && __free_from_pool(cpu_addr, size)) {
+       struct arm_dma_buffer *buf;
+       struct arm_dma_free_args args = {
+               .dev = dev,
+               .size = PAGE_ALIGN(size),
+               .cpu_addr = cpu_addr,
+               .page = page,
+               .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs),
+       };
+
+       buf = arm_dma_buffer_find(cpu_addr);
+       if (WARN(!buf, "Freeing invalid buffer %p\n", cpu_addr))
                return;
-       } else if (!dev_get_cma_area(dev)) {
-               if (want_vaddr && !is_coherent)
-                       __dma_free_remap(cpu_addr, size);
-               __dma_free_buffer(page, size);
-       } else {
-               /*
-                * Non-atomic allocations cannot be freed with IRQs disabled
-                */
-               WARN_ON(irqs_disabled());
-               __free_from_contiguous(dev, page, cpu_addr, size, want_vaddr);
-       }
+
+       buf->allocator->free(&args);
+       kfree(buf);
 }
 
 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,
        spin_unlock_irqrestore(&mapping->lock, flags);
 }
 
+/* We'll try 2M, 1M, 64K, and finally 4K; array must end with 0! */
+static const int iommu_order_array[] = { 9, 8, 4, 0 };
+
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
                                          gfp_t gfp, struct dma_attrs *attrs)
 {
@@ -1129,6 +1270,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
        int count = size >> PAGE_SHIFT;
        int array_size = count * sizeof(struct page *);
        int i = 0;
+       int order_idx = 0;
 
        if (array_size <= PAGE_SIZE)
                pages = kzalloc(array_size, GFP_KERNEL);
@@ -1154,6 +1296,10 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
                return pages;
        }
 
+       /* Go straight to 4K chunks if caller says it's OK. */
+       if (dma_get_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, attrs))
+               order_idx = ARRAY_SIZE(iommu_order_array) - 1;
+
        /*
         * IOMMU can map any pages, so himem can also be used here
         */
@@ -1162,22 +1308,24 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
        while (count) {
                int j, order;
 
-               for (order = __fls(count); order > 0; --order) {
-                       /*
-                        * We do not want OOM killer to be invoked as long
-                        * as we can fall back to single pages, so we force
-                        * __GFP_NORETRY for orders higher than zero.
-                        */
-                       pages[i] = alloc_pages(gfp | __GFP_NORETRY, order);
-                       if (pages[i])
-                               break;
+               order = iommu_order_array[order_idx];
+
+               /* Drop down when we get small */
+               if (__fls(count) < order) {
+                       order_idx++;
+                       continue;
                }
 
-               if (!pages[i]) {
-                       /*
-                        * Fall back to single page allocation.
-                        * Might invoke OOM killer as last resort.
-                        */
+               if (order) {
+                       /* See if it's easy to allocate a high-order chunk */
+                       pages[i] = alloc_pages(gfp | __GFP_NORETRY, order);
+
+                       /* Go down a notch at first sign of pressure */
+                       if (!pages[i]) {
+                               order_idx++;
+                               continue;
+                       }
+               } else {
                        pages[i] = alloc_pages(gfp, 0);
                        if (!pages[i])
                                goto error;
index d65909697165b20cc1936f50073bd3eea7521aec..bd274a05b8ffa9446160d1de69f777d9431c629b 100644 (file)
@@ -15,7 +15,7 @@
  * page tables.
  */
 pgd_t *idmap_pgd;
-phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
+unsigned long (*arch_virt_to_idmap)(unsigned long x);
 
 #ifdef CONFIG_ARM_LPAE
 static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
index 49bd08178008adc38cca29b5e50bf26aa14a07c9..370581aeb87104273df695409af37876956c639f 100644 (file)
@@ -572,8 +572,9 @@ void __init mem_init(void)
        }
 }
 
-#ifdef CONFIG_ARM_KERNMEM_PERMS
+#ifdef CONFIG_DEBUG_RODATA
 struct section_perm {
+       const char *name;
        unsigned long start;
        unsigned long end;
        pmdval_t mask;
@@ -581,9 +582,13 @@ struct section_perm {
        pmdval_t clear;
 };
 
+/* First section-aligned location at or after __start_rodata. */
+extern char __start_rodata_section_aligned[];
+
 static struct section_perm nx_perms[] = {
        /* Make pages tables, etc before _stext RW (set NX). */
        {
+               .name   = "pre-text NX",
                .start  = PAGE_OFFSET,
                .end    = (unsigned long)_stext,
                .mask   = ~PMD_SECT_XN,
@@ -591,26 +596,26 @@ static struct section_perm nx_perms[] = {
        },
        /* Make init RW (set NX). */
        {
+               .name   = "init NX",
                .start  = (unsigned long)__init_begin,
                .end    = (unsigned long)_sdata,
                .mask   = ~PMD_SECT_XN,
                .prot   = PMD_SECT_XN,
        },
-#ifdef CONFIG_DEBUG_RODATA
        /* Make rodata NX (set RO in ro_perms below). */
        {
-               .start  = (unsigned long)__start_rodata,
+               .name   = "rodata NX",
+               .start  = (unsigned long)__start_rodata_section_aligned,
                .end    = (unsigned long)__init_begin,
                .mask   = ~PMD_SECT_XN,
                .prot   = PMD_SECT_XN,
        },
-#endif
 };
 
-#ifdef CONFIG_DEBUG_RODATA
 static struct section_perm ro_perms[] = {
        /* Make kernel code and rodata RX (set RO). */
        {
+               .name   = "text/rodata RO",
                .start  = (unsigned long)_stext,
                .end    = (unsigned long)__init_begin,
 #ifdef CONFIG_ARM_LPAE
@@ -623,7 +628,6 @@ static struct section_perm ro_perms[] = {
 #endif
        },
 };
-#endif
 
 /*
  * 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,
        for (i = 0; i < n; i++) {
                if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) ||
                    !IS_ALIGNED(perms[i].end, SECTION_SIZE)) {
-                       pr_err("BUG: section %lx-%lx not aligned to %lx\n",
-                               perms[i].start, perms[i].end,
+                       pr_err("BUG: %s section %lx-%lx not aligned to %lx\n",
+                               perms[i].name, perms[i].start, perms[i].end,
                                SECTION_SIZE);
                        continue;
                }
@@ -712,7 +716,6 @@ void fix_kernmem_perms(void)
        stop_machine(__fix_kernmem_perms, NULL, NULL);
 }
 
-#ifdef CONFIG_DEBUG_RODATA
 int __mark_rodata_ro(void *unused)
 {
        update_sections_early(ro_perms, ARRAY_SIZE(ro_perms));
@@ -735,11 +738,10 @@ void set_kernel_text_ro(void)
        set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
                                current->active_mm);
 }
-#endif /* CONFIG_DEBUG_RODATA */
 
 #else
 static inline void fix_kernmem_perms(void) { }
-#endif /* CONFIG_ARM_KERNMEM_PERMS */
+#endif /* CONFIG_DEBUG_RODATA */
 
 void free_tcmmem(void)
 {
index 88fbe0d23ca613a77b68f7da292f0b5864238647..62f4d01941f718bf02a6e24c19042d6c65b961d9 100644 (file)
@@ -1253,7 +1253,7 @@ static inline void prepare_page_table(void)
 
 #ifdef CONFIG_XIP_KERNEL
        /* The XIP kernel is mapped in the module area -- skip over it */
-       addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
+       addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
 #endif
        for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
@@ -1335,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
 #ifdef CONFIG_XIP_KERNEL
        map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
        map.virtual = MODULES_VADDR;
-       map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+       map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
        map.type = MT_ROM;
        create_mapping(&map);
 #endif
@@ -1426,7 +1426,11 @@ static void __init kmap_init(void)
 static void __init map_lowmem(void)
 {
        struct memblock_region *reg;
+#ifdef CONFIG_XIP_KERNEL
+       phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
+#else
        phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+#endif
        phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 
        /* Map all the lowmem memory banks. */
index 0f92d575a3040b53f6584759b95a0bd1217ea3c2..0f8963a7e7d9db28465c63a2bab69a615fb6a2cb 100644 (file)
@@ -487,7 +487,7 @@ __errata_finish:
 
        .align  2
 __v7_setup_stack_ptr:
-       .word   __v7_setup_stack - .
+       .word   PHYS_RELATIVE(__v7_setup_stack, .)
 ENDPROC(__v7_setup)
 
        .bss
index 8085a8aac8124839d889849d4d5877be3fa22252..ffb93db68e9c80b3003e6d93c7e93d25eb76182e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/irq.h>
 #include <linux/sched_clock.h>
 #include <plat/time.h>
+#include <asm/delay.h>
 
 /*
  * MBus bridge block registers.
@@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base)
        timer_base = _timer_base;
 }
 
+static unsigned long orion_delay_timer_read(void)
+{
+       return ~readl(timer_base + TIMER0_VAL_OFF);
+}
+
+static struct delay_timer orion_delay_timer = {
+       .read_current_timer = orion_delay_timer_read,
+};
+
 void __init
 orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
                unsigned int irq, unsigned int tclk)
@@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
 
        ticks_per_jiffy = (tclk + HZ/2) / HZ;
 
+       orion_delay_timer.freq = tclk;
+       register_current_timer_delay(&orion_delay_timer);
+
        /*
         * Set scale and timer for sched_clock.
         */
index f67f35b6edb12e4d34e1db17750b07a0bec72e39..42816bebb1e0f732d788780fde431028f202c31a 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/smp.h>
 #include <linux/delay.h>
 #include <linux/psci.h>
-#include <linux/slab.h>
 
 #include <uapi/linux/psci.h>
 
 #include <asm/cpu_ops.h>
 #include <asm/errno.h>
 #include <asm/smp_plat.h>
-#include <asm/suspend.h>
-
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
-
-static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu)
-{
-       int i, ret, count = 0;
-       u32 *psci_states;
-       struct device_node *state_node, *cpu_node;
-
-       cpu_node = of_get_cpu_node(cpu, NULL);
-       if (!cpu_node)
-               return -ENODEV;
-
-       /*
-        * If the PSCI cpu_suspend function hook has not been initialized
-        * idle states must not be enabled, so bail out
-        */
-       if (!psci_ops.cpu_suspend)
-               return -EOPNOTSUPP;
-
-       /* Count idle states */
-       while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
-                                             count))) {
-               count++;
-               of_node_put(state_node);
-       }
-
-       if (!count)
-               return -ENODEV;
-
-       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
-       if (!psci_states)
-               return -ENOMEM;
-
-       for (i = 0; i < count; i++) {
-               u32 state;
-
-               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
-
-               ret = of_property_read_u32(state_node,
-                                          "arm,psci-suspend-param",
-                                          &state);
-               if (ret) {
-                       pr_warn(" * %s missing arm,psci-suspend-param property\n",
-                               state_node->full_name);
-                       of_node_put(state_node);
-                       goto free_mem;
-               }
-
-               of_node_put(state_node);
-               pr_debug("psci-power-state %#x index %d\n", state, i);
-               if (!psci_power_state_is_valid(state)) {
-                       pr_warn("Invalid PSCI power state %#x\n", state);
-                       ret = -EINVAL;
-                       goto free_mem;
-               }
-               psci_states[i] = state;
-       }
-       /* Idle states parsed correctly, initialize per-cpu pointer */
-       per_cpu(psci_power_state, cpu) = psci_states;
-       return 0;
-
-free_mem:
-       kfree(psci_states);
-       return ret;
-}
 
 static int __init cpu_psci_cpu_init(unsigned int cpu)
 {
@@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 }
 #endif
 
-static int psci_suspend_finisher(unsigned long index)
-{
-       u32 *state = __this_cpu_read(psci_power_state);
-
-       return psci_ops.cpu_suspend(state[index - 1],
-                                   virt_to_phys(cpu_resume));
-}
-
-static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
-{
-       int ret;
-       u32 *state = __this_cpu_read(psci_power_state);
-       /*
-        * idle state index 0 corresponds to wfi, should never be called
-        * from the cpu_suspend operations
-        */
-       if (WARN_ON_ONCE(!index))
-               return -EINVAL;
-
-       if (!psci_power_state_loses_context(state[index - 1]))
-               ret = psci_ops.cpu_suspend(state[index - 1], 0);
-       else
-               ret = cpu_suspend(index, psci_suspend_finisher);
-
-       return ret;
-}
-
 const struct cpu_operations cpu_psci_ops = {
        .name           = "psci",
 #ifdef CONFIG_CPU_IDLE
-       .cpu_init_idle  = cpu_psci_cpu_init_idle,
-       .cpu_suspend    = cpu_psci_cpu_suspend,
+       .cpu_init_idle  = psci_cpu_init_idle,
+       .cpu_suspend    = psci_cpu_suspend_enter,
 #endif
        .cpu_init       = cpu_psci_cpu_init,
        .cpu_prepare    = cpu_psci_cpu_prepare,
index c4da2df62e02525617a23ebe68fff4af0bb69350..16688f50729cfac7112a740804c00b226680ca4a 100644 (file)
@@ -560,6 +560,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
        struct device_attach_data *data = _data;
        struct device *dev = data->dev;
        bool async_allowed;
+       int ret;
 
        /*
         * Check if device has already been claimed. This may
@@ -570,8 +571,17 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
        if (dev->driver)
                return -EBUSY;
 
-       if (!driver_match_device(drv, dev))
+       ret = driver_match_device(drv, dev);
+       if (ret == 0) {
+               /* no match */
                return 0;
+       } else if (ret == -EPROBE_DEFER) {
+               dev_dbg(dev, "Device match requests probe deferral\n");
+               driver_deferred_probe_add(dev);
+       } else if (ret < 0) {
+               dev_dbg(dev, "Bus failed to match device: %d", ret);
+               return ret;
+       } /* ret > 0 means positive match */
 
        async_allowed = driver_allows_async_probing(drv);
 
@@ -691,6 +701,7 @@ void device_initial_probe(struct device *dev)
 static int __driver_attach(struct device *dev, void *data)
 {
        struct device_driver *drv = data;
+       int ret;
 
        /*
         * 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)
         * is an error.
         */
 
-       if (!driver_match_device(drv, dev))
+       ret = driver_match_device(drv, dev);
+       if (ret == 0) {
+               /* no match */
                return 0;
+       } else if (ret == -EPROBE_DEFER) {
+               dev_dbg(dev, "Device match requests probe deferral\n");
+               driver_deferred_probe_add(dev);
+       } else if (ret < 0) {
+               dev_dbg(dev, "Bus failed to match device: %d", ret);
+               return ret;
+       } /* ret > 0 means positive match */
 
        if (dev->parent)        /* Needed for USB */
                device_lock(dev->parent);
index 779b6ff0c7ad4040a680a2155964bd3016363767..eb20b941154babe8ad145633b642e53ac9891069 100644 (file)
@@ -353,11 +353,25 @@ void clkdev_drop(struct clk_lookup *cl)
 }
 EXPORT_SYMBOL(clkdev_drop);
 
+static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
+                                               const char *con_id,
+                                               const char *dev_id, ...)
+{
+       struct clk_lookup *cl;
+       va_list ap;
+
+       va_start(ap, dev_id);
+       cl = vclkdev_create(hw, con_id, dev_id, ap);
+       va_end(ap);
+
+       return cl;
+}
+
 /**
  * clk_register_clkdev - register one clock lookup for a struct clk
  * @clk: struct clk to associate with all clk_lookups
  * @con_id: connection ID string on device
- * @dev_id: format string describing device name
+ * @dev_id: string describing device name
  *
  * con_id or dev_id may be NULL as a wildcard, just as in the rest of
  * clkdev.
@@ -368,17 +382,22 @@ EXPORT_SYMBOL(clkdev_drop);
  * after clk_register().
  */
 int clk_register_clkdev(struct clk *clk, const char *con_id,
-       const char *dev_fmt, ...)
+       const char *dev_id)
 {
        struct clk_lookup *cl;
-       va_list ap;
 
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       va_start(ap, dev_fmt);
-       cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
-       va_end(ap);
+       /*
+        * Since dev_id can be NULL, and NULL is handled specially, we must
+        * pass it as either a NULL format string, or with "%s".
+        */
+       if (dev_id)
+               cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s",
+                                          dev_id);
+       else
+               cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL);
 
        return cl ? 0 : -ENOMEM;
 }
index f25cd79c8a79f834f8d3e169684d20ee4ced08e6..11bfee8b79a9f65418bcbe53dfc708edb220e69d 100644 (file)
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) "psci: " fmt
 
 #include <linux/arm-smccc.h>
+#include <linux/cpuidle.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/of.h>
 #include <linux/printk.h>
 #include <linux/psci.h>
 #include <linux/reboot.h>
+#include <linux/slab.h>
 #include <linux/suspend.h>
 
 #include <uapi/linux/psci.h>
 
+#include <asm/cpuidle.h>
 #include <asm/cputype.h>
 #include <asm/system_misc.h>
 #include <asm/smp_plat.h>
@@ -244,6 +247,123 @@ static int __init psci_features(u32 psci_func_id)
                              psci_func_id, 0, 0);
 }
 
+#ifdef CONFIG_CPU_IDLE
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
+static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
+{
+       int i, ret, count = 0;
+       u32 *psci_states;
+       struct device_node *state_node;
+
+       /*
+        * If the PSCI cpu_suspend function hook has not been initialized
+        * idle states must not be enabled, so bail out
+        */
+       if (!psci_ops.cpu_suspend)
+               return -EOPNOTSUPP;
+
+       /* Count idle states */
+       while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+                                             count))) {
+               count++;
+               of_node_put(state_node);
+       }
+
+       if (!count)
+               return -ENODEV;
+
+       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+       if (!psci_states)
+               return -ENOMEM;
+
+       for (i = 0; i < count; i++) {
+               u32 state;
+
+               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+
+               ret = of_property_read_u32(state_node,
+                                          "arm,psci-suspend-param",
+                                          &state);
+               if (ret) {
+                       pr_warn(" * %s missing arm,psci-suspend-param property\n",
+                               state_node->full_name);
+                       of_node_put(state_node);
+                       goto free_mem;
+               }
+
+               of_node_put(state_node);
+               pr_debug("psci-power-state %#x index %d\n", state, i);
+               if (!psci_power_state_is_valid(state)) {
+                       pr_warn("Invalid PSCI power state %#x\n", state);
+                       ret = -EINVAL;
+                       goto free_mem;
+               }
+               psci_states[i] = state;
+       }
+       /* Idle states parsed correctly, initialize per-cpu pointer */
+       per_cpu(psci_power_state, cpu) = psci_states;
+       return 0;
+
+free_mem:
+       kfree(psci_states);
+       return ret;
+}
+
+int psci_cpu_init_idle(unsigned int cpu)
+{
+       struct device_node *cpu_node;
+       int ret;
+
+       cpu_node = of_get_cpu_node(cpu, NULL);
+       if (!cpu_node)
+               return -ENODEV;
+
+       ret = psci_dt_cpu_init_idle(cpu_node, cpu);
+
+       of_node_put(cpu_node);
+
+       return ret;
+}
+
+static int psci_suspend_finisher(unsigned long index)
+{
+       u32 *state = __this_cpu_read(psci_power_state);
+
+       return psci_ops.cpu_suspend(state[index - 1],
+                                   virt_to_phys(cpu_resume));
+}
+
+int psci_cpu_suspend_enter(unsigned long index)
+{
+       int ret;
+       u32 *state = __this_cpu_read(psci_power_state);
+       /*
+        * idle state index 0 corresponds to wfi, should never be called
+        * from the cpu_suspend operations
+        */
+       if (WARN_ON_ONCE(!index))
+               return -EINVAL;
+
+       if (!psci_power_state_loses_context(state[index - 1]))
+               ret = psci_ops.cpu_suspend(state[index - 1], 0);
+       else
+               ret = cpu_suspend(index, psci_suspend_finisher);
+
+       return ret;
+}
+
+/* ARM specific CPU idle operations */
+#ifdef CONFIG_ARM
+static struct cpuidle_ops psci_cpuidle_ops __initdata = {
+       .suspend = psci_cpu_suspend_enter,
+       .init = psci_dt_cpu_init_idle,
+};
+
+CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops);
+#endif
+#endif
+
 static int psci_system_suspend(unsigned long unused)
 {
        return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
index c33127284cfeed93ba4bf9993c49c470b8587802..5361197f3e5741f6225db0393fb416f0dbeab03b 100644 (file)
 
 struct vb2_dc_conf {
        struct device           *dev;
+       struct dma_attrs        attrs;
 };
 
 struct vb2_dc_buf {
        struct device                   *dev;
        void                            *vaddr;
        unsigned long                   size;
+       void                            *cookie;
        dma_addr_t                      dma_addr;
+       struct dma_attrs                attrs;
        enum dma_data_direction         dma_dir;
        struct sg_table                 *dma_sgt;
        struct frame_vector             *vec;
@@ -131,7 +134,8 @@ static void vb2_dc_put(void *buf_priv)
                sg_free_table(buf->sgt_base);
                kfree(buf->sgt_base);
        }
-       dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+       dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr,
+                       &buf->attrs);
        put_device(buf->dev);
        kfree(buf);
 }
@@ -147,14 +151,18 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size,
        if (!buf)
                return ERR_PTR(-ENOMEM);
 
-       buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr,
-                                               GFP_KERNEL | gfp_flags);
-       if (!buf->vaddr) {
+       buf->attrs = conf->attrs;
+       buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr,
+                                       GFP_KERNEL | gfp_flags, &buf->attrs);
+       if (!buf->cookie) {
                dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
                kfree(buf);
                return ERR_PTR(-ENOMEM);
        }
 
+       if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->attrs))
+               buf->vaddr = buf->cookie;
+
        /* Prevent the device from being released while the buffer is used */
        buf->dev = get_device(dev);
        buf->size = size;
@@ -185,8 +193,8 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
         */
        vma->vm_pgoff = 0;
 
-       ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
-               buf->dma_addr, buf->size);
+       ret = dma_mmap_attrs(buf->dev, vma, buf->cookie,
+               buf->dma_addr, buf->size, &buf->attrs);
 
        if (ret) {
                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)
 {
        struct vb2_dc_buf *buf = dbuf->priv;
 
-       return buf->vaddr + pgnum * PAGE_SIZE;
+       return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL;
 }
 
 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)
                return NULL;
        }
 
-       ret = dma_get_sgtable(buf->dev, sgt, buf->vaddr, buf->dma_addr,
-               buf->size);
+       ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
+               buf->size, &buf->attrs);
        if (ret < 0) {
                dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
                kfree(sgt);
@@ -721,7 +729,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-void *vb2_dma_contig_init_ctx(struct device *dev)
+void *vb2_dma_contig_init_ctx_attrs(struct device *dev,
+                                   struct dma_attrs *attrs)
 {
        struct vb2_dc_conf *conf;
 
@@ -730,10 +739,12 @@ void *vb2_dma_contig_init_ctx(struct device *dev)
                return ERR_PTR(-ENOMEM);
 
        conf->dev = dev;
+       if (attrs)
+               conf->attrs = *attrs;
 
        return conf;
 }
-EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx);
+EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx_attrs);
 
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 {
index 33557481d4522c9ff02d4129939ec38b2d3327d5..fc82743aefb6574f6a1e47ecd68e1d0b1557507f 100644 (file)
@@ -62,7 +62,7 @@ static int nvdimm_bus_match(struct device *dev, struct device_driver *drv)
 {
        struct nd_device_driver *nd_drv = to_nd_device_driver(drv);
 
-       return test_bit(to_nd_device_type(dev), &nd_drv->type);
+       return !!test_bit(to_nd_device_type(dev), &nd_drv->type);
 }
 
 static struct module *to_bus_provider(struct device *dev)
index 08bffcc466de7e5bce4359b3174ba8105e734a35..c2c04f7cbe8ac4584dfa427f4f324c7bd0093396 100644 (file)
@@ -44,8 +44,7 @@ struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 void clkdev_add_table(struct clk_lookup *, size_t);
 int clk_add_alias(const char *, const char *, const char *, struct device *);
 
-int clk_register_clkdev(struct clk *, const char *, const char *, ...)
-       __printf(3, 4);
+int clk_register_clkdev(struct clk *, const char *, const char *);
 int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
 
 #ifdef CONFIG_COMMON_CLK
index 2d0e6e541d525dd0be21dfe2dea20df7204e791a..88192d098aed6656db545770cd3ca597ea261e1f 100644 (file)
@@ -70,8 +70,11 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * @dev_groups:        Default attributes of the devices on the bus.
  * @drv_groups: Default attributes of the device drivers on the bus.
  * @match:     Called, perhaps multiple times, whenever a new device or driver
- *             is added for this bus. It should return a nonzero value if the
- *             given device can be handled by the given driver.
+ *             is added for this bus. It should return a positive value if the
+ *             given device can be handled by the given driver and zero
+ *             otherwise. It may also return error code if determining that
+ *             the driver supports the device is not possible. In case of
+ *             -EPROBE_DEFER it will queue the device for deferred probing.
  * @uevent:    Called when a device is added, removed, or a few other things
  *             that generate uevents to add the environment variables.
  * @probe:     Called when a new device or driver add to this bus, and callback
index 99c0be00b47c4993f205babd17ca8a8442274171..5246239a495388164284b06be899066df14360db 100644 (file)
@@ -18,6 +18,7 @@ enum dma_attr {
        DMA_ATTR_NO_KERNEL_MAPPING,
        DMA_ATTR_SKIP_CPU_SYNC,
        DMA_ATTR_FORCE_CONTIGUOUS,
+       DMA_ATTR_ALLOC_SINGLE_PAGES,
        DMA_ATTR_MAX,
 };
 
index 12c4865457adc3d0412c573b710feec7d3d6fd81..393efe2edf9afb9d8a38d1a16201e78c64881026 100644 (file)
@@ -24,6 +24,9 @@ bool psci_tos_resident_on(int cpu);
 bool psci_power_state_loses_context(u32 state);
 bool psci_power_state_is_valid(u32 state);
 
+int psci_cpu_init_idle(unsigned int cpu);
+int psci_cpu_suspend_enter(unsigned long index);
+
 struct psci_operations {
        int (*cpu_suspend)(u32 state, unsigned long entry_point);
        int (*cpu_off)(u32 state);
index c33dfa69d7abedfccfa3fd792dd9091066fb96f2..2087c9a68be3dab07b4355c8f230e5cb34feeb92 100644 (file)
@@ -16,6 +16,8 @@
 #include <media/videobuf2-v4l2.h>
 #include <linux/dma-mapping.h>
 
+struct dma_attrs;
+
 static inline dma_addr_t
 vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
 {
@@ -24,7 +26,14 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
        return *addr;
 }
 
-void *vb2_dma_contig_init_ctx(struct device *dev);
+void *vb2_dma_contig_init_ctx_attrs(struct device *dev,
+                                   struct dma_attrs *attrs);
+
+static inline void *vb2_dma_contig_init_ctx(struct device *dev)
+{
+       return vb2_dma_contig_init_ctx_attrs(dev, NULL);
+}
+
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
 
 extern const struct vb2_mem_ops vb2_dma_contig_memops;