Merge branch 'parisc-4.21-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Jan 2019 19:44:20 +0000 (11:44 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Jan 2019 19:44:20 +0000 (11:44 -0800)
Pull parisc fix from Helge Deller:
 "Fix boot issues with a series of parisc servers since kernel 4.20.

  Remapping kernel text with set_kernel_text_rw() missed to remap from
  lowest up until the highest huge-page aligned kernel text addresss"

* 'parisc-4.21-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Remap hugepage-aligned pages in set_kernel_text_rw()

295 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/devicetree/bindings/arm/rda.txt [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/process/coding-style.rst
Documentation/process/submitting-patches.rst
Documentation/sysctl/kernel.txt
MAINTAINERS
arch/Kconfig
arch/alpha/include/asm/bitops.h
arch/alpha/include/asm/pgalloc.h
arch/arc/include/asm/bitops.h
arch/arc/include/asm/pgalloc.h
arch/arc/mm/fault.c
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/atags_to_fdt.c
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/rda8810pl-orangepi-2g-iot.dts [new file with mode: 0644]
arch/arm/boot/dts/rda8810pl-orangepi-i96.dts [new file with mode: 0644]
arch/arm/boot/dts/rda8810pl.dtsi [new file with mode: 0644]
arch/arm/common/sa1111.c
arch/arm/configs/multi_v7_defconfig
arch/arm/include/asm/assembler.h
arch/arm/include/asm/hardware/sa1111.h
arch/arm/include/asm/pgalloc.h
arch/arm/include/asm/uaccess.h
arch/arm/kernel/head.S
arch/arm/kernel/smp.c
arch/arm/lib/copy_from_user.S
arch/arm/lib/copy_to_user.S
arch/arm/lib/getuser.S
arch/arm/lib/putuser.S
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/include/mach/mainstone.h
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-rda/Kconfig [new file with mode: 0644]
arch/arm/mach-rda/Makefile [new file with mode: 0644]
arch/arm/mach-realview/Makefile
arch/arm/mach-realview/hotplug.c [deleted file]
arch/arm/mach-realview/hotplug.h [deleted file]
arch/arm/mach-realview/platsmp-dt.c
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/h3100.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sti/Makefile
arch/arm/mach-sti/headsmp.S [deleted file]
arch/arm/mach-sti/platsmp.c
arch/arm/mach-vexpress/Makefile
arch/arm/mach-vexpress/core.h
arch/arm/mach-vexpress/hotplug.c [deleted file]
arch/arm/mach-vexpress/platsmp.c
arch/arm/mm/copypage-fa.c
arch/arm/mm/copypage-feroceon.c
arch/arm/mm/copypage-v4mc.c
arch/arm/mm/copypage-v4wb.c
arch/arm/mm/copypage-v4wt.c
arch/arm/mm/copypage-xsc3.c
arch/arm/mm/copypage-xscale.c
arch/arm/mm/fault.c
arch/arm/mm/proc-macros.S
arch/arm/mm/pv-fixup-asm.S
arch/arm/plat-omap/Kconfig
arch/arm/plat-versatile/Makefile
arch/arm/plat-versatile/headsmp.S
arch/arm/plat-versatile/hotplug.c [new file with mode: 0644]
arch/arm/plat-versatile/include/plat/platsmp.h
arch/arm/plat-versatile/platsmp.c
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
arch/arm64/boot/dts/exynos/exynos5433.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/imx8mq-evk.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq.dtsi [new file with mode: 0644]
arch/arm64/configs/defconfig
arch/arm64/include/asm/pgalloc.h
arch/arm64/include/asm/smp.h
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/arm64/include/uapi/asm/ptrace.h
arch/arm64/include/uapi/asm/sigcontext.h
arch/arm64/include/uapi/asm/sve_context.h [new file with mode: 0644]
arch/arm64/kernel/Makefile
arch/arm64/kernel/entry.S
arch/arm64/kernel/sys_compat.c
arch/arm64/kernel/syscall.c
arch/arm64/mm/init.c
arch/c6x/include/asm/bitops.h
arch/csky/Kconfig
arch/csky/Makefile
arch/csky/abiv1/inc/abi/pgtable-bits.h
arch/csky/abiv1/inc/abi/switch_context.h [new file with mode: 0644]
arch/csky/abiv2/Makefile
arch/csky/abiv2/inc/abi/entry.h
arch/csky/abiv2/inc/abi/pgtable-bits.h
arch/csky/abiv2/inc/abi/switch_context.h [new file with mode: 0644]
arch/csky/abiv2/mcount.S [new file with mode: 0644]
arch/csky/abiv2/memcpy.S
arch/csky/include/asm/bitops.h
arch/csky/include/asm/elf.h
arch/csky/include/asm/ftrace.h [new file with mode: 0644]
arch/csky/include/asm/perf_event.h [new file with mode: 0644]
arch/csky/include/asm/processor.h
arch/csky/include/asm/smp.h
arch/csky/include/asm/syscall.h
arch/csky/include/asm/thread_info.h
arch/csky/include/uapi/asm/Kbuild
arch/csky/include/uapi/asm/ptrace.h
arch/csky/kernel/Makefile
arch/csky/kernel/asm-offsets.c
arch/csky/kernel/dumpstack.c
arch/csky/kernel/entry.S
arch/csky/kernel/ftrace.c [new file with mode: 0644]
arch/csky/kernel/perf_event.c [new file with mode: 0644]
arch/csky/kernel/process.c
arch/csky/kernel/ptrace.c
arch/csky/kernel/signal.c
arch/csky/kernel/smp.c
arch/csky/kernel/stacktrace.c [new file with mode: 0644]
arch/csky/kernel/traps.c
arch/csky/mm/fault.c
arch/csky/mm/ioremap.c
arch/h8300/include/asm/Kbuild
arch/h8300/include/asm/pci.h [deleted file]
arch/hexagon/include/asm/bitops.h
arch/hexagon/include/asm/pgalloc.h
arch/ia64/Kconfig
arch/ia64/include/asm/bitops.h
arch/ia64/include/asm/pgalloc.h
arch/ia64/mm/init.c
arch/m68k/include/asm/bitops.h
arch/m68k/include/asm/mcf_pgalloc.h
arch/m68k/include/asm/motorola_pgalloc.h
arch/m68k/include/asm/sun3_pgalloc.h
arch/microblaze/include/asm/pgalloc.h
arch/microblaze/mm/pgtable.c
arch/mips/include/asm/bitops.h
arch/mips/include/asm/pgalloc.h
arch/nds32/include/asm/pgalloc.h
arch/nios2/include/asm/pgalloc.h
arch/openrisc/include/asm/bitops/fls.h
arch/openrisc/include/asm/pgalloc.h
arch/openrisc/mm/ioremap.c
arch/parisc/include/asm/bitops.h
arch/parisc/include/asm/pgalloc.h
arch/powerpc/include/asm/book3s/32/pgalloc.h
arch/powerpc/include/asm/book3s/64/pgalloc.h
arch/powerpc/include/asm/nohash/32/pgalloc.h
arch/powerpc/include/asm/nohash/64/pgalloc.h
arch/powerpc/mm/pgtable-frag.c
arch/powerpc/mm/pgtable_32.c
arch/riscv/include/asm/pgalloc.h
arch/s390/include/asm/bitops.h
arch/s390/include/asm/pgalloc.h
arch/sh/include/asm/pgalloc.h
arch/sparc/include/asm/pgalloc_32.h
arch/sparc/include/asm/pgalloc_64.h
arch/sparc/mm/init_64.c
arch/sparc/mm/srmmu.c
arch/um/include/asm/pgalloc.h
arch/um/kernel/mem.c
arch/unicore32/include/asm/bitops.h
arch/unicore32/include/asm/pgalloc.h
arch/x86/Kconfig
arch/x86/include/asm/bitops.h
arch/x86/include/asm/io.h
arch/x86/include/asm/pgalloc.h
arch/x86/include/asm/string_64.h
arch/x86/include/asm/uaccess.h
arch/x86/lib/Makefile
arch/x86/lib/iomem.c [new file with mode: 0644]
arch/x86/mm/pgtable.c
arch/xtensa/include/asm/pgalloc.h
drivers/base/platform.c
drivers/clocksource/timer-mp-csky.c
drivers/dma-buf/udmabuf.c
drivers/firmware/arm_sdei.c
drivers/firmware/memmap.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/memory/Kconfig
drivers/memory/Makefile
drivers/memory/pl353-smc.c [new file with mode: 0644]
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/max1600.c [new file with mode: 0644]
drivers/pcmcia/max1600.h [new file with mode: 0644]
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/sa1111_jornada720.c
drivers/pcmcia/sa1111_lubbock.c
drivers/pcmcia/sa1111_neponset.c
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
drivers/tee/optee/core.c
drivers/tee/optee/supp.c
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/rda-uart.c [new file with mode: 0644]
fs/afs/file.c
fs/afs/fs_probe.c
fs/afs/vl_probe.c
fs/autofs/autofs_i.h
fs/autofs/dev-ioctl.c
fs/autofs/init.c
fs/autofs/inode.c
fs/autofs/root.c
fs/autofs/waitq.c
fs/bfs/bfs.h
fs/bfs/dir.c
fs/bfs/file.c
fs/bfs/inode.c
fs/binfmt_script.c
fs/btrfs/extent_io.c
fs/buffer.c
fs/ceph/addr.c
fs/cifs/file.c
fs/eventpoll.c
fs/exec.c
fs/ext4/readpage.c
fs/fat/cache.c
fs/fat/dir.c
fs/fat/fat.h
fs/fat/fatent.c
fs/fat/inode.c
fs/fat/misc.c
fs/hfsplus/dir.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/ocfs2/aops.c
fs/orangefs/inode.c
fs/orangefs/orangefs-bufmap.c
fs/proc/base.c
fs/proc/inode.c
fs/proc/util.c
include/asm-generic/bitops/builtin-fls.h
include/asm-generic/bitops/fls.h
include/linux/binfmts.h
include/linux/build_bug.h
include/linux/genalloc.h
include/linux/kernel.h
include/linux/mm.h
include/linux/mm_inline.h
include/linux/pl353-smc.h [new file with mode: 0644]
include/linux/printk.h
include/linux/qcom_scm.h
include/linux/sched/task.h
include/linux/uaccess.h
include/uapi/linux/audit.h
include/uapi/linux/auto_fs.h
include/uapi/linux/bfs_fs.h
include/uapi/linux/elf-em.h
include/uapi/linux/msdos_fs.h
include/uapi/linux/serial_core.h
include/uapi/linux/sysctl.h
init/initramfs.c
init/main.c
kernel/compat.c
kernel/exit.c
kernel/fork.c
kernel/hung_task.c
kernel/kcov.c
kernel/locking/mutex.c
kernel/panic.c
kernel/sched/core.c
kernel/sched/swait.c
kernel/sched/wait.c
kernel/sysctl.c
kernel/sysctl_binary.c
lib/find_bit_benchmark.c
lib/genalloc.c
lib/strncpy_from_user.c
lib/strnlen_user.c
mm/filemap.c
mm/gup.c
mm/huge_memory.c
mm/hugetlb.c
mm/kasan/init.c
mm/memory.c
mm/migrate.c
mm/mremap.c
mm/page_io.c
mm/swap.c
mm/userfaultfd.c
scripts/checkpatch.pl
scripts/gdb/linux/proc.py
tools/include/asm-generic/bitops/fls.h
virt/kvm/arm/mmu.c

index 408781ee142c9f0242520e9e240400fc35ca8e58..b799bcf67d7b5ae080694467442b113b49c92567 100644 (file)
                        specified address. The serial port must already be
                        setup and configured. Options are not yet supported.
 
+               rda,<addr>
+                       Start an early, polled-mode console on a serial port
+                       of an RDA Micro SoC, such as RDA8810PL, at the
+                       specified address. The serial port must already be
+                       setup and configured. Options are not yet supported.
+
                smh     Use ARM semihosting calls for early console.
 
                s3c2410,<addr>
                        timeout < 0: reboot immediately
                        Format: <timeout>
 
+       panic_print=    Bitmask for printing system info when panic happens.
+                       User can chose combination of the following bits:
+                       bit 0: print all tasks info
+                       bit 1: print system memory info
+                       bit 2: print timer info
+                       bit 3: print locks info if CONFIG_LOCKDEP is on
+                       bit 4: print ftrace buffer
+
        panic_on_warn   panic() instead of WARN().  Useful to cause kdump
                        on a WARN().
 
diff --git a/Documentation/devicetree/bindings/arm/rda.txt b/Documentation/devicetree/bindings/arm/rda.txt
new file mode 100644 (file)
index 0000000..43c8076
--- /dev/null
@@ -0,0 +1,17 @@
+RDA Micro platforms device tree bindings
+----------------------------------------
+
+RDA8810PL SoC
+=============
+
+Required root node properties:
+
+ - compatible :  must contain "rda,8810pl"
+
+
+Boards:
+
+Root node property compatible must contain, depending on board:
+
+ - Orange Pi 2G-IoT: "xunlong,orangepi-2g-iot"
+ - Orange Pi i96: "xunlong,orangepi-i96"
diff --git a/Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt b/Documentation/devicetree/bindings/memory-controllers/pl353-smc.txt
new file mode 100644 (file)
index 0000000..d56615f
--- /dev/null
@@ -0,0 +1,47 @@
+Device tree bindings for ARM PL353 static memory controller
+
+PL353 static memory controller supports two kinds of memory
+interfaces.i.e NAND and SRAM/NOR interfaces.
+The actual devices are instantiated from the child nodes of pl353 smc node.
+
+Required properties:
+- compatible           : Should be "arm,pl353-smc-r2p1", "arm,primecell".
+- reg                  : Controller registers map and length.
+- clock-names          : List of input clock names - "memclk", "apb_pclk"
+                         (See clock bindings for details).
+- clocks               : Clock phandles (see clock bindings for details).
+- address-cells                : Must be 2.
+- size-cells           : Must be 1.
+
+Child nodes:
+ For NAND the "arm,pl353-nand-r2p1" and for NOR the "cfi-flash" drivers are
+supported as child nodes.
+
+for NAND partition information please refer the below file
+Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+       smcc: memory-controller@e000e000
+                       compatible = "arm,pl353-smc-r2p1", "arm,primecell";
+                       clock-names = "memclk", "apb_pclk";
+                       clocks = <&clkc 11>, <&clkc 44>;
+                       reg = <0xe000e000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0xe1000000 0x1000000 //Nand CS Region
+                                 0x1 0x0 0xe2000000 0x2000000 //SRAM/NOR CS Region
+                                 0x2 0x0 0xe4000000 0x2000000>; //SRAM/NOR CS Region
+                       nand_0: flash@e1000000 {
+                               compatible = "arm,pl353-nand-r2p1"
+                               reg = <0 0 0x1000000>;
+                               (...)
+                       };
+                       nor0: flash@e2000000 {
+                               compatible = "cfi-flash";
+                               reg = <1 0 0x2000000>;
+                       };
+                       nor1: flash@e4000000 {
+                               compatible = "cfi-flash";
+                               reg = <2 0 0x2000000>;
+                       };
+       };
diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
new file mode 100644 (file)
index 0000000..a08df97
--- /dev/null
@@ -0,0 +1,17 @@
+RDA Micro UART
+
+Required properties:
+- compatible :  "rda,8810pl-uart" for RDA8810PL SoCs.
+- reg        :  Offset and length of the register set for the device.
+- interrupts :  Should contain UART interrupt.
+- clocks     :  Phandle to the input clock.
+
+
+Example:
+
+               uart2: serial@20a90000 {
+                       compatible = "rda,8810pl-uart";
+                       reg = <0x20a90000 0x1000>;
+                       interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&uart_clk>;
+               };
index 3bbe3b87a1ff9f34239a500e61503cfeb6244596..389508584f48d36414894f9da0f8e1044ef25593 100644 (file)
@@ -325,6 +325,7 @@ ralink      Mediatek/Ralink Technology Corp.
 ramtron        Ramtron International
 raspberrypi    Raspberry Pi Foundation
 raydium        Raydium Semiconductor Corp.
+rda    Unisoc Communications, Inc.
 realtek Realtek Semiconductor Corp.
 renesas        Renesas Electronics Corporation
 richtek        Richtek Technology Corporation
index 277c113376a6f0182ec1c816746f6a6db10928d3..b78dd680c038094904b274f1de36349a98aec688 100644 (file)
@@ -443,6 +443,9 @@ In function prototypes, include parameter names with their data types.
 Although this is not required by the C language, it is preferred in Linux
 because it is a simple way to add valuable information for the reader.
 
+Do not use the `extern' keyword with function prototypes as this makes
+lines longer and isn't strictly necessary.
+
 
 7) Centralized exiting of functions
 -----------------------------------
index c0917107b90ab5f3b163f1eea3978a232c7c3287..30dc00a364e8947382ef88886cb188797871019b 100644 (file)
@@ -510,7 +510,7 @@ tracking your trees, and to people trying to troubleshoot bugs in your
 tree.
 
 
-12) When to use Acked-by:, Cc:, and Co-Developed-by:
+12) When to use Acked-by:, Cc:, and Co-developed-by:
 -------------------------------------------------------
 
 The Signed-off-by: tag indicates that the signer was involved in the
@@ -543,7 +543,7 @@ person it names - but it should indicate that this person was copied on the
 patch.  This tag documents that potentially interested parties
 have been included in the discussion.
 
-A Co-Developed-by: states that the patch was also created by another developer
+A Co-developed-by: states that the patch was also created by another developer
 along with the original author.  This is useful at times when multiple people
 work on a single patch.  Note, this person also needs to have a Signed-off-by:
 line in the patch as well.
index 1b8775298cf7a0223c04aa7098cf1d1e4d24fefd..c0527d8a468a1dbcd401270c3127d3998b4f2c05 100644 (file)
@@ -60,6 +60,7 @@ show up in /proc/sys/kernel:
 - panic_on_stackoverflow
 - panic_on_unrecovered_nmi
 - panic_on_warn
+- panic_print
 - panic_on_rcu_stall
 - perf_cpu_time_max_percent
 - perf_event_paranoid
@@ -654,6 +655,22 @@ a kernel rebuild when attempting to kdump at the location of a WARN().
 
 ==============================================================
 
+panic_print:
+
+Bitmask for printing system info when panic happens. User can chose
+combination of the following bits:
+
+bit 0: print all tasks info
+bit 1: print system memory info
+bit 2: print timer info
+bit 3: print locks info if CONFIG_LOCKDEP is on
+bit 4: print ftrace buffer
+
+So for example to print tasks and memory info on panic, user can:
+  echo 3 > /proc/sys/kernel/panic_print
+
+==============================================================
+
 panic_on_rcu_stall:
 
 When set to 1, calls panic() after RCU stall detection messages. This
index 99113b9fcdd289ca594c5960c616851755c7c3ed..58551782e960698d38c529afa7a3fdb54bb43829 100644 (file)
@@ -1540,6 +1540,7 @@ F:        arch/arm/mach-imx/
 F:     arch/arm/mach-mxs/
 F:     arch/arm/boot/dts/imx*
 F:     arch/arm/configs/imx*_defconfig
+F:     arch/arm64/boot/dts/freescale/imx*
 F:     drivers/clk/imx/
 F:     drivers/firmware/imx/
 F:     drivers/soc/imx/
@@ -1967,6 +1968,20 @@ M:       Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/RDA MICRO ARCHITECTURE
+M:     Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-unisoc@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/boot/dts/rda8810pl-*
+F:     drivers/clocksource/timer-rda.c
+F:     drivers/irqchip/irq-rda-intc.c
+F:     drivers/tty/serial/rda-uart.c
+F:     Documentation/devicetree/bindings/arm/rda.txt
+F:     Documentation/devicetree/bindings/interrupt-controller/rda,8810pl-intc.txt
+F:     Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
+F:     Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt
+
 ARM/REALTEK ARCHITECTURE
 M:     Andreas Färber <afaerber@suse.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
index e1e540ffa9793d5279c68d9bca412e8a3ef115ae..b70c952ac838c8d0247d46fb053f697823794822 100644 (file)
@@ -535,6 +535,11 @@ config HAVE_IRQ_TIME_ACCOUNTING
          Archs need to ensure they use a high enough resolution clock to
          support irq time accounting and then call enable_sched_clock_irqtime().
 
+config HAVE_MOVE_PMD
+       bool
+       help
+         Archs that select this are able to move page tables at the PMD level.
+
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
        bool
 
index ca43f4d0b93751b3cb262889fb638cf9c07a7011..5adca78830b5e9a3349e5fb410188b0eb98e3bd3 100644 (file)
@@ -391,9 +391,9 @@ static inline unsigned long __fls(unsigned long x)
        return fls64(x) - 1;
 }
 
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
-       return fls64((unsigned int) x);
+       return fls64(x);
 }
 
 /*
index ab3e3a8638fbe56c40cd0d2eeb0d83f89aa240b3..02f9f91bb4f06967cca66f736efb5c1ef21bbbf9 100644 (file)
@@ -52,7 +52,7 @@ pmd_free(struct mm_struct *mm, pmd_t *pmd)
 }
 
 static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
        return pte;
@@ -65,9 +65,9 @@ pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 }
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pte_alloc_one(struct mm_struct *mm)
 {
-       pte_t *pte = pte_alloc_one_kernel(mm, address);
+       pte_t *pte = pte_alloc_one_kernel(mm);
        struct page *page;
 
        if (!pte)
index 8da87feec59aab58a1309fbd5f92fb12b72d8799..ee9246184033b3138f8d09878fc7763502b11e5c 100644 (file)
@@ -278,7 +278,7 @@ static inline __attribute__ ((const)) int clz(unsigned int x)
        return res;
 }
 
-static inline int constant_fls(int x)
+static inline int constant_fls(unsigned int x)
 {
        int r = 32;
 
@@ -312,7 +312,7 @@ static inline int constant_fls(int x)
  * @result: [1-32]
  * fls(1) = 1, fls(0x80000000) = 32, fls(0) = 0
  */
-static inline __attribute__ ((const)) int fls(unsigned long x)
+static inline __attribute__ ((const)) int fls(unsigned int x)
 {
        if (__builtin_constant_p(x))
               return constant_fls(x);
index 3749234b74196cb2f4770b7ed19290aa9cdcc98b..9c9b5a5ebf2e74e149d550e41324fe54bab24c07 100644 (file)
@@ -90,8 +90,7 @@ static inline int __get_order_pte(void)
        return get_order(PTRS_PER_PTE * sizeof(pte_t));
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                       unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -102,7 +101,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 }
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pte_alloc_one(struct mm_struct *mm)
 {
        pgtable_t pte_pg;
        struct page *page;
index e2d9fc3fea01e7a93b4e7bb0b16c7b0874d33e5f..a1d7231970848dbc6f1f097fd7536153d63cf38d 100644 (file)
@@ -142,7 +142,7 @@ good_area:
        fault = handle_mm_fault(vma, address, flags);
 
        /* If Pagefault was interrupted by SIGKILL, exit page fault "early" */
-       if (unlikely(fatal_signal_pending(current))) {
+       if (fatal_signal_pending(current)) {
                if ((fault & VM_FAULT_ERROR) && !(fault & VM_FAULT_RETRY))
                        up_read(&mm->mmap_sem);
                if (user_mode(regs))
index a3f436ba554d68b8becca9c86105914be4c98078..664e918e26249a6dd0a43fa1c80eaf187a040821 100644 (file)
@@ -28,14 +28,14 @@ config ARM
        select ARCH_WANT_IPC_PARSE_VERSION
        select BUILDTIME_EXTABLE_SORT if MMU
        select CLONE_BACKWARDS
-       select CPU_PM if (SUSPEND || CPU_IDLE)
+       select CPU_PM if SUSPEND || CPU_IDLE
        select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
        select DMA_REMAP if MMU
        select EDAC_SUPPORT
        select EDAC_ATOMIC_SCRUB
        select GENERIC_ALLOCATOR
        select GENERIC_ARCH_TOPOLOGY if ARM_CPU_TOPOLOGY
-       select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
+       select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
        select GENERIC_CPU_AUTOPROBE
        select GENERIC_EARLY_IOREMAP
@@ -50,12 +50,12 @@ config ARM
        select GENERIC_STRNLEN_USER
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
-       select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
+       select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
        select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
        select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
        select HAVE_ARCH_MMAP_RND_BITS if MMU
-       select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
+       select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT
        select HAVE_ARCH_THREAD_STRUCT_WHITELIST
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARM_SMCCC if CPU_V7
@@ -64,16 +64,16 @@ config ARM
        select HAVE_C_RECORDMCOUNT
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS if MMU
-       select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU
+       select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
        select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
        select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
        select HAVE_EXIT_THREAD
-       select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
-       select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
-       select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+       select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
+       select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL
+       select HAVE_FUNCTION_TRACER if !XIP_KERNEL
        select HAVE_GCC_PLUGINS
        select HAVE_GENERIC_DMA_COHERENT
-       select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+       select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
        select HAVE_IDE if PCI || ISA || PCMCIA
        select HAVE_IRQ_TIME_ACCOUNTING
        select HAVE_KERNEL_GZIP
@@ -82,15 +82,15 @@ config ARM
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_XZ
        select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
-       select HAVE_KRETPROBES if (HAVE_KPROBES)
+       select HAVE_KRETPROBES if HAVE_KPROBES
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI
-       select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
+       select HAVE_OPROFILE if HAVE_PERF_EVENTS
        select HAVE_OPTPROBES if !THUMB2_KERNEL
        select HAVE_PERF_EVENTS
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE)
+       select HAVE_RCU_TABLE_FREE if SMP && ARM_LPAE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RSEQ
        select HAVE_STACKPROTECTOR
@@ -787,6 +787,8 @@ source "arch/arm/plat-pxa/Kconfig"
 
 source "arch/arm/mach-qcom/Kconfig"
 
+source "arch/arm/mach-rda/Kconfig"
+
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-rockchip/Kconfig"
@@ -1738,7 +1740,6 @@ config PARAVIRT
 config PARAVIRT_TIME_ACCOUNTING
        bool "Paravirtual steal time accounting"
        select PARAVIRT
-       default n
        help
          Select this option to enable fine granularity task steal time
          accounting. Time spent executing other tasks in parallel with
index 0436002d509190c38fd6d037967b0ebf4df9a4f7..9db3c584b2cb46fb45d10a61b72be150a830435d 100644 (file)
@@ -202,6 +202,7 @@ machine-$(CONFIG_ARCH_ORION5X)              += orion5x
 machine-$(CONFIG_ARCH_PICOXCELL)       += picoxcell
 machine-$(CONFIG_ARCH_PXA)             += pxa
 machine-$(CONFIG_ARCH_QCOM)            += qcom
+machine-$(CONFIG_ARCH_RDA)             += rda
 machine-$(CONFIG_ARCH_REALVIEW)                += realview
 machine-$(CONFIG_ARCH_ROCKCHIP)                += rockchip
 machine-$(CONFIG_ARCH_RPC)             += rpc
index 41fa7316c52b9014b63bae76896a4288b5ff4e30..330cd3c2eae55b1f83c3a92c1a1089414594eb8a 100644 (file)
@@ -98,6 +98,24 @@ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
        setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 
+static void hex_str(char *out, uint32_t value)
+{
+       uint32_t digit;
+       int idx;
+
+       for (idx = 7; idx >= 0; idx--) {
+               digit = value >> 28;
+               value <<= 4;
+               digit &= 0xf;
+               if (digit < 10)
+                       digit += '0';
+               else
+                       digit += 'A'-10;
+               *out++ = digit;
+       }
+       *out = '\0';
+}
+
 /*
  * Convert and fold provided ATAGs into the provided FDT.
  *
@@ -180,6 +198,11 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
                                        initrd_start);
                        setprop_cell(fdt, "/chosen", "linux,initrd-end",
                                        initrd_start + initrd_size);
+               } else if (atag->hdr.tag == ATAG_SERIAL) {
+                       char serno[16+2];
+                       hex_str(serno, atag->u.serialnr.high);
+                       hex_str(serno+8, atag->u.serialnr.low);
+                       setprop_string(fdt, "/", "serial-number", serno);
                }
        }
 
index 78551c4375d5203ff4cc47e53a7d12d7c87246d5..bd40148a15b26362ead2215c8f481d8c857450a0 100644 (file)
@@ -822,6 +822,9 @@ dtb-$(CONFIG_ARCH_QCOM) += \
        qcom-msm8974-sony-xperia-castor.dtb \
        qcom-msm8974-sony-xperia-honami.dtb \
        qcom-mdm9615-wp8548-mangoh-green.dtb
+dtb-$(CONFIG_ARCH_RDA) += \
+       rda8810pl-orangepi-2g-iot.dtb \
+       rda8810pl-orangepi-i96.dtb
 dtb-$(CONFIG_ARCH_REALVIEW) += \
        arm-realview-pb1176.dtb \
        arm-realview-pb11mp.dtb \
diff --git a/arch/arm/boot/dts/rda8810pl-orangepi-2g-iot.dts b/arch/arm/boot/dts/rda8810pl-orangepi-2g-iot.dts
new file mode 100644 (file)
index 0000000..98e3424
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2018 Manivannan Sadhasivam
+ */
+
+/dts-v1/;
+
+#include "rda8810pl.dtsi"
+
+/ {
+       compatible = "xunlong,orangepi-2g-iot", "rda,8810pl";
+       model = "Orange Pi 2G-IoT";
+
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+       };
+
+       chosen {
+               stdout-path = "serial2:921600n8";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>;
+       };
+
+       uart_clk: uart-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <921600>;
+               #clock-cells = <0>;
+       };
+};
+
+&uart1 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
+
+&uart2 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
+
+&uart3 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
diff --git a/arch/arm/boot/dts/rda8810pl-orangepi-i96.dts b/arch/arm/boot/dts/rda8810pl-orangepi-i96.dts
new file mode 100644 (file)
index 0000000..728f769
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2018 Manivannan Sadhasivam
+ */
+
+/dts-v1/;
+
+#include "rda8810pl.dtsi"
+
+/ {
+       compatible = "xunlong,orangepi-i96", "rda,8810pl";
+       model = "Orange Pi i96";
+
+       aliases {
+               serial0 = &uart2;
+               serial1 = &uart1;
+               serial2 = &uart3;
+       };
+
+       chosen {
+               stdout-path = "serial2:921600n8";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>;
+       };
+
+       uart_clk: uart-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <921600>;
+               #clock-cells = <0>;
+       };
+};
+
+&uart1 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
+
+&uart2 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
+
+&uart3 {
+       status = "okay";
+       clocks = <&uart_clk>;
+};
diff --git a/arch/arm/boot/dts/rda8810pl.dtsi b/arch/arm/boot/dts/rda8810pl.dtsi
new file mode 100644 (file)
index 0000000..19cde89
--- /dev/null
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * RDA8810PL SoC
+ *
+ * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2018 Manivannan Sadhasivam
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       compatible = "rda,8810pl";
+       interrupt-parent = <&intc>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a5";
+                       reg = <0x0>;
+               };
+       };
+
+       sram@100000 {
+               compatible = "mmio-sram";
+               reg = <0x100000 0x10000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+       };
+
+       apb@20800000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x20800000 0x100000>;
+
+               intc: interrupt-controller@0 {
+                       compatible = "rda,8810pl-intc";
+                       reg = <0x0 0x1000>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       apb@20900000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x20900000 0x100000>;
+
+               timer@10000 {
+                       compatible = "rda,8810pl-timer";
+                       reg = <0x10000 0x1000>;
+                       interrupts = <16 IRQ_TYPE_LEVEL_HIGH>,
+                                    <17 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hwtimer", "ostimer";
+               };
+       };
+
+       apb@20a00000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x20a00000 0x100000>;
+
+               uart1: serial@0 {
+                       compatible = "rda,8810pl-uart";
+                       reg = <0x0 0x1000>;
+                       interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               uart2: serial@10000 {
+                       compatible = "rda,8810pl-uart";
+                       reg = <0x10000 0x1000>;
+                       interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               uart3: serial@90000 {
+                       compatible = "rda,8810pl-uart";
+                       reg = <0x90000 0x1000>;
+                       interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+       };
+
+       l2: cache-controller@21100000 {
+               compatible = "arm,pl310-cache";
+               reg = <0x21100000 0x1000>;
+               cache-unified;
+               cache-level = <2>;
+       };
+};
index a2c878769eaf5a2c616117ff732b1df540778ac8..45412d21aa6b7da2241cb6377a747977a1f80748 100644 (file)
@@ -1282,65 +1282,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
 }
 EXPORT_SYMBOL(sa1111_get_audio_rate);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev,
-                      unsigned int bits, unsigned int dir,
-                      unsigned int sleep_dir)
-{
-       struct sa1111 *sachip = sa1111_chip_driver(sadev);
-       unsigned long flags;
-       unsigned int val;
-       void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-#define MODIFY_BITS(port, mask, dir)           \
-       if (mask) {                             \
-               val = readl_relaxed(port);      \
-               val &= ~(mask);                 \
-               val |= (dir) & (mask);          \
-               writel_relaxed(val, port);      \
-       }
-
-       spin_lock_irqsave(&sachip->lock, flags);
-       MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
-       MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
-       MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
-
-       MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
-       MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
-       MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
-       spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io_dir);
-
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-       struct sa1111 *sachip = sa1111_chip_driver(sadev);
-       unsigned long flags;
-       unsigned int val;
-       void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-       spin_lock_irqsave(&sachip->lock, flags);
-       MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
-       MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
-       MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
-       spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io);
-
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-       struct sa1111 *sachip = sa1111_chip_driver(sadev);
-       unsigned long flags;
-       unsigned int val;
-       void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-       spin_lock_irqsave(&sachip->lock, flags);
-       MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
-       MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
-       MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
-       spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-
 /*
  * Individual device operations.
  */
index f29f49a9f36c9679a77e738e030a7241bfdfa818..5bee34a7ff2e45f6aabaa17453e6efd6145ce5c1 100644 (file)
@@ -867,6 +867,7 @@ CONFIG_STM32_DMA=y
 CONFIG_STM32_DMAMUX=y
 CONFIG_STM32_MDMA=y
 CONFIG_TEGRA20_APB_DMA=y
+CONFIG_UNIPHIER_MDMAC=y
 CONFIG_XILINX_DMA=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_DW_DMAC=y
index 88286dd483ff901bd1d215fb5450db32add47bd2..28a48e0d4cca04f65b8bc90179c8daf5a3632397 100644 (file)
        .endm
 #endif
 
-#define USER(x...)                             \
+#define USERL(l, x...)                         \
 9999:  x;                                      \
        .pushsection __ex_table,"a";            \
        .align  3;                              \
-       .long   9999b,9001f;                    \
+       .long   9999b,l;                        \
        .popsection
 
+#define USER(x...)     USERL(9001f, x)
+
 #ifdef CONFIG_SMP
 #define ALT_SMP(instr...)                                      \
 9998:  instr
index 798e520e8a495a3d12f45cf2985d2bebf5e3792c..d134b9a5ff94794b6f1b251cf97f66b28d531dd2 100644 (file)
@@ -433,10 +433,6 @@ int sa1111_check_dma_bug(dma_addr_t addr);
 int sa1111_driver_register(struct sa1111_driver *);
 void sa1111_driver_unregister(struct sa1111_driver *);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-
 struct sa1111_platform_data {
        int     irq_base;       /* base for cascaded on-chip IRQs */
        unsigned disable_devs;
index 2d7344f0e2085b2a72da34f04fc3264e88834b3a..17ab72f0cc4e619622b12f1dab331973d69aa0c2 100644 (file)
@@ -81,7 +81,7 @@ static inline void clean_pte_table(pte_t *pte)
  *  +------------+
  */
 static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -93,7 +93,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 }
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 27ed17ec45fe2a5728f8cec106baf3a8596afb2f..42aa4a22803c2760d7799bdd17b4434d9cc387bd 100644 (file)
@@ -349,6 +349,13 @@ do {                                                                       \
 #define __get_user_asm_byte(x, addr, err)                      \
        __get_user_asm(x, addr, err, ldrb)
 
+#if __LINUX_ARM_ARCH__ >= 6
+
+#define __get_user_asm_half(x, addr, err)                      \
+       __get_user_asm(x, addr, err, ldrh)
+
+#else
+
 #ifndef __ARMEB__
 #define __get_user_asm_half(x, __gu_addr, err)                 \
 ({                                                             \
@@ -367,6 +374,8 @@ do {                                                                        \
 })
 #endif
 
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
 #define __get_user_asm_word(x, addr, err)                      \
        __get_user_asm(x, addr, err, ldr)
 #endif
@@ -442,6 +451,13 @@ do {                                                                       \
 #define __put_user_asm_byte(x, __pu_addr, err)                 \
        __put_user_asm(x, __pu_addr, err, strb)
 
+#if __LINUX_ARM_ARCH__ >= 6
+
+#define __put_user_asm_half(x, __pu_addr, err)                 \
+       __put_user_asm(x, __pu_addr, err, strh)
+
+#else
+
 #ifndef __ARMEB__
 #define __put_user_asm_half(x, __pu_addr, err)                 \
 ({                                                             \
@@ -458,6 +474,8 @@ do {                                                                        \
 })
 #endif
 
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
 #define __put_user_asm_word(x, __pu_addr, err)                 \
        __put_user_asm(x, __pu_addr, err, str)
 
index 6b1148cafffdbe09070f996343287a4db9bb1baa..4485d0404514cda1b18e5bbd11594f5378a5366f 100644 (file)
@@ -398,7 +398,7 @@ ENTRY(secondary_startup)
        ldmia   r4, {r5, r7, r12}               @ address to jump to after
        sub     lr, r4, r5                      @ mmu has been enabled
        add     r3, r7, lr
-       ldrd    r4, [r3, #0]                    @ get secondary_data.pgdir
+       ldrd    r4, r5, [r3, #0]                @ get secondary_data.pgdir
 ARM_BE8(eor    r4, r4, r5)                     @ Swap r5 and r4 in BE:
 ARM_BE8(eor    r5, r4, r5)                     @ it can be done in 3 steps
 ARM_BE8(eor    r4, r4, r5)                     @ without using a temp reg.
index 12a6172263c0b057a94f2041accf581088374fb0..3bf82232b1bed4bce829749ce6af885bbc43c191 100644 (file)
@@ -724,6 +724,21 @@ void smp_send_stop(void)
                pr_warn("SMP: failed to stop secondary CPUs\n");
 }
 
+/* In case panic() and panic() called at the same time on CPU1 and CPU2,
+ * and CPU 1 calls panic_smp_self_stop() before crash_smp_send_stop()
+ * CPU1 can't receive the ipi irqs from CPU2, CPU1 will be always online,
+ * kdump fails. So split out the panic_smp_self_stop() and add
+ * set_cpu_online(smp_processor_id(), false).
+ */
+void panic_smp_self_stop(void)
+{
+       pr_debug("CPU %u will stop doing anything useful since another CPU has paniced\n",
+                smp_processor_id());
+       set_cpu_online(smp_processor_id(), false);
+       while (1)
+               cpu_relax();
+}
+
 /*
  * not supported here
  */
index 6709a8d33963b679b0a0f6ec683e3291a7f07a71..0d4c189c7f4f00ca4795ae7aa78917838697580b 100644 (file)
  *     Number of bytes NOT copied.
  */
 
+#ifdef CONFIG_CPU_USE_DOMAINS
+
 #ifndef CONFIG_THUMB2_KERNEL
 #define LDR1W_SHIFT    0
 #else
 #define LDR1W_SHIFT    1
 #endif
-#define STR1W_SHIFT    0
 
        .macro ldr1w ptr reg abort
        ldrusr  \reg, \ptr, 4, abort=\abort
        ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
        .endm
 
+#else
+
+#define LDR1W_SHIFT    0
+
+       .macro ldr1w ptr reg abort
+       USERL(\abort, W(ldr) \reg, [\ptr], #4)
+       .endm
+
+       .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+       USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4})
+       .endm
+
+       .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+       USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
+       .endm
+
+#endif /* CONFIG_CPU_USE_DOMAINS */
+
        .macro ldr1b ptr reg cond=al abort
        ldrusr  \reg, \ptr, 1, \cond, abort=\abort
        .endm
 
+#define STR1W_SHIFT    0
+
        .macro str1w ptr reg abort
        W(str) \reg, [\ptr], #4
        .endm
index 970abe521197fa1881473c2f7b1423bcea77227c..97a6ff4b7e3cab0bd4501498bf8a7433dc9ca08a 100644 (file)
  */
 
 #define LDR1W_SHIFT    0
-#ifndef CONFIG_THUMB2_KERNEL
-#define STR1W_SHIFT    0
-#else
-#define STR1W_SHIFT    1
-#endif
 
        .macro ldr1w ptr reg abort
        W(ldr) \reg, [\ptr], #4
        ldr\cond\()b \reg, [\ptr], #1
        .endm
 
+#ifdef CONFIG_CPU_USE_DOMAINS
+
+#ifndef CONFIG_THUMB2_KERNEL
+#define STR1W_SHIFT    0
+#else
+#define STR1W_SHIFT    1
+#endif
+
        .macro str1w ptr reg abort
        strusr  \reg, \ptr, 4, abort=\abort
        .endm
        str1w \ptr, \reg8, \abort
        .endm
 
+#else
+
+#define STR1W_SHIFT    0
+
+       .macro str1w ptr reg abort
+       USERL(\abort, W(str) \reg, [\ptr], #4)
+       .endm
+
+       .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+       USERL(\abort, stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
+       .endm
+
+#endif /* CONFIG_CPU_USE_DOMAINS */
+
        .macro str1b ptr reg cond=al abort
        strusr  \reg, \ptr, 1, \cond, abort=\abort
        .endm
index 746e7801dcdf70fed9e339c2d6800b3f275c49b7..b2e4bc3a635e22002fd90eaf4d802b528f6dab32 100644 (file)
@@ -42,6 +42,12 @@ _ASM_NOKPROBE(__get_user_1)
 
 ENTRY(__get_user_2)
        check_uaccess r0, 2, r1, r2, __get_user_bad
+#if __LINUX_ARM_ARCH__ >= 6
+
+2: TUSER(ldrh) r2, [r0]
+
+#else
+
 #ifdef CONFIG_CPU_USE_DOMAINS
 rb     .req    ip
 2:     ldrbt   r2, [r0], #1
@@ -56,6 +62,9 @@ rb    .req    r0
 #else
        orr     r2, rb, r2, lsl #8
 #endif
+
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
        mov     r0, #0
        ret     lr
 ENDPROC(__get_user_2)
@@ -145,7 +154,9 @@ _ASM_NOKPROBE(__get_user_bad8)
 .pushsection __ex_table, "a"
        .long   1b, __get_user_bad
        .long   2b, __get_user_bad
+#if __LINUX_ARM_ARCH__ < 6
        .long   3b, __get_user_bad
+#endif
        .long   4b, __get_user_bad
        .long   5b, __get_user_bad8
        .long   6b, __get_user_bad8
index 38d660d3705f4f259c5299d2cc8c1126f0a1dbb4..515eeaa9975c6cbf75b8aba01d85df7deb063b25 100644 (file)
@@ -41,16 +41,13 @@ ENDPROC(__put_user_1)
 
 ENTRY(__put_user_2)
        check_uaccess r0, 2, r1, ip, __put_user_bad
-       mov     ip, r2, lsr #8
-#ifdef CONFIG_THUMB2_KERNEL
-#ifndef __ARMEB__
-2: TUSER(strb) r2, [r0]
-3: TUSER(strb) ip, [r0, #1]
+#if __LINUX_ARM_ARCH__ >= 6
+
+2: TUSER(strh) r2, [r0]
+
 #else
-2: TUSER(strb) ip, [r0]
-3: TUSER(strb) r2, [r0, #1]
-#endif
-#else  /* !CONFIG_THUMB2_KERNEL */
+
+       mov     ip, r2, lsr #8
 #ifndef __ARMEB__
 2: TUSER(strb) r2, [r0], #1
 3: TUSER(strb) ip, [r0]
@@ -58,7 +55,8 @@ ENTRY(__put_user_2)
 2: TUSER(strb) ip, [r0], #1
 3: TUSER(strb) r2, [r0]
 #endif
-#endif /* CONFIG_THUMB2_KERNEL */
+
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
        mov     r0, #0
        ret     lr
 ENDPROC(__put_user_2)
@@ -91,7 +89,9 @@ ENDPROC(__put_user_bad)
 .pushsection __ex_table, "a"
        .long   1b, __put_user_bad
        .long   2b, __put_user_bad
+#if __LINUX_ARM_ARCH__ < 6
        .long   3b, __put_user_bad
+#endif
        .long   4b, __put_user_bad
        .long   5b, __put_user_bad
        .long   6b, __put_user_bad
index 9f27b486a5362fca0bbd3819d3498e6e55755201..5e33d1a9066473fe6aa9cd871b15c1f80cc486c7 100644 (file)
@@ -223,7 +223,6 @@ config MACH_NOKIA_N8X0
 config OMAP3_SDRC_AC_TIMING
        bool "Enable SDRC AC timing register changes"
        depends on ARCH_OMAP3
-       default n
        help
          If you know that none of your system initiators will attempt to
          access SDRAM during CORE DVFS, select Y here.  This should boost
index 1c73694c871ad8289b572056d5c3727f3ee22eb2..10e070368f64f6997b8f5b9ad933bfe708e7a507 100644 (file)
@@ -69,8 +69,6 @@ static const struct omap_smp_config omap5_cfg __initconst = {
        .startup_addr = omap5_secondary_startup,
 };
 
-static DEFINE_SPINLOCK(boot_lock);
-
 void __iomem *omap4_get_scu_base(void)
 {
        return cfg.scu_base;
@@ -173,12 +171,6 @@ static void omap4_secondary_init(unsigned int cpu)
                /* Enable ACR to allow for ICUALLU workaround */
                omap5_secondary_harden_predictor();
        }
-
-       /*
-        * Synchronise with the boot thread.
-        */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
 }
 
 static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -187,12 +179,6 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
        static bool booted;
        static struct powerdomain *cpu1_pwrdm;
 
-       /*
-        * Set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       spin_lock(&boot_lock);
-
        /*
         * Update the AuxCoreBoot0 with boot state for secondary core.
         * omap4_secondary_startup() routine will hold the secondary core till
@@ -266,12 +252,6 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
        arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 
-       /*
-        * Now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       spin_unlock(&boot_lock);
-
        return 0;
 }
 
index b185794549be464c9db36b86f36d766858f5895e..dc8e4f4b7adeef460cc58767f5dabe155c327498 100644 (file)
@@ -46,6 +46,7 @@ config ARCH_LUBBOCK
 
 config MACH_MAINSTONE
        bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
+       select GPIO_REG
        select PXA27x
 
 config MACH_ZYLONITE
@@ -551,7 +552,6 @@ config TOSA_BT
 config TOSA_USE_EXT_KEYCODES
        bool "Tosa keyboard: use extended keycodes"
        depends on MACH_TOSA
-       default n
        help
          Say Y here to enable the tosa keyboard driver to generate extended
          (>= 127) keycodes. Be aware, that they can't be correctly interpreted
index e82a7d31104e02f5c21987d198fe229bad8afff5..474041a83d80b09de20840468bd2218e2114a78f 100644 (file)
 #define MST_PCMCIA_PWR_VCC_33   0x8       /* voltage VCC = 3.3V */
 #define MST_PCMCIA_PWR_VCC_50   0x4       /* voltage VCC = 5.0V */
 
+#define MST_PCMCIA_INPUTS \
+       (MST_PCMCIA_nIRQ | MST_PCMCIA_nSPKR_BVD2 | MST_PCMCIA_nSTSCHG_BVD1 | \
+        MST_PCMCIA_nVS2 | MST_PCMCIA_nVS1 | MST_PCMCIA_nCD)
+
 /* board specific IRQs */
 #define MAINSTONE_NR_IRQS      IRQ_BOARD_START
 
index c576e8462043c998009095b6e169b0a3f30641a7..a1391e113ef464638ef649eb157a85c08b3144a3 100644 (file)
@@ -136,10 +136,26 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
        // no D+ pullup; lubbock can't connect/disconnect in software
 };
 
+/* GPIOs for SA1111 PCMCIA */
+static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = {
+       .dev_id = "1800",
+       .table = {
+               { "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH },
+               { "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH },
+               { "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH },
+               { "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH },
+               { "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH },
+               { "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH },
+               { },
+       },
+};
+
 static void lubbock_init_pcmcia(void)
 {
        struct clk *clk;
 
+       gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table);
+
        /* Add an alias for the SA1111 PCMCIA clock */
        clk = clk_get_sys("pxa2xx-pcmcia", NULL);
        if (!IS_ERR(clk)) {
index 9e39fc2ad2d97c6188aeda052067fdfda1329d49..d6e17d407ac0c555912379441a946e15d2649b27 100644 (file)
@@ -13,6 +13,7 @@
  *  published by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -504,12 +505,64 @@ static void __init mainstone_init_keypad(void)
 static inline void mainstone_init_keypad(void) {}
 #endif
 
+static int mst_pcmcia0_irqs[11] = {
+       [0 ... 10] = -1,
+       [5] = MAINSTONE_S0_CD_IRQ,
+       [8] = MAINSTONE_S0_STSCHG_IRQ,
+       [10] = MAINSTONE_S0_IRQ,
+};
+
+static int mst_pcmcia1_irqs[11] = {
+       [0 ... 10] = -1,
+       [5] = MAINSTONE_S1_CD_IRQ,
+       [8] = MAINSTONE_S1_STSCHG_IRQ,
+       [10] = MAINSTONE_S1_IRQ,
+};
+
+static struct gpiod_lookup_table mainstone_pcmcia_gpio_table = {
+       .dev_id = "pxa2xx-pcmcia",
+       .table = {
+               GPIO_LOOKUP("mst-pcmcia0",  0, "a0vpp",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  1, "a1vpp",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  2, "a0vcc",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  3, "a1vcc",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  4, "areset",  GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  5, "adetect", GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia0",  6, "avs1",    GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia0",  7, "avs2",    GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia0",  8, "abvd1",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0",  9, "abvd2",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia0", 10, "aready",  GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  0, "b0vpp",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  1, "b1vpp",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  2, "b0vcc",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  3, "b1vcc",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  4, "breset",  GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  5, "bdetect", GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia1",  6, "bvs1",    GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia1",  7, "bvs2",    GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("mst-pcmcia1",  8, "bbvd1",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1",  9, "bbvd2",   GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("mst-pcmcia1", 10, "bready",  GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static void __init mainstone_init(void)
 {
        int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
 
+       /* Register board control register(s) as GPIOs */
+       gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0, -1, 11,
+                     "mst-pcmcia0", MST_PCMCIA_INPUTS, 0, NULL,
+                     NULL, mst_pcmcia0_irqs);
+       gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA1, -1, 11,
+                     "mst-pcmcia1", MST_PCMCIA_INPUTS, 0, NULL,
+                     NULL, mst_pcmcia1_irqs);
+       gpiod_add_lookup_table(&mainstone_pcmcia_gpio_table);
+
        pxa_set_ffuart_info(NULL);
        pxa_set_btuart_info(NULL);
        pxa_set_stuart_info(NULL);
diff --git a/arch/arm/mach-rda/Kconfig b/arch/arm/mach-rda/Kconfig
new file mode 100644 (file)
index 0000000..4df8b8e
--- /dev/null
@@ -0,0 +1,7 @@
+menuconfig ARCH_RDA
+       bool "RDA Micro SoCs"
+       depends on ARCH_MULTI_V7
+       select RDA_INTC
+       select RDA_TIMER
+       help
+         This enables support for the RDA Micro 8810PL SoC family.
diff --git a/arch/arm/mach-rda/Makefile b/arch/arm/mach-rda/Makefile
new file mode 100644 (file)
index 0000000..6bea3d3
--- /dev/null
@@ -0,0 +1 @@
+obj- += dummy.o
index adf39ad71cc310d91a55a88a2b466ff09427fb81..6ca6400fa51e142469293b878d68daad4c8a5930 100644 (file)
@@ -5,4 +5,3 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-versatile/inc
 
 obj-y                                  += realview-dt.o
 obj-$(CONFIG_SMP)                      += platsmp-dt.o
-obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
deleted file mode 100644 (file)
index 968e2d1..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/hotplug.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/cp15.h>
-#include <asm/smp_plat.h>
-
-static inline void cpu_enter_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-       "       mcr     p15, 0, %1, c7, c5, 0\n"
-       "       mcr     p15, 0, %1, c7, c10, 4\n"
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, #0x20\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-         : "=&r" (v)
-         : "r" (0), "Ir" (CR_C)
-         : "cc");
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(   "mrc    p15, 0, %0, c1, c0, 0\n"
-       "       orr     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       orr     %0, %0, #0x20\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-         : "=&r" (v)
-         : "Ir" (CR_C)
-         : "cc");
-}
-
-static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
-{
-       /*
-        * there is no power-control hardware on this platform, so all
-        * we can do is put the core into WFI; this is safe as the calling
-        * code will have already disabled interrupts
-        */
-       for (;;) {
-               /*
-                * here's the WFI
-                */
-               asm(".word      0xe320f003\n"
-                   :
-                   :
-                   : "memory", "cc");
-
-               if (pen_release == cpu_logical_map(cpu)) {
-                       /*
-                        * OK, proper wakeup, we're done
-                        */
-                       break;
-               }
-
-               /*
-                * Getting here, means that we have come out of WFI without
-                * having been woken up - this shouldn't happen
-                *
-                * Just note it happening - when we're woken, we can report
-                * its occurrence.
-                */
-               (*spurious)++;
-       }
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void realview_cpu_die(unsigned int cpu)
-{
-       int spurious = 0;
-
-       /*
-        * we're ready for shutdown now, so do it
-        */
-       cpu_enter_lowpower();
-       platform_do_lowpower(cpu, &spurious);
-
-       /*
-        * bring this CPU back into the world of cache
-        * coherency, and then restore interrupts
-        */
-       cpu_leave_lowpower();
-
-       if (spurious)
-               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
-}
diff --git a/arch/arm/mach-realview/hotplug.h b/arch/arm/mach-realview/hotplug.h
deleted file mode 100644 (file)
index eacd7a4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-void realview_cpu_die(unsigned int cpu);
index c242423bf8db5a5e64d9818f01c42e0b23b699fd..ce331b3dbf54d46ae75a58ba92f6f1b90b5401e9 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/smp_scu.h>
 
 #include <plat/platsmp.h>
-#include "hotplug.h"
 
 #define REALVIEW_SYS_FLAGSSET_OFFSET   0x30
 
@@ -79,6 +78,13 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
                     __pa_symbol(versatile_secondary_startup));
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void realview_cpu_die(unsigned int cpu)
+{
+       return versatile_immitation_cpu_die(cpu, 0x20);
+}
+#endif
+
 static const struct smp_operations realview_dt_smp_ops __initconst = {
        .smp_prepare_cpus       = realview_smp_prepare_cpus,
        .smp_secondary_init     = versatile_secondary_init,
index acb2c520ae8b55a0ec420924d186091bbf9ce11b..ce41c6708a8309337601e72423921b07e48d9bc4 100644 (file)
@@ -6,6 +6,7 @@ config SA1100_ASSABET
        bool "Assabet"
        select ARM_SA1110_CPUFREQ
        select GPIO_REG
+       select LEDS_GPIO_REGISTER
        select REGULATOR
        select REGULATOR_FIXED_VOLTAGE
        help
@@ -24,6 +25,7 @@ config ASSABET_NEPONSET
 config SA1100_CERF
        bool "CerfBoard"
        select ARM_SA1110_CPUFREQ
+       select LEDS_GPIO_REGISTER
        help
          The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
          More information is available at:
index 3e8c0948abcc3ef52e557429211936268e4cf034..dfa42496ec27957f8a1cddff3b640626d430c374 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/gpio/gpio-reg.h>
 #include <linux/gpio/machine.h>
+#include <linux/gpio_keys.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/regulator/fixed.h>
@@ -101,7 +102,7 @@ static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
 
        assabet_bcr_gc = gc;
 
-       return 0;
+       return gc->base;
 }
 
 /*
@@ -479,6 +480,49 @@ static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = {
        },
 };
 
+static struct gpio_led assabet_leds[] __initdata = {
+       {
+               .name = "assabet:red",
+               .default_trigger = "cpu0",
+               .active_low = 1,
+               .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+       }, {
+               .name = "assabet:green",
+               .default_trigger = "heartbeat",
+               .active_low = 1,
+               .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+       },
+};
+
+static const struct gpio_led_platform_data assabet_leds_pdata __initconst = {
+       .num_leds = ARRAY_SIZE(assabet_leds),
+       .leds = assabet_leds,
+};
+
+static struct gpio_keys_button assabet_keys_buttons[] = {
+       {
+               .gpio = 0,
+               .irq = IRQ_GPIO0,
+               .desc = "gpio0",
+               .wakeup = 1,
+               .can_disable = 1,
+               .debounce_interval = 5,
+       }, {
+               .gpio = 1,
+               .irq = IRQ_GPIO1,
+               .desc = "gpio1",
+               .wakeup = 1,
+               .can_disable = 1,
+               .debounce_interval = 5,
+       },
+};
+
+static const struct gpio_keys_platform_data assabet_keys_pdata = {
+       .buttons = assabet_keys_buttons,
+       .nbuttons = ARRAY_SIZE(assabet_keys_buttons),
+       .rep = 0,
+};
+
 static void __init assabet_init(void)
 {
        /*
@@ -533,6 +577,13 @@ static void __init assabet_init(void)
 
        }
 
+       platform_device_register_resndata(NULL, "gpio-keys", 0,
+                                         NULL, 0,
+                                         &assabet_keys_pdata,
+                                         sizeof(assabet_keys_pdata));
+
+       gpio_led_register_device(-1, &assabet_leds_pdata);
+
 #ifndef ASSABET_PAL_VIDEO
        sa11x0_register_lcd(&lq039q2ds54_info);
 #else
@@ -726,92 +777,9 @@ static void __init assabet_map_io(void)
        sa1100_register_uart(2, 3);
 }
 
-/* LEDs */
-#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
-struct assabet_led {
-       struct led_classdev cdev;
-       u32 mask;
-};
-
-/*
- * The triggers lines up below will only be used if the
- * LED triggers are compiled in.
- */
-static const struct {
-       const char *name;
-       const char *trigger;
-} assabet_leds[] = {
-       { "assabet:red", "cpu0",},
-       { "assabet:green", "heartbeat", },
-};
-
-/*
- * The LED control in Assabet is reversed:
- *  - setting bit means turn off LED
- *  - clearing bit means turn on LED
- */
-static void assabet_led_set(struct led_classdev *cdev,
-               enum led_brightness b)
-{
-       struct assabet_led *led = container_of(cdev,
-                       struct assabet_led, cdev);
-
-       if (b != LED_OFF)
-               ASSABET_BCR_clear(led->mask);
-       else
-               ASSABET_BCR_set(led->mask);
-}
-
-static enum led_brightness assabet_led_get(struct led_classdev *cdev)
-{
-       struct assabet_led *led = container_of(cdev,
-                       struct assabet_led, cdev);
-
-       return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
-}
-
-static int __init assabet_leds_init(void)
-{
-       int i;
-
-       if (!machine_is_assabet())
-               return -ENODEV;
-
-       for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
-               struct assabet_led *led;
-
-               led = kzalloc(sizeof(*led), GFP_KERNEL);
-               if (!led)
-                       break;
-
-               led->cdev.name = assabet_leds[i].name;
-               led->cdev.brightness_set = assabet_led_set;
-               led->cdev.brightness_get = assabet_led_get;
-               led->cdev.default_trigger = assabet_leds[i].trigger;
-
-               if (!i)
-                       led->mask = ASSABET_BCR_LED_RED;
-               else
-                       led->mask = ASSABET_BCR_LED_GREEN;
-
-               if (led_classdev_register(NULL, &led->cdev) < 0) {
-                       kfree(led);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Since we may have triggers on any subsystem, defer registration
- * until after subsystem_init.
- */
-fs_initcall(assabet_leds_init);
-#endif
-
 void __init assabet_init_irq(void)
 {
+       unsigned int assabet_gpio_base;
        u32 def_val;
 
        sa1100_init_irq();
@@ -826,7 +794,10 @@ void __init assabet_init_irq(void)
         *
         * This must precede any driver calls to BCR_set() or BCR_clear().
         */
-       assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+       assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+
+       assabet_leds[0].gpio = assabet_gpio_base + 13;
+       assabet_leds[1].gpio = assabet_gpio_base + 14;
 }
 
 MACHINE_START(ASSABET, "Intel-Assabet")
index b2a4b41626efbb3f920efd6ea99fa35205b6e7a3..88e526561a2440f2ea1b66411bb1ba238a038169 100644 (file)
@@ -89,18 +89,8 @@ static struct gpio_led_platform_data cerf_gpio_led_info = {
        .num_leds       = ARRAY_SIZE(cerf_gpio_leds),
 };
 
-static struct platform_device cerf_leds = {
-       .name   = "leds-gpio",
-       .id     = -1,
-       .dev    = {
-               .platform_data  = &cerf_gpio_led_info,
-       }
-};
-
-
 static struct platform_device *cerf_devices[] __initdata = {
        &cerfuart2_device,
-       &cerf_leds,
 };
 
 #ifdef CONFIG_SA1100_CERF_FLASH_32MB
@@ -176,6 +166,7 @@ static void __init cerf_init(void)
 {
        sa11x0_ppc_configure_mcp();
        platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
+       gpio_led_register_device(-1, &cerf_gpio_led_info);
        sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
        sa11x0_register_mcp(&cerf_mcp_data);
        sa11x0_register_pcmcia(1, &cerf_cf_gpio_table);
index 800321c6cbd8cf5edb209904b52634292f35c735..755290bf658b49f825d0dc57e5e6cdb58e925c4d 100644 (file)
@@ -235,18 +235,11 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
        sa11x0_register_device(&sa11x0fb_device, inf);
 }
 
-static bool sa11x0pcmcia_legacy = true;
-static struct platform_device sa11x0pcmcia_device = {
-       .name           = "sa11x0-pcmcia",
-       .id             = -1,
-};
-
 void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
 {
        if (table)
                gpiod_add_lookup_table(table);
        platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
-       sa11x0pcmcia_legacy = false;
 }
 
 static struct platform_device sa11x0mtd_device = {
@@ -331,9 +324,6 @@ static int __init sa1100_init(void)
 {
        pm_power_off = sa1100_power_off;
 
-       if (sa11x0pcmcia_legacy)
-               platform_device_register(&sa11x0pcmcia_device);
-
        regulator_has_full_constraints();
 
        return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
index c6b412054a3c9057a3840acacbca0fd49bc70947..9dc5bcb7326bbcbcad649db51f93c5d2dbd783a8 100644 (file)
@@ -126,6 +126,7 @@ static void __init h3100_mach_init(void)
 {
        h3xxx_mach_init();
 
+       sa11x0_register_pcmcia(-1, NULL);
        sa11x0_register_lcd(&h3100_lcd_info);
        sa11x0_register_irda(&h3100_irda_data);
 }
index 0a2ca9be00e6dff68a8dcbd60e66468c4cf66680..6298bad09ef35ee1abeb658309dbc00d11ac8cc1 100644 (file)
@@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = {
        .resource       = s1d13xxxfb_resources,
 };
 
+static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
+       .dev_id = "1800",
+       .table = {
+               GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static struct resource sa1111_resources[] = {
        [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
        [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
@@ -265,6 +276,7 @@ static int __init jornada720_init(void)
                udelay(20);             /* give it some time to restart */
 
                gpiod_add_lookup_table(&jornada_ts_gpiod_table);
+               gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
 
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
index b1823f445358cf99ffba59704a77d6917d181378..eb60a71cf125a4b78c57e51bcbe5d55f53eb49c6 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/gpio-reg.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -96,6 +97,19 @@ struct neponset_drvdata {
        struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_pcmcia_table = {
+       .dev_id = "1800",
+       .table = {
+               GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev)
                           d->base + AUD_CTL, AUD_NGPIO, false,
                           neponset_aud_names);
 
+       gpiod_add_lookup_table(&neponset_pcmcia_table);
+
        /*
         * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
         * something on the Neponset activates this IRQ on sleep (eth?)
@@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev)
                platform_device_unregister(d->sa1111);
        if (!IS_ERR(d->smc91x))
                platform_device_unregister(d->smc91x);
+
+       gpiod_remove_lookup_table(&neponset_pcmcia_table);
+
        irq_set_chained_handler(irq, NULL);
        irq_free_descs(d->irq_base, NEP_IRQ_NR);
        nep = NULL;
index acb330916333039510c562d18de547020b3c2044..f85ff059cfba47c092bd2c6a0be72c25673abe0b 100644 (file)
@@ -1,2 +1,2 @@
-obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
+obj-$(CONFIG_SMP)              += platsmp.o
 obj-$(CONFIG_ARCH_STI)                 += board-dt.o
diff --git a/arch/arm/mach-sti/headsmp.S b/arch/arm/mach-sti/headsmp.S
deleted file mode 100644 (file)
index e0ad451..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  arch/arm/mach-sti/headsmp.S
- *
- * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
- *             http://www.st.com
- *
- * Cloned from linux/arch/arm/mach-vexpress/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-/*
- * ST specific entry point for secondary CPUs.  This provides
- * a "holding pen" into which all secondary cores are held until we're
- * ready for them to initialise.
- */
-ENTRY(sti_secondary_startup)
-       mrc     p15, 0, r0, c0, c0, 5
-       and     r0, r0, #15
-       adr     r4, 1f
-       ldmia   r4, {r5, r6}
-       sub     r4, r4, r5
-       add     r6, r6, r4
-pen:   ldr     r7, [r6]
-       cmp     r7, r0
-       bne     pen
-
-       /*
-        * we've been released from the holding pen: secondary_stack
-        * should now contain the SVC stack for this core
-        */
-       b       secondary_startup
-ENDPROC(sti_secondary_startup)
-
-1:     .long   .
-       .long   pen_release
index 231f19e174365229f034c9897b6e61984b92d84c..d0272a839ffb3d4d24d42a24af1f03474b2359fa 100644 (file)
 
 #include "smp.h"
 
-static void write_pen_release(int val)
-{
-       pen_release = val;
-       smp_wmb();
-       sync_cache_w(&pen_release);
-}
-
-static DEFINE_SPINLOCK(boot_lock);
-
-static void sti_secondary_init(unsigned int cpu)
-{
-       /*
-        * let the primary processor know we're out of the
-        * pen, then head off into the C entry point
-        */
-       write_pen_release(-1);
-
-       /*
-        * Synchronise with the boot thread.
-        */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
-}
+static u32 __iomem *cpu_strt_ptr;
 
 static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       unsigned long timeout;
-
-       /*
-        * set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       spin_lock(&boot_lock);
+       unsigned long entry_pa = __pa_symbol(secondary_startup);
 
        /*
-        * The secondary processor is waiting to be released from
-        * the holding pen - release it, then wait for it to flag
-        * that it has been released by resetting pen_release.
-        *
-        * Note that "pen_release" is the hardware CPU ID, whereas
-        * "cpu" is Linux's internal ID.
+        * Secondary CPU is initialised and started by a U-BOOTROM firmware.
+        * Secondary CPU is spinning and waiting for a write at cpu_strt_ptr.
+        * Writing secondary_startup address at cpu_strt_ptr makes it to
+        * jump directly to secondary_startup().
         */
-       write_pen_release(cpu_logical_map(cpu));
+       __raw_writel(entry_pa, cpu_strt_ptr);
 
-       /*
-        * Send the secondary CPU a soft interrupt, thereby causing
-        * it to jump to the secondary entrypoint.
-        */
-       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               smp_rmb();
-               if (pen_release == -1)
-                       break;
-
-               udelay(10);
-       }
-
-       /*
-        * now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       spin_unlock(&boot_lock);
+       /* wmb so that data is actually written before cache flush is done */
+       smp_wmb();
+       sync_cache_w(cpu_strt_ptr);
 
-       return pen_release != -1 ? -ENOSYS : 0;
+       return 0;
 }
 
 static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
 {
        struct device_node *np;
        void __iomem *scu_base;
-       u32 __iomem *cpu_strt_ptr;
        u32 release_phys;
        int cpu;
-       unsigned long entry_pa = __pa_symbol(sti_secondary_startup);
 
        np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 
@@ -131,8 +82,8 @@ static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
                }
 
                /*
-                * holding pen is usually configured in SBC DMEM but can also be
-                * in RAM.
+                * cpu-release-addr is usually configured in SBC DMEM but can
+                * also be in RAM.
                 */
 
                if (!memblock_is_memory(release_phys))
@@ -142,22 +93,11 @@ static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
                        cpu_strt_ptr =
                                (u32 __iomem *)phys_to_virt(release_phys);
 
-               __raw_writel(entry_pa, cpu_strt_ptr);
-
-               /*
-                * wmb so that data is actually written
-                * before cache flush is done
-                */
-               smp_wmb();
-               sync_cache_w(cpu_strt_ptr);
-
-               if (!memblock_is_memory(release_phys))
-                       iounmap(cpu_strt_ptr);
+               set_cpu_possible(cpu, true);
        }
 }
 
 const struct smp_operations sti_smp_ops __initconst = {
        .smp_prepare_cpus       = sti_smp_prepare_cpus,
-       .smp_secondary_init     = sti_secondary_init,
        .smp_boot_secondary     = sti_boot_secondary,
 };
index 51c35e2b737aa6eb6123b384ab36880d0f5fa633..3651a1ed0f2b197f875470782bc60f745ed4b5dd 100644 (file)
@@ -15,6 +15,5 @@ obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM)    += tc2_pm.o
 CFLAGS_tc2_pm.o                                += -march=armv7-a
 CFLAGS_REMOVE_tc2_pm.o                 = -pg
 obj-$(CONFIG_SMP)                      += platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
 
 obj-$(CONFIG_ARCH_MPS2)                        += v2m-mps2.o
index a162ab46ee0253d4493873676b0f1758e3130c1f..f4a7519084f170fb949139e7ccfe3ac37ccef57b 100644 (file)
@@ -1,5 +1,3 @@
 bool vexpress_smp_init_ops(void);
 
 extern const struct smp_operations vexpress_smp_dt_ops;
-
-extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
deleted file mode 100644 (file)
index d8f1a05..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/hotplug.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/smp_plat.h>
-#include <asm/cp15.h>
-
-#include "core.h"
-
-static inline void cpu_enter_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mcr    p15, 0, %1, c7, c5, 0\n"
-       "       mcr     p15, 0, %1, c7, c10, 4\n"
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, %3\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-         : "=&r" (v)
-         : "r" (0), "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mrc    p15, 0, %0, c1, c0, 0\n"
-       "       orr     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       orr     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-         : "=&r" (v)
-         : "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
-static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
-{
-       /*
-        * there is no power-control hardware on this platform, so all
-        * we can do is put the core into WFI; this is safe as the calling
-        * code will have already disabled interrupts
-        */
-       for (;;) {
-               wfi();
-
-               if (pen_release == cpu_logical_map(cpu)) {
-                       /*
-                        * OK, proper wakeup, we're done
-                        */
-                       break;
-               }
-
-               /*
-                * Getting here, means that we have come out of WFI without
-                * having been woken up - this shouldn't happen
-                *
-                * Just note it happening - when we're woken, we can report
-                * its occurrence.
-                */
-               (*spurious)++;
-       }
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void vexpress_cpu_die(unsigned int cpu)
-{
-       int spurious = 0;
-
-       /*
-        * we're ready for shutdown now, so do it
-        */
-       cpu_enter_lowpower();
-       platform_do_lowpower(cpu, &spurious);
-
-       /*
-        * bring this CPU back into the world of cache
-        * coherency, and then restore interrupts
-        */
-       cpu_leave_lowpower();
-
-       if (spurious)
-               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
-}
index 742499bac6d09f27eaed8580e2df4b06e63a3252..af0113be597035d7f666847b948a48f83ce7bec3 100644 (file)
@@ -82,6 +82,13 @@ static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
        vexpress_flags_set(__pa_symbol(versatile_secondary_startup));
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void vexpress_cpu_die(unsigned int cpu)
+{
+       versatile_immitation_cpu_die(cpu, 0x40);
+}
+#endif
+
 const struct smp_operations vexpress_smp_dt_ops __initconst = {
        .smp_prepare_cpus       = vexpress_smp_dt_prepare_cpus,
        .smp_secondary_init     = versatile_secondary_init,
index d130a5ece5d55658b1c6cdd11f2721e7ea3f53f6..bf24690ec83aff157e2042e5d4a2a4f2a078d6b4 100644 (file)
 /*
  * Faraday optimised copy_user_page
  */
-static void __naked
-fa_copy_user_page(void *kto, const void *kfrom)
+static void fa_copy_user_page(void *kto, const void *kfrom)
 {
-       asm("\
-       stmfd   sp!, {r4, lr}                   @ 2\n\
-       mov     r2, %0                          @ 1\n\
-1:     ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       stmia   r0, {r3, r4, ip, lr}            @ 4\n\
-       mcr     p15, 0, r0, c7, c14, 1          @ 1   clean and invalidate D line\n\
-       add     r0, r0, #16                     @ 1\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       stmia   r0, {r3, r4, ip, lr}            @ 4\n\
-       mcr     p15, 0, r0, c7, c14, 1          @ 1   clean and invalidate D line\n\
-       add     r0, r0, #16                     @ 1\n\
-       subs    r2, r2, #1                      @ 1\n\
+       int tmp;
+
+       asm volatile ("\
+1:     ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       stmia   %0, {r3, r4, ip, lr}            @ 4\n\
+       mcr     p15, 0, %0, c7, c14, 1          @ 1   clean and invalidate D line\n\
+       add     %0, %0, #16                     @ 1\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       stmia   %0, {r3, r4, ip, lr}            @ 4\n\
+       mcr     p15, 0, %0, c7, c14, 1          @ 1   clean and invalidate D line\n\
+       add     %0, %0, #16                     @ 1\n\
+       subs    %2, %2, #1                      @ 1\n\
        bne     1b                              @ 1\n\
-       mcr     p15, 0, r2, c7, c10, 4          @ 1   drain WB\n\
-       ldmfd   sp!, {r4, pc}                   @ 3"
-       :
-       : "I" (PAGE_SIZE / 32));
+       mcr     p15, 0, %2, c7, c10, 4          @ 1   drain WB"
+       : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 32)
+       : "r3", "r4", "ip", "lr");
 }
 
 void fa_copy_user_highpage(struct page *to, struct page *from,
index 49ee0c1a720972bc93d0a7335c8b365b01fdf93e..cc819732d9b820e393567ab7a01b4e2d0b5d6cbd 100644 (file)
 #include <linux/init.h>
 #include <linux/highmem.h>
 
-static void __naked
-feroceon_copy_user_page(void *kto, const void *kfrom)
+static void feroceon_copy_user_page(void *kto, const void *kfrom)
 {
-       asm("\
-       stmfd   sp!, {r4-r9, lr}                \n\
-       mov     ip, %2                          \n\
-1:     mov     lr, r1                          \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       pld     [lr, #32]                       \n\
-       pld     [lr, #64]                       \n\
-       pld     [lr, #96]                       \n\
-       pld     [lr, #128]                      \n\
-       pld     [lr, #160]                      \n\
-       pld     [lr, #192]                      \n\
-       pld     [lr, #224]                      \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       ldmia   r1!, {r2 - r9}                  \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
-       stmia   r0, {r2 - r9}                   \n\
-       subs    ip, ip, #(32 * 8)               \n\
-       mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D line\n\
-       add     r0, r0, #32                     \n\
+       int tmp;
+
+       asm volatile ("\
+1:     ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       pld     [%1, #0]                        \n\
+       pld     [%1, #32]                       \n\
+       pld     [%1, #64]                       \n\
+       pld     [%1, #96]                       \n\
+       pld     [%1, #128]                      \n\
+       pld     [%1, #160]                      \n\
+       pld     [%1, #192]                      \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       ldmia   %1!, {r2 - r7, ip, lr}          \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
+       stmia   %0, {r2 - r7, ip, lr}           \n\
+       subs    %2, %2, #(32 * 8)               \n\
+       mcr     p15, 0, %0, c7, c14, 1          @ clean and invalidate D line\n\
+       add     %0, %0, #32                     \n\
        bne     1b                              \n\
-       mcr     p15, 0, ip, c7, c10, 4          @ drain WB\n\
-       ldmfd   sp!, {r4-r9, pc}"
-       :
-       : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
+       mcr     p15, 0, %2, c7, c10, 4          @ drain WB"
+       : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
+       : "2" (PAGE_SIZE)
+       : "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
 }
 
 void feroceon_copy_user_highpage(struct page *to, struct page *from,
index 0224416cba3c8f323f04cf284fd2cd629e81c6ef..b03202cddddb2d07bf2fcfe3ee2d9d118066f846 100644 (file)
@@ -40,12 +40,11 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
  * instruction.  If your processor does not supply this, you have to write your
  * own copy_user_highpage that does the right thing.
  */
-static void __naked
-mc_copy_user_page(void *from, void *to)
+static void mc_copy_user_page(void *from, void *to)
 {
-       asm volatile(
-       "stmfd  sp!, {r4, lr}                   @ 2\n\
-       mov     r4, %2                          @ 1\n\
+       int tmp;
+
+       asm volatile ("\
        ldmia   %0!, {r2, r3, ip, lr}           @ 4\n\
 1:     mcr     p15, 0, %1, c7, c6, 1           @ 1   invalidate D line\n\
        stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
@@ -55,13 +54,13 @@ mc_copy_user_page(void *from, void *to)
        mcr     p15, 0, %1, c7, c6, 1           @ 1   invalidate D line\n\
        stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
        ldmia   %0!, {r2, r3, ip, lr}           @ 4\n\
-       subs    r4, r4, #1                      @ 1\n\
+       subs    %2, %2, #1                      @ 1\n\
        stmia   %1!, {r2, r3, ip, lr}           @ 4\n\
        ldmneia %0!, {r2, r3, ip, lr}           @ 4\n\
-       bne     1b                              @ 1\n\
-       ldmfd   sp!, {r4, pc}                   @ 3"
-       :
-       : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
+       bne     1b                              @ "
+       : "+&r" (from), "+&r" (to), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 64)
+       : "r2", "r3", "ip", "lr");
 }
 
 void v4_mc_copy_user_highpage(struct page *to, struct page *from,
index 067d0fdd630c1082a0f895fee16bddfb4b002fa4..cd3e165afeedeb400c19b1dbb1b578e10b0d2400 100644 (file)
  * instruction.  If your processor does not supply this, you have to write your
  * own copy_user_highpage that does the right thing.
  */
-static void __naked
-v4wb_copy_user_page(void *kto, const void *kfrom)
+static void v4wb_copy_user_page(void *kto, const void *kfrom)
 {
-       asm("\
-       stmfd   sp!, {r4, lr}                   @ 2\n\
-       mov     r2, %2                          @ 1\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-1:     mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4+1\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       subs    r2, r2, #1                      @ 1\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmneia r1!, {r3, r4, ip, lr}           @ 4\n\
+       int tmp;
+
+       asm volatile ("\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+1:     mcr     p15, 0, %0, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4+1\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       mcr     p15, 0, %0, c7, c6, 1           @ 1   invalidate D line\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       subs    %2, %2, #1                      @ 1\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmneia %1!, {r3, r4, ip, lr}           @ 4\n\
        bne     1b                              @ 1\n\
-       mcr     p15, 0, r1, c7, c10, 4          @ 1   drain WB\n\
-       ldmfd    sp!, {r4, pc}                  @ 3"
-       :
-       : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
+       mcr     p15, 0, %1, c7, c10, 4          @ 1   drain WB"
+       : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 64)
+       : "r3", "r4", "ip", "lr");
 }
 
 void v4wb_copy_user_highpage(struct page *to, struct page *from,
index b85c5da2e510ea8a3cfe337eb797ef7a26d17dba..8614572e1296ba904a018fd07b2dfe66843a5272 100644 (file)
  * dirty data in the cache.  However, we do have to ensure that
  * subsequent reads are up to date.
  */
-static void __naked
-v4wt_copy_user_page(void *kto, const void *kfrom)
+static void v4wt_copy_user_page(void *kto, const void *kfrom)
 {
-       asm("\
-       stmfd   sp!, {r4, lr}                   @ 2\n\
-       mov     r2, %2                          @ 1\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-1:     stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4+1\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmia   r1!, {r3, r4, ip, lr}           @ 4\n\
-       subs    r2, r2, #1                      @ 1\n\
-       stmia   r0!, {r3, r4, ip, lr}           @ 4\n\
-       ldmneia r1!, {r3, r4, ip, lr}           @ 4\n\
+       int tmp;
+
+       asm volatile ("\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+1:     stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4+1\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmia   %1!, {r3, r4, ip, lr}           @ 4\n\
+       subs    %2, %2, #1                      @ 1\n\
+       stmia   %0!, {r3, r4, ip, lr}           @ 4\n\
+       ldmneia %1!, {r3, r4, ip, lr}           @ 4\n\
        bne     1b                              @ 1\n\
-       mcr     p15, 0, r2, c7, c7, 0           @ flush ID cache\n\
-       ldmfd   sp!, {r4, pc}                   @ 3"
-       :
-       : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
+       mcr     p15, 0, %2, c7, c7, 0           @ flush ID cache"
+       : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 64)
+       : "r3", "r4", "ip", "lr");
 }
 
 void v4wt_copy_user_highpage(struct page *to, struct page *from,
index 03a2042aced5f88b54e224396720c95d5fc3acce..a08158241ad16d4fd2d52808526bc4e10e19f30b 100644 (file)
 
 /*
  * XSC3 optimised copy_user_highpage
- *  r0 = destination
- *  r1 = source
  *
  * The source page may have some clean entries in the cache already, but we
  * can safely ignore them - break_cow() will flush them out of the cache
  * if we eventually end up using our copied page.
  *
  */
-static void __naked
-xsc3_mc_copy_user_page(void *kto, const void *kfrom)
+static void xsc3_mc_copy_user_page(void *kto, const void *kfrom)
 {
-       asm("\
-       stmfd   sp!, {r4, r5, lr}               \n\
-       mov     lr, %2                          \n\
-                                               \n\
-       pld     [r1, #0]                        \n\
-       pld     [r1, #32]                       \n\
-1:     pld     [r1, #64]                       \n\
-       pld     [r1, #96]                       \n\
+       int tmp;
+
+       asm volatile ("\
+       pld     [%1, #0]                        \n\
+       pld     [%1, #32]                       \n\
+1:     pld     [%1, #64]                       \n\
+       pld     [%1, #96]                       \n\
                                                \n\
-2:     ldrd    r2, [r1], #8                    \n\
-       mov     ip, r0                          \n\
-       ldrd    r4, [r1], #8                    \n\
-       mcr     p15, 0, ip, c7, c6, 1           @ invalidate\n\
-       strd    r2, [r0], #8                    \n\
-       ldrd    r2, [r1], #8                    \n\
-       strd    r4, [r0], #8                    \n\
-       ldrd    r4, [r1], #8                    \n\
-       strd    r2, [r0], #8                    \n\
-       strd    r4, [r0], #8                    \n\
-       ldrd    r2, [r1], #8                    \n\
-       mov     ip, r0                          \n\
-       ldrd    r4, [r1], #8                    \n\
-       mcr     p15, 0, ip, c7, c6, 1           @ invalidate\n\
-       strd    r2, [r0], #8                    \n\
-       ldrd    r2, [r1], #8                    \n\
-       subs    lr, lr, #1                      \n\
-       strd    r4, [r0], #8                    \n\
-       ldrd    r4, [r1], #8                    \n\
-       strd    r2, [r0], #8                    \n\
-       strd    r4, [r0], #8                    \n\
+2:     ldrd    r2, r3, [%1], #8                \n\
+       ldrd    r4, r5, [%1], #8                \n\
+       mcr     p15, 0, %0, c7, c6, 1           @ invalidate\n\
+       strd    r2, r3, [%0], #8                \n\
+       ldrd    r2, r3, [%1], #8                \n\
+       strd    r4, r5, [%0], #8                \n\
+       ldrd    r4, r5, [%1], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r4, r5, [%0], #8                \n\
+       ldrd    r2, r3, [%1], #8                \n\
+       ldrd    r4, r5, [%1], #8                \n\
+       mcr     p15, 0, %0, c7, c6, 1           @ invalidate\n\
+       strd    r2, r3, [%0], #8                \n\
+       ldrd    r2, r3, [%1], #8                \n\
+       subs    %2, %2, #1                      \n\
+       strd    r4, r5, [%0], #8                \n\
+       ldrd    r4, r5, [%1], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r4, r5, [%0], #8                \n\
        bgt     1b                              \n\
-       beq     2b                              \n\
-                                               \n\
-       ldmfd   sp!, {r4, r5, pc}"
-       :
-       : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
+       beq     2b                              "
+       : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 64 - 1)
+       : "r2", "r3", "r4", "r5");
 }
 
 void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
@@ -85,8 +78,6 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
 
 /*
  * XScale optimised clear_user_page
- *  r0 = destination
- *  r1 = virtual user address of ultimate destination page
  */
 void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
@@ -96,10 +87,10 @@ void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
        mov     r2, #0                          \n\
        mov     r3, #0                          \n\
 1:     mcr     p15, 0, %0, c7, c6, 1           @ invalidate line\n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
        subs    r1, r1, #1                      \n\
        bne     1b"
        : "=r" (ptr)
index 97972379f4d6ad24ff28d1bef2ffbdbc5d295afb..63b92193675458747467cb329d41e8edd69d1c45 100644 (file)
@@ -36,52 +36,51 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
  * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
  * and merged as appropriate.
  */
-static void __naked
-mc_copy_user_page(void *from, void *to)
+static void mc_copy_user_page(void *from, void *to)
 {
+       int tmp;
+
        /*
         * Strangely enough, best performance is achieved
         * when prefetching destination as well.  (NP)
         */
-       asm volatile(
-       "stmfd  sp!, {r4, r5, lr}               \n\
-       mov     lr, %2                          \n\
-       pld     [r0, #0]                        \n\
-       pld     [r0, #32]                       \n\
-       pld     [r1, #0]                        \n\
-       pld     [r1, #32]                       \n\
-1:     pld     [r0, #64]                       \n\
-       pld     [r0, #96]                       \n\
-       pld     [r1, #64]                       \n\
-       pld     [r1, #96]                       \n\
-2:     ldrd    r2, [r0], #8                    \n\
-       ldrd    r4, [r0], #8                    \n\
-       mov     ip, r1                          \n\
-       strd    r2, [r1], #8                    \n\
-       ldrd    r2, [r0], #8                    \n\
-       strd    r4, [r1], #8                    \n\
-       ldrd    r4, [r0], #8                    \n\
-       strd    r2, [r1], #8                    \n\
-       strd    r4, [r1], #8                    \n\
+       asm volatile ("\
+       pld     [%0, #0]                        \n\
+       pld     [%0, #32]                       \n\
+       pld     [%1, #0]                        \n\
+       pld     [%1, #32]                       \n\
+1:     pld     [%0, #64]                       \n\
+       pld     [%0, #96]                       \n\
+       pld     [%1, #64]                       \n\
+       pld     [%1, #96]                       \n\
+2:     ldrd    r2, r3, [%0], #8                \n\
+       ldrd    r4, r5, [%0], #8                \n\
+       mov     ip, %1                          \n\
+       strd    r2, r3, [%1], #8                \n\
+       ldrd    r2, r3, [%0], #8                \n\
+       strd    r4, r5, [%1], #8                \n\
+       ldrd    r4, r5, [%0], #8                \n\
+       strd    r2, r3, [%1], #8                \n\
+       strd    r4, r5, [%1], #8                \n\
        mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
-       ldrd    r2, [r0], #8                    \n\
+       ldrd    r2, r3, [%0], #8                \n\
        mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
-       ldrd    r4, [r0], #8                    \n\
-       mov     ip, r1                          \n\
-       strd    r2, [r1], #8                    \n\
-       ldrd    r2, [r0], #8                    \n\
-       strd    r4, [r1], #8                    \n\
-       ldrd    r4, [r0], #8                    \n\
-       strd    r2, [r1], #8                    \n\
-       strd    r4, [r1], #8                    \n\
+       ldrd    r4, r5, [%0], #8                \n\
+       mov     ip, %1                          \n\
+       strd    r2, r3, [%1], #8                \n\
+       ldrd    r2, r3, [%0], #8                \n\
+       strd    r4, r5, [%1], #8                \n\
+       ldrd    r4, r5, [%0], #8                \n\
+       strd    r2, r3, [%1], #8                \n\
+       strd    r4, r5, [%1], #8                \n\
        mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
-       subs    lr, lr, #1                      \n\
+       subs    %2, %2, #1                      \n\
        mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
        bgt     1b                              \n\
-       beq     2b                              \n\
-       ldmfd   sp!, {r4, r5, pc}               "
-       :
-       : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
+       beq     2b                              "
+       : "+&r" (from), "+&r" (to), "=&r" (tmp)
+       : "2" (PAGE_SIZE / 64 - 1)
+       : "r2", "r3", "r4", "r5", "ip");
 }
 
 void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
@@ -115,10 +114,10 @@ xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
        mov     r2, #0                          \n\
        mov     r3, #0                          \n\
 1:     mov     ip, %0                          \n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
-       strd    r2, [%0], #8                    \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
+       strd    r2, r3, [%0], #8                \n\
        mcr     p15, 0, ip, c7, c10, 1          @ clean D line\n\
        subs    r1, r1, #1                      \n\
        mcr     p15, 0, ip, c7, c6, 1           @ invalidate D line\n\
index f4ea4c62c613ccbea22eca928984ac72a9057e8d..58f69fa07df95640151ec2576b3a0419a0991da5 100644 (file)
@@ -173,6 +173,12 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
                show_regs(regs);
        }
 #endif
+#ifndef CONFIG_KUSER_HELPERS
+       if ((sig == SIGSEGV) && ((addr & PAGE_MASK) == 0xffff0000))
+               printk_ratelimited(KERN_DEBUG
+                                  "%s: CONFIG_KUSER_HELPERS disabled at 0x%08lx\n",
+                                  tsk->comm, addr);
+#endif
 
        tsk->thread.address = addr;
        tsk->thread.error_code = fsr;
index 19516fbc2c55a65c761094bf3a67c8cd69568183..5461d589a1e25e7b63207f83968f63429860263b 100644 (file)
  * If we are building for big.Little with branch predictor hardening,
  * we need the processor function tables to remain available after boot.
  */
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
        .section ".rodata"
 #endif
        .type   \name\()_processor_functions, #object
@@ -316,7 +316,7 @@ ENTRY(\name\()_processor_functions)
        .endif
 
        .size   \name\()_processor_functions, . - \name\()_processor_functions
-#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
        .previous
 #endif
 .endm
index 1867f3e430161ff6cf530302aa77eb9cea314054..fd2ff9034d177ff1088cf515bb40eed7eb792d72 100644 (file)
@@ -33,10 +33,10 @@ ENTRY(lpae_pgtables_remap_asm)
        add     r7, r2, #0x1000
        add     r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
        add     r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
-1:     ldrd    r4, [r7]
+1:     ldrd    r4, r5, [r7]
        adds    r4, r4, r0
        adc     r5, r5, r1
-       strd    r4, [r7], #1 << L2_ORDER
+       strd    r4, r5, [r7], #1 << L2_ORDER
        cmp     r7, r6
        bls     1b
 
@@ -44,22 +44,22 @@ ENTRY(lpae_pgtables_remap_asm)
        add     r7, r2, #0x1000
        add     r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER
        bic     r7, r7, #(1 << L2_ORDER) - 1
-       ldrd    r4, [r7]
+       ldrd    r4, r5, [r7]
        adds    r4, r4, r0
        adc     r5, r5, r1
-       strd    r4, [r7], #1 << L2_ORDER
-       ldrd    r4, [r7]
+       strd    r4, r5, [r7], #1 << L2_ORDER
+       ldrd    r4, r5, [r7]
        adds    r4, r4, r0
        adc     r5, r5, r1
-       strd    r4, [r7]
+       strd    r4, r5, [r7]
 
        /* Update level 1 entries */
        mov     r6, #4
        mov     r7, r2
-2:     ldrd    r4, [r7]
+2:     ldrd    r4, r5, [r7]
        adds    r4, r4, r0
        adc     r5, r5, r1
-       strd    r4, [r7], #1 << L1_ORDER
+       strd    r4, r5, [r7], #1 << L1_ORDER
        subs    r6, r6, #1
        bne     2b
 
index c0a242cae79afd3df963a292ae73d7e5914530b7..93fd7fc537cf4259622e6bef6753ed6404b1866d 100644 (file)
@@ -92,7 +92,6 @@ config OMAP_32K_TIMER
 config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
        bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
        depends on ARCH_OMAP3 && PM
-       default n
        help
          Without this option, L2 Auxiliary control register contents are
          lost during off-mode entry on HS/EMU devices. This feature
index bff3ba889882e7debd1587ed0be2f5c7563ed9a4..b2f0ddfdc4ccb460b6c1bb818784f1b5b5839137 100644 (file)
@@ -2,3 +2,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
 
 obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
index 40f27e52de759aed3ab7d3f7e912bf4feab3a358..e99396dfa6f3393e3290669c9e63bf6324801e83 100644 (file)
@@ -37,5 +37,5 @@ pen:  ldr     r7, [r6]
 
        .align
 1:     .long   .
-       .long   pen_release
+       .long   versatile_cpu_release
 ENDPROC(versatile_secondary_startup)
diff --git a/arch/arm/plat-versatile/hotplug.c b/arch/arm/plat-versatile/hotplug.c
new file mode 100644 (file)
index 0000000..c974958
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This hotplug implementation is _specific_ to the situation found on
+ * ARM development platforms where there is _no_ possibility of actually
+ * taking a CPU offline, resetting it, or otherwise.  Real platforms must
+ * NOT copy this code.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/smp_plat.h>
+#include <asm/cp15.h>
+
+#include <plat/platsmp.h>
+
+static inline void versatile_immitation_enter_lowpower(unsigned int actrl_mask)
+{
+       unsigned int v;
+
+       asm volatile(
+               "mcr    p15, 0, %1, c7, c5, 0\n"
+       "       mcr     p15, 0, %1, c7, c10, 4\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %3\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0), "Ir" (CR_C), "Ir" (actrl_mask)
+         : "cc");
+}
+
+static inline void versatile_immitation_leave_lowpower(unsigned int actrl_mask)
+{
+       unsigned int v;
+
+       asm volatile(
+               "mrc    p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       orr     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+         : "=&r" (v)
+         : "Ir" (CR_C), "Ir" (actrl_mask)
+         : "cc");
+}
+
+static inline void versatile_immitation_do_lowpower(unsigned int cpu, int *spurious)
+{
+       /*
+        * there is no power-control hardware on this platform, so all
+        * we can do is put the core into WFI; this is safe as the calling
+        * code will have already disabled interrupts.
+        *
+        * This code should not be used outside Versatile platforms.
+        */
+       for (;;) {
+               wfi();
+
+               if (versatile_cpu_release == cpu_logical_map(cpu)) {
+                       /*
+                        * OK, proper wakeup, we're done
+                        */
+                       break;
+               }
+
+               /*
+                * Getting here, means that we have come out of WFI without
+                * having been woken up - this shouldn't happen
+                *
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
+                */
+               (*spurious)++;
+       }
+}
+
+/*
+ * platform-specific code to shutdown a CPU.
+ * This code supports immitation-style CPU hotplug for Versatile/Realview/
+ * Versatile Express platforms that are unable to do real CPU hotplug.
+ */
+void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask)
+{
+       int spurious = 0;
+
+       versatile_immitation_enter_lowpower(actrl_mask);
+       versatile_immitation_do_lowpower(cpu, &spurious);
+       versatile_immitation_leave_lowpower(actrl_mask);
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
index 50fb830192e0367d9cb9ea7cc0c13547fab7bfeb..1b087fbbc700ec4c92dcd73027743528ba283a5b 100644 (file)
@@ -8,7 +8,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+extern volatile int versatile_cpu_release;
 
 extern void versatile_secondary_startup(void);
 extern void versatile_secondary_init(unsigned int cpu);
 extern int  versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
+void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask);
index c2366510187a8fb54eb27b994b3d7b998f3cad72..6e2836243187c678229a61ec6ea53d23fd16ff6a 100644 (file)
@@ -7,6 +7,11 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ *
+ * This code is specific to the hardware found on ARM Realview and
+ * Versatile Express platforms where the CPUs are unable to be individually
+ * woken, and where there is no way to hot-unplug CPUs.  Real platforms
+ * should not copy this code.
  */
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <plat/platsmp.h>
 
 /*
- * Write pen_release in a way that is guaranteed to be visible to all
- * observers, irrespective of whether they're taking part in coherency
+ * versatile_cpu_release controls the release of CPUs from the holding
+ * pen in headsmp.S, which exists because we are not always able to
+ * control the release of individual CPUs from the board firmware.
+ * Production platforms do not need this.
+ */
+volatile int versatile_cpu_release = -1;
+
+/*
+ * Write versatile_cpu_release in a way that is guaranteed to be visible to
+ * all observers, irrespective of whether they're taking part in coherency
  * or not.  This is necessary for the hotplug code to work reliably.
  */
-static void write_pen_release(int val)
+static void versatile_write_cpu_release(int val)
 {
-       pen_release = val;
+       versatile_cpu_release = val;
        smp_wmb();
-       sync_cache_w(&pen_release);
+       sync_cache_w(&versatile_cpu_release);
 }
 
-static DEFINE_SPINLOCK(boot_lock);
+/*
+ * versatile_lock exists to avoid running the loops_per_jiffy delay loop
+ * calibrations on the secondary CPU while the requesting CPU is using
+ * the limited-bandwidth bus - which affects the calibration value.
+ * Production platforms do not need this.
+ */
+static DEFINE_RAW_SPINLOCK(versatile_lock);
 
 void versatile_secondary_init(unsigned int cpu)
 {
@@ -40,13 +59,13 @@ void versatile_secondary_init(unsigned int cpu)
         * let the primary processor know we're out of the
         * pen, then head off into the C entry point
         */
-       write_pen_release(-1);
+       versatile_write_cpu_release(-1);
 
        /*
         * Synchronise with the boot thread.
         */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
+       raw_spin_lock(&versatile_lock);
+       raw_spin_unlock(&versatile_lock);
 }
 
 int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -57,7 +76,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
         * Set synchronisation state between this boot processor
         * and the secondary one
         */
-       spin_lock(&boot_lock);
+       raw_spin_lock(&versatile_lock);
 
        /*
         * This is really belt and braces; we hold unintended secondary
@@ -65,7 +84,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
         * since we haven't sent them a soft interrupt, they shouldn't
         * be there.
         */
-       write_pen_release(cpu_logical_map(cpu));
+       versatile_write_cpu_release(cpu_logical_map(cpu));
 
        /*
         * Send the secondary CPU a soft interrupt, thereby causing
@@ -77,7 +96,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
                smp_rmb();
-               if (pen_release == -1)
+               if (versatile_cpu_release == -1)
                        break;
 
                udelay(10);
@@ -87,7 +106,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
         * now the secondary core is starting up let it run its
         * calibrations, then wait for it to finish
         */
-       spin_unlock(&boot_lock);
+       raw_spin_unlock(&versatile_lock);
 
-       return pen_release != -1 ? -ENOSYS : 0;
+       return versatile_cpu_release != -1 ? -ENOSYS : 0;
 }
index 28f052185eb6e6b37865d5bb52bad6f6547620a3..251ecf34cb020710a62363a86b65d4b3d7ffeba2 100644 (file)
@@ -142,6 +142,14 @@ config ARCH_MVEBU
           - Armada 7K SoC Family
           - Armada 8K SoC Family
 
+config ARCH_MXC
+       bool "ARMv8 based NXP i.MX SoC family"
+       select ARM64_ERRATUM_843419
+       select ARM64_ERRATUM_845719
+       help
+         This enables support for the ARMv8 based SoCs in the
+         NXP i.MX family.
+
 config ARCH_QCOM
        bool "Qualcomm Platforms"
        select GPIOLIB
index f3ed4c078ba59d37ca41638e6db0387461fcdfa2..d88e2f0e179a96c632ffe30cb50e4c1852f9f5f1 100644 (file)
        status = "okay";
 };
 
+&serial_3 {
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               max-speed = <3000000>;
+               shutdown-gpios = <&gpd4 0 GPIO_ACTIVE_HIGH>;
+               device-wakeup-gpios = <&gpr3 7 GPIO_ACTIVE_HIGH>;
+               host-wakeup-gpios = <&gpa2 2 GPIO_ACTIVE_HIGH>;
+               clocks = <&s2mps13_osc S2MPS11_CLK_BT>;
+               clock-names = "extclk";
+       };
+};
+
 &spi_1 {
        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
        status = "okay";
index 84446f95b2ebfd70f87850c00c758d5d59895d1e..e7cd3b67d8180df3a5358592762455ab2d37abb1 100644 (file)
                        power-domains = <&pd_cam1>;
                };
 
+               cmu_imem: clock-controller@11060000 {
+                       compatible = "samsung,exynos5433-cmu-imem";
+                       reg = <0x11060000 0x1000>;
+                       #clock-cells = <1>;
+
+                       clock-names = "oscclk",
+                               "aclk_imem_sssx_266",
+                               "aclk_imem_266",
+                               "aclk_imem_200";
+                       clocks = <&xxti>,
+                               <&cmu_top CLK_DIV_ACLK_IMEM_SSSX_266>,
+                               <&cmu_top CLK_DIV_ACLK_IMEM_266>,
+                               <&cmu_top CLK_DIV_ACLK_IMEM_200>;
+               };
+
                pd_gscl: power-domain@105c4000 {
                        compatible = "samsung,exynos5433-pd";
                        reg = <0x105c4000 0x20>;
index 7748e6dfc3c9eb7cc95522c4b33f3f2f168ec656..f9be2426f83cb4d19be38de692fcf1c61a871bef 100644 (file)
@@ -18,3 +18,5 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
+
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
new file mode 100644 (file)
index 0000000..64acccc
--- /dev/null
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2017 NXP
+ * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
+ */
+
+/dts-v1/;
+
+#include "imx8mq.dtsi"
+
+/ {
+       model = "NXP i.MX8MQ EVK";
+       compatible = "fsl,imx8mq-evk", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000 0 0xc0000000>;
+       };
+
+       reg_usdhc2_vmmc: regulator-vsd-3v3 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_usdhc2>;
+               compatible = "regulator-fixed";
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic@8 {
+               compatible = "fsl,pfuze100";
+               reg = <0x8>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <825000>;
+                               regulator-max-microvolt = <1100000>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <825000>;
+                               regulator-max-microvolt = <1100000>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3ab {
+                               regulator-min-microvolt = <825000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <975000>;
+                               regulator-always-on;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1675000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-always-on;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1625000>;
+                               regulator-max-microvolt = <1875000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <3075000>;
+                               regulator-max-microvolt = <3625000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       vqmmc-supply = <&sw4_reg>;
+       bus-width = <8>;
+       non-removable;
+       no-sd;
+       no-sdio;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                 0x3
+                       MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO               0x23
+                       MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3           0x1f
+                       MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2           0x1f
+                       MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1           0x1f
+                       MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0           0x1f
+                       MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3           0x91
+                       MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2           0x91
+                       MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1           0x91
+                       MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0           0x91
+                       MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC           0x1f
+                       MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC           0x91
+                       MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9               0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_reg_usdhc2: regusdhc2grpgpio {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19             0x41
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc3
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x83
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1-100grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x85
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc5
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x85
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1-200grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x87
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc7
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x87
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x83
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2-100grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x85
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc5
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2-200grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x87
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc7
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_wdog: wdog1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B            0xc6
+               >;
+       };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h
new file mode 100644 (file)
index 0000000..b94b020
--- /dev/null
@@ -0,0 +1,623 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ */
+
+#ifndef __DTS_IMX8MQ_PINFUNC_H
+#define __DTS_IMX8MQ_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MX8MQ_IOMUXC_PMIC_STBY_REQ_CCMSRCGPCMIX_PMIC_STBY_REQ               0x014 0x27C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_PMIC_ON_REQ_SNVSMIX_PMIC_ON_REQ                        0x018 0x280 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ONOFF_SNVSMIX_ONOFF                                    0x01C 0x284 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_POR_B_SNVSMIX_POR_B                                    0x020 0x288 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC_RESET_B_SNVSMIX_RTC_RESET_B                        0x024 0x28C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0                                   0x028 0x290 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_ENET_PHY_REF_CLK_ROOT          0x028 0x290 0x4C0 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K                          0x028 0x290 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_CCMSRCGPCMIX_EXT_CLK1                       0x028 0x290 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO00_SJC_FAIL                                    0x028 0x290 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_GPIO1_IO1                                   0x02C 0x294 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_PWM1_OUT                                    0x02C 0x294 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_ANAMIX_REF_CLK_24M                          0x02C 0x294 0x4BC 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_CCMSRCGPCMIX_EXT_CLK2                       0x02C 0x294 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO01_SJC_ACTIVE                                  0x02C 0x294 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_GPIO1_IO2                                   0x030 0x298 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B                                0x030 0x298 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_ANY                              0x030 0x298 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO02_SJC_DE_B                                    0x030 0x298 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3                                   0x034 0x29C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_USDHC1_VSELECT                              0x034 0x29C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SDMA1_EXT_EVENT0                            0x034 0x29C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_ANAMIX_XTAL_OK                              0x034 0x29C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO03_SJC_DONE                                    0x034 0x29C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4                                   0x038 0x2A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT                              0x038 0x2A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_SDMA1_EXT_EVENT1                            0x038 0x2A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_ANAMIX_XTAL_OK_LV                           0x038 0x2A0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO04_USDHC1_TEST_TRIG                            0x038 0x2A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5                                   0x03C 0x2A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_M4_NMI                                      0x03C 0x2A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_PMIC_READY                     0x03C 0x2A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_CCMSRCGPCMIX_INT_BOOT                       0x03C 0x2A4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO05_USDHC2_TEST_TRIG                            0x03C 0x2A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6                                   0x040 0x2A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ENET1_MDC                                   0x040 0x2A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_USDHC1_CD_B                                 0x040 0x2A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_CCMSRCGPCMIX_EXT_CLK3                       0x040 0x2A8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO06_ECSPI1_TEST_TRIG                            0x040 0x2A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7                                   0x044 0x2AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ENET1_MDIO                                  0x044 0x2AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_USDHC1_WP                                   0x044 0x2AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_CCMSRCGPCMIX_EXT_CLK4                       0x044 0x2AC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO07_ECSPI2_TEST_TRIG                            0x044 0x2AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8                                   0x048 0x2B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_ENET1_1588_EVENT0_IN                        0x048 0x2B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_USDHC2_RESET_B                              0x048 0x2B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_CCMSRCGPCMIX_WAIT                           0x048 0x2B0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO08_QSPI_TEST_TRIG                              0x048 0x2B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9                                   0x04C 0x2B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_ENET1_1588_EVENT0_OUT                       0x04C 0x2B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_SDMA2_EXT_EVENT0                            0x04C 0x2B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_CCMSRCGPCMIX_STOP                           0x04C 0x2B4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO09_RAWNAND_TEST_TRIG                           0x04C 0x2B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10                                  0x050 0x2B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_USB1_OTG_ID                                 0x050 0x2B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO10_OCOTP_CTRL_WRAPPER_FUSE_LATCHED             0x050 0x2B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11                                  0x054 0x2BC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_USB2_OTG_ID                                 0x054 0x2BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_PMIC_READY                     0x054 0x2BC 0x4BC 0x5 0x1
+#define MX8MQ_IOMUXC_GPIO1_IO11_CCMSRCGPCMIX_OUT0                           0x054 0x2BC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO11_CAAM_WRAPPER_RNG_OSC_OBS                    0x054 0x2BC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12                                  0x058 0x2C0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_USB1_OTG_PWR                                0x058 0x2C0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_SDMA2_EXT_EVENT1                            0x058 0x2C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CCMSRCGPCMIX_OUT1                           0x058 0x2C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO12_CSU_CSU_ALARM_AUT0                          0x058 0x2C0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13                                  0x05C 0x2C4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_USB1_OTG_OC                                 0x05C 0x2C4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT                                    0x05C 0x2C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CCMSRCGPCMIX_OUT2                           0x05C 0x2C4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO13_CSU_CSU_ALARM_AUT1                          0x05C 0x2C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_GPIO1_IO14                                  0x060 0x2C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_USB2_OTG_PWR                                0x060 0x2C8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_PWM3_OUT                                    0x060 0x2C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1                          0x060 0x2C8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO14_CSU_CSU_ALARM_AUT2                          0x060 0x2C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_GPIO1_IO15                                  0x064 0x2CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_USB2_OTG_OC                                 0x064 0x2CC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_PWM4_OUT                                    0x064 0x2CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2                          0x064 0x2CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_GPIO1_IO15_CSU_CSU_INT_DEB                             0x064 0x2CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                                     0x068 0x2D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_MDC_GPIO1_IO16                                    0x068 0x2D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO                                   0x06C 0x2D4 0x4C0 0x0 0x1
+#define MX8MQ_IOMUXC_ENET_MDIO_GPIO1_IO17                                   0x06C 0x2D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3                               0x070 0x2D8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD3_GPIO1_IO18                                    0x070 0x2D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2                               0x074 0x2DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_ENET1_TX_CLK                                  0x074 0x2DC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TD2_GPIO1_IO19                                    0x074 0x2DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1                               0x078 0x2E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD1_GPIO1_IO20                                    0x078 0x2E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0                               0x07C 0x2E4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TD0_GPIO1_IO21                                    0x07C 0x2E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL                         0x080 0x2E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TX_CTL_GPIO1_IO22                                 0x080 0x2E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC                               0x084 0x2EC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_ENET1_TX_ER                                   0x084 0x2EC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_TXC_GPIO1_IO23                                    0x084 0x2EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL                         0x088 0x2F0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RX_CTL_GPIO1_IO24                                 0x088 0x2F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC                               0x08C 0x2F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_ENET1_RX_ER                                   0x08C 0x2F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ENET_RXC_GPIO1_IO25                                    0x08C 0x2F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0                               0x090 0x2F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD0_GPIO1_IO26                                    0x090 0x2F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1                               0x094 0x2FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD1_GPIO1_IO27                                    0x094 0x2FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2                               0x098 0x300 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD2_GPIO1_IO28                                    0x098 0x300 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3                               0x09C 0x304 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ENET_RD3_GPIO1_IO29                                    0x09C 0x304 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                                     0x0A0 0x308 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CLK_GPIO2_IO0                                      0x0A0 0x308 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                                     0x0A4 0x30C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1                                      0x0A4 0x30C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0                                 0x0A8 0x310 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2                                    0x0A8 0x31  0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1                                 0x0AC 0x314 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3                                    0x0AC 0x314 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2                                 0x0B0 0x318 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA2_GPIO2_IO4                                    0x0B0 0x318 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3                                 0x0B4 0x31C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA3_GPIO2_IO5                                    0x0B4 0x31C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4                                 0x0B8 0x320 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA4_GPIO2_IO6                                    0x0B8 0x320 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5                                 0x0BC 0x324 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA5_GPIO2_IO7                                    0x0BC 0x324 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6                                 0x0C0 0x328 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA6_GPIO2_IO8                                    0x0C0 0x328 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7                                 0x0C4 0x32C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_DATA7_GPIO2_IO9                                    0x0C4 0x32C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B                             0x0C8 0x330 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10                                 0x0C8 0x330 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE                               0x0CC 0x334 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11                                  0x0CC 0x334 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_USDHC2_CD_B                                   0x0D0 0x338 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12                                    0x0D0 0x338 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                                     0x0D4 0x33C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_GPIO2_IO13                                     0x0D4 0x33C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_CCMSRCGPCMIX_OBSERVE0                          0x0D4 0x33C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CLK_OBSERVE_MUX_OUT0                               0x0D4 0x33C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                                     0x0D8 0x340 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_GPIO2_IO14                                     0x0D8 0x340 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_CCMSRCGPCMIX_OBSERVE1                          0x0D8 0x340 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_CMD_OBSERVE_MUX_OUT1                               0x0D8 0x340 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0                                 0x0DC 0x344 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_GPIO2_IO15                                   0x0DC 0x344 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_CCMSRCGPCMIX_OBSERVE2                        0x0DC 0x344 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA0_OBSERVE_MUX_OUT2                             0x0DC 0x344 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1                                 0x0E0 0x348 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_GPIO2_IO16                                   0x0E0 0x348 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_CCMSRCGPCMIX_WAIT                            0x0E0 0x348 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA1_OBSERVE_MUX_OUT3                             0x0E0 0x348 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2                                 0x0E4 0x34C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_GPIO2_IO17                                   0x0E4 0x34C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_CCMSRCGPCMIX_STOP                            0x0E4 0x34C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_DATA2_OBSERVE_MUX_OUT4                             0x0E4 0x34C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3                                 0x0E8 0x350 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_GPIO2_IO18                                   0x0E8 0x350 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_DATA3_CCMSRCGPCMIX_EARLY_RESET                     0x0E8 0x350 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_USDHC2_RESET_B                             0x0EC 0x354 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19                                 0x0EC 0x354 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_RESET_B_CCMSRCGPCMIX_SYSTEM_RESET                  0x0EC 0x354 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SD2_WP_USDHC2_WP                                       0x0F0 0x358 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20                                      0x0F0 0x358 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SD2_WP_SIM_M_HMASTLOCK                                 0x0F0 0x358 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_RAWNAND_ALE                                   0x0F4 0x35C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK                                   0x0F4 0x35C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_GPIO3_IO0                                     0x0F4 0x35C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_ALE_SIM_M_HPROT0                                  0x0F4 0x35C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_RAWNAND_CE0_B                               0x0F8 0x360 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B                                0x0F8 0x360 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_GPIO3_IO1                                   0x0F8 0x360 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE0_B_SIM_M_HPROT1                                0x0F8 0x360 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_RAWNAND_CE1_B                               0x0FC 0x364 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B                                0x0FC 0x364 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_GPIO3_IO2                                   0x0FC 0x364 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE1_B_SIM_M_HPROT2                                0x0FC 0x364 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_RAWNAND_CE2_B                               0x100 0x368 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_QSPI_B_SS0_B                                0x100 0x368 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3                                   0x100 0x368 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE2_B_SIM_M_HPROT3                                0x100 0x368 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_RAWNAND_CE3_B                               0x104 0x36C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_QSPI_B_SS1_B                                0x104 0x36C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_GPIO3_IO4                                   0x104 0x36C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CE3_B_SIM_M_HADDR0                                0x104 0x36C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_RAWNAND_CLE                                   0x108 0x370 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_QSPI_B_SCLK                                   0x108 0x370 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5                                     0x108 0x370 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_CLE_SIM_M_HADDR1                                  0x108 0x370 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_RAWNAND_DATA00                             0x10C 0x374 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0                               0x10C 0x374 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_GPIO3_IO6                                  0x10C 0x374 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA00_SIM_M_HADDR2                               0x10C 0x374 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_RAWNAND_DATA01                             0x110 0x378 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1                               0x110 0x378 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_GPIO3_IO7                                  0x110 0x378 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA01_SIM_M_HADDR3                               0x110 0x378 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_RAWNAND_DATA02                             0x114 0x37C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2                               0x114 0x37C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_GPIO3_IO8                                  0x114 0x37C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA02_SIM_M_HADDR4                               0x114 0x37C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_RAWNAND_DATA03                             0x118 0x380 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3                               0x118 0x380 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_GPIO3_IO9                                  0x118 0x380 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA03_SIM_M_HADDR5                               0x118 0x380 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_RAWNAND_DATA04                             0x11C 0x384 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_QSPI_B_DATA0                               0x11C 0x384 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10                                 0x11C 0x384 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA04_SIM_M_HADDR6                               0x11C 0x384 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_RAWNAND_DATA05                             0x120 0x388 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_QSPI_B_DATA1                               0x120 0x388 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11                                 0x120 0x388 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA05_SIM_M_HADDR7                               0x120 0x388 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_RAWNAND_DATA06                             0x124 0x38C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_QSPI_B_DATA2                               0x124 0x38C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12                                 0x124 0x38C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA06_SIM_M_HADDR8                               0x124 0x38C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_RAWNAND_DATA07                             0x128 0x390 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_QSPI_B_DATA3                               0x128 0x390 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_GPIO3_IO13                                 0x128 0x390 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DATA07_SIM_M_HADDR9                               0x128 0x390 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_RAWNAND_DQS                                   0x12C 0x394 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_QSPI_A_DQS                                    0x12C 0x394 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14                                    0x12C 0x394 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_DQS_SIM_M_HADDR10                                 0x12C 0x394 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_RAWNAND_RE_B                                 0x130 0x398 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_QSPI_B_DQS                                   0x130 0x398 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_GPIO3_IO15                                   0x130 0x398 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_RE_B_SIM_M_HADDR11                                0x130 0x398 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_RAWNAND_READY_B                           0x134 0x39C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_GPIO3_IO16                                0x134 0x39C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_READY_B_SIM_M_HADDR12                             0x134 0x39C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_RAWNAND_WE_B                                 0x138 0x3A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_GPIO3_IO17                                   0x138 0x3A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WE_B_SIM_M_HADDR13                                0x138 0x3A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_RAWNAND_WP_B                                 0x13C 0x3A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18                                   0x13C 0x3A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_NAND_WP_B_SIM_M_HADDR14                                0x13C 0x3A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC                                 0x140 0x3A8 0x4E4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_SAI1_TX_DATA0                                0x140 0x3A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXFS_GPIO3_IO19                                   0x140 0x3A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI5_RX_BCLK                                  0x144 0x3AC 0x4D0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_SAI1_TX_DATA1                                 0x144 0x3AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXC_GPIO3_IO20                                    0x144 0x3AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0                                0x148 0x3B0 0x4D4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_SAI1_TX_DATA2                                0x148 0x3B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD0_GPIO3_IO21                                   0x148 0x3B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1                                0x14C 0x3B4 0x4D8 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_DATA3                                0x14C 0x3B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI1_TX_SYNC                                 0x14C 0x3B4 0x4CC 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC                                 0x14C 0x3B4 0x4EC 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22                                   0x14C 0x3B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2                                0x150 0x3B8 0x4DC 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
+#define MX8MQ_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI1_TX_SYNC                                 0x154 0x3BC 0x4CC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0                                0x154 0x3BC 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24                                   0x154 0x3BC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI5_MCLK                                    0x158 0x3C0 0x52C 0x0 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI1_TX_BCLK                                 0x158 0x3C0 0x4C8 0x1 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_SAI4_MCLK                                    0x158 0x3C0 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_GPIO3_IO25                                   0x158 0x3C0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI5_MCLK_CCMSRCGPCMIX_TESTER_ACK                      0x158 0x3C0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI1_RX_SYNC                                 0x15C 0x3C4 0x4C4 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SAI5_RX_SYNC                                 0x15C 0x3C4 0x4E4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXFS_CORESIGHT_TRACE_CLK                          0x15C 0x3C4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_GPIO4_IO0                                    0x15C 0x3C4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXFS_SIM_M_HADDR15                                0x15C 0x3C4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI1_RX_BCLK                                  0x160 0x3C8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SAI5_RX_BCLK                                  0x160 0x3C8 0x4D0 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXC_CORESIGHT_TRACE_CTL                           0x160 0x3C8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_GPIO4_IO1                                     0x160 0x3C8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXC_SIM_M_HADDR16                                 0x160 0x3C8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0                                0x164 0x3CC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SAI5_RX_DATA0                                0x164 0x3CC 0x4D4 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD0_CORESIGHT_TRACE0                             0x164 0x3CC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_GPIO4_IO2                                    0x164 0x3CC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_CCMSRCGPCMIX_BOOT_CFG0                       0x164 0x3CC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD0_SIM_M_HADDR17                                0x164 0x3CC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI1_RX_DATA1                                0x168 0x3D0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SAI5_RX_DATA1                                0x168 0x3D0 0x4D8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD1_CORESIGHT_TRACE1                             0x168 0x3D0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_GPIO4_IO3                                    0x168 0x3D0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_CCMSRCGPCMIX_BOOT_CFG1                       0x168 0x3D0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD1_SIM_M_HADDR18                                0x168 0x3D0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI1_RX_DATA2                                0x16C 0x3D4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SAI5_RX_DATA2                                0x16C 0x3D4 0x4DC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD2_CORESIGHT_TRACE2                             0x16C 0x3D4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_GPIO4_IO4                                    0x16C 0x3D4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_CCMSRCGPCMIX_BOOT_CFG2                       0x16C 0x3D4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD2_SIM_M_HADDR19                                0x16C 0x3D4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI1_RX_DATA3                                0x170 0x3D8 0x4E0 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD3_SAI5_RX_DATA3                                0x170 0x3D8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CORESIGHT_TRACE3                             0x170 0x3D8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_GPIO4_IO5                                    0x170 0x3D8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_CCMSRCGPCMIX_BOOT_CFG3                       0x170 0x3D8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD3_SIM_M_HADDR20                                0x170 0x3D8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI1_RX_DATA4                                0x174 0x3DC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK                                 0x174 0x3DC 0x51C 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SAI6_RX_BCLK                                 0x174 0x3DC 0x510 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CORESIGHT_TRACE4                             0x174 0x3DC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_GPIO4_IO6                                    0x174 0x3DC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_CCMSRCGPCMIX_BOOT_CFG4                       0x174 0x3DC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD4_SIM_M_HADDR21                                0x174 0x3DC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_DATA5                                0x178 0x3E0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0                                0x178 0x3E0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI6_RX_DATA0                                0x178 0x3E0 0x514 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SAI1_RX_SYNC                                 0x178 0x3E0 0x4C4 0x3 0x1
+#define MX8MQ_IOMUXC_SAI1_RXD5_CORESIGHT_TRACE5                             0x178 0x3E0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_GPIO4_IO7                                    0x178 0x3E0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_CCMSRCGPCMIX_BOOT_CFG5                       0x178 0x3E0 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD5_SIM_M_HADDR22                                0x178 0x3E0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI1_RX_DATA6                                0x17C 0x3E4 0x520 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC                                 0x17C 0x3E4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SAI6_RX_SYNC                                 0x17C 0x3E4 0x518 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CORESIGHT_TRACE6                             0x17C 0x3E4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_GPIO4_IO8                                    0x17C 0x3E4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_CCMSRCGPCMIX_BOOT_CFG6                       0x17C 0x3E4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD6_SIM_M_HADDR23                                0x17C 0x3E4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_RX_DATA7                                0x180 0x3E8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI6_MCLK                                    0x180 0x3E8 0x530 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC                                 0x180 0x3E8 0x4CC 0x2 0x4
+#define MX8MQ_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4                                0x180 0x3E8 0x000 0x3 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CORESIGHT_TRACE7                             0x180 0x3E8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_GPIO4_IO9                                    0x180 0x3E8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_CCMSRCGPCMIX_BOOT_CFG7                       0x180 0x3E8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_RXD7_SIM_M_HADDR24                                0x180 0x3E8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC                                 0x184 0x3EC 0x4CC 0x0 0x3
+#define MX8MQ_IOMUXC_SAI1_TXFS_SAI5_TX_SYNC                                 0x184 0x3EC 0x4EC 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXFS_CORESIGHT_EVENTO                             0x184 0x3EC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_GPIO4_IO10                                   0x184 0x3EC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXFS_SIM_M_HADDR25                                0x184 0x3EC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK                                  0x188 0x3F0 0x4C8 0x0 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_SAI5_TX_BCLK                                  0x188 0x3F0 0x4E8 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXC_CORESIGHT_EVENTI                              0x188 0x3F0 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_GPIO4_IO11                                    0x188 0x3F0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXC_SIM_M_HADDR26                                 0x188 0x3F0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0                                0x18C 0x3F4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SAI5_TX_DATA0                                0x18C 0x3F4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CORESIGHT_TRACE8                             0x18C 0x3F4 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_GPIO4_IO12                                   0x18C 0x3F4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_CCMSRCGPCMIX_BOOT_CFG8                       0x18C 0x3F4 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD0_SIM_M_HADDR27                                0x18C 0x3F4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1                                0x190 0x3F8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SAI5_TX_DATA1                                0x190 0x3F8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CORESIGHT_TRACE9                             0x190 0x3F8 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_GPIO4_IO13                                   0x190 0x3F8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_CCMSRCGPCMIX_BOOT_CFG9                       0x190 0x3F8 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD1_SIM_M_HADDR28                                0x190 0x3F8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2                                0x194 0x3FC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SAI5_TX_DATA2                                0x194 0x3FC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CORESIGHT_TRACE10                            0x194 0x3FC 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_GPIO4_IO14                                   0x194 0x3FC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_CCMSRCGPCMIX_BOOT_CFG10                      0x194 0x3FC 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD2_SIM_M_HADDR29                                0x194 0x3FC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3                                0x198 0x400 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SAI5_TX_DATA3                                0x198 0x400 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CORESIGHT_TRACE11                            0x198 0x400 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_GPIO4_IO15                                   0x198 0x400 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_CCMSRCGPCMIX_BOOT_CFG11                      0x198 0x400 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD3_SIM_M_HADDR30                                0x198 0x400 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4                                0x19C 0x404 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_RX_BCLK                                 0x19C 0x404 0x510 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_SAI6_TX_BCLK                                 0x19C 0x404 0x51C 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD4_CORESIGHT_TRACE12                            0x19C 0x404 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_GPIO4_IO16                                   0x19C 0x404 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_CCMSRCGPCMIX_BOOT_CFG12                      0x19C 0x404 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD4_SIM_M_HADDR31                                0x19C 0x404 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5                                0x1A0 0x408 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0                                0x1A0 0x408 0x514 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD5_SAI6_TX_DATA0                                0x1A0 0x408 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CORESIGHT_TRACE13                            0x1A0 0x408 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_GPIO4_IO17                                   0x1A0 0x408 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_CCMSRCGPCMIX_BOOT_CFG13                      0x1A0 0x408 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD5_SIM_M_HBURST0                                0x1A0 0x408 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6                                0x1A4 0x40C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_RX_SYNC                                 0x1A4 0x40C 0x518 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_SAI6_TX_SYNC                                 0x1A4 0x40C 0x520 0x2 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD6_CORESIGHT_TRACE14                            0x1A4 0x40C 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_GPIO4_IO18                                   0x1A4 0x40C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_CCMSRCGPCMIX_BOOT_CFG14                      0x1A4 0x40C 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD6_SIM_M_HBURST1                                0x1A4 0x40C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7                                0x1A8 0x410 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SAI6_MCLK                                    0x1A8 0x410 0x530 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_TXD7_CORESIGHT_TRACE15                            0x1A8 0x410 0x000 0x4 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_GPIO4_IO19                                   0x1A8 0x410 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_CCMSRCGPCMIX_BOOT_CFG15                      0x1A8 0x410 0x000 0x6 0x0
+#define MX8MQ_IOMUXC_SAI1_TXD7_SIM_M_HBURST2                                0x1A8 0x410 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK                                    0x1AC 0x414 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI5_MCLK                                    0x1AC 0x414 0x52C 0x1 0x1
+#define MX8MQ_IOMUXC_SAI1_MCLK_SAI1_TX_BCLK                                 0x1AC 0x414 0x4C8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI1_MCLK_GPIO4_IO20                                   0x1AC 0x414 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI1_MCLK_SIM_M_HRESP                                  0x1AC 0x414 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC                                 0x1B0 0x418 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC                                 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21                                   0x1B0 0x418 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0                                 0x1B0 0x418 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK                                  0x1B4 0x41C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SAI5_TX_BCLK                                  0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_RXC_GPIO4_IO22                                    0x1B4 0x41C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXC_SIM_M_HSIZE1                                  0x1B4 0x41C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0                                0x1B8 0x420 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0                                0x1B8 0x420 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_GPIO4_IO23                                   0x1B8 0x420 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2                                 0x1B8 0x420 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC                                 0x1BC 0x424 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1                                0x1BC 0x424 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_GPIO4_IO24                                   0x1BC 0x424 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXFS_SIM_M_HWRITE                                 0x1BC 0x424 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK                                  0x1C0 0x428 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SAI5_TX_DATA2                                 0x1C0 0x428 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_GPIO4_IO25                                    0x1C0 0x428 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXC_SIM_M_HREADYOUT                               0x1C0 0x428 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0                                0x1C4 0x42C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_SAI5_TX_DATA3                                0x1C4 0x42C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_GPIO4_IO26                                   0x1C4 0x42C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_TXD0_TPSMP_CLK                                    0x1C4 0x42C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK                                    0x1C8 0x430 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_SAI5_MCLK                                    0x1C8 0x430 0x52C 0x1 0x2
+#define MX8MQ_IOMUXC_SAI2_MCLK_GPIO4_IO27                                   0x1C8 0x430 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI2_MCLK_TPSMP_HDATA_DIR                              0x1C8 0x430 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC                                 0x1CC 0x434 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPT1_CAPTURE1                                0x1CC 0x434 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_SAI5_RX_SYNC                                 0x1CC 0x434 0x4E4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXFS_GPIO4_IO28                                   0x1CC 0x434 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXFS_TPSMP_HTRANS0                                0x1CC 0x434 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI3_RX_BCLK                                  0x1D0 0x438 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_GPT1_CAPTURE2                                 0x1D0 0x438 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_SAI5_RX_BCLK                                  0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXC_GPIO4_IO29                                    0x1D0 0x438 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXC_TPSMP_HTRANS1                                 0x1D0 0x438 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI3_RX_DATA0                                 0x1D4 0x43C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_GPT1_COMPARE1                                 0x1D4 0x43C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_SAI5_RX_DATA0                                 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_RXD_GPIO4_IO30                                    0x1D4 0x43C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_RXD_TPSMP_HDATA0                                  0x1D4 0x43C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPT1_CLK                                     0x1D8 0x440 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI3_TX_BCLK                                  0x1DC 0x444 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_GPT1_COMPARE3                                 0x1E0 0x448 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_SAI5_RX_DATA3                                 0x1E0 0x448 0x4E0 0x2 0x2
+#define MX8MQ_IOMUXC_SAI3_TXD_GPIO5_IO1                                     0x1E0 0x448 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_TXD_TPSMP_HDATA3                                  0x1E0 0x448 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI3_MCLK                                    0x1E4 0x44C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_PWM4_OUT                                     0x1E4 0x44C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_SAI5_MCLK                                    0x1E4 0x44C 0x52C 0x2 0x3
+#define MX8MQ_IOMUXC_SAI3_MCLK_GPIO5_IO2                                    0x1E4 0x44C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SAI3_MCLK_TPSMP_HDATA4                                 0x1E4 0x44C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_SPDIF1_OUT                                    0x1E8 0x450 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_PWM3_OUT                                      0x1E8 0x450 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_GPIO5_IO3                                     0x1E8 0x450 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_TX_TPSMP_HDATA5                                  0x1E8 0x450 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_SPDIF1_IN                                     0x1EC 0x454 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_PWM2_OUT                                      0x1EC 0x454 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_GPIO5_IO4                                     0x1EC 0x454 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_RX_TPSMP_HDATA6                                  0x1EC 0x454 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_SPDIF1_EXT_CLK                           0x1F0 0x458 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT                                 0x1F0 0x458 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5                                0x1F0 0x458 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_SPDIF_EXT_CLK_TPSMP_HDATA7                             0x1F0 0x458 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_ECSPI1_SCLK                                0x1F4 0x45C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX                               0x1F4 0x45C 0x504 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_UART3_DTE_TX                               0x1F4 0x45C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6                                  0x1F4 0x45C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SCLK_TPSMP_HDATA8                               0x1F4 0x45C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI                                0x1F8 0x460 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX                               0x1F8 0x460 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_UART3_DTE_RX                               0x1F8 0x460 0x504 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_GPIO5_IO7                                  0x1F8 0x460 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MOSI_TPSMP_HDATA9                               0x1F8 0x460 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_ECSPI1_MISO                                0x1FC 0x464 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B                            0x1FC 0x464 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DTE_RTS_B                            0x1FC 0x464 0x500 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_GPIO5_IO8                                  0x1FC 0x464 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_MISO_TPSMP_HDATA10                              0x1FC 0x464 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_ECSPI1_SS0                                  0x200 0x468 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B                             0x200 0x468 0x500 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DTE_CTS_B                             0x200 0x468 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9                                   0x200 0x468 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI1_SS0_TPSMP_HDATA11                               0x200 0x468 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK                                0x204 0x46C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX                               0x204 0x46C 0x50C 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_UART4_DTE_TX                               0x204 0x46C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_GPIO5_IO10                                 0x204 0x46C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SCLK_TPSMP_HDATA12                              0x204 0x46C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI                                0x208 0x470 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DCE_TX                               0x208 0x470 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_UART4_DTE_RX                               0x208 0x470 0x50C 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_GPIO5_IO11                                 0x208 0x470 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MOSI_TPSMP_HDATA13                              0x208 0x470 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO                                0x20C 0x474 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DCE_CTS_B                            0x20C 0x474 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_UART4_DTE_RTS_B                            0x20C 0x474 0x508 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_GPIO5_IO12                                 0x20C 0x474 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_MISO_TPSMP_HDATA14                              0x20C 0x474 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_ECSPI2_SS0                                  0x210 0x478 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DCE_RTS_B                             0x210 0x478 0x508 0x1 0x1
+#define MX8MQ_IOMUXC_ECSPI2_SS0_UART4_DTE_CTS_B                             0x210 0x478 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_GPIO5_IO13                                  0x210 0x478 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_ECSPI2_SS0_TPSMP_HDATA15                               0x210 0x478 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                                      0x214 0x47C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_ENET1_MDC                                     0x214 0x47C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_GPIO5_IO14                                    0x214 0x47C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SCL_TPSMP_HDATA16                                 0x214 0x47C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                                      0x218 0x480 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_ENET1_MDIO                                    0x218 0x480 0x4C0 0x1 0x2
+#define MX8MQ_IOMUXC_I2C1_SDA_GPIO5_IO15                                    0x218 0x480 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C1_SDA_TPSMP_HDATA17                                 0x218 0x480 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL                                      0x21C 0x484 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_ENET1_1588_EVENT1_IN                          0x21C 0x484 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_GPIO5_IO16                                    0x21C 0x484 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SCL_TPSMP_HDATA18                                 0x21C 0x484 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA                                      0x220 0x488 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_ENET1_1588_EVENT1_OUT                         0x220 0x488 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_GPIO5_IO17                                    0x220 0x488 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C2_SDA_TPSMP_HDATA19                                 0x220 0x488 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL                                      0x224 0x48C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_PWM4_OUT                                      0x224 0x48C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPT2_CLK                                      0x224 0x48C 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_GPIO5_IO18                                    0x224 0x48C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SCL_TPSMP_HDATA20                                 0x224 0x48C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA                                      0x228 0x490 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_PWM3_OUT                                      0x228 0x490 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPT3_CLK                                      0x228 0x490 0x000 0x2 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_GPIO5_IO19                                    0x228 0x490 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C3_SDA_TPSMP_HDATA21                                 0x228 0x490 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL                                      0x22C 0x494 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PWM2_OUT                                      0x22C 0x494 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B                                0x22C 0x494 0x524 0x2 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_GPIO5_IO20                                    0x22C 0x494 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SCL_TPSMP_HDATA22                                 0x22C 0x494 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA                                      0x230 0x498 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PWM1_OUT                                      0x230 0x498 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_PCIE2_CLKREQ_B                                0x230 0x498 0x528 0x2 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_GPIO5_IO21                                    0x230 0x498 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_I2C4_SDA_TPSMP_HDATA23                                 0x230 0x498 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX                                 0x234 0x49C 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_UART1_DTE_TX                                 0x234 0x49C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_ECSPI3_SCLK                                  0x234 0x49C 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_GPIO5_IO22                                   0x234 0x49C 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_RXD_TPSMP_HDATA24                                0x234 0x49C 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX                                 0x238 0x4A0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_UART1_DTE_RX                                 0x238 0x4A0 0x4F4 0x0 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_ECSPI3_MOSI                                  0x238 0x4A0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_GPIO5_IO23                                   0x238 0x4A0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART1_TXD_TPSMP_HDATA25                                0x238 0x4A0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX                                 0x23C 0x4A4 0x4FC 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_UART2_DTE_TX                                 0x23C 0x4A4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_ECSPI3_MISO                                  0x23C 0x4A4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_GPIO5_IO24                                   0x23C 0x4A4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_RXD_TPSMP_HDATA26                                0x23C 0x4A4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX                                 0x240 0x4A8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_UART2_DTE_RX                                 0x240 0x4A8 0x4FC 0x0 0x1
+#define MX8MQ_IOMUXC_UART2_TXD_ECSPI3_SS0                                   0x240 0x4A8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_GPIO5_IO25                                   0x240 0x4A8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART2_TXD_TPSMP_HDATA27                                0x240 0x4A8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX                                 0x244 0x4AC 0x504 0x0 0x2
+#define MX8MQ_IOMUXC_UART3_RXD_UART3_DTE_TX                                 0x244 0x4AC 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DCE_CTS_B                              0x244 0x4AC 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_UART1_DTE_RTS_B                              0x244 0x4AC 0x4F0 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_GPIO5_IO26                                   0x244 0x4AC 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_RXD_TPSMP_HDATA28                                0x244 0x4AC 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX                                 0x248 0x4B0 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_UART3_DTE_RX                                 0x248 0x4B0 0x504 0x0 0x3
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DCE_RTS_B                              0x248 0x4B0 0x4F0 0x1 0x1
+#define MX8MQ_IOMUXC_UART3_TXD_UART1_DTE_CTS_B                              0x248 0x4B0 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_GPIO5_IO27                                   0x248 0x4B0 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART3_TXD_TPSMP_HDATA29                                0x248 0x4B0 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DCE_RX                                 0x24C 0x4B4 0x50C 0x0 0x2
+#define MX8MQ_IOMUXC_UART4_RXD_UART4_DTE_TX                                 0x24C 0x4B4 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B                              0x24C 0x4B4 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_UART2_DTE_RTS_B                              0x24C 0x4B4 0x4F8 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_PCIE1_CLKREQ_B                               0x24C 0x4B4 0x524 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_RXD_GPIO5_IO28                                   0x24C 0x4B4 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_RXD_TPSMP_HDATA30                                0x24C 0x4B4 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DCE_TX                                 0x250 0x4B8 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_UART4_DTE_RX                                 0x250 0x4B8 0x50C 0x0 0x3
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B                              0x250 0x4B8 0x4F8 0x1 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_UART2_DTE_CTS_B                              0x250 0x4B8 0x000 0x1 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_PCIE2_CLKREQ_B                               0x250 0x4B8 0x528 0x2 0x1
+#define MX8MQ_IOMUXC_UART4_TXD_GPIO5_IO29                                   0x250 0x4B8 0x000 0x5 0x0
+#define MX8MQ_IOMUXC_UART4_TXD_TPSMP_HDATA31                                0x250 0x4B8 0x000 0x7 0x0
+#define MX8MQ_IOMUXC_TEST_MODE                                              0x000 0x254 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE0                                             0x000 0x258 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_BOOT_MODE1                                             0x000 0x25C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_MOD                                               0x000 0x260 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TRST_B                                            0x000 0x264 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDI                                               0x000 0x268 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TMS                                               0x000 0x26C 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TCK                                               0x000 0x270 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_JTAG_TDO                                               0x000 0x274 0x000 0x0 0x0
+#define MX8MQ_IOMUXC_RTC                                                    0x000 0x278 0x000 0x0 0x0
+
+#endif /* __DTS_IMX8MQ_PINFUNC_H */
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
new file mode 100644 (file)
index 0000000..8e9d6d5
--- /dev/null
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2017 NXP
+ * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de>
+ */
+
+#include <dt-bindings/clock/imx8mq-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx8mq-pinfunc.h"
+
+/ {
+       /* This should really be the GPC, but we need a driver for this first */
+       interrupt-parent = <&gic>;
+
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+       };
+
+       ckil: clock-ckil {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "ckil";
+       };
+
+       osc_25m: clock-osc-25m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <25000000>;
+               clock-output-names = "osc_25m";
+       };
+
+       osc_27m: clock-osc-27m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <27000000>;
+               clock-output-names = "osc_27m";
+       };
+
+       clk_ext1: clock-ext1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext1";
+       };
+
+       clk_ext2: clock-ext2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext2";
+       };
+
+       clk_ext3: clock-ext3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext3";
+       };
+
+       clk_ext4: clock-ext4 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency= <133000000>;
+               clock-output-names = "clk_ext4";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               A53_0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+               };
+
+               A53_1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+               };
+
+               A53_2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x2>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+               };
+
+               A53_3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x3>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+               };
+
+               A53_L2: l2-cache0 {
+                       compatible = "cache";
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
+               interrupt-parent = <&gic>;
+               arm,no-tick-in-suspend;
+       };
+
+       soc@0 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x0 0x3e000000>;
+
+               bus@30000000 { /* AIPS1 */
+                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x30000000 0x30000000 0x400000>;
+
+                       gpio1: gpio@30200000 {
+                               compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+                               reg = <0x30200000 0x10000>;
+                               interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@30210000 {
+                               compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+                               reg = <0x30210000 0x10000>;
+                               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@30220000 {
+                               compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+                               reg = <0x30220000 0x10000>;
+                               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@30230000 {
+                               compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+                               reg = <0x30230000 0x10000>;
+                               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio5: gpio@30240000 {
+                               compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
+                               reg = <0x30240000 0x10000>;
+                               interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       iomuxc: iomuxc@30330000 {
+                               compatible = "fsl,imx8mq-iomuxc";
+                               reg = <0x30330000 0x10000>;
+                       };
+
+                       iomuxc_gpr: syscon@30340000 {
+                               compatible = "fsl,imx8mq-iomuxc-gpr", "syscon";
+                               reg = <0x30340000 0x10000>;
+                       };
+
+                       anatop: syscon@30360000 {
+                               compatible = "fsl,imx8mq-anatop", "syscon";
+                               reg = <0x30360000 0x10000>;
+                               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+
+                       clk: clock-controller@30380000 {
+                               compatible = "fsl,imx8mq-ccm";
+                               reg = <0x30380000 0x10000>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                               #clock-cells = <1>;
+                               clocks = <&ckil>, <&osc_25m>, <&osc_27m>,
+                                        <&clk_ext1>, <&clk_ext2>,
+                                        <&clk_ext3>, <&clk_ext4>;
+                               clock-names = "ckil", "osc_25m", "osc_27m",
+                                             "clk_ext1", "clk_ext2",
+                                             "clk_ext3", "clk_ext4";
+                       };
+
+                       wdog1: watchdog@30280000 {
+                               compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+                               reg = <0x30280000 0x10000>;
+                               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_WDOG1_ROOT>;
+                               status = "disabled";
+                       };
+
+                       wdog2: watchdog@30290000 {
+                               compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+                               reg = <0x30290000 0x10000>;
+                               interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_WDOG2_ROOT>;
+                               status = "disabled";
+                       };
+
+                       wdog3: watchdog@302a0000 {
+                               compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt";
+                               reg = <0x302a0000 0x10000>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_WDOG3_ROOT>;
+                               status = "disabled";
+                       };
+               };
+
+               bus@30400000 { /* AIPS2 */
+                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x30400000 0x30400000 0x400000>;
+               };
+
+               bus@30800000 { /* AIPS3 */
+                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x30800000 0x30800000 0x400000>;
+
+                       uart1: serial@30860000 {
+                               compatible = "fsl,imx8mq-uart",
+                                            "fsl,imx6q-uart";
+                               reg = <0x30860000 0x10000>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_UART1_ROOT>,
+                                        <&clk IMX8MQ_CLK_UART1_ROOT>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart3: serial@30880000 {
+                               compatible = "fsl,imx8mq-uart",
+                                            "fsl,imx6q-uart";
+                               reg = <0x30880000 0x10000>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_UART3_ROOT>,
+                                        <&clk IMX8MQ_CLK_UART3_ROOT>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart2: serial@30890000 {
+                               compatible = "fsl,imx8mq-uart",
+                                            "fsl,imx6q-uart";
+                               reg = <0x30890000 0x10000>;
+                               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_UART2_ROOT>,
+                                        <&clk IMX8MQ_CLK_UART2_ROOT>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@30a20000 {
+                               compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+                               reg = <0x30a20000 0x10000>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_I2C1_ROOT>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@30a30000 {
+                               compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+                               reg = <0x30a30000 0x10000>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_I2C2_ROOT>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@30a40000 {
+                               compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+                               reg = <0x30a40000 0x10000>;
+                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_I2C3_ROOT>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@30a50000 {
+                               compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
+                               reg = <0x30a50000 0x10000>;
+                               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_I2C4_ROOT>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@30a60000 {
+                               compatible = "fsl,imx8mq-uart",
+                                            "fsl,imx6q-uart";
+                               reg = <0x30a60000 0x10000>;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_UART4_ROOT>,
+                                        <&clk IMX8MQ_CLK_UART4_ROOT>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       usdhc1: mmc@30b40000 {
+                               compatible = "fsl,imx8mq-usdhc",
+                                            "fsl,imx7d-usdhc";
+                               reg = <0x30b40000 0x10000>;
+                               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_DUMMY>,
+                                        <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+                                        <&clk IMX8MQ_CLK_USDHC1_ROOT>;
+                               clock-names = "ipg", "ahb", "per";
+                               fsl,tuning-start-tap = <20>;
+                               fsl,tuning-step = <2>;
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc2: mmc@30b50000 {
+                               compatible = "fsl,imx8mq-usdhc",
+                                            "fsl,imx7d-usdhc";
+                               reg = <0x30b50000 0x10000>;
+                               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_DUMMY>,
+                                        <&clk IMX8MQ_CLK_NAND_USDHC_BUS>,
+                                        <&clk IMX8MQ_CLK_USDHC2_ROOT>;
+                               clock-names = "ipg", "ahb", "per";
+                               fsl,tuning-start-tap = <20>;
+                               fsl,tuning-step = <2>;
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       fec1: ethernet@30be0000 {
+                               compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec";
+                               reg = <0x30be0000 0x10000>;
+                               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>,
+                                        <&clk IMX8MQ_CLK_ENET1_ROOT>,
+                                        <&clk IMX8MQ_CLK_ENET_TIMER>,
+                                        <&clk IMX8MQ_CLK_ENET_REF>,
+                                        <&clk IMX8MQ_CLK_ENET_PHY_REF>;
+                               clock-names = "ipg", "ahb", "ptp",
+                                             "enet_clk_ref", "enet_out";
+                               fsl,num-tx-queues = <3>;
+                               fsl,num-rx-queues = <3>;
+                               status = "disabled";
+                       };
+               };
+
+               gic: interrupt-controller@38800000 {
+                       compatible = "arm,gic-v3";
+                       reg = <0x38800000 0x10000>,     /* GIC Dist */
+                             <0x38880000 0xc0000>,     /* GICR */
+                             <0x31000000 0x2000>,      /* GICC */
+                             <0x31010000 0x2000>,      /* GICV */
+                             <0x31020000 0x2000>;      /* GICH */
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-parent = <&gic>;
+               };
+       };
+};
index d0724d4e0546d85c20b377619fbfd8d662664adf..3ef443cfbab628b7bbadaff86edf421e0ffa0a74 100644 (file)
@@ -403,6 +403,7 @@ CONFIG_THERMAL_EMULATION=y
 CONFIG_ROCKCHIP_THERMAL=m
 CONFIG_RCAR_GEN3_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
+CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_TEGRA_BPMP_THERMAL=m
index 2e05bcd944c8395b9fd5af993b6214054352aefc..52fa47c73bf042efc0c84796dcf1a21c10c534c1 100644 (file)
@@ -91,13 +91,13 @@ extern pgd_t *pgd_alloc(struct mm_struct *mm);
 extern void pgd_free(struct mm_struct *mm, pgd_t *pgdp);
 
 static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return (pte_t *)__get_free_page(PGALLOC_GFP);
 }
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 1895561839a98a5b72f3e42808b0ff3056211bb4..18553f399e083891d9c3552e1b311d296dbe7087 100644 (file)
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
+#include <linux/const.h>
+
 /* Values for secondary_data.status */
 #define CPU_STUCK_REASON_SHIFT         (8)
-#define CPU_BOOT_STATUS_MASK           ((1U << CPU_STUCK_REASON_SHIFT) - 1)
+#define CPU_BOOT_STATUS_MASK           ((UL(1) << CPU_STUCK_REASON_SHIFT) - 1)
 
 #define CPU_MMU_OFF                    (-1)
 #define CPU_BOOT_SUCCESS               (0)
@@ -29,8 +31,8 @@
 /* Fatal system error detected by secondary CPU, crash the system */
 #define CPU_PANIC_KERNEL               (3)
 
-#define CPU_STUCK_REASON_52_BIT_VA     (1U << CPU_STUCK_REASON_SHIFT)
-#define CPU_STUCK_REASON_NO_GRAN       (2U << CPU_STUCK_REASON_SHIFT)
+#define CPU_STUCK_REASON_52_BIT_VA     (UL(1) << CPU_STUCK_REASON_SHIFT)
+#define CPU_STUCK_REASON_NO_GRAN       (UL(2) << CPU_STUCK_REASON_SHIFT)
 
 #ifndef __ASSEMBLY__
 
index b13ca091f83329fe4eb3fb5cba348ce4c57f1cf7..a7b1fc58ffdffdd0d58b22297b25a9d91995cd0e 100644 (file)
  * The following SVCs are ARM private.
  */
 #define __ARM_NR_COMPAT_BASE           0x0f0000
-#define __ARM_NR_compat_cacheflush     (__ARM_NR_COMPAT_BASE+2)
-#define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE+5)
+#define __ARM_NR_compat_cacheflush     (__ARM_NR_COMPAT_BASE + 2)
+#define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE + 5)
+#define __ARM_NR_COMPAT_END            (__ARM_NR_COMPAT_BASE + 0x800)
 
-#define __NR_compat_syscalls           399
+#define __NR_compat_syscalls           400
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
index 2cd6dcf8d246313ed111ad3d42cad861dd1f5b18..04ee190b90fe6f2fe6c1655ba9f94f49aaee9958 100644 (file)
@@ -819,6 +819,8 @@ __SYSCALL(__NR_pkey_free, sys_pkey_free)
 __SYSCALL(__NR_statx, sys_statx)
 #define __NR_rseq 398
 __SYSCALL(__NR_rseq, sys_rseq)
+#define __NR_io_pgetevents 399
+__SYSCALL(__NR_io_pgetevents, compat_sys_io_pgetevents)
 
 /*
  * Please add new compat syscalls above this comment and update
index c2f249bcd82981ef472cdc37a606ca5e74ad8e95..28d77c9ed53110b89a2751c921931087dc453f96 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/types.h>
 
 #include <asm/hwcap.h>
-#include <asm/sigcontext.h>
+#include <asm/sve_context.h>
 
 
 /*
@@ -130,9 +130,9 @@ struct user_sve_header {
  */
 
 /* Offset from the start of struct user_sve_header to the register data */
-#define SVE_PT_REGS_OFFSET                                     \
-       ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1))      \
-               / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_REGS_OFFSET                                             \
+       ((sizeof(struct user_sve_header) + (__SVE_VQ_BYTES - 1))        \
+               / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
 /*
  * The register data content and layout depends on the value of the
@@ -178,39 +178,36 @@ struct user_sve_header {
  * Additional data might be appended in the future.
  */
 
-#define SVE_PT_SVE_ZREG_SIZE(vq)       SVE_SIG_ZREG_SIZE(vq)
-#define SVE_PT_SVE_PREG_SIZE(vq)       SVE_SIG_PREG_SIZE(vq)
-#define SVE_PT_SVE_FFR_SIZE(vq)                SVE_SIG_FFR_SIZE(vq)
+#define SVE_PT_SVE_ZREG_SIZE(vq)       __SVE_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq)       __SVE_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq)                __SVE_FFR_SIZE(vq)
 #define SVE_PT_SVE_FPSR_SIZE           sizeof(__u32)
 #define SVE_PT_SVE_FPCR_SIZE           sizeof(__u32)
 
-#define __SVE_SIG_TO_PT(offset) \
-       ((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET)
-
 #define SVE_PT_SVE_OFFSET              SVE_PT_REGS_OFFSET
 
 #define SVE_PT_SVE_ZREGS_OFFSET \
-       __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET)
+       (SVE_PT_REGS_OFFSET + __SVE_ZREGS_OFFSET)
 #define SVE_PT_SVE_ZREG_OFFSET(vq, n) \
-       __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n))
+       (SVE_PT_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
 #define SVE_PT_SVE_ZREGS_SIZE(vq) \
-       (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
+       (SVE_PT_SVE_ZREG_OFFSET(vq, __SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
 
 #define SVE_PT_SVE_PREGS_OFFSET(vq) \
-       __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq))
+       (SVE_PT_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
 #define SVE_PT_SVE_PREG_OFFSET(vq, n) \
-       __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n))
+       (SVE_PT_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
 #define SVE_PT_SVE_PREGS_SIZE(vq) \
-       (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - \
+       (SVE_PT_SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - \
                SVE_PT_SVE_PREGS_OFFSET(vq))
 
 #define SVE_PT_SVE_FFR_OFFSET(vq) \
-       __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq))
+       (SVE_PT_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
 
 #define SVE_PT_SVE_FPSR_OFFSET(vq)                             \
        ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + \
-                       (SVE_VQ_BYTES - 1))                     \
-               / SVE_VQ_BYTES * SVE_VQ_BYTES)
+                       (__SVE_VQ_BYTES - 1))                   \
+               / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 #define SVE_PT_SVE_FPCR_OFFSET(vq) \
        (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
 
@@ -221,8 +218,8 @@ struct user_sve_header {
 
 #define SVE_PT_SVE_SIZE(vq, flags)                                     \
        ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE             \
-                       - SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1))       \
-               / SVE_VQ_BYTES * SVE_VQ_BYTES)
+                       - SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1))     \
+               / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
 #define SVE_PT_SIZE(vq, flags)                                         \
         (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?             \
index dca8f8b5168b44828b30d6048660a2d69e198b71..5f3c0cec5af921fb56970d4b1384fe097c8e2d76 100644 (file)
@@ -130,6 +130,8 @@ struct sve_context {
 
 #endif /* !__ASSEMBLY__ */
 
+#include <asm/sve_context.h>
+
 /*
  * The SVE architecture leaves space for future expansion of the
  * vector length beyond its initial architectural limit of 2048 bits
@@ -138,21 +140,20 @@ struct sve_context {
  * See linux/Documentation/arm64/sve.txt for a description of the VL/VQ
  * terminology.
  */
-#define SVE_VQ_BYTES           16      /* number of bytes per quadword */
+#define SVE_VQ_BYTES           __SVE_VQ_BYTES  /* bytes per quadword */
 
-#define SVE_VQ_MIN             1
-#define SVE_VQ_MAX             512
+#define SVE_VQ_MIN             __SVE_VQ_MIN
+#define SVE_VQ_MAX             __SVE_VQ_MAX
 
-#define SVE_VL_MIN             (SVE_VQ_MIN * SVE_VQ_BYTES)
-#define SVE_VL_MAX             (SVE_VQ_MAX * SVE_VQ_BYTES)
+#define SVE_VL_MIN             __SVE_VL_MIN
+#define SVE_VL_MAX             __SVE_VL_MAX
 
-#define SVE_NUM_ZREGS          32
-#define SVE_NUM_PREGS          16
+#define SVE_NUM_ZREGS          __SVE_NUM_ZREGS
+#define SVE_NUM_PREGS          __SVE_NUM_PREGS
 
-#define sve_vl_valid(vl) \
-       ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
-#define sve_vq_from_vl(vl)     ((vl) / SVE_VQ_BYTES)
-#define sve_vl_from_vq(vq)     ((vq) * SVE_VQ_BYTES)
+#define sve_vl_valid(vl)       __sve_vl_valid(vl)
+#define sve_vq_from_vl(vl)     __sve_vq_from_vl(vl)
+#define sve_vl_from_vq(vq)     __sve_vl_from_vq(vq)
 
 /*
  * If the SVE registers are currently live for the thread at signal delivery,
@@ -205,34 +206,33 @@ struct sve_context {
  * Additional data might be appended in the future.
  */
 
-#define SVE_SIG_ZREG_SIZE(vq)  ((__u32)(vq) * SVE_VQ_BYTES)
-#define SVE_SIG_PREG_SIZE(vq)  ((__u32)(vq) * (SVE_VQ_BYTES / 8))
-#define SVE_SIG_FFR_SIZE(vq)   SVE_SIG_PREG_SIZE(vq)
+#define SVE_SIG_ZREG_SIZE(vq)  __SVE_ZREG_SIZE(vq)
+#define SVE_SIG_PREG_SIZE(vq)  __SVE_PREG_SIZE(vq)
+#define SVE_SIG_FFR_SIZE(vq)   __SVE_FFR_SIZE(vq)
 
 #define SVE_SIG_REGS_OFFSET                                    \
-       ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1))      \
-               / SVE_VQ_BYTES * SVE_VQ_BYTES)
+       ((sizeof(struct sve_context) + (__SVE_VQ_BYTES - 1))    \
+               / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
-#define SVE_SIG_ZREGS_OFFSET   SVE_SIG_REGS_OFFSET
+#define SVE_SIG_ZREGS_OFFSET \
+               (SVE_SIG_REGS_OFFSET + __SVE_ZREGS_OFFSET)
 #define SVE_SIG_ZREG_OFFSET(vq, n) \
-       (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))
-#define SVE_SIG_ZREGS_SIZE(vq) \
-       (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)
+               (SVE_SIG_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
+#define SVE_SIG_ZREGS_SIZE(vq) __SVE_ZREGS_SIZE(vq)
 
 #define SVE_SIG_PREGS_OFFSET(vq) \
-       (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))
+               (SVE_SIG_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
 #define SVE_SIG_PREG_OFFSET(vq, n) \
-       (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))
-#define SVE_SIG_PREGS_SIZE(vq) \
-       (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))
+               (SVE_SIG_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
+#define SVE_SIG_PREGS_SIZE(vq) __SVE_PREGS_SIZE(vq)
 
 #define SVE_SIG_FFR_OFFSET(vq) \
-       (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))
+               (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
 
 #define SVE_SIG_REGS_SIZE(vq) \
-       (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
-
-#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
+               (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
 
+#define SVE_SIG_CONTEXT_SIZE(vq) \
+               (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 
 #endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
new file mode 100644 (file)
index 0000000..754ab75
--- /dev/null
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (C) 2017-2018 ARM Limited */
+
+/*
+ * For use by other UAPI headers only.
+ * Do not make direct use of header or its definitions.
+ */
+
+#ifndef _UAPI__ASM_SVE_CONTEXT_H
+#define _UAPI__ASM_SVE_CONTEXT_H
+
+#include <linux/types.h>
+
+#define __SVE_VQ_BYTES         16      /* number of bytes per quadword */
+
+#define __SVE_VQ_MIN           1
+#define __SVE_VQ_MAX           512
+
+#define __SVE_VL_MIN           (__SVE_VQ_MIN * __SVE_VQ_BYTES)
+#define __SVE_VL_MAX           (__SVE_VQ_MAX * __SVE_VQ_BYTES)
+
+#define __SVE_NUM_ZREGS                32
+#define __SVE_NUM_PREGS                16
+
+#define __sve_vl_valid(vl)                     \
+       ((vl) % __SVE_VQ_BYTES == 0 &&          \
+        (vl) >= __SVE_VL_MIN &&                \
+        (vl) <= __SVE_VL_MAX)
+
+#define __sve_vq_from_vl(vl)   ((vl) / __SVE_VQ_BYTES)
+#define __sve_vl_from_vq(vq)   ((vq) * __SVE_VQ_BYTES)
+
+#define __SVE_ZREG_SIZE(vq)    ((__u32)(vq) * __SVE_VQ_BYTES)
+#define __SVE_PREG_SIZE(vq)    ((__u32)(vq) * (__SVE_VQ_BYTES / 8))
+#define __SVE_FFR_SIZE(vq)     __SVE_PREG_SIZE(vq)
+
+#define __SVE_ZREGS_OFFSET     0
+#define __SVE_ZREG_OFFSET(vq, n) \
+       (__SVE_ZREGS_OFFSET + __SVE_ZREG_SIZE(vq) * (n))
+#define __SVE_ZREGS_SIZE(vq) \
+       (__SVE_ZREG_OFFSET(vq, __SVE_NUM_ZREGS) - __SVE_ZREGS_OFFSET)
+
+#define __SVE_PREGS_OFFSET(vq) \
+       (__SVE_ZREGS_OFFSET + __SVE_ZREGS_SIZE(vq))
+#define __SVE_PREG_OFFSET(vq, n) \
+       (__SVE_PREGS_OFFSET(vq) + __SVE_PREG_SIZE(vq) * (n))
+#define __SVE_PREGS_SIZE(vq) \
+       (__SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - __SVE_PREGS_OFFSET(vq))
+
+#define __SVE_FFR_OFFSET(vq) \
+       (__SVE_PREGS_OFFSET(vq) + __SVE_PREGS_SIZE(vq))
+
+#endif /* ! _UAPI__ASM_SVE_CONTEXT_H */
index df08d735b21d37ef85b28064ed12a90ce99ad66b..cd434d0719c1cf8ade1aaacdec52a7c69d11d605 100644 (file)
@@ -12,7 +12,7 @@ CFLAGS_REMOVE_insn.o = -pg
 CFLAGS_REMOVE_return_address.o = -pg
 
 # Object file lists.
-arm64-obj-y            := debug-monitors.o entry.o irq.o fpsimd.o              \
+obj-y                  := debug-monitors.o entry.o irq.o fpsimd.o              \
                           entry-fpsimd.o process.o ptrace.o setup.o signal.o   \
                           sys.o stacktrace.o time.o traps.o io.o vdso.o        \
                           hyp-stub.o psci.o cpu_ops.o insn.o   \
@@ -27,41 +27,40 @@ OBJCOPYFLAGS := --prefix-symbols=__efistub_
 $(obj)/%.stub.o: $(obj)/%.o FORCE
        $(call if_changed,objcopy)
 
-arm64-obj-$(CONFIG_COMPAT)             += sys32.o kuser32.o signal32.o         \
+obj-$(CONFIG_COMPAT)                   += sys32.o kuser32.o signal32.o         \
                                           sys_compat.o
-arm64-obj-$(CONFIG_FUNCTION_TRACER)    += ftrace.o entry-ftrace.o
-arm64-obj-$(CONFIG_MODULES)            += module.o
-arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)  += module-plts.o
-arm64-obj-$(CONFIG_PERF_EVENTS)                += perf_regs.o perf_callchain.o
-arm64-obj-$(CONFIG_HW_PERF_EVENTS)     += perf_event.o
-arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
-arm64-obj-$(CONFIG_CPU_PM)             += sleep.o suspend.o
-arm64-obj-$(CONFIG_CPU_IDLE)           += cpuidle.o
-arm64-obj-$(CONFIG_JUMP_LABEL)         += jump_label.o
-arm64-obj-$(CONFIG_KGDB)               += kgdb.o
-arm64-obj-$(CONFIG_EFI)                        += efi.o efi-entry.stub.o               \
+obj-$(CONFIG_FUNCTION_TRACER)          += ftrace.o entry-ftrace.o
+obj-$(CONFIG_MODULES)                  += module.o
+obj-$(CONFIG_ARM64_MODULE_PLTS)                += module-plts.o
+obj-$(CONFIG_PERF_EVENTS)              += perf_regs.o perf_callchain.o
+obj-$(CONFIG_HW_PERF_EVENTS)           += perf_event.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)       += hw_breakpoint.o
+obj-$(CONFIG_CPU_PM)                   += sleep.o suspend.o
+obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
+obj-$(CONFIG_JUMP_LABEL)               += jump_label.o
+obj-$(CONFIG_KGDB)                     += kgdb.o
+obj-$(CONFIG_EFI)                      += efi.o efi-entry.stub.o               \
                                           efi-rt-wrapper.o
-arm64-obj-$(CONFIG_PCI)                        += pci.o
-arm64-obj-$(CONFIG_ARMV8_DEPRECATED)   += armv8_deprecated.o
-arm64-obj-$(CONFIG_ACPI)               += acpi.o
-arm64-obj-$(CONFIG_ACPI_NUMA)          += acpi_numa.o
-arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)        += acpi_parking_protocol.o
-arm64-obj-$(CONFIG_PARAVIRT)           += paravirt.o
-arm64-obj-$(CONFIG_RANDOMIZE_BASE)     += kaslr.o
-arm64-obj-$(CONFIG_HIBERNATION)                += hibernate.o hibernate-asm.o
-arm64-obj-$(CONFIG_KEXEC_CORE)         += machine_kexec.o relocate_kernel.o    \
+obj-$(CONFIG_PCI)                      += pci.o
+obj-$(CONFIG_ARMV8_DEPRECATED)         += armv8_deprecated.o
+obj-$(CONFIG_ACPI)                     += acpi.o
+obj-$(CONFIG_ACPI_NUMA)                        += acpi_numa.o
+obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)      += acpi_parking_protocol.o
+obj-$(CONFIG_PARAVIRT)                 += paravirt.o
+obj-$(CONFIG_RANDOMIZE_BASE)           += kaslr.o
+obj-$(CONFIG_HIBERNATION)              += hibernate.o hibernate-asm.o
+obj-$(CONFIG_KEXEC_CORE)               += machine_kexec.o relocate_kernel.o    \
                                           cpu-reset.o
-arm64-obj-$(CONFIG_KEXEC_FILE)         += machine_kexec_file.o kexec_image.o
-arm64-obj-$(CONFIG_ARM64_RELOC_TEST)   += arm64-reloc-test.o
+obj-$(CONFIG_KEXEC_FILE)               += machine_kexec_file.o kexec_image.o
+obj-$(CONFIG_ARM64_RELOC_TEST)         += arm64-reloc-test.o
 arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
-arm64-obj-$(CONFIG_CRASH_DUMP)         += crash_dump.o
-arm64-obj-$(CONFIG_CRASH_CORE)         += crash_core.o
-arm64-obj-$(CONFIG_ARM_SDE_INTERFACE)  += sdei.o
-arm64-obj-$(CONFIG_ARM64_SSBD)         += ssbd.o
-arm64-obj-$(CONFIG_ARM64_PTR_AUTH)     += pointer_auth.o
+obj-$(CONFIG_CRASH_DUMP)               += crash_dump.o
+obj-$(CONFIG_CRASH_CORE)               += crash_core.o
+obj-$(CONFIG_ARM_SDE_INTERFACE)                += sdei.o
+obj-$(CONFIG_ARM64_SSBD)               += ssbd.o
+obj-$(CONFIG_ARM64_PTR_AUTH)           += pointer_auth.o
 
-obj-y                                  += $(arm64-obj-y) vdso/ probes/
-obj-m                                  += $(arm64-obj-m)
+obj-y                                  += vdso/ probes/
 head-y                                 := head.o
 extra-y                                        += $(head-y) vmlinux.lds
 
index 763f03dc4d9e75cbef3ceb085ea7fe70d16a78d5..0ec0c46b2c0c9e24082eb951dcf10af6159f03bc 100644 (file)
@@ -392,17 +392,7 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
        mov     sp, x19
        .endm
 
-/*
- * These are the registers used in the syscall handler, and allow us to
- * have in theory up to 7 arguments to a function - x0 to x6.
- *
- * x7 is reserved for the system call number in 32-bit mode.
- */
-wsc_nr .req    w25             // number of system calls
-xsc_nr .req    x25             // number of system calls (zero-extended)
-wscno  .req    w26             // syscall number
-xscno  .req    x26             // syscall number (zero-extended)
-stbl   .req    x27             // syscall table pointer
+/* GPRs used by entry code */
 tsk    .req    x28             // current thread_info
 
 /*
index 21005dfe8406cc390fd34594d017853709d79858..c832a5c24efc93870643909e7836b23cdced5723 100644 (file)
@@ -66,12 +66,11 @@ do_compat_cache_op(unsigned long start, unsigned long end, int flags)
 /*
  * Handle all unrecognised system calls.
  */
-long compat_arm_syscall(struct pt_regs *regs)
+long compat_arm_syscall(struct pt_regs *regs, int scno)
 {
-       unsigned int no = regs->regs[7];
        void __user *addr;
 
-       switch (no) {
+       switch (scno) {
        /*
         * Flush a region from virtual address 'r0' to virtual address 'r1'
         * _exclusive_.  There is no alignment requirement on either address;
@@ -102,12 +101,12 @@ long compat_arm_syscall(struct pt_regs *regs)
 
        default:
                /*
-                * Calls 9f00xx..9f07ff are defined to return -ENOSYS
+                * Calls 0xf0xxx..0xf07ff are defined to return -ENOSYS
                 * if not implemented, rather than raising SIGILL. This
                 * way the calling program can gracefully determine whether
                 * a feature is supported.
                 */
-               if ((no & 0xffff) <= 0x7ff)
+               if (scno < __ARM_NR_COMPAT_END)
                        return -ENOSYS;
                break;
        }
@@ -116,6 +115,6 @@ long compat_arm_syscall(struct pt_regs *regs)
                (compat_thumb_mode(regs) ? 2 : 4);
 
        arm64_notify_die("Oops - bad compat syscall(2)", regs,
-                        SIGILL, ILL_ILLTRP, addr, no);
+                        SIGILL, ILL_ILLTRP, addr, scno);
        return 0;
 }
index 032d223128815bbfdf0b9f5e4b85a22ce2ab7e2f..5610ac01c1ec0212fe5bb4082c58b5e1f9f4dcb2 100644 (file)
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
 
-long compat_arm_syscall(struct pt_regs *regs);
-
+long compat_arm_syscall(struct pt_regs *regs, int scno);
 long sys_ni_syscall(void);
 
-asmlinkage long do_ni_syscall(struct pt_regs *regs)
+static long do_ni_syscall(struct pt_regs *regs, int scno)
 {
 #ifdef CONFIG_COMPAT
        long ret;
        if (is_compat_task()) {
-               ret = compat_arm_syscall(regs);
+               ret = compat_arm_syscall(regs, scno);
                if (ret != -ENOSYS)
                        return ret;
        }
@@ -47,7 +46,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
                syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
                ret = __invoke_syscall(regs, syscall_fn);
        } else {
-               ret = do_ni_syscall(regs);
+               ret = do_ni_syscall(regs, scno);
        }
 
        regs->regs[0] = ret;
index a8f2e4792ef97b52a1f0850766e04dc9994c861f..7205a9085b4de23edf68ae194b20c54ceacc029e 100644 (file)
@@ -439,7 +439,7 @@ void __init arm64_memblock_init(void)
                 * memory spans, randomize the linear region as well.
                 */
                if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
-                       range = range / ARM64_MEMSTART_ALIGN + 1;
+                       range /= ARM64_MEMSTART_ALIGN;
                        memstart_addr -= ARM64_MEMSTART_ALIGN *
                                         ((range * memstart_offset_seed) >> 16);
                }
index f0ab012401b67c10d6717cab8aa52f6987ba0ba3..8b68234ace181bbacdbf9c709d86051fc09b11de 100644 (file)
@@ -54,7 +54,7 @@ static inline unsigned long __ffs(unsigned long x)
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        if (!x)
                return 0;
index 37bed8aadf95b395f72b9e5c6550593e68e1c170..398113c845f56c0d14a3d367af4d515b1586f7ad 100644 (file)
@@ -28,10 +28,13 @@ config CSKY
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_LZMA
+       select HAVE_PERF_EVENTS
        select HAVE_C_RECORDMCOUNT
        select HAVE_DMA_API_DEBUG
        select HAVE_DMA_CONTIGUOUS
@@ -40,7 +43,7 @@ config CSKY
        select OF
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
-       select PERF_USE_VMALLOC
+       select PERF_USE_VMALLOC if CPU_CK610
        select RTC_LIB
        select TIMER_OF
        select USB_ARCH_HAS_EHCI
@@ -93,6 +96,9 @@ config MMU
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
+config STACKTRACE_SUPPORT
+       def_bool y
+
 config TIME_LOW_RES
        def_bool y
 
@@ -144,6 +150,19 @@ config CPU_CK860
        select CPU_HAS_FPUV2
 endchoice
 
+choice
+       prompt "C-SKY PMU type"
+       depends on PERF_EVENTS
+       depends on CPU_CK807 || CPU_CK810 || CPU_CK860
+
+config CPU_PMU_NONE
+       bool "None"
+
+config CSKY_PMU_V1
+       bool "Performance Monitoring Unit Ver.1"
+
+endchoice
+
 choice
        prompt "Power Manager Instruction (wait/doze/stop)"
        default CPU_PM_NONE
@@ -197,6 +216,15 @@ config RAM_BASE
        hex "DRAM start addr (the same with memory-section in dts)"
        default 0x0
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs"
+       select GENERIC_IRQ_MIGRATION
+       depends on SMP
+       help
+         Say Y here to allow turning CPUs off and on. CPUs can be
+         controlled through /sys/devices/system/cpu/cpu1/hotplug/target.
+
+         Say N if you want to disable CPU hotplug.
 endmenu
 
 source "kernel/Kconfig.hz"
index c639fc167895d7a2f00909bf079e5ea2e6b0558c..3607a6e8f66cbd7883caf995589d8d51d9245738 100644 (file)
@@ -47,6 +47,10 @@ ifeq ($(CSKYABI),abiv2)
 KBUILD_CFLAGS += -mno-stack-size
 endif
 
+ifdef CONFIG_STACKTRACE
+KBUILD_CFLAGS += -mbacktrace
+endif
+
 abidirs := $(patsubst %,arch/csky/%/,$(CSKYABI))
 KBUILD_CFLAGS += $(patsubst %,-I$(srctree)/%inc,$(abidirs))
 
index 455075b5db0da5391a8d50b7d1d18409b613ab11..d605445aad9ad4362f51d3ad41f47707c1946a07 100644 (file)
@@ -26,6 +26,7 @@
 
 #define _PAGE_CACHE            (3<<9)
 #define _PAGE_UNCACHE          (2<<9)
+#define _PAGE_SO               _PAGE_UNCACHE
 
 #define _CACHE_MASK            (7<<9)
 
diff --git a/arch/csky/abiv1/inc/abi/switch_context.h b/arch/csky/abiv1/inc/abi/switch_context.h
new file mode 100644 (file)
index 0000000..17c8268
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#ifndef __ABI_CSKY_PTRACE_H
+#define __ABI_CSKY_PTRACE_H
+
+struct switch_stack {
+       unsigned long r8;
+       unsigned long r9;
+       unsigned long r10;
+       unsigned long r11;
+       unsigned long r12;
+       unsigned long r13;
+       unsigned long r14;
+       unsigned long r15;
+};
+#endif /* __ABI_CSKY_PTRACE_H */
index 069ca7276b99ac1a13c168d835d5db2be0c204ad..b1d44f6fbcbdd90841bb5fffaca498476ead8f5e 100644 (file)
@@ -8,3 +8,4 @@ obj-y                           += strcmp.o
 obj-y                          += strcpy.o
 obj-y                          += strlen.o
 obj-y                          += strksyms.o
+obj-$(CONFIG_FUNCTION_TRACER)  += mcount.o
index acd05214d4e3adabcc406c4d28d7f059b945705d..edc5cc04c4de59621121c4031ba68d9ebcb92af9 100644 (file)
@@ -57,6 +57,8 @@
        stw     lr, (sp, 60)
        mflo    lr
        stw     lr, (sp, 64)
+       mfcr    lr, cr14
+       stw     lr, (sp, 68)
 #endif
        subi    sp, 80
 .endm
@@ -77,6 +79,8 @@
        mthi    a0
        ldw     a0, (sp, 144)
        mtlo    a0
+       ldw     a0, (sp, 148)
+       mtcr    a0, cr14
 #endif
 
        ldw     a0, (sp, 24)
@@ -93,9 +97,9 @@
 .endm
 
 .macro SAVE_SWITCH_STACK
-       subi    sp, 64
+       subi    sp, 64
        stm     r4-r11, (sp)
-       stw     r15, (sp, 32)
+       stw     lr,  (sp, 32)
        stw     r16, (sp, 36)
        stw     r17, (sp, 40)
        stw     r26, (sp, 44)
        stw     r28, (sp, 52)
        stw     r29, (sp, 56)
        stw     r30, (sp, 60)
+#ifdef CONFIG_CPU_HAS_HILO
+       subi    sp, 16
+       mfhi    lr
+       stw     lr, (sp, 0)
+       mflo    lr
+       stw     lr, (sp, 4)
+       mfcr    lr, cr14
+       stw     lr, (sp, 8)
+#endif
 .endm
 
 .macro RESTORE_SWITCH_STACK
+#ifdef CONFIG_CPU_HAS_HILO
+       ldw     lr, (sp, 0)
+       mthi    lr
+       ldw     lr, (sp, 4)
+       mtlo    lr
+       ldw     lr, (sp, 8)
+       mtcr    lr, cr14
+       addi    sp, 16
+#endif
        ldm     r4-r11, (sp)
-       ldw     r15, (sp, 32)
+       ldw     lr,  (sp, 32)
        ldw     r16, (sp, 36)
        ldw     r17, (sp, 40)
        ldw     r26, (sp, 44)
index b20ae19702e3c5fd1153f3215a3a052da09427bc..137f7932c83b3be191e9971da02bce7270b9ad62 100644 (file)
@@ -32,6 +32,6 @@
 #define _CACHE_MASK            _PAGE_CACHE
 
 #define _CACHE_CACHED          (_PAGE_VALID | _PAGE_CACHE | _PAGE_BUF)
-#define _CACHE_UNCACHED                (_PAGE_VALID | _PAGE_SO)
+#define _CACHE_UNCACHED                (_PAGE_VALID)
 
 #endif /* __ASM_CSKY_PGTABLE_BITS_H */
diff --git a/arch/csky/abiv2/inc/abi/switch_context.h b/arch/csky/abiv2/inc/abi/switch_context.h
new file mode 100644 (file)
index 0000000..73a8124
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#ifndef __ABI_CSKY_PTRACE_H
+#define __ABI_CSKY_PTRACE_H
+
+struct switch_stack {
+#ifdef CONFIG_CPU_HAS_HILO
+       unsigned long rhi;
+       unsigned long rlo;
+       unsigned long cr14;
+       unsigned long pad;
+#endif
+       unsigned long r4;
+       unsigned long r5;
+       unsigned long r6;
+       unsigned long r7;
+       unsigned long r8;
+       unsigned long r9;
+       unsigned long r10;
+       unsigned long r11;
+
+       unsigned long r15;
+       unsigned long r16;
+       unsigned long r17;
+       unsigned long r26;
+       unsigned long r27;
+       unsigned long r28;
+       unsigned long r29;
+       unsigned long r30;
+};
+#endif /* __ABI_CSKY_PTRACE_H */
diff --git a/arch/csky/abiv2/mcount.S b/arch/csky/abiv2/mcount.S
new file mode 100644 (file)
index 0000000..c633379
--- /dev/null
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/linkage.h>
+#include <asm/ftrace.h>
+
+/*
+ * csky-gcc with -pg will put the following asm after prologue:
+ *      push   r15
+ *      jsri   _mcount
+ *
+ * stack layout after mcount_enter in _mcount():
+ *
+ * current sp => 0:+-------+
+ *                 | a0-a3 | -> must save all argument regs
+ *             +16:+-------+
+ *                 | lr    | -> _mcount lr (instrumente function's pc)
+ *             +20:+-------+
+ *                 | fp=r8 | -> instrumented function fp
+ *             +24:+-------+
+ *                 | plr   | -> instrumented function lr (parent's pc)
+ *                 +-------+
+ */
+
+.macro mcount_enter
+       subi    sp, 24
+       stw     a0, (sp, 0)
+       stw     a1, (sp, 4)
+       stw     a2, (sp, 8)
+       stw     a3, (sp, 12)
+       stw     lr, (sp, 16)
+       stw     r8, (sp, 20)
+.endm
+
+.macro mcount_exit
+       ldw     a0, (sp, 0)
+       ldw     a1, (sp, 4)
+       ldw     a2, (sp, 8)
+       ldw     a3, (sp, 12)
+       ldw     t1, (sp, 16)
+       ldw     r8, (sp, 20)
+       ldw     lr, (sp, 24)
+       addi    sp, 28
+       jmp     t1
+.endm
+
+.macro save_return_regs
+       subi    sp, 16
+       stw     a0, (sp, 0)
+       stw     a1, (sp, 4)
+       stw     a2, (sp, 8)
+       stw     a3, (sp, 12)
+.endm
+
+.macro restore_return_regs
+       mov     lr, a0
+       ldw     a0, (sp, 0)
+       ldw     a1, (sp, 4)
+       ldw     a2, (sp, 8)
+       ldw     a3, (sp, 12)
+       addi    sp, 16
+.endm
+
+ENTRY(ftrace_stub)
+       jmp     lr
+END(ftrace_stub)
+
+ENTRY(_mcount)
+       mcount_enter
+
+       /* r26 is link register, only used with jsri translation */
+       lrw     r26, ftrace_trace_function
+       ldw     r26, (r26, 0)
+       lrw     a1, ftrace_stub
+       cmpne   r26, a1
+       bf      skip_ftrace
+
+       mov     a0, lr
+       subi    a0, MCOUNT_INSN_SIZE
+       ldw     a1, (sp, 24)
+
+       jsr     r26
+
+#ifndef CONFIG_FUNCTION_GRAPH_TRACER
+skip_ftrace:
+       mcount_exit
+#else
+skip_ftrace:
+       lrw     a0, ftrace_graph_return
+       ldw     a0, (a0, 0)
+       lrw     a1, ftrace_stub
+       cmpne   a0, a1
+       bt      ftrace_graph_caller
+
+       lrw     a0, ftrace_graph_entry
+       ldw     a0, (a0, 0)
+       lrw     a1, ftrace_graph_entry_stub
+       cmpne   a0, a1
+       bt      ftrace_graph_caller
+
+       mcount_exit
+#endif
+END(_mcount)
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+       mov     a0, sp
+       addi    a0, 24
+       ldw     a1, (sp, 16)
+       subi    a1, MCOUNT_INSN_SIZE
+       mov     a2, r8
+       lrw     r26, prepare_ftrace_return
+       jsr     r26
+       mcount_exit
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+       save_return_regs
+       mov     a0, r8
+       jsri    ftrace_return_to_handler
+       restore_return_regs
+       jmp     lr
+END(return_to_handler)
+#endif
index 987fec60ab97d03d446f6392adf94db4a76dbf1f..145bf3a9360ee18636a4c66862ef34d4591e14fa 100644 (file)
@@ -27,13 +27,7 @@ ENTRY(memcpy)
 
        LABLE_ALIGN
 .L_len_larger_16bytes:
-#if defined(__CSKY_VDSPV2__)
-       vldx.8  vr0, (r1), r19
-       PRE_BNEZAD (r18)
-       addi    r1, 16
-       vstx.8  vr0, (r0), r19
-       addi    r0, 16
-#elif defined(__CK860__)
+#if defined(__CK860__)
        ldw     r3, (r1, 0)
        stw     r3, (r0, 0)
        ldw     r3, (r1, 4)
index 335f2883fb1ee85aef5e6e4800f763c975047743..43b9838bff63d153a1942c1d292f8bc81af70599 100644 (file)
@@ -40,7 +40,7 @@ static __always_inline unsigned long __ffs(unsigned long x)
 /*
  * asm-generic/bitops/fls.h
  */
-static __always_inline int fls(int x)
+static __always_inline int fls(unsigned int x)
 {
        asm volatile(
                "ff1 %0\n"
index 773b133ca2972bbae32c90aefbfb481966b7e83c..e1ec558278bc9bba3511d198aa3344415824ffc5 100644 (file)
@@ -7,7 +7,8 @@
 #include <asm/ptrace.h>
 #include <abi/regdef.h>
 
-#define ELF_ARCH 252
+#define ELF_ARCH EM_CSKY
+#define EM_CSKY_OLD 39
 
 /* CSKY Relocations */
 #define R_CSKY_NONE               0
@@ -31,14 +32,20 @@ typedef unsigned long elf_greg_t;
 
 typedef struct user_fp elf_fpregset_t;
 
-#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+/*
+ * In gdb/bfd elf32-csky.c, csky_elf_grok_prstatus() use fixed size of
+ * elf_prstatus. It's 148 for abiv1 and 220 for abiv2, the size is enough
+ * for coredump and no need full sizeof(struct pt_regs).
+ */
+#define ELF_NGREG ((sizeof(struct pt_regs) / sizeof(elf_greg_t)) - 2)
 
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
-#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+#define elf_check_arch(x) (((x)->e_machine == ELF_ARCH) || \
+                          ((x)->e_machine == EM_CSKY_OLD))
 
 /*
  * These are used to set parameters in the core dumps.
diff --git a/arch/csky/include/asm/ftrace.h b/arch/csky/include/asm/ftrace.h
new file mode 100644 (file)
index 0000000..7547c45
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#ifndef __ASM_CSKY_FTRACE_H
+#define __ASM_CSKY_FTRACE_H
+
+#define MCOUNT_INSN_SIZE 4
+
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
+#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
+
+#endif /* __ASM_CSKY_FTRACE_H */
diff --git a/arch/csky/include/asm/perf_event.h b/arch/csky/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..ea81931
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#ifndef __ASM_CSKY_PERF_EVENT_H
+#define __ASM_CSKY_PERF_EVENT_H
+
+#endif /* __ASM_PERF_EVENT_ELF_H */
index b1748659b2e9578ab11d7342ea202639863a83cb..8f454810514f21be1356bd9d763f28e68f8d70b5 100644 (file)
 #include <asm/cache.h>
 #include <abi/reg_ops.h>
 #include <abi/regdef.h>
+#include <abi/switch_context.h>
 #ifdef CONFIG_CPU_HAS_FPU
 #include <abi/fpu.h>
 #endif
 
 struct cpuinfo_csky {
-       unsigned long udelay_val;
        unsigned long asid_cache;
-       /*
-        * Capability and feature descriptor structure for CSKY CPU
-        */
-       unsigned long options;
-       unsigned int processor_id[4];
-       unsigned int fpu_id;
 } __aligned(SMP_CACHE_BYTES);
 
 extern struct cpuinfo_csky cpu_data[];
@@ -49,13 +43,6 @@ extern struct cpuinfo_csky cpu_data[];
 struct thread_struct {
        unsigned long  ksp;       /* kernel stack pointer */
        unsigned long  sr;        /* saved status register */
-       unsigned long  esp0;      /* points to SR of stack frame */
-       unsigned long  hi;
-       unsigned long  lo;
-
-       /* Other stuff associated with the thread. */
-       unsigned long address;      /* Last user fault */
-       unsigned long error_code;
 
        /* FPU regs */
        struct user_fp __aligned(16) user_fp;
index 4a929c4d6437fd43fc97a72db8b1fa6a6cda483b..668b79ce29ea111d700f66d4ccf348acd85a3f7b 100644 (file)
@@ -21,6 +21,10 @@ void __init set_send_ipi(void (*func)(const struct cpumask *mask), int irq);
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
+int __cpu_disable(void);
+
+void __cpu_die(unsigned int cpu);
+
 #endif /* CONFIG_SMP */
 
 #endif /* __ASM_CSKY_SMP_H */
index 926a64a8b4eee8465e822ec426aa24e33b214036..d637445737b78fd5c78c9994173a1e7c73eb3d1f 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <abi/regdef.h>
+#include <uapi/linux/audit.h>
 
 static inline int
 syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
@@ -68,4 +69,10 @@ syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
        memcpy(&regs->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0));
 }
 
+static inline int
+syscall_get_arch(void)
+{
+       return AUDIT_ARCH_CSKY;
+}
+
 #endif /* __ASM_SYSCALL_H */
index a2c69a7836f700f6698d785368f997d7d993d616..0e9d035d712b675a96353408a426bd118fb14528 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/types.h>
 #include <asm/page.h>
 #include <asm/processor.h>
+#include <abi/switch_context.h>
 
 struct thread_info {
        struct task_struct      *task;
@@ -36,6 +37,9 @@ struct thread_info {
 
 #define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
 
+#define thread_saved_fp(tsk) \
+       ((unsigned long)(((struct switch_stack *)(tsk->thread.ksp))->r8))
+
 static inline struct thread_info *current_thread_info(void)
 {
        unsigned long sp;
index e02fd44e6447865e57ed57cb126eeadf876f63c0..7449fdeb973dbc88b5c66d72cc89506c5f50b52b 100644 (file)
@@ -1,7 +1,5 @@
 include include/uapi/asm-generic/Kbuild.asm
 
-header-y += cachectl.h
-
 generic-y += auxvec.h
 generic-y += param.h
 generic-y += bpf_perf_event.h
index f10d02c8b09e037bb83443e1fd4757360c805e7e..a4eaa8ddf0b1d070e58548a4a0c40d2c931942aa 100644 (file)
@@ -36,7 +36,7 @@ struct pt_regs {
 
        unsigned long   rhi;
        unsigned long   rlo;
-       unsigned long   pad; /* reserved */
+       unsigned long   dcsr;
 #endif
 };
 
@@ -48,43 +48,6 @@ struct user_fp {
        unsigned long   reserved;
 };
 
-/*
- * Switch stack for switch_to after push pt_regs.
- *
- * ABI_CSKYV2: r4 ~ r11, r15 ~ r17, r26 ~ r30;
- * ABI_CSKYV1: r8 ~ r14, r15;
- */
-struct  switch_stack {
-#if defined(__CSKYABIV2__)
-       unsigned long   r4;
-       unsigned long   r5;
-       unsigned long   r6;
-       unsigned long   r7;
-       unsigned long   r8;
-       unsigned long   r9;
-       unsigned long   r10;
-       unsigned long   r11;
-#else
-       unsigned long   r8;
-       unsigned long   r9;
-       unsigned long   r10;
-       unsigned long   r11;
-       unsigned long   r12;
-       unsigned long   r13;
-       unsigned long   r14;
-#endif
-       unsigned long   r15;
-#if defined(__CSKYABIV2__)
-       unsigned long   r16;
-       unsigned long   r17;
-       unsigned long   r26;
-       unsigned long   r27;
-       unsigned long   r28;
-       unsigned long   r29;
-       unsigned long   r30;
-#endif
-};
-
 #ifdef __KERNEL__
 
 #define PS_S   0x80000000 /* Supervisor Mode */
index 4422de756cdefc5470d74bb0c33d9aa1db6cd3ec..484e6d3a364719b521c6586a4a06df9d57d12b82 100644 (file)
@@ -6,3 +6,10 @@ obj-y += process.o cpu-probe.o ptrace.o dumpstack.o
 
 obj-$(CONFIG_MODULES)                  += module.o
 obj-$(CONFIG_SMP)                      += smp.o
+obj-$(CONFIG_FUNCTION_TRACER)          += ftrace.o
+obj-$(CONFIG_STACKTRACE)               += stacktrace.o
+obj-$(CONFIG_CSKY_PMU_V1)              += perf_event.o
+
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
+endif
index 8d3ed811321fd1095589351e090ba6e57f907778..9b48b1b1a61b57cee9f37de3336cfb6f2deffb3d 100644 (file)
@@ -20,12 +20,9 @@ int main(void)
        /* offsets into the thread struct */
        DEFINE(THREAD_KSP,        offsetof(struct thread_struct, ksp));
        DEFINE(THREAD_SR,         offsetof(struct thread_struct, sr));
-       DEFINE(THREAD_ESP0,       offsetof(struct thread_struct, esp0));
        DEFINE(THREAD_FESR,       offsetof(struct thread_struct, user_fp.fesr));
        DEFINE(THREAD_FCR,        offsetof(struct thread_struct, user_fp.fcr));
        DEFINE(THREAD_FPREG,      offsetof(struct thread_struct, user_fp.vr));
-       DEFINE(THREAD_DSPHI,      offsetof(struct thread_struct, hi));
-       DEFINE(THREAD_DSPLO,      offsetof(struct thread_struct, lo));
 
        /* offsets into the thread_info struct */
        DEFINE(TINFO_FLAGS,       offsetof(struct thread_info, flags));
index a9a03ac57ec58cea5d3de1b90b58874552efd744..659253e9989cb062e84f38c04ce9d4219ebf1d2e 100644 (file)
@@ -7,60 +7,39 @@ int kstack_depth_to_print = 48;
 
 void show_trace(unsigned long *stack)
 {
-       unsigned long *endstack;
+       unsigned long *stack_end;
+       unsigned long *stack_start;
+       unsigned long *fp;
        unsigned long addr;
-       int i;
 
-       pr_info("Call Trace:\n");
-       addr = (unsigned long)stack + THREAD_SIZE - 1;
-       endstack = (unsigned long *)(addr & -THREAD_SIZE);
-       i = 0;
-       while (stack + 1 <= endstack) {
-               addr = *stack++;
-               /*
-                * If the address is either in the text segment of the
-                * kernel, or in the region which contains vmalloc'ed
-                * memory, it *may* be the address of a calling
-                * routine; if so, print it so that someone tracing
-                * down the cause of the crash will be able to figure
-                * out the call path that was taken.
-                */
-               if (__kernel_text_address(addr)) {
-#ifndef CONFIG_KALLSYMS
-                       if (i % 5 == 0)
-                               pr_cont("\n       ");
+       addr = (unsigned long) stack & THREAD_MASK;
+       stack_start = (unsigned long *) addr;
+       stack_end = (unsigned long *) (addr + THREAD_SIZE);
+
+       fp = stack;
+       pr_info("\nCall Trace:");
+
+       while (fp > stack_start && fp < stack_end) {
+#ifdef CONFIG_STACKTRACE
+               addr    = fp[1];
+               fp      = (unsigned long *) fp[0];
+#else
+               addr    = *fp++;
 #endif
-                       pr_cont(" [<%08lx>] %pS\n", addr, (void *)addr);
-                       i++;
-               }
+               if (__kernel_text_address(addr))
+                       pr_cont("\n[<%08lx>] %pS", addr, (void *)addr);
        }
        pr_cont("\n");
 }
 
 void show_stack(struct task_struct *task, unsigned long *stack)
 {
-       unsigned long *p;
-       unsigned long *endstack;
-       int i;
-
        if (!stack) {
                if (task)
-                       stack = (unsigned long *)task->thread.esp0;
+                       stack = (unsigned long *)thread_saved_fp(task);
                else
                        stack = (unsigned long *)&stack;
        }
-       endstack = (unsigned long *)
-               (((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
 
-       pr_info("Stack from %08lx:", (unsigned long)stack);
-       p = stack;
-       for (i = 0; i < kstack_depth_to_print; i++) {
-               if (p + 1 > endstack)
-                       break;
-               if (i % 8 == 0)
-                       pr_cont("\n       ");
-               pr_cont(" %08lx", *p++);
-       }
-       pr_cont("\n");
        show_trace(stack);
 }
index 79f92b8606c8a11df17cf57e2e4d0f5e5e73e2ce..5137ed9062bdc1448e0ccb491ef67f3abc2d734d 100644 (file)
@@ -122,16 +122,6 @@ ENTRY(csky_systemcall)
 
        psrset  ee, ie
 
-       /* Stack frame for syscall, origin call set_esp0 */
-       mov     r12, sp
-
-       bmaski  r11, 13
-       andn    r12, r11
-       bgeni   r11, 9
-       addi    r11, 32
-       addu    r12, r11
-       st      sp, (r12, 0)
-
        lrw     r11, __NR_syscalls
        cmphs   syscallid, r11          /* Check nr of syscall */
        bt      ret_from_exception
@@ -183,18 +173,10 @@ ENTRY(csky_systemcall)
 #endif
        stw     a0, (sp, LSAVE_A0)      /* Save return value */
 
-       movi    a0, 1                   /* leave system call */
-       mov     a1, sp                  /* sp = pt_regs pointer */
-       jbsr    syscall_trace
-
-syscall_exit_work:
-       ld      syscallid, (sp, LSAVE_PSR)
-       btsti   syscallid, 31
-       bt      2f
-
-       jmpi    resume_userspace
-
-2:      RESTORE_ALL
+       movi    a0, 1                   /* leave system call */
+       mov     a1, sp                  /* right now, sp --> pt_regs */
+       jbsr    syscall_trace
+       br      ret_from_exception
 
 ENTRY(ret_from_kernel_thread)
        jbsr    schedule_tail
@@ -238,8 +220,6 @@ resume_userspace:
 1:  RESTORE_ALL
 
 exit_work:
-       mov     a0, sp                  /* Stack address is arg[0] */
-       jbsr    set_esp0                /* Call C level */
        btsti   r8, TIF_NEED_RESCHED
        bt      work_resched
        /* If thread_info->flag is empty, RESTORE_ALL */
@@ -354,34 +334,12 @@ ENTRY(__switch_to)
 
        stw     sp, (a3, THREAD_KSP)
 
-#ifdef CONFIG_CPU_HAS_HILO
-       lrw     r10, THREAD_DSPHI
-       add     r10, a3
-       mfhi    r6
-       mflo    r7
-       stw     r6, (r10, 0)            /* THREAD_DSPHI */
-       stw     r7, (r10, 4)            /* THREAD_DSPLO */
-       mfcr    r6, cr14
-       stw     r6, (r10, 8)            /* THREAD_DSPCSR */
-#endif
-
        /* Set up next process to run */
        lrw     a3, TASK_THREAD
        addu    a3, a1
 
        ldw     sp, (a3, THREAD_KSP)    /* Set next kernel sp */
 
-#ifdef CONFIG_CPU_HAS_HILO
-       lrw     r10, THREAD_DSPHI
-       add     r10, a3
-       ldw     r6, (r10, 8)            /* THREAD_DSPCSR */
-       mtcr    r6, cr14
-       ldw     r6, (r10, 0)            /* THREAD_DSPHI */
-       ldw     r7, (r10, 4)            /* THREAD_DSPLO */
-       mthi    r6
-       mtlo    r7
-#endif
-
        ldw     a2, (a3, THREAD_SR)     /* Set next PSR */
        mtcr    a2, psr
 
diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c
new file mode 100644 (file)
index 0000000..274c431
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/ftrace.h>
+#include <linux/uaccess.h>
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+                          unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long)&return_to_handler;
+       unsigned long old;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return;
+
+       old = *parent;
+
+       if (!function_graph_enter(old, self_addr,
+                       *(unsigned long *)frame_pointer, parent)) {
+               /*
+                * For csky-gcc function has sub-call:
+                * subi sp,     sp, 8
+                * stw  r8,     (sp, 0)
+                * mov  r8,     sp
+                * st.w r15,    (sp, 0x4)
+                * push r15
+                * jl   _mcount
+                * We only need set *parent for resume
+                *
+                * For csky-gcc function has no sub-call:
+                * subi sp,     sp, 4
+                * stw  r8,     (sp, 0)
+                * mov  r8,     sp
+                * push r15
+                * jl   _mcount
+                * We need set *parent and *(frame_pointer + 4) for resume,
+                * because lr is resumed twice.
+                */
+               *parent = return_hooker;
+               frame_pointer += 4;
+               if (*(unsigned long *)frame_pointer == old)
+                       *(unsigned long *)frame_pointer = return_hooker;
+       }
+}
+#endif
+
+/* _mcount is defined in abi's mcount.S */
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
diff --git a/arch/csky/kernel/perf_event.c b/arch/csky/kernel/perf_event.c
new file mode 100644 (file)
index 0000000..376c972
--- /dev/null
@@ -0,0 +1,1031 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+
+#define CSKY_PMU_MAX_EVENTS 32
+
+#define HPCR           "<0, 0x0>"      /* PMU Control reg */
+#define HPCNTENR       "<0, 0x4>"      /* Count Enable reg */
+
+static uint64_t (*hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS])(void);
+static void (*hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS])(uint64_t val);
+
+struct csky_pmu_t {
+       struct pmu      pmu;
+       uint32_t        hpcr;
+} csky_pmu;
+
+#define cprgr(reg)                             \
+({                                             \
+       unsigned int tmp;                       \
+       asm volatile("cprgr %0, "reg"\n"        \
+                    : "=r"(tmp)                \
+                    :                          \
+                    : "memory");               \
+       tmp;                                    \
+})
+
+#define cpwgr(reg, val)                \
+({                             \
+       asm volatile(           \
+       "cpwgr %0, "reg"\n"     \
+       :                       \
+       : "r"(val)              \
+       : "memory");            \
+})
+
+#define cprcr(reg)                             \
+({                                             \
+       unsigned int tmp;                       \
+       asm volatile("cprcr %0, "reg"\n"        \
+                    : "=r"(tmp)                \
+                    :                          \
+                    : "memory");               \
+       tmp;                                    \
+})
+
+#define cpwcr(reg, val)                \
+({                             \
+       asm volatile(           \
+       "cpwcr %0, "reg"\n"     \
+       :                       \
+       : "r"(val)              \
+       : "memory");            \
+})
+
+/* cycle counter */
+static uint64_t csky_pmu_read_cc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x3>");
+               lo  = cprgr("<0, 0x2>");
+               hi  = cprgr("<0, 0x3>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_cc(uint64_t val)
+{
+       cpwgr("<0, 0x2>", (uint32_t)  val);
+       cpwgr("<0, 0x3>", (uint32_t) (val >> 32));
+}
+
+/* instruction counter */
+static uint64_t csky_pmu_read_ic(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x5>");
+               lo  = cprgr("<0, 0x4>");
+               hi  = cprgr("<0, 0x5>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_ic(uint64_t val)
+{
+       cpwgr("<0, 0x4>", (uint32_t)  val);
+       cpwgr("<0, 0x5>", (uint32_t) (val >> 32));
+}
+
+/* l1 icache access counter */
+static uint64_t csky_pmu_read_icac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x7>");
+               lo  = cprgr("<0, 0x6>");
+               hi  = cprgr("<0, 0x7>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_icac(uint64_t val)
+{
+       cpwgr("<0, 0x6>", (uint32_t)  val);
+       cpwgr("<0, 0x7>", (uint32_t) (val >> 32));
+}
+
+/* l1 icache miss counter */
+static uint64_t csky_pmu_read_icmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x9>");
+               lo  = cprgr("<0, 0x8>");
+               hi  = cprgr("<0, 0x9>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_icmc(uint64_t val)
+{
+       cpwgr("<0, 0x8>", (uint32_t)  val);
+       cpwgr("<0, 0x9>", (uint32_t) (val >> 32));
+}
+
+/* l1 dcache access counter */
+static uint64_t csky_pmu_read_dcac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0xb>");
+               lo  = cprgr("<0, 0xa>");
+               hi  = cprgr("<0, 0xb>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcac(uint64_t val)
+{
+       cpwgr("<0, 0xa>", (uint32_t)  val);
+       cpwgr("<0, 0xb>", (uint32_t) (val >> 32));
+}
+
+/* l1 dcache miss counter */
+static uint64_t csky_pmu_read_dcmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0xd>");
+               lo  = cprgr("<0, 0xc>");
+               hi  = cprgr("<0, 0xd>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcmc(uint64_t val)
+{
+       cpwgr("<0, 0xc>", (uint32_t)  val);
+       cpwgr("<0, 0xd>", (uint32_t) (val >> 32));
+}
+
+/* l2 cache access counter */
+static uint64_t csky_pmu_read_l2ac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0xf>");
+               lo  = cprgr("<0, 0xe>");
+               hi  = cprgr("<0, 0xf>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2ac(uint64_t val)
+{
+       cpwgr("<0, 0xe>", (uint32_t)  val);
+       cpwgr("<0, 0xf>", (uint32_t) (val >> 32));
+}
+
+/* l2 cache miss counter */
+static uint64_t csky_pmu_read_l2mc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x11>");
+               lo  = cprgr("<0, 0x10>");
+               hi  = cprgr("<0, 0x11>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2mc(uint64_t val)
+{
+       cpwgr("<0, 0x10>", (uint32_t)  val);
+       cpwgr("<0, 0x11>", (uint32_t) (val >> 32));
+}
+
+/* I-UTLB miss counter */
+static uint64_t csky_pmu_read_iutlbmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x15>");
+               lo  = cprgr("<0, 0x14>");
+               hi  = cprgr("<0, 0x15>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_iutlbmc(uint64_t val)
+{
+       cpwgr("<0, 0x14>", (uint32_t)  val);
+       cpwgr("<0, 0x15>", (uint32_t) (val >> 32));
+}
+
+/* D-UTLB miss counter */
+static uint64_t csky_pmu_read_dutlbmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x17>");
+               lo  = cprgr("<0, 0x16>");
+               hi  = cprgr("<0, 0x17>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dutlbmc(uint64_t val)
+{
+       cpwgr("<0, 0x16>", (uint32_t)  val);
+       cpwgr("<0, 0x17>", (uint32_t) (val >> 32));
+}
+
+/* JTLB miss counter */
+static uint64_t csky_pmu_read_jtlbmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x19>");
+               lo  = cprgr("<0, 0x18>");
+               hi  = cprgr("<0, 0x19>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_jtlbmc(uint64_t val)
+{
+       cpwgr("<0, 0x18>", (uint32_t)  val);
+       cpwgr("<0, 0x19>", (uint32_t) (val >> 32));
+}
+
+/* software counter */
+static uint64_t csky_pmu_read_softc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x1b>");
+               lo  = cprgr("<0, 0x1a>");
+               hi  = cprgr("<0, 0x1b>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_softc(uint64_t val)
+{
+       cpwgr("<0, 0x1a>", (uint32_t)  val);
+       cpwgr("<0, 0x1b>", (uint32_t) (val >> 32));
+}
+
+/* conditional branch mispredict counter */
+static uint64_t csky_pmu_read_cbmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x1d>");
+               lo  = cprgr("<0, 0x1c>");
+               hi  = cprgr("<0, 0x1d>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_cbmc(uint64_t val)
+{
+       cpwgr("<0, 0x1c>", (uint32_t)  val);
+       cpwgr("<0, 0x1d>", (uint32_t) (val >> 32));
+}
+
+/* conditional branch instruction counter */
+static uint64_t csky_pmu_read_cbic(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x1f>");
+               lo  = cprgr("<0, 0x1e>");
+               hi  = cprgr("<0, 0x1f>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_cbic(uint64_t val)
+{
+       cpwgr("<0, 0x1e>", (uint32_t)  val);
+       cpwgr("<0, 0x1f>", (uint32_t) (val >> 32));
+}
+
+/* indirect branch mispredict counter */
+static uint64_t csky_pmu_read_ibmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x21>");
+               lo  = cprgr("<0, 0x20>");
+               hi  = cprgr("<0, 0x21>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_ibmc(uint64_t val)
+{
+       cpwgr("<0, 0x20>", (uint32_t)  val);
+       cpwgr("<0, 0x21>", (uint32_t) (val >> 32));
+}
+
+/* indirect branch instruction counter */
+static uint64_t csky_pmu_read_ibic(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x23>");
+               lo  = cprgr("<0, 0x22>");
+               hi  = cprgr("<0, 0x23>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_ibic(uint64_t val)
+{
+       cpwgr("<0, 0x22>", (uint32_t)  val);
+       cpwgr("<0, 0x23>", (uint32_t) (val >> 32));
+}
+
+/* LSU spec fail counter */
+static uint64_t csky_pmu_read_lsfc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x25>");
+               lo  = cprgr("<0, 0x24>");
+               hi  = cprgr("<0, 0x25>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_lsfc(uint64_t val)
+{
+       cpwgr("<0, 0x24>", (uint32_t)  val);
+       cpwgr("<0, 0x25>", (uint32_t) (val >> 32));
+}
+
+/* store instruction counter */
+static uint64_t csky_pmu_read_sic(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x27>");
+               lo  = cprgr("<0, 0x26>");
+               hi  = cprgr("<0, 0x27>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_sic(uint64_t val)
+{
+       cpwgr("<0, 0x26>", (uint32_t)  val);
+       cpwgr("<0, 0x27>", (uint32_t) (val >> 32));
+}
+
+/* dcache read access counter */
+static uint64_t csky_pmu_read_dcrac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x29>");
+               lo  = cprgr("<0, 0x28>");
+               hi  = cprgr("<0, 0x29>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcrac(uint64_t val)
+{
+       cpwgr("<0, 0x28>", (uint32_t)  val);
+       cpwgr("<0, 0x29>", (uint32_t) (val >> 32));
+}
+
+/* dcache read miss counter */
+static uint64_t csky_pmu_read_dcrmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x2b>");
+               lo  = cprgr("<0, 0x2a>");
+               hi  = cprgr("<0, 0x2b>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcrmc(uint64_t val)
+{
+       cpwgr("<0, 0x2a>", (uint32_t)  val);
+       cpwgr("<0, 0x2b>", (uint32_t) (val >> 32));
+}
+
+/* dcache write access counter */
+static uint64_t csky_pmu_read_dcwac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x2d>");
+               lo  = cprgr("<0, 0x2c>");
+               hi  = cprgr("<0, 0x2d>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcwac(uint64_t val)
+{
+       cpwgr("<0, 0x2c>", (uint32_t)  val);
+       cpwgr("<0, 0x2d>", (uint32_t) (val >> 32));
+}
+
+/* dcache write miss counter */
+static uint64_t csky_pmu_read_dcwmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x2f>");
+               lo  = cprgr("<0, 0x2e>");
+               hi  = cprgr("<0, 0x2f>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_dcwmc(uint64_t val)
+{
+       cpwgr("<0, 0x2e>", (uint32_t)  val);
+       cpwgr("<0, 0x2f>", (uint32_t) (val >> 32));
+}
+
+/* l2cache read access counter */
+static uint64_t csky_pmu_read_l2rac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x31>");
+               lo  = cprgr("<0, 0x30>");
+               hi  = cprgr("<0, 0x31>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2rac(uint64_t val)
+{
+       cpwgr("<0, 0x30>", (uint32_t)  val);
+       cpwgr("<0, 0x31>", (uint32_t) (val >> 32));
+}
+
+/* l2cache read miss counter */
+static uint64_t csky_pmu_read_l2rmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x33>");
+               lo  = cprgr("<0, 0x32>");
+               hi  = cprgr("<0, 0x33>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2rmc(uint64_t val)
+{
+       cpwgr("<0, 0x32>", (uint32_t)  val);
+       cpwgr("<0, 0x33>", (uint32_t) (val >> 32));
+}
+
+/* l2cache write access counter */
+static uint64_t csky_pmu_read_l2wac(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x35>");
+               lo  = cprgr("<0, 0x34>");
+               hi  = cprgr("<0, 0x35>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2wac(uint64_t val)
+{
+       cpwgr("<0, 0x34>", (uint32_t)  val);
+       cpwgr("<0, 0x35>", (uint32_t) (val >> 32));
+}
+
+/* l2cache write miss counter */
+static uint64_t csky_pmu_read_l2wmc(void)
+{
+       uint32_t lo, hi, tmp;
+       uint64_t result;
+
+       do {
+               tmp = cprgr("<0, 0x37>");
+               lo  = cprgr("<0, 0x36>");
+               hi  = cprgr("<0, 0x37>");
+       } while (hi != tmp);
+
+       result = (uint64_t) (hi) << 32;
+       result |= lo;
+
+       return result;
+}
+
+static void csky_pmu_write_l2wmc(uint64_t val)
+{
+       cpwgr("<0, 0x36>", (uint32_t)  val);
+       cpwgr("<0, 0x37>", (uint32_t) (val >> 32));
+}
+
+#define HW_OP_UNSUPPORTED      0xffff
+static const int csky_pmu_hw_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]              = 0x1,
+       [PERF_COUNT_HW_INSTRUCTIONS]            = 0x2,
+       [PERF_COUNT_HW_CACHE_REFERENCES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]            = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0xf,
+       [PERF_COUNT_HW_BRANCH_MISSES]           = 0xe,
+       [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_REF_CPU_CYCLES]          = HW_OP_UNSUPPORTED,
+};
+
+#define C(_x)                  PERF_COUNT_HW_CACHE_##_x
+#define CACHE_OP_UNSUPPORTED   0xffff
+static const int csky_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = 0x14,
+                       [C(RESULT_MISS)]        = 0x15,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = 0x16,
+                       [C(RESULT_MISS)]        = 0x17,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = 0x5,
+                       [C(RESULT_MISS)]        = 0x6,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = 0x3,
+                       [C(RESULT_MISS)]        = 0x4,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = 0x18,
+                       [C(RESULT_MISS)]        = 0x19,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = 0x1a,
+                       [C(RESULT_MISS)]        = 0x1b,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = 0x7,
+                       [C(RESULT_MISS)]        = 0x8,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = 0x5,
+                       [C(RESULT_MISS)]        = 0xb,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = 0x3,
+                       [C(RESULT_MISS)]        = 0xa,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(NODE)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+static void csky_perf_event_update(struct perf_event *event,
+                                  struct hw_perf_event *hwc)
+{
+       uint64_t prev_raw_count = local64_read(&hwc->prev_count);
+       uint64_t new_raw_count = hw_raw_read_mapping[hwc->idx]();
+       int64_t delta = new_raw_count - prev_raw_count;
+
+       /*
+        * We aren't afraid of hwc->prev_count changing beneath our feet
+        * because there's no way for us to re-enter this function anytime.
+        */
+       local64_set(&hwc->prev_count, new_raw_count);
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
+}
+
+static void csky_pmu_read(struct perf_event *event)
+{
+       csky_perf_event_update(event, &event->hw);
+}
+
+static int csky_pmu_cache_event(u64 config)
+{
+       unsigned int cache_type, cache_op, cache_result;
+
+       cache_type      = (config >>  0) & 0xff;
+       cache_op        = (config >>  8) & 0xff;
+       cache_result    = (config >> 16) & 0xff;
+
+       if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+               return -EINVAL;
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+               return -EINVAL;
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+               return -EINVAL;
+
+       return csky_pmu_cache_map[cache_type][cache_op][cache_result];
+}
+
+static int csky_pmu_event_init(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int ret;
+
+       if (event->attr.exclude_user)
+               csky_pmu.hpcr = BIT(2);
+       else if (event->attr.exclude_kernel)
+               csky_pmu.hpcr = BIT(3);
+       else
+               csky_pmu.hpcr = BIT(2) | BIT(3);
+
+       csky_pmu.hpcr |= BIT(1) | BIT(0);
+
+       switch (event->attr.type) {
+       case PERF_TYPE_HARDWARE:
+               if (event->attr.config >= PERF_COUNT_HW_MAX)
+                       return -ENOENT;
+               ret = csky_pmu_hw_map[event->attr.config];
+               if (ret == HW_OP_UNSUPPORTED)
+                       return -ENOENT;
+               hwc->idx = ret;
+               return 0;
+       case PERF_TYPE_HW_CACHE:
+               ret = csky_pmu_cache_event(event->attr.config);
+               if (ret == CACHE_OP_UNSUPPORTED)
+                       return -ENOENT;
+               hwc->idx = ret;
+               return 0;
+       case PERF_TYPE_RAW:
+               if (hw_raw_read_mapping[event->attr.config] == NULL)
+                       return -ENOENT;
+               hwc->idx = event->attr.config;
+               return 0;
+       default:
+               return -ENOENT;
+       }
+}
+
+/* starts all counters */
+static void csky_pmu_enable(struct pmu *pmu)
+{
+       cpwcr(HPCR, csky_pmu.hpcr);
+}
+
+/* stops all counters */
+static void csky_pmu_disable(struct pmu *pmu)
+{
+       cpwcr(HPCR, BIT(1));
+}
+
+static void csky_pmu_start(struct perf_event *event, int flags)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+
+       if (WARN_ON_ONCE(idx == -1))
+               return;
+
+       if (flags & PERF_EF_RELOAD)
+               WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+       hwc->state = 0;
+
+       cpwcr(HPCNTENR, BIT(idx) | cprcr(HPCNTENR));
+}
+
+static void csky_pmu_stop(struct perf_event *event, int flags)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+
+       if (!(event->hw.state & PERF_HES_STOPPED)) {
+               cpwcr(HPCNTENR, ~BIT(idx) & cprcr(HPCNTENR));
+               event->hw.state |= PERF_HES_STOPPED;
+       }
+
+       if ((flags & PERF_EF_UPDATE) &&
+           !(event->hw.state & PERF_HES_UPTODATE)) {
+               csky_perf_event_update(event, &event->hw);
+               event->hw.state |= PERF_HES_UPTODATE;
+       }
+}
+
+static void csky_pmu_del(struct perf_event *event, int flags)
+{
+       csky_pmu_stop(event, PERF_EF_UPDATE);
+
+       perf_event_update_userpage(event);
+}
+
+/* allocate hardware counter and optionally start counting */
+static int csky_pmu_add(struct perf_event *event, int flags)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       local64_set(&hwc->prev_count, 0);
+
+       if (hw_raw_write_mapping[hwc->idx] != NULL)
+               hw_raw_write_mapping[hwc->idx](0);
+
+       hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+       if (flags & PERF_EF_START)
+               csky_pmu_start(event, PERF_EF_RELOAD);
+
+       perf_event_update_userpage(event);
+
+       return 0;
+}
+
+int __init init_hw_perf_events(void)
+{
+       csky_pmu.pmu = (struct pmu) {
+               .pmu_enable     = csky_pmu_enable,
+               .pmu_disable    = csky_pmu_disable,
+               .event_init     = csky_pmu_event_init,
+               .add            = csky_pmu_add,
+               .del            = csky_pmu_del,
+               .start          = csky_pmu_start,
+               .stop           = csky_pmu_stop,
+               .read           = csky_pmu_read,
+       };
+
+       memset((void *)hw_raw_read_mapping, 0,
+               sizeof(hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS]));
+
+       hw_raw_read_mapping[0x1]  = csky_pmu_read_cc;
+       hw_raw_read_mapping[0x2]  = csky_pmu_read_ic;
+       hw_raw_read_mapping[0x3]  = csky_pmu_read_icac;
+       hw_raw_read_mapping[0x4]  = csky_pmu_read_icmc;
+       hw_raw_read_mapping[0x5]  = csky_pmu_read_dcac;
+       hw_raw_read_mapping[0x6]  = csky_pmu_read_dcmc;
+       hw_raw_read_mapping[0x7]  = csky_pmu_read_l2ac;
+       hw_raw_read_mapping[0x8]  = csky_pmu_read_l2mc;
+       hw_raw_read_mapping[0xa]  = csky_pmu_read_iutlbmc;
+       hw_raw_read_mapping[0xb]  = csky_pmu_read_dutlbmc;
+       hw_raw_read_mapping[0xc]  = csky_pmu_read_jtlbmc;
+       hw_raw_read_mapping[0xd]  = csky_pmu_read_softc;
+       hw_raw_read_mapping[0xe]  = csky_pmu_read_cbmc;
+       hw_raw_read_mapping[0xf]  = csky_pmu_read_cbic;
+       hw_raw_read_mapping[0x10] = csky_pmu_read_ibmc;
+       hw_raw_read_mapping[0x11] = csky_pmu_read_ibic;
+       hw_raw_read_mapping[0x12] = csky_pmu_read_lsfc;
+       hw_raw_read_mapping[0x13] = csky_pmu_read_sic;
+       hw_raw_read_mapping[0x14] = csky_pmu_read_dcrac;
+       hw_raw_read_mapping[0x15] = csky_pmu_read_dcrmc;
+       hw_raw_read_mapping[0x16] = csky_pmu_read_dcwac;
+       hw_raw_read_mapping[0x17] = csky_pmu_read_dcwmc;
+       hw_raw_read_mapping[0x18] = csky_pmu_read_l2rac;
+       hw_raw_read_mapping[0x19] = csky_pmu_read_l2rmc;
+       hw_raw_read_mapping[0x1a] = csky_pmu_read_l2wac;
+       hw_raw_read_mapping[0x1b] = csky_pmu_read_l2wmc;
+
+       memset((void *)hw_raw_write_mapping, 0,
+               sizeof(hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS]));
+
+       hw_raw_write_mapping[0x1]  = csky_pmu_write_cc;
+       hw_raw_write_mapping[0x2]  = csky_pmu_write_ic;
+       hw_raw_write_mapping[0x3]  = csky_pmu_write_icac;
+       hw_raw_write_mapping[0x4]  = csky_pmu_write_icmc;
+       hw_raw_write_mapping[0x5]  = csky_pmu_write_dcac;
+       hw_raw_write_mapping[0x6]  = csky_pmu_write_dcmc;
+       hw_raw_write_mapping[0x7]  = csky_pmu_write_l2ac;
+       hw_raw_write_mapping[0x8]  = csky_pmu_write_l2mc;
+       hw_raw_write_mapping[0xa]  = csky_pmu_write_iutlbmc;
+       hw_raw_write_mapping[0xb]  = csky_pmu_write_dutlbmc;
+       hw_raw_write_mapping[0xc]  = csky_pmu_write_jtlbmc;
+       hw_raw_write_mapping[0xd]  = csky_pmu_write_softc;
+       hw_raw_write_mapping[0xe]  = csky_pmu_write_cbmc;
+       hw_raw_write_mapping[0xf]  = csky_pmu_write_cbic;
+       hw_raw_write_mapping[0x10] = csky_pmu_write_ibmc;
+       hw_raw_write_mapping[0x11] = csky_pmu_write_ibic;
+       hw_raw_write_mapping[0x12] = csky_pmu_write_lsfc;
+       hw_raw_write_mapping[0x13] = csky_pmu_write_sic;
+       hw_raw_write_mapping[0x14] = csky_pmu_write_dcrac;
+       hw_raw_write_mapping[0x15] = csky_pmu_write_dcrmc;
+       hw_raw_write_mapping[0x16] = csky_pmu_write_dcwac;
+       hw_raw_write_mapping[0x17] = csky_pmu_write_dcwmc;
+       hw_raw_write_mapping[0x18] = csky_pmu_write_l2rac;
+       hw_raw_write_mapping[0x19] = csky_pmu_write_l2rmc;
+       hw_raw_write_mapping[0x1a] = csky_pmu_write_l2wac;
+       hw_raw_write_mapping[0x1b] = csky_pmu_write_l2wmc;
+
+       csky_pmu.pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+
+       cpwcr(HPCR, BIT(31) | BIT(30) | BIT(1));
+
+       return perf_pmu_register(&csky_pmu.pmu, "cpu", PERF_TYPE_RAW);
+}
+arch_initcall(init_hw_perf_events);
index 8ed20028b1609e129918c3415e884543affdc108..e555740c0be5768d001c81fe8ff91e98e71e0e4b 100644 (file)
@@ -93,26 +93,31 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs)
 
 unsigned long get_wchan(struct task_struct *p)
 {
-       unsigned long esp, pc;
-       unsigned long stack_page;
+       unsigned long lr;
+       unsigned long *fp, *stack_start, *stack_end;
        int count = 0;
 
        if (!p || p == current || p->state == TASK_RUNNING)
                return 0;
 
-       stack_page = (unsigned long)p;
-       esp = p->thread.esp0;
+       stack_start = (unsigned long *)end_of_stack(p);
+       stack_end = (unsigned long *)(task_stack_page(p) + THREAD_SIZE);
+
+       fp = (unsigned long *) thread_saved_fp(p);
        do {
-               if (esp < stack_page+sizeof(struct task_struct) ||
-                   esp >= 8184+stack_page)
+               if (fp < stack_start || fp > stack_end)
                        return 0;
-               /*FIXME: There's may be error here!*/
-               pc = ((unsigned long *)esp)[1];
-               /* FIXME: This depends on the order of these functions. */
-               if (!in_sched_functions(pc))
-                       return pc;
-               esp = *(unsigned long *) esp;
+#ifdef CONFIG_STACKTRACE
+               lr = fp[1];
+               fp = (unsigned long *)fp[0];
+#else
+               lr = *fp++;
+#endif
+               if (!in_sched_functions(lr) &&
+                   __kernel_text_address(lr))
+                       return lr;
        } while (count++ < 16);
+
        return 0;
 }
 EXPORT_SYMBOL(get_wchan);
index 34b30257298f80e2a2645ed12c94b9aca0b0350b..57f1afe19a52cb7896021a47691fc17c37d0b4bb 100644 (file)
@@ -50,15 +50,11 @@ static void singlestep_enable(struct task_struct *tsk)
  */
 void user_enable_single_step(struct task_struct *child)
 {
-       if (child->thread.esp0 == 0)
-               return;
        singlestep_enable(child);
 }
 
 void user_disable_single_step(struct task_struct *child)
 {
-       if (child->thread.esp0 == 0)
-               return;
        singlestep_disable(child);
 }
 
@@ -95,7 +91,9 @@ static int gpr_set(struct task_struct *target,
                return ret;
 
        regs.sr = task_pt_regs(target)->sr;
-
+#ifdef CONFIG_CPU_HAS_HILO
+       regs.dcsr = task_pt_regs(target)->dcsr;
+#endif
        task_thread_info(target)->tp_value = regs.tls;
 
        *task_pt_regs(target) = regs;
@@ -239,6 +237,7 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
        regs->regs[SYSTRACE_SAVENUM] = saved_why;
 }
 
+extern void show_stack(struct task_struct *task, unsigned long *stack);
 void show_regs(struct pt_regs *fp)
 {
        unsigned long   *sp;
@@ -261,35 +260,37 @@ void show_regs(struct pt_regs *fp)
                       (int) (((unsigned long) current) + 2 * PAGE_SIZE));
        }
 
-       pr_info("PC: 0x%08lx\n", (long)fp->pc);
+       pr_info("PC: 0x%08lx (%pS)\n", (long)fp->pc, (void *)fp->pc);
+       pr_info("LR: 0x%08lx (%pS)\n", (long)fp->lr, (void *)fp->lr);
+       pr_info("SP: 0x%08lx\n", (long)fp);
        pr_info("orig_a0: 0x%08lx\n", fp->orig_a0);
        pr_info("PSR: 0x%08lx\n", (long)fp->sr);
 
-       pr_info("a0: 0x%08lx  a1: 0x%08lx  a2: 0x%08lx  a3: 0x%08lx\n",
-              fp->a0, fp->a1, fp->a2, fp->a3);
+       pr_info(" a0: 0x%08lx   a1: 0x%08lx   a2: 0x%08lx   a3: 0x%08lx\n",
+               fp->a0, fp->a1, fp->a2, fp->a3);
 #if defined(__CSKYABIV2__)
-       pr_info("r4: 0x%08lx  r5: 0x%08lx    r6: 0x%08lx    r7: 0x%08lx\n",
+       pr_info(" r4: 0x%08lx   r5: 0x%08lx   r6: 0x%08lx   r7: 0x%08lx\n",
                fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]);
-       pr_info("r8: 0x%08lx  r9: 0x%08lx   r10: 0x%08lx   r11: 0x%08lx\n",
+       pr_info(" r8: 0x%08lx   r9: 0x%08lx  r10: 0x%08lx  r11: 0x%08lx\n",
                fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]);
-       pr_info("r12 0x%08lx  r13: 0x%08lx   r15: 0x%08lx\n",
+       pr_info("r12: 0x%08lx  r13: 0x%08lx  r15: 0x%08lx\n",
                fp->regs[8], fp->regs[9], fp->lr);
-       pr_info("r16:0x%08lx   r17: 0x%08lx   r18: 0x%08lx    r19: 0x%08lx\n",
+       pr_info("r16: 0x%08lx  r17: 0x%08lx  r18: 0x%08lx  r19: 0x%08lx\n",
                fp->exregs[0], fp->exregs[1], fp->exregs[2], fp->exregs[3]);
-       pr_info("r20 0x%08lx   r21: 0x%08lx   r22: 0x%08lx    r23: 0x%08lx\n",
+       pr_info("r20: 0x%08lx  r21: 0x%08lx  r22: 0x%08lx  r23: 0x%08lx\n",
                fp->exregs[4], fp->exregs[5], fp->exregs[6], fp->exregs[7]);
-       pr_info("r24 0x%08lx   r25: 0x%08lx   r26: 0x%08lx    r27: 0x%08lx\n",
+       pr_info("r24: 0x%08lx  r25: 0x%08lx  r26: 0x%08lx  r27: 0x%08lx\n",
                fp->exregs[8], fp->exregs[9], fp->exregs[10], fp->exregs[11]);
-       pr_info("r28 0x%08lx   r29: 0x%08lx   r30: 0x%08lx    tls: 0x%08lx\n",
+       pr_info("r28: 0x%08lx  r29: 0x%08lx  r30: 0x%08lx  tls: 0x%08lx\n",
                fp->exregs[12], fp->exregs[13], fp->exregs[14], fp->tls);
-       pr_info("hi 0x%08lx    lo: 0x%08lx\n",
+       pr_info(" hi: 0x%08lx   lo: 0x%08lx\n",
                fp->rhi, fp->rlo);
 #else
-       pr_info("r6: 0x%08lx   r7: 0x%08lx   r8: 0x%08lx   r9: 0x%08lx\n",
+       pr_info(" r6: 0x%08lx   r7: 0x%08lx   r8: 0x%08lx   r9: 0x%08lx\n",
                fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]);
-       pr_info("r10: 0x%08lx   r11: 0x%08lx   r12: 0x%08lx   r13: 0x%08lx\n",
+       pr_info("r10: 0x%08lx  r11: 0x%08lx  r12: 0x%08lx  r13: 0x%08lx\n",
                fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]);
-       pr_info("r14 0x%08lx   r1: 0x%08lx   r15: 0x%08lx\n",
+       pr_info("r14: 0x%08lx   r1: 0x%08lx  r15: 0x%08lx\n",
                fp->regs[8], fp->regs[9], fp->lr);
 #endif
 
@@ -311,4 +312,7 @@ void show_regs(struct pt_regs *fp)
                pr_cont("%08x ", (int) *sp++);
        }
        pr_cont("\n");
+
+       show_stack(NULL, (unsigned long *)fp->regs[4]);
+       return;
 }
index 9967c10eee2bff00f7bab79ef4ab3fd1b6023430..207a891479d26e63100ea88c7665a673a6574f62 100644 (file)
@@ -238,8 +238,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
        if (!user_mode(regs))
                return;
 
-       current->thread.esp0 = (unsigned long)regs;
-
        /*
         * If we were from a system call, check for system call restarting...
         */
index 36ebaf9834e1c4221747a24605ba5288b8ad815b..ddc4dd79f2826f837b3557a239043f7b0aa1c162 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of.h>
 #include <linux/sched/task_stack.h>
 #include <linux/sched/mm.h>
+#include <linux/sched/hotplug.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
 #include <asm/sections.h>
@@ -112,12 +113,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 {
 }
 
-static void __init enable_smp_ipi(void)
-{
-       enable_percpu_irq(ipi_irq, 0);
-}
-
 static int ipi_dummy_dev;
+
 void __init setup_smp_ipi(void)
 {
        int rc;
@@ -130,7 +127,7 @@ void __init setup_smp_ipi(void)
        if (rc)
                panic("%s IRQ request failed\n", __func__);
 
-       enable_smp_ipi();
+       enable_percpu_irq(ipi_irq, 0);
 }
 
 void __init setup_smp(void)
@@ -138,7 +135,7 @@ void __init setup_smp(void)
        struct device_node *node = NULL;
        int cpu;
 
-       while ((node = of_find_node_by_type(node, "cpu"))) {
+       for_each_of_cpu_node(node) {
                if (!of_device_is_available(node))
                        continue;
 
@@ -161,12 +158,10 @@ volatile unsigned int secondary_stack;
 
 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-       unsigned int tmp;
-
-       secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE;
+       unsigned long mask = 1 << cpu;
 
+       secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE - 8;
        secondary_hint = mfcr("cr31");
-
        secondary_ccr  = mfcr("cr18");
 
        /*
@@ -176,10 +171,13 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
         */
        mtcr("cr17", 0x22);
 
-       /* Enable cpu in SMP reset ctrl reg */
-       tmp = mfcr("cr<29, 0>");
-       tmp |= 1 << cpu;
-       mtcr("cr<29, 0>", tmp);
+       if (mask & mfcr("cr<29, 0>")) {
+               send_arch_ipi(cpumask_of(cpu));
+       } else {
+               /* Enable cpu in SMP reset ctrl reg */
+               mask |= mfcr("cr<29, 0>");
+               mtcr("cr<29, 0>", mask);
+       }
 
        /* Wait for the cpu online */
        while (!cpu_online(cpu));
@@ -219,7 +217,7 @@ void csky_start_secondary(void)
        init_fpu();
 #endif
 
-       enable_smp_ipi();
+       enable_percpu_irq(ipi_irq, 0);
 
        mmget(mm);
        mmgrab(mm);
@@ -235,3 +233,46 @@ void csky_start_secondary(void)
        preempt_disable();
        cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpu_disable(void)
+{
+       unsigned int cpu = smp_processor_id();
+
+       set_cpu_online(cpu, false);
+
+       irq_migrate_all_off_this_cpu();
+
+       clear_tasks_mm_cpumask(cpu);
+
+       return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       if (!cpu_wait_death(cpu, 5)) {
+               pr_crit("CPU%u: shutdown failed\n", cpu);
+               return;
+       }
+       pr_notice("CPU%u: shutdown\n", cpu);
+}
+
+void arch_cpu_idle_dead(void)
+{
+       idle_task_exit();
+
+       cpu_report_death();
+
+       while (!secondary_stack)
+               arch_cpu_idle();
+
+       local_irq_disable();
+
+       asm volatile(
+               "mov    sp, %0\n"
+               "mov    r8, %0\n"
+               "jmpi   csky_start_secondary"
+               :
+               : "r" (secondary_stack));
+}
+#endif
diff --git a/arch/csky/kernel/stacktrace.c b/arch/csky/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..fec777a
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/sched/debug.h>
+#include <linux/sched/task_stack.h>
+#include <linux/stacktrace.h>
+#include <linux/ftrace.h>
+
+void save_stack_trace(struct stack_trace *trace)
+{
+       save_stack_trace_tsk(current, trace);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+       unsigned long *fp, *stack_start, *stack_end;
+       unsigned long addr;
+       int skip = trace->skip;
+       int savesched;
+       int graph_idx = 0;
+
+       if (tsk == current) {
+               asm volatile("mov %0, r8\n":"=r"(fp));
+               savesched = 1;
+       } else {
+               fp = (unsigned long *)thread_saved_fp(tsk);
+               savesched = 0;
+       }
+
+       addr = (unsigned long) fp & THREAD_MASK;
+       stack_start = (unsigned long *) addr;
+       stack_end = (unsigned long *) (addr + THREAD_SIZE);
+
+       while (fp > stack_start && fp < stack_end) {
+               unsigned long lpp, fpp;
+
+               fpp = fp[0];
+               lpp = fp[1];
+               if (!__kernel_text_address(lpp))
+                       break;
+               else
+                       lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);
+
+               if (savesched || !in_sched_functions(lpp)) {
+                       if (skip) {
+                               skip--;
+                       } else {
+                               trace->entries[trace->nr_entries++] = lpp;
+                               if (trace->nr_entries >= trace->max_entries)
+                                       break;
+                       }
+               }
+               fp = (unsigned long *)fpp;
+       }
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
index a8368ed43517c3d403bcad793bb426fd59b9ac90..f487a9b996ae1e4e23b33d34db193dcbf2205279 100644 (file)
@@ -106,7 +106,6 @@ void buserr(struct pt_regs *regs)
        pr_err("User mode Bus Error\n");
        show_regs(regs);
 
-       current->thread.esp0 = (unsigned long) regs;
        force_sig_fault(SIGSEGV, 0, (void __user *)regs->pc, current);
 }
 
@@ -162,8 +161,3 @@ asmlinkage void trap_c(struct pt_regs *regs)
        }
        send_sig(sig, current, 0);
 }
-
-asmlinkage void set_esp0(unsigned long ssp)
-{
-       current->thread.esp0 = ssp;
-}
index 7df57f90b52ccc948acea7a7bdcc94e0d012329d..d6f4b66b93e21c8ede70e2cc4070861d6df7730d 100644 (file)
@@ -172,8 +172,6 @@ bad_area:
 bad_area_nosemaphore:
        /* User mode accesses just cause a SIGSEGV */
        if (user_mode(regs)) {
-               tsk->thread.address = address;
-               tsk->thread.error_code = write;
                force_sig_fault(SIGSEGV, si_code, (void __user *)address, current);
                return;
        }
@@ -188,8 +186,8 @@ no_context:
         * terminate things with extreme prejudice.
         */
        bust_spinlocks(1);
-       pr_alert("Unable to %s at vaddr: %08lx, epc: %08lx\n",
-                __func__, address, regs->pc);
+       pr_alert("Unable to handle kernel paging request at virtual "
+                "address 0x%08lx, pc: 0x%08lx\n", address, regs->pc);
        die_if_kernel("Oops", regs, write);
 
 out_of_memory:
@@ -207,6 +205,5 @@ do_sigbus:
        if (!user_mode(regs))
                goto no_context;
 
-       tsk->thread.address = address;
        force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, current);
 }
index 7ad3ff103f4a865ab48f533c1d721daef2d2ccf9..cb7c03e5cd218a4236d1cb686a2cc36f0e4f91ff 100644 (file)
@@ -30,7 +30,7 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
        vaddr = (unsigned long)area->addr;
 
        prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
-                       _PAGE_GLOBAL | _CACHE_UNCACHED);
+                       _PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
 
        if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
                free_vm_area(area);
index a5d0b2991f474bac3460ab59f7a2cfc655d95bd2..cd400d353d182b22a5b32300b4d8e3fc9f628bc7 100644 (file)
@@ -33,6 +33,7 @@ generic-y += mmu.h
 generic-y += mmu_context.h
 generic-y += module.h
 generic-y += parport.h
+generic-y += pci.h
 generic-y += percpu.h
 generic-y += pgalloc.h
 generic-y += preempt.h
diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h
deleted file mode 100644 (file)
index d4d345a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_H8300_PCI_H
-#define _ASM_H8300_PCI_H
-
-/*
- * asm-h8300/pci.h - H8/300 specific PCI declarations.
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- */
-
-#define pcibios_assign_all_busses()    0
-
-static inline void pcibios_penalize_isa_irq(int irq, int active)
-{
-       /* We don't do dynamic PCI IRQ allocation */
-}
-
-#endif /* _ASM_H8300_PCI_H */
index 2691a1857d203db2522ae178fe744225c71d2da9..bee97426238705e78fca708d3d0d0c4b965cdb60 100644 (file)
@@ -211,7 +211,7 @@ static inline long ffz(int x)
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        int r;
 
index eeebf862c46c6aa16a5a994686f80439b4db6c4b..d36183887b60aad389119068095d7c85179fcc6c 100644 (file)
@@ -59,8 +59,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_page((unsigned long) pgd);
 }
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-                                        unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
@@ -75,8 +74,7 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm,
 }
 
 /* _kernel variant gets to use a different allocator */
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        gfp_t flags =  GFP_KERNEL | __GFP_ZERO;
        return (pte_t *) __get_free_page(flags);
index ccd56f5df8cdd827703a7df7591076819230310f..8d7396bd1790319eb7fa9a10b671d2b922081b36 100644 (file)
@@ -31,7 +31,7 @@ config IA64
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_VIRT_CPU_ACCOUNTING
        select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
-       select ARCH_HAS_SYNC_DMA_FOR_CPU
+       select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB
        select VIRT_TO_BUS
        select ARCH_DISCARD_MEMBLOCK
        select GENERIC_IRQ_PROBE
index 56a774bf13fa73fe3b9523f1d1f25bd3237f0243..2f24ee6459d20ff49e07ebdb1aa5c137c85e1953 100644 (file)
@@ -388,8 +388,7 @@ ia64_fls (unsigned long x)
  * Find the last (most significant) bit set.  Returns 0 for x==0 and
  * bits are numbered from 1..32 (e.g., fls(9) == 4).
  */
-static inline int
-fls (int t)
+static inline int fls(unsigned int t)
 {
        unsigned long x = t & 0xffffffffu;
 
index 3ee5362f2661457d04059c1d4cc564d61391bd2c..c9e481023c25bd48857ad3ec9eaaf9e925fb8795 100644 (file)
@@ -83,7 +83,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
        pmd_val(*pmd_entry) = __pa(pte);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page;
        void *pg;
@@ -99,8 +99,7 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr)
        return page;
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long addr)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return quicklist_alloc(0, GFP_KERNEL, NULL);
 }
index 055382622f07c8d7706f7e244b341586ecec6d25..29d841525ca1fef5adf33247fa3e9ebebbda4fa0 100644 (file)
@@ -67,6 +67,7 @@ __ia64_sync_icache_dcache (pte_t pte)
        set_bit(PG_arch_1, &page->flags);       /* mark page as clean */
 }
 
+#ifdef CONFIG_SWIOTLB
 /*
  * Since DMA is i-cache coherent, any (complete) pages that were written via
  * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
@@ -81,6 +82,7 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
                set_bit(PG_arch_1, &pfn_to_page(pfn)->flags);
        } while (++pfn <= PHYS_PFN(paddr + size - 1));
 }
+#endif
 
 inline void
 ia64_set_rbs_bot (void)
index d979f38af751cfeaa8a83cfc7389b15088ef3e21..10133a968c8e150b10d6cd0a9e778701bbaff882 100644 (file)
@@ -502,7 +502,7 @@ static inline unsigned long __ffs(unsigned long x)
 /*
  *     fls: find last bit set.
  */
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        int cnt;
 
index 12fe700632f458ea632a18bb9cdccd6660efd241..4399d712f6db72e3f0194b690720a456c4c6a7fc 100644 (file)
@@ -12,8 +12,7 @@ extern inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 
 extern const char bad_pmd_string[];
 
-extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-       unsigned long address)
+extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        unsigned long page = __get_free_page(GFP_DMA);
 
@@ -32,8 +31,6 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
 #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)      ({ BUG(); ((pmd_t *)2); })
 
-#define pte_alloc_one_fast(mm, addr) pte_alloc_one(mm, addr)
-
 #define pmd_populate(mm, pmd, page) (pmd_val(*pmd) = \
        (unsigned long)(page_address(page)))
 
@@ -50,8 +47,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
 
 #define __pmd_free_tlb(tlb, pmd, address) do { } while (0)
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-       unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page = alloc_pages(GFP_DMA, 0);
        pte_t *pte;
index 7859a86319cf7ba52127c994fde1fa2514042be2..d04d9ba9b976744a379c03955d0534fbb21db0e4 100644 (file)
@@ -8,7 +8,7 @@
 extern pmd_t *get_pointer_table(void);
 extern int free_pointer_table(pmd_t *);
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -28,7 +28,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
        free_page((unsigned long) pte);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page;
        pte_t *pte;
index 11485d38de4e6ed569c71fcd155859160e1dbb9f..1456c5eecbd94054690299baca2d6428f268d0e2 100644 (file)
@@ -35,8 +35,7 @@ do {                                                  \
        tlb_remove_page((tlb), pte);                    \
 } while (0)
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        unsigned long page = __get_free_page(GFP_KERNEL);
 
@@ -47,8 +46,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        return (pte_t *) (page);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                       unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
         struct page *page = alloc_pages(GFP_KERNEL, 0);
 
index 7c89390c0c13dc8bfafd35c30bd9fd7372ffa385..f4cc9ffc449e10219831a60a841775a032e0b15b 100644 (file)
@@ -108,10 +108,9 @@ static inline void free_pgd_slow(pgd_t *pgd)
 #define pmd_alloc_one_fast(mm, address)        ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)     ({ BUG(); ((pmd_t *)2); })
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-               unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *ptepage;
 
@@ -132,20 +131,6 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm,
        return ptepage;
 }
 
-static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm,
-               unsigned long address)
-{
-       unsigned long *ret;
-
-       ret = pte_quicklist;
-       if (ret != NULL) {
-               pte_quicklist = (unsigned long *)(*ret);
-               ret[0] = 0;
-               pgtable_cache_size--;
-       }
-       return (pte_t *)ret;
-}
-
 static inline void pte_free_fast(pte_t *pte)
 {
        *(unsigned long **)pte = pte_quicklist;
index 7f525962cdfaa0951321bbdccfc4809a140cf6cf..c2ce1e42b8887178335c6ef52bcec08030aafbfc 100644 (file)
@@ -235,8 +235,7 @@ unsigned long iopa(unsigned long addr)
        return pa;
 }
 
-__ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-               unsigned long address)
+__ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
        if (mem_init_done) {
index f2a840fb6a9af6739a792359b3224f5b46d231f0..c4675957b21bca1e5be2cddd37f8af71a24eb6b9 100644 (file)
@@ -555,7 +555,7 @@ static inline unsigned long __ffs(unsigned long word)
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        int r;
 
index 39b9f311c4ef471a725fa0be8b0d3178ebd947ca..27808d9461f477a26d6007ba2ba72f7b2db047f1 100644 (file)
@@ -50,14 +50,12 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_pages((unsigned long)pgd, PGD_ORDER);
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-       unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return (pte_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, PTE_ORDER);
 }
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-       unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 27448869131afc7d7168d27f384f39b5a45624b6..3c5fee5b5759539d71dc8b731e448dd7843f6184 100644 (file)
@@ -22,8 +22,7 @@ extern void pgd_free(struct mm_struct *mm, pgd_t * pgd);
 
 #define check_pgt_cache()              do { } while (0)
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long addr)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -34,7 +33,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        return pte;
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        pgtable_t pte;
 
index bb47d08c8ef76f085676fe9ce7d26810a90fffa7..3a149ead1207167d419f69ad1ac26746e2d2bff2 100644 (file)
@@ -37,8 +37,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_pages((unsigned long)pgd, PGD_ORDER);
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-       unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -47,8 +46,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        return pte;
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-       unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 9efbf9ad86c409bb8a6671e4a49ea50e2ec35bde..57de5a1115bfd99ea57a208e50057af2afe0b924 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifdef CONFIG_OPENRISC_HAVE_INST_FL1
 
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        int ret;
 
index 8999b922651210f6c20c83e7aa72b3bccf6c3d58..149c82ee4b8b22320c315b22ad73f92e430285ab 100644 (file)
@@ -70,10 +70,9 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_page((unsigned long)pgd);
 }
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-                                        unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
        pte = alloc_pages(GFP_KERNEL, 0);
index c9697529b3f079c6ff4c5c84299f1f975d0b3d6d..270d1c9bc0d66966cc1aa64e7f63d0d67cfe5c8f 100644 (file)
@@ -118,8 +118,7 @@ EXPORT_SYMBOL(iounmap);
  * the memblock infrastructure.
  */
 
-pte_t __ref *pte_alloc_one_kernel(struct mm_struct *mm,
-                                        unsigned long address)
+pte_t __ref *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
index 53252d4f9a570c7a7ee889bbba7cb167d9bef2f9..a09eaebfdfd07f8caff2dbc2b77fa315770f10e0 100644 (file)
@@ -188,7 +188,7 @@ static __inline__ int ffs(int x)
  * fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 
-static __inline__ int fls(int x)
+static __inline__ int fls(unsigned int x)
 {
        int ret;
        if (!x)
index cf13275f7c6d8c58ec2bb252570e00566f8dc905..d05c678c77c43e65bb78565c74d304f1d8b4bd75 100644 (file)
@@ -122,7 +122,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page = alloc_page(GFP_KERNEL|__GFP_ZERO);
        if (!page)
@@ -135,7 +135,7 @@ pte_alloc_one(struct mm_struct *mm, unsigned long address)
 }
 
 static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
        return pte;
index b5b955eb2fb733685a5c9bef250be58e09bc9faa..3633502e102cec215ba926cd14b1e73b9dd19a97 100644 (file)
@@ -61,10 +61,10 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
 
 #define pmd_pgtable(pmd) ((pgtable_t)pmd_page_vaddr(pmd))
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
-extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
+extern pgtable_t pte_alloc_one(struct mm_struct *mm);
 void pte_frag_destroy(void *pte_frag);
-pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel);
+pte_t *pte_fragment_alloc(struct mm_struct *mm, int kernel);
 void pte_fragment_free(unsigned long *table, int kernel);
 
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
index 4aba625389c47aa2c26010f191304cb07f2ec862..9c1173283b96bfd1af86255e98ee7730dcc39f20 100644 (file)
@@ -39,7 +39,7 @@ extern struct vmemmap_backing *vmemmap_list;
 extern struct kmem_cache *pgtable_cache[];
 #define PGT_CACHE(shift) pgtable_cache[shift]
 
-extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int);
+extern pte_t *pte_fragment_alloc(struct mm_struct *, int);
 extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long);
 extern void pte_fragment_free(unsigned long *, int);
 extern void pmd_fragment_free(unsigned long *);
@@ -190,16 +190,14 @@ static inline pgtable_t pmd_pgtable(pmd_t pmd)
        return (pgtable_t)pmd_page_vaddr(pmd);
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
-       return (pte_t *)pte_fragment_alloc(mm, address, 1);
+       return (pte_t *)pte_fragment_alloc(mm, 1);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                     unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
-       return (pgtable_t)pte_fragment_alloc(mm, address, 0);
+       return (pgtable_t)pte_fragment_alloc(mm, 0);
 }
 
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
index 17963951bdb06570966cae406323f9cbf893551b..bd186e85b4f701cd01a57c22469d96193f9420c0 100644 (file)
@@ -79,10 +79,10 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
 #define pmd_pgtable(pmd) ((pgtable_t)pmd_page_vaddr(pmd))
 #endif
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
-extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
+extern pgtable_t pte_alloc_one(struct mm_struct *mm);
 void pte_frag_destroy(void *pte_frag);
-pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel);
+pte_t *pte_fragment_alloc(struct mm_struct *mm, int kernel);
 void pte_fragment_free(unsigned long *table, int kernel);
 
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
index e95eb499a1744b5b46ec5ac2d4dd0802b67ed173..66d086f85bd5b1a9b7f3071b111e3b819dd346ef 100644 (file)
@@ -93,14 +93,12 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 }
 
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                     unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page;
        pte_t *pte;
index af23a587f0193b054ba8f5b6ba8fdd67a09413bf..a7b05214760ce3c538f4f8621bbd2325199a1bc9 100644 (file)
@@ -95,7 +95,7 @@ static pte_t *__alloc_for_ptecache(struct mm_struct *mm, int kernel)
        return (pte_t *)ret;
 }
 
-pte_t *pte_fragment_alloc(struct mm_struct *mm, unsigned long vmaddr, int kernel)
+pte_t *pte_fragment_alloc(struct mm_struct *mm, int kernel)
 {
        pte_t *pte;
 
index d67215248d822677644a6a87a9dfb8d32a236188..ded71126ce4c6784d1e8aad82fd51081e88ec44c 100644 (file)
@@ -43,17 +43,17 @@ EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */
 
 extern char etext[], _stext[], _sinittext[], _einittext[];
 
-__ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+__ref pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        if (!slab_is_available())
                return memblock_alloc(PTE_FRAG_SIZE, PTE_FRAG_SIZE);
 
-       return (pte_t *)pte_fragment_alloc(mm, address, 1);
+       return (pte_t *)pte_fragment_alloc(mm, 1);
 }
 
-pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
-       return (pgtable_t)pte_fragment_alloc(mm, address, 0);
+       return (pgtable_t)pte_fragment_alloc(mm, 0);
 }
 
 void __iomem *
index a79ed5faff3aaaca774ee84ff657f87fd22e8897..94043cf83c90fe9e10844b0dfa89c997339a64d1 100644 (file)
@@ -82,15 +82,13 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 
 #endif /* __PAGETABLE_PMD_FOLDED */
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-       unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return (pte_t *)__get_free_page(
                GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_ZERO);
 }
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-       unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 86e5b2fdee3c8ee1b6da3f290de5be4b4460734c..d1f8a4d94cca02269841b6b6e0928ac699089b6b 100644 (file)
@@ -397,9 +397,9 @@ static inline int fls64(unsigned long word)
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static inline int fls(int word)
+static inline int fls(unsigned int word)
 {
-       return fls64((unsigned int)word);
+       return fls64(word);
 }
 
 #else /* CONFIG_HAVE_MARCH_Z9_109_FEATURES */
index 5ee733720a5716b2308210d497f9c8ab73485cfa..bccb8f4a63e204728b5c024f24b048a5c68e1f26 100644 (file)
@@ -139,8 +139,8 @@ static inline void pmd_populate(struct mm_struct *mm,
 /*
  * page table entry allocation/free routines.
  */
-#define pte_alloc_one_kernel(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
-#define pte_alloc_one(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
+#define pte_alloc_one_kernel(mm) ((pte_t *)page_table_alloc(mm))
+#define pte_alloc_one(mm) ((pte_t *)page_table_alloc(mm))
 
 #define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
 #define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
index ed053a359ab74684a17d51323f772b24b736234f..8ad73cb311216a0a8801ee3890ed27788a79ad61 100644 (file)
@@ -32,14 +32,12 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 /*
  * Allocate and free page tables.
  */
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                       unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page;
        void *pg;
index 90459481c6c7a8c4d2f98e0b59e841c364d3cbbb..282be50a4adfcf8fc7a6bdb231cef62dad9c7bb3 100644 (file)
@@ -58,10 +58,9 @@ void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep);
 void pmd_set(pmd_t *pmdp, pte_t *ptep);
 #define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE)
 
-pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
+pgtable_t pte_alloc_one(struct mm_struct *mm);
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 }
index 874632f34f624b8ff00e1fdde776ae72815c362e..48abccba49915f18dbdade44ccefb778a91404b9 100644 (file)
@@ -60,10 +60,8 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
        kmem_cache_free(pgtable_cache, pmd);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                           unsigned long address);
-pgtable_t pte_alloc_one(struct mm_struct *mm,
-                       unsigned long address);
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
+pgtable_t pte_alloc_one(struct mm_struct *mm);
 void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
 void pte_free(struct mm_struct *mm, pgtable_t ptepage);
 
index 3c8aac21f4260bd9227849a4fdc6f93820aa49e8..b4221d3727d0a5abe88eb631b39a3ef320877bfe 100644 (file)
@@ -2925,8 +2925,7 @@ void __flush_tlb_all(void)
                             : : "r" (pstate));
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                           unsigned long address)
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
        pte_t *pte = NULL;
@@ -2937,8 +2936,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        return pte;
 }
 
-pgtable_t pte_alloc_one(struct mm_struct *mm,
-                       unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
        if (!page)
index a6142c5abf6141e468331e64b85d6aee1a5a5d30..b609362e846fcce0ceceba0795598cad03358ec7 100644 (file)
@@ -364,12 +364,12 @@ pgd_t *get_pgd_fast(void)
  * Alignments up to the page size are the same for physical and virtual
  * addresses of the nocache area.
  */
-pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        unsigned long pte;
        struct page *page;
 
-       if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0)
+       if ((pte = (unsigned long)pte_alloc_one_kernel(mm)) == 0)
                return NULL;
        page = pfn_to_page(__nocache_pa(pte) >> PAGE_SHIFT);
        if (!pgtable_page_ctor(page)) {
index bf90b2aa20025456445ef4d008821ef43f4a7262..99eb5682792a30b948e02b1e0bf64b46789a613a 100644 (file)
@@ -25,8 +25,8 @@
 extern pgd_t *pgd_alloc(struct mm_struct *);
 extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
-extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *);
+extern pgtable_t pte_alloc_one(struct mm_struct *);
 
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
index 8d21a83dd28933721fa479711b112be745d27b7a..799b571a8f884b9356b3ea9f6c849c51337e3f0d 100644 (file)
@@ -199,7 +199,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_page((unsigned long) pgd);
 }
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -207,7 +207,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
        return pte;
 }
 
-pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index c0cbdbe1716809115431e0c999363e37f7156d65..de5853761c22ca0b6485f12a06c73f25bb320286 100644 (file)
@@ -22,7 +22,7 @@
  * the cntlz instruction for much better code efficiency.
  */
 
-static inline int fls(int x)
+static inline int fls(unsigned int x)
 {
        int ret;
 
index f0fdb268f8f2efd07de226976bc26d231b2145fa..7cceabecf4e37fcb08e0c725364c8f6b5e688674 100644 (file)
@@ -34,7 +34,7 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
  * Allocate one PTE table.
  */
 static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *pte;
 
@@ -46,7 +46,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 }
 
 static inline pgtable_t
-pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index e260460210e17a6009097542d15b8797e596b1d6..6185d4f332965e32b2229547c626269dd5bb9b16 100644 (file)
@@ -172,6 +172,7 @@ config X86
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MIXED_BREAKPOINTS_REGS
        select HAVE_MOD_ARCH_SPECIFIC
+       select HAVE_MOVE_PMD
        select HAVE_NMI
        select HAVE_OPROFILE
        select HAVE_OPTPROBES
index 124f9195eb3ef5545f96fbb111ee4a111de5f0d0..ad7b210aa3f621c5902f4f077eab0932b4924593 100644 (file)
@@ -448,7 +448,7 @@ static __always_inline int ffs(int x)
  * set bit if value is nonzero. The last (most significant) bit is
  * at position 32.
  */
-static __always_inline int fls(int x)
+static __always_inline int fls(unsigned int x)
 {
        int r;
 
index 832da8229cc78019d3a790346e764ca630b1c03e..686247db3106f2b01e058ff6ab3e7a20948b2ddf 100644 (file)
@@ -221,6 +221,14 @@ extern void set_iounmap_nonlazy(void);
 
 #ifdef __KERNEL__
 
+void memcpy_fromio(void *, const volatile void __iomem *, size_t);
+void memcpy_toio(volatile void __iomem *, const void *, size_t);
+void memset_io(volatile void __iomem *, int, size_t);
+
+#define memcpy_fromio memcpy_fromio
+#define memcpy_toio memcpy_toio
+#define memset_io memset_io
+
 #include <asm-generic/iomap.h>
 
 /*
index 1ea41aaef68bf4ecbfa808ebdd5dab34987f601f..a281e61ec60c55eda5c3ec4ec527863ec5994012 100644 (file)
@@ -47,8 +47,8 @@ extern gfp_t __userpte_alloc_gfp;
 extern pgd_t *pgd_alloc(struct mm_struct *);
 extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
-extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *);
+extern pgtable_t pte_alloc_one(struct mm_struct *);
 
 /* Should really implement gc for free page table pages. This could be
    done with a reference count in struct page. */
index 7ad41bfcc16cfa32cf2b59312ed2cec2a972c873..4e4194e21a097e1a9e052580a5d5e50db33cbbf0 100644 (file)
@@ -7,24 +7,6 @@
 
 /* Written 2002 by Andi Kleen */
 
-/* Only used for special circumstances. Stolen from i386/string.h */
-static __always_inline void *__inline_memcpy(void *to, const void *from, size_t n)
-{
-       unsigned long d0, d1, d2;
-       asm volatile("rep ; movsl\n\t"
-                    "testb $2,%b4\n\t"
-                    "je 1f\n\t"
-                    "movsw\n"
-                    "1:\ttestb $1,%b4\n\t"
-                    "je 2f\n\t"
-                    "movsb\n"
-                    "2:"
-                    : "=&c" (d0), "=&D" (d1), "=&S" (d2)
-                    : "0" (n / 4), "q" (n), "1" ((long)to), "2" ((long)from)
-                    : "memory");
-       return to;
-}
-
 /* Even with __builtin_ the compiler may decide to use the out of line
    function. */
 
index 3920f456db79a11f24ecf0f5f859ee4fc00ea258..a77445d1b0348675b5b750ad6acd617321b49b1b 100644 (file)
@@ -186,19 +186,14 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
 
 #ifdef CONFIG_X86_32
-#define __put_user_asm_u64(x, addr, err, errret)                       \
-       asm volatile("\n"                                               \
-                    "1:        movl %%eax,0(%2)\n"                     \
-                    "2:        movl %%edx,4(%2)\n"                     \
-                    "3:"                                               \
-                    ".section .fixup,\"ax\"\n"                         \
-                    "4:        movl %3,%0\n"                           \
-                    "  jmp 3b\n"                                       \
-                    ".previous\n"                                      \
-                    _ASM_EXTABLE_UA(1b, 4b)                            \
-                    _ASM_EXTABLE_UA(2b, 4b)                            \
-                    : "=r" (err)                                       \
-                    : "A" (x), "r" (addr), "i" (errret), "0" (err))
+#define __put_user_goto_u64(x, addr, label)                    \
+       asm_volatile_goto("\n"                                  \
+                    "1:        movl %%eax,0(%1)\n"             \
+                    "2:        movl %%edx,4(%1)\n"             \
+                    _ASM_EXTABLE_UA(1b, %l2)                   \
+                    _ASM_EXTABLE_UA(2b, %l2)                   \
+                    : : "A" (x), "r" (addr)                    \
+                    : : label)
 
 #define __put_user_asm_ex_u64(x, addr)                                 \
        asm volatile("\n"                                               \
@@ -213,8 +208,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
        asm volatile("call __put_user_8" : "=a" (__ret_pu)      \
                     : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
 #else
-#define __put_user_asm_u64(x, ptr, retval, errret) \
-       __put_user_asm(x, ptr, retval, "q", "", "er", errret)
+#define __put_user_goto_u64(x, ptr, label) \
+       __put_user_goto(x, ptr, "q", "", "er", label)
 #define __put_user_asm_ex_u64(x, addr) \
        __put_user_asm_ex(x, addr, "q", "", "er")
 #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu)
@@ -275,23 +270,21 @@ extern void __put_user_8(void);
        __builtin_expect(__ret_pu, 0);                          \
 })
 
-#define __put_user_size(x, ptr, size, retval, errret)                  \
+#define __put_user_size(x, ptr, size, label)                           \
 do {                                                                   \
-       retval = 0;                                                     \
        __chk_user_ptr(ptr);                                            \
        switch (size) {                                                 \
        case 1:                                                         \
-               __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \
+               __put_user_goto(x, ptr, "b", "b", "iq", label); \
                break;                                                  \
        case 2:                                                         \
-               __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \
+               __put_user_goto(x, ptr, "w", "w", "ir", label);         \
                break;                                                  \
        case 4:                                                         \
-               __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \
+               __put_user_goto(x, ptr, "l", "k", "ir", label);         \
                break;                                                  \
        case 8:                                                         \
-               __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval,  \
-                                  errret);                             \
+               __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \
                break;                                                  \
        default:                                                        \
                __put_user_bad();                                       \
@@ -436,9 +429,12 @@ do {                                                                       \
 
 #define __put_user_nocheck(x, ptr, size)                       \
 ({                                                             \
-       int __pu_err;                                           \
+       __label__ __pu_label;                                   \
+       int __pu_err = -EFAULT;                                 \
        __uaccess_begin();                                      \
-       __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
+       __put_user_size((x), (ptr), (size), __pu_label);        \
+       __pu_err = 0;                                           \
+__pu_label:                                                    \
        __uaccess_end();                                        \
        __builtin_expect(__pu_err, 0);                          \
 })
@@ -463,17 +459,23 @@ struct __large_struct { unsigned long buf[100]; };
  * we do not write to any memory gcc knows about, so there are no
  * aliasing issues.
  */
-#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
-       asm volatile("\n"                                               \
-                    "1:        mov"itype" %"rtype"1,%2\n"              \
-                    "2:\n"                                             \
-                    ".section .fixup,\"ax\"\n"                         \
-                    "3:        mov %3,%0\n"                            \
-                    "  jmp 2b\n"                                       \
-                    ".previous\n"                                      \
-                    _ASM_EXTABLE_UA(1b, 3b)                            \
-                    : "=r"(err)                                        \
-                    : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
+#define __put_user_goto(x, addr, itype, rtype, ltype, label)   \
+       asm_volatile_goto("\n"                                          \
+               "1:     mov"itype" %"rtype"0,%1\n"                      \
+               _ASM_EXTABLE_UA(1b, %l2)                                        \
+               : : ltype(x), "m" (__m(addr))                           \
+               : : label)
+
+#define __put_user_failed(x, addr, itype, rtype, ltype, errret)                \
+       ({      __label__ __puflab;                                     \
+               int __pufret = errret;                                  \
+               __put_user_goto(x,addr,itype,rtype,ltype,__puflab);     \
+               __pufret = 0;                                           \
+       __puflab: __pufret; })
+
+#define __put_user_asm(x, addr, retval, itype, rtype, ltype, errret)   do {    \
+       retval = __put_user_failed(x, addr, itype, rtype, ltype, errret);       \
+} while (0)
 
 #define __put_user_asm_ex(x, addr, itype, rtype, ltype)                        \
        asm volatile("1:        mov"itype" %"rtype"0,%1\n"              \
@@ -705,16 +707,18 @@ extern struct movsl_mask {
  * checking before using them, but you have to surround them with the
  * user_access_begin/end() pair.
  */
-#define user_access_begin()    __uaccess_begin()
+static __must_check inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+       if (unlikely(!access_ok(ptr,len)))
+               return 0;
+       __uaccess_begin();
+       return 1;
+}
+#define user_access_begin(a,b) user_access_begin(a,b)
 #define user_access_end()      __uaccess_end()
 
-#define unsafe_put_user(x, ptr, err_label)                                     \
-do {                                                                           \
-       int __pu_err;                                                           \
-       __typeof__(*(ptr)) __pu_val = (x);                                      \
-       __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);    \
-       if (unlikely(__pu_err)) goto err_label;                                 \
-} while (0)
+#define unsafe_put_user(x, ptr, label) \
+       __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
 
 #define unsafe_get_user(x, ptr, err_label)                                     \
 do {                                                                           \
index 25a972c61b0ae9816a817eb9681f4cd374e9e32a..ce28829f12811ff5a3b482ab3cd2867c57630719 100644 (file)
@@ -30,6 +30,7 @@ lib-$(CONFIG_FUNCTION_ERROR_INJECTION)        += error-inject.o
 lib-$(CONFIG_RETPOLINE) += retpoline.o
 
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
+obj-y += iomem.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/iomem.c b/arch/x86/lib/iomem.c
new file mode 100644 (file)
index 0000000..6689467
--- /dev/null
@@ -0,0 +1,42 @@
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+/* Originally from i386/string.h */
+static __always_inline void __iomem_memcpy(void *to, const void *from, size_t n)
+{
+       unsigned long d0, d1, d2;
+       asm volatile("rep ; movsl\n\t"
+                    "testb $2,%b4\n\t"
+                    "je 1f\n\t"
+                    "movsw\n"
+                    "1:\ttestb $1,%b4\n\t"
+                    "je 2f\n\t"
+                    "movsb\n"
+                    "2:"
+                    : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+                    : "0" (n / 4), "q" (n), "1" ((long)to), "2" ((long)from)
+                    : "memory");
+}
+
+void memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
+{
+       __iomem_memcpy(to, (const void *)from, n);
+}
+EXPORT_SYMBOL(memcpy_fromio);
+
+void memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
+{
+       __iomem_memcpy((void *)to, (const void *) from, n);
+}
+EXPORT_SYMBOL(memcpy_toio);
+
+void memset_io(volatile void __iomem *a, int b, size_t c)
+{
+       /*
+        * TODO: memset can mangle the IO patterns quite a bit.
+        * perhaps it would be better to use a dumb one:
+        */
+       memset((void *)a, b, c);
+}
+EXPORT_SYMBOL(memset_io);
index b0284eab14dc6c04f1b287f5089e61b2b3ca4143..7bd01709a0914abb16873c1b1e2eb73e6230ce24 100644 (file)
@@ -23,12 +23,12 @@ EXPORT_SYMBOL(physical_mask);
 
 gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP;
 
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        return (pte_t *)__get_free_page(PGALLOC_GFP & ~__GFP_ACCOUNT);
 }
 
-pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        struct page *pte;
 
index 1065bc8bcae56bba87f8d1a55b2c5155d489777d..b3b388ff2f01e4a3e8b48dd898cbf4001b49156e 100644 (file)
@@ -38,8 +38,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
        free_page((unsigned long)pgd);
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                        unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 {
        pte_t *ptep;
        int i;
@@ -52,13 +51,12 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        return ptep;
 }
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                       unsigned long addr)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
 {
        pte_t *pte;
        struct page *page;
 
-       pte = pte_alloc_one_kernel(mm, addr);
+       pte = pte_alloc_one_kernel(mm);
        if (!pte)
                return NULL;
        page = virt_to_page(pte);
index be6c1eb3cbe2042718dcf7a8649056f4d12f2e03..1c958eb33ef4d2ee3ae7d4dbed3d78368a7603b3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/clk/clk-conf.h>
 #include <linux/limits.h>
 #include <linux/property.h>
+#include <linux/kmemleak.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -524,6 +525,8 @@ struct platform_device *platform_device_register_full(
                if (!pdev->dev.dma_mask)
                        goto err;
 
+               kmemleak_ignore(pdev->dev.dma_mask);
+
                *pdev->dev.dma_mask = pdevinfo->dma_mask;
                pdev->dev.coherent_dma_mask = pdevinfo->dma_mask;
        }
index a8acc431a774c61cd526abe4c945acd2b7f301cb..183a9955160a80dd89bdc2d2c82cd358a487c6e9 100644 (file)
@@ -79,11 +79,11 @@ static int csky_mptimer_starting_cpu(unsigned int cpu)
 
        to->clkevt.cpumask = cpumask_of(cpu);
 
+       enable_percpu_irq(csky_mptimer_irq, 0);
+
        clockevents_config_and_register(&to->clkevt, timer_of_rate(to),
                                        2, ULONG_MAX);
 
-       enable_percpu_irq(csky_mptimer_irq, 0);
-
        return 0;
 }
 
@@ -97,7 +97,7 @@ static int csky_mptimer_dying_cpu(unsigned int cpu)
 /*
  * clock source
  */
-static u64 sched_clock_read(void)
+static u64 notrace sched_clock_read(void)
 {
        return (u64)mfcr(PTIM_CCVR);
 }
index fc359ca4503d127fda5f9f631f95d98c4a1d671a..cd57747286f286d44dcc57f1829bcee64214a9f2 100644 (file)
@@ -20,7 +20,7 @@ struct udmabuf {
        struct page **pages;
 };
 
-static int udmabuf_vm_fault(struct vm_fault *vmf)
+static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct udmabuf *ubuf = vma->vm_private_data;
index 1ea71640fdc21dd6b8b96c93d1383babc6e89a33..c64c7da738297453ee05f173c1a6c0d4c0fadbe9 100644 (file)
@@ -1009,7 +1009,6 @@ static struct platform_driver sdei_driver = {
 
 static bool __init sdei_present_dt(void)
 {
-       struct platform_device *pdev;
        struct device_node *np, *fw_np;
 
        fw_np = of_find_node_by_name(NULL, "firmware");
@@ -1017,14 +1016,9 @@ static bool __init sdei_present_dt(void)
                return false;
 
        np = of_find_matching_node(fw_np, sdei_of_match);
-       of_node_put(fw_np);
        if (!np)
                return false;
-
-       pdev = of_platform_device_create(np, sdei_driver.driver.name, NULL);
        of_node_put(np);
-       if (!pdev)
-               return false;
 
        return true;
 }
index d168c87c7d3085655d1fd627a6b65b792129cb03..ec4fd253a4e92aa0375d10d8fd70873ed54f9f26 100644 (file)
@@ -333,7 +333,7 @@ int __init firmware_map_add_early(u64 start, u64 end, const char *type)
 {
        struct firmware_map_entry *entry;
 
-       entry = memblock_alloc(sizeof(struct firmware_map_entry),
+       entry = memblock_alloc_nopanic(sizeof(struct firmware_map_entry),
                               SMP_CACHE_BYTES);
        if (WARN_ON(!entry))
                return -ENOMEM;
index 55d8f9b8777fc1156bc0136544f67c5d84e589fa..485b259127c36fdb4aeb619559e790f394ff412a 100644 (file)
@@ -1624,7 +1624,9 @@ end_user:
                 * happened we would make the mistake of assuming that the
                 * relocations were valid.
                 */
-               user_access_begin();
+               if (!user_access_begin(urelocs, size))
+                       goto end_user;
+
                for (copied = 0; copied < nreloc; copied++)
                        unsafe_put_user(-1,
                                        &urelocs[copied].presumed_offset,
@@ -2606,7 +2608,16 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
                unsigned int i;
 
                /* Copy the new buffer offsets back to the user's exec list. */
-               user_access_begin();
+               /*
+                * Note: count * sizeof(*user_exec_list) does not overflow,
+                * because we checked 'count' in check_buffer_count().
+                *
+                * And this range already got effectively checked earlier
+                * when we did the "copy_from_user()" above.
+                */
+               if (!user_access_begin(user_exec_list, count * sizeof(*user_exec_list)))
+                       goto end_user;
+
                for (i = 0; i < args->buffer_count; i++) {
                        if (!(exec2_list[i].offset & UPDATE))
                                continue;
index 63389f075f1dcab5637f4a72bc1081303fc86075..2d91b00e3591e78f6616faa4b0ce95ebffafbb24 100644 (file)
@@ -145,6 +145,15 @@ config DA8XX_DDRCTL
          Texas Instruments da8xx SoCs. It's used to tweak various memory
          controller configuration options.
 
+config PL353_SMC
+       tristate "ARM PL35X Static Memory Controller(SMC) driver"
+       default y
+       depends on ARM
+       depends on ARM_AMBA
+       help
+         This driver is for the ARM PL351/PL353 Static Memory
+         Controller(SMC) module.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
index a01ab3e22f94db6dc81c7032b06adab9ec4bc48e..90161dec6fa50cf591dc06e800ae9f2d4d8367e6 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_MVEBU_DEVBUS)    += mvebu-devbus.o
 obj-$(CONFIG_JZ4780_NEMC)      += jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)          += mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL)     += da8xx-ddrctl.o
+obj-$(CONFIG_PL353_SMC)                += pl353-smc.o
 
 obj-$(CONFIG_SAMSUNG_MC)       += samsung/
 obj-$(CONFIG_TEGRA_MC)         += tegra/
diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c
new file mode 100644 (file)
index 0000000..73bd302
--- /dev/null
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM PL353 SMC driver
+ *
+ * Copyright (C) 2012 - 2018 Xilinx, Inc
+ * Author: Punnaiah Choudary Kalluri <punnaiah@xilinx.com>
+ * Author: Naga Sureshkumar Relli <nagasure@xilinx.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pl353-smc.h>
+#include <linux/amba/bus.h>
+
+/* Register definitions */
+#define PL353_SMC_MEMC_STATUS_OFFS     0       /* Controller status reg, RO */
+#define PL353_SMC_CFG_CLR_OFFS         0xC     /* Clear config reg, WO */
+#define PL353_SMC_DIRECT_CMD_OFFS      0x10    /* Direct command reg, WO */
+#define PL353_SMC_SET_CYCLES_OFFS      0x14    /* Set cycles register, WO */
+#define PL353_SMC_SET_OPMODE_OFFS      0x18    /* Set opmode register, WO */
+#define PL353_SMC_ECC_STATUS_OFFS      0x400   /* ECC status register */
+#define PL353_SMC_ECC_MEMCFG_OFFS      0x404   /* ECC mem config reg */
+#define PL353_SMC_ECC_MEMCMD1_OFFS     0x408   /* ECC mem cmd1 reg */
+#define PL353_SMC_ECC_MEMCMD2_OFFS     0x40C   /* ECC mem cmd2 reg */
+#define PL353_SMC_ECC_VALUE0_OFFS      0x418   /* ECC value 0 reg */
+
+/* Controller status register specific constants */
+#define PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT  6
+
+/* Clear configuration register specific constants */
+#define PL353_SMC_CFG_CLR_INT_CLR_1    0x10
+#define PL353_SMC_CFG_CLR_ECC_INT_DIS_1        0x40
+#define PL353_SMC_CFG_CLR_INT_DIS_1    0x2
+#define PL353_SMC_CFG_CLR_DEFAULT_MASK (PL353_SMC_CFG_CLR_INT_CLR_1 | \
+                                        PL353_SMC_CFG_CLR_ECC_INT_DIS_1 | \
+                                        PL353_SMC_CFG_CLR_INT_DIS_1)
+
+/* Set cycles register specific constants */
+#define PL353_SMC_SET_CYCLES_T0_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T0_SHIFT  0
+#define PL353_SMC_SET_CYCLES_T1_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T1_SHIFT  4
+#define PL353_SMC_SET_CYCLES_T2_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T2_SHIFT  8
+#define PL353_SMC_SET_CYCLES_T3_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T3_SHIFT  11
+#define PL353_SMC_SET_CYCLES_T4_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T4_SHIFT  14
+#define PL353_SMC_SET_CYCLES_T5_MASK   0x7
+#define PL353_SMC_SET_CYCLES_T5_SHIFT  17
+#define PL353_SMC_SET_CYCLES_T6_MASK   0xF
+#define PL353_SMC_SET_CYCLES_T6_SHIFT  20
+
+/* ECC status register specific constants */
+#define PL353_SMC_ECC_STATUS_BUSY      BIT(6)
+#define PL353_SMC_ECC_REG_SIZE_OFFS    4
+
+/* ECC memory config register specific constants */
+#define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC
+#define PL353_SMC_ECC_MEMCFG_MODE_SHIFT        2
+#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK       0xC
+
+#define PL353_SMC_DC_UPT_NAND_REGS     ((4 << 23) |    /* CS: NAND chip */ \
+                                (2 << 21))     /* UpdateRegs operation */
+
+#define PL353_NAND_ECC_CMD1    ((0x80)       | /* Write command */ \
+                                (0 << 8)     | /* Read command */ \
+                                (0x30 << 16) | /* Read End command */ \
+                                (1 << 24))     /* Read End command calid */
+
+#define PL353_NAND_ECC_CMD2    ((0x85)       | /* Write col change cmd */ \
+                                (5 << 8)     | /* Read col change cmd */ \
+                                (0xE0 << 16) | /* Read col change end cmd */ \
+                                (1 << 24)) /* Read col change end cmd valid */
+#define PL353_NAND_ECC_BUSY_TIMEOUT    (1 * HZ)
+/**
+ * struct pl353_smc_data - Private smc driver structure
+ * @memclk:            Pointer to the peripheral clock
+ * @aclk:              Pointer to the APER clock
+ */
+struct pl353_smc_data {
+       struct clk              *memclk;
+       struct clk              *aclk;
+};
+
+/* SMC virtual register base */
+static void __iomem *pl353_smc_base;
+
+/**
+ * pl353_smc_set_buswidth - Set memory buswidth
+ * @bw: Memory buswidth (8 | 16)
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_buswidth(unsigned int bw)
+{
+       if (bw != PL353_SMC_MEM_WIDTH_8  && bw != PL353_SMC_MEM_WIDTH_16)
+               return -EINVAL;
+
+       writel(bw, pl353_smc_base + PL353_SMC_SET_OPMODE_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_buswidth);
+
+/**
+ * pl353_smc_set_cycles - Set memory timing parameters
+ * @timings: NAND controller timing parameters
+ *
+ * Sets NAND chip specific timing parameters.
+ */
+void pl353_smc_set_cycles(u32 timings[])
+{
+       /*
+        * Set write pulse timing. This one is easy to extract:
+        *
+        * NWE_PULSE = tWP
+        */
+       timings[0] &= PL353_SMC_SET_CYCLES_T0_MASK;
+       timings[1] = (timings[1] & PL353_SMC_SET_CYCLES_T1_MASK) <<
+                       PL353_SMC_SET_CYCLES_T1_SHIFT;
+       timings[2] = (timings[2]  & PL353_SMC_SET_CYCLES_T2_MASK) <<
+                       PL353_SMC_SET_CYCLES_T2_SHIFT;
+       timings[3] = (timings[3]  & PL353_SMC_SET_CYCLES_T3_MASK) <<
+                       PL353_SMC_SET_CYCLES_T3_SHIFT;
+       timings[4] = (timings[4] & PL353_SMC_SET_CYCLES_T4_MASK) <<
+                       PL353_SMC_SET_CYCLES_T4_SHIFT;
+       timings[5]  = (timings[5]  & PL353_SMC_SET_CYCLES_T5_MASK) <<
+                       PL353_SMC_SET_CYCLES_T5_SHIFT;
+       timings[6]  = (timings[6]  & PL353_SMC_SET_CYCLES_T6_MASK) <<
+                       PL353_SMC_SET_CYCLES_T6_SHIFT;
+       timings[0] |= timings[1] | timings[2] | timings[3] |
+                       timings[4] | timings[5] | timings[6];
+
+       writel(timings[0], pl353_smc_base + PL353_SMC_SET_CYCLES_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_cycles);
+
+/**
+ * pl353_smc_ecc_is_busy - Read ecc busy flag
+ * Return: the ecc_status bit from the ecc_status register. 1 = busy, 0 = idle
+ */
+bool pl353_smc_ecc_is_busy(void)
+{
+       return ((readl(pl353_smc_base + PL353_SMC_ECC_STATUS_OFFS) &
+                 PL353_SMC_ECC_STATUS_BUSY) == PL353_SMC_ECC_STATUS_BUSY);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_ecc_is_busy);
+
+/**
+ * pl353_smc_get_ecc_val - Read ecc_valueN registers
+ * @ecc_reg: Index of the ecc_value reg (0..3)
+ * Return: the content of the requested ecc_value register.
+ *
+ * There are four valid ecc_value registers. The argument is truncated to stay
+ * within this valid boundary.
+ */
+u32 pl353_smc_get_ecc_val(int ecc_reg)
+{
+       u32 addr, reg;
+
+       addr = PL353_SMC_ECC_VALUE0_OFFS +
+               (ecc_reg * PL353_SMC_ECC_REG_SIZE_OFFS);
+       reg = readl(pl353_smc_base + addr);
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_get_ecc_val);
+
+/**
+ * pl353_smc_get_nand_int_status_raw - Get NAND interrupt status bit
+ * Return: the raw_int_status1 bit from the memc_status register
+ */
+int pl353_smc_get_nand_int_status_raw(void)
+{
+       u32 reg;
+
+       reg = readl(pl353_smc_base + PL353_SMC_MEMC_STATUS_OFFS);
+       reg >>= PL353_SMC_MEMC_STATUS_RAW_INT_1_SHIFT;
+       reg &= 1;
+
+       return reg;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_get_nand_int_status_raw);
+
+/**
+ * pl353_smc_clr_nand_int - Clear NAND interrupt
+ */
+void pl353_smc_clr_nand_int(void)
+{
+       writel(PL353_SMC_CFG_CLR_INT_CLR_1,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+}
+EXPORT_SYMBOL_GPL(pl353_smc_clr_nand_int);
+
+/**
+ * pl353_smc_set_ecc_mode - Set SMC ECC mode
+ * @mode: ECC mode (BYPASS, APB, MEM)
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode)
+{
+       u32 reg;
+       int ret = 0;
+
+       switch (mode) {
+       case PL353_SMC_ECCMODE_BYPASS:
+       case PL353_SMC_ECCMODE_APB:
+       case PL353_SMC_ECCMODE_MEM:
+
+               reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+               reg &= ~PL353_SMC_ECC_MEMCFG_MODE_MASK;
+               reg |= mode << PL353_SMC_ECC_MEMCFG_MODE_SHIFT;
+               writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_mode);
+
+/**
+ * pl353_smc_set_ecc_pg_size - Set SMC ECC page size
+ * @pg_sz: ECC page size
+ * Return: 0 on success or negative errno.
+ */
+int pl353_smc_set_ecc_pg_size(unsigned int pg_sz)
+{
+       u32 reg, sz;
+
+       switch (pg_sz) {
+       case 0:
+               sz = 0;
+               break;
+       case SZ_512:
+               sz = 1;
+               break;
+       case SZ_1K:
+               sz = 2;
+               break;
+       case SZ_2K:
+               sz = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       reg = readl(pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+       reg &= ~PL353_SMC_ECC_MEMCFG_PGSIZE_MASK;
+       reg |= sz;
+       writel(reg, pl353_smc_base + PL353_SMC_ECC_MEMCFG_OFFS);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pl353_smc_set_ecc_pg_size);
+
+static int __maybe_unused pl353_smc_suspend(struct device *dev)
+{
+       struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
+
+       clk_disable(pl353_smc->memclk);
+       clk_disable(pl353_smc->aclk);
+
+       return 0;
+}
+
+static int __maybe_unused pl353_smc_resume(struct device *dev)
+{
+       int ret;
+       struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);
+
+       ret = clk_enable(pl353_smc->aclk);
+       if (ret) {
+               dev_err(dev, "Cannot enable axi domain clock.\n");
+               return ret;
+       }
+
+       ret = clk_enable(pl353_smc->memclk);
+       if (ret) {
+               dev_err(dev, "Cannot enable memory clock.\n");
+               clk_disable(pl353_smc->aclk);
+               return ret;
+       }
+
+       return ret;
+}
+
+static struct amba_driver pl353_smc_driver;
+
+static SIMPLE_DEV_PM_OPS(pl353_smc_dev_pm_ops, pl353_smc_suspend,
+                        pl353_smc_resume);
+
+/**
+ * pl353_smc_init_nand_interface - Initialize the NAND interface
+ * @adev: Pointer to the amba_device struct
+ * @nand_node: Pointer to the pl353_nand device_node struct
+ */
+static void pl353_smc_init_nand_interface(struct amba_device *adev,
+                                         struct device_node *nand_node)
+{
+       unsigned long timeout;
+
+       pl353_smc_set_buswidth(PL353_SMC_MEM_WIDTH_8);
+       writel(PL353_SMC_CFG_CLR_INT_CLR_1,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+       writel(PL353_SMC_DC_UPT_NAND_REGS, pl353_smc_base +
+              PL353_SMC_DIRECT_CMD_OFFS);
+
+       timeout = jiffies + PL353_NAND_ECC_BUSY_TIMEOUT;
+       /* Wait till the ECC operation is complete */
+       do {
+               if (pl353_smc_ecc_is_busy())
+                       cpu_relax();
+               else
+                       break;
+       } while (!time_after_eq(jiffies, timeout));
+
+       if (time_after_eq(jiffies, timeout))
+               return;
+
+       writel(PL353_NAND_ECC_CMD1,
+              pl353_smc_base + PL353_SMC_ECC_MEMCMD1_OFFS);
+       writel(PL353_NAND_ECC_CMD2,
+              pl353_smc_base + PL353_SMC_ECC_MEMCMD2_OFFS);
+}
+
+static const struct of_device_id pl353_smc_supported_children[] = {
+       {
+               .compatible = "cfi-flash"
+       },
+       {
+               .compatible = "arm,pl353-nand-r2p1",
+               .data = pl353_smc_init_nand_interface
+       },
+       {}
+};
+
+static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
+{
+       struct pl353_smc_data *pl353_smc;
+       struct device_node *child;
+       struct resource *res;
+       int err;
+       struct device_node *of_node = adev->dev.of_node;
+       static void (*init)(struct amba_device *adev,
+                           struct device_node *nand_node);
+       const struct of_device_id *match = NULL;
+
+       pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL);
+       if (!pl353_smc)
+               return -ENOMEM;
+
+       /* Get the NAND controller virtual address */
+       res = &adev->res;
+       pl353_smc_base = devm_ioremap_resource(&adev->dev, res);
+       if (IS_ERR(pl353_smc_base))
+               return PTR_ERR(pl353_smc_base);
+
+       pl353_smc->aclk = devm_clk_get(&adev->dev, "apb_pclk");
+       if (IS_ERR(pl353_smc->aclk)) {
+               dev_err(&adev->dev, "aclk clock not found.\n");
+               return PTR_ERR(pl353_smc->aclk);
+       }
+
+       pl353_smc->memclk = devm_clk_get(&adev->dev, "memclk");
+       if (IS_ERR(pl353_smc->memclk)) {
+               dev_err(&adev->dev, "memclk clock not found.\n");
+               return PTR_ERR(pl353_smc->memclk);
+       }
+
+       err = clk_prepare_enable(pl353_smc->aclk);
+       if (err) {
+               dev_err(&adev->dev, "Unable to enable AXI clock.\n");
+               return err;
+       }
+
+       err = clk_prepare_enable(pl353_smc->memclk);
+       if (err) {
+               dev_err(&adev->dev, "Unable to enable memory clock.\n");
+               goto out_clk_dis_aper;
+       }
+
+       amba_set_drvdata(adev, pl353_smc);
+
+       /* clear interrupts */
+       writel(PL353_SMC_CFG_CLR_DEFAULT_MASK,
+              pl353_smc_base + PL353_SMC_CFG_CLR_OFFS);
+
+       /* Find compatible children. Only a single child is supported */
+       for_each_available_child_of_node(of_node, child) {
+               match = of_match_node(pl353_smc_supported_children, child);
+               if (!match) {
+                       dev_warn(&adev->dev, "unsupported child node\n");
+                       continue;
+               }
+               break;
+       }
+       if (!match) {
+               dev_err(&adev->dev, "no matching children\n");
+               goto out_clk_disable;
+       }
+
+       init = match->data;
+       if (init)
+               init(adev, child);
+       of_platform_device_create(child, NULL, &adev->dev);
+
+       return 0;
+
+out_clk_disable:
+       clk_disable_unprepare(pl353_smc->memclk);
+out_clk_dis_aper:
+       clk_disable_unprepare(pl353_smc->aclk);
+
+       return err;
+}
+
+static int pl353_smc_remove(struct amba_device *adev)
+{
+       struct pl353_smc_data *pl353_smc = amba_get_drvdata(adev);
+
+       clk_disable_unprepare(pl353_smc->memclk);
+       clk_disable_unprepare(pl353_smc->aclk);
+
+       return 0;
+}
+
+static const struct amba_id pl353_ids[] = {
+       {
+       .id = 0x00041353,
+       .mask = 0x000fffff,
+       },
+       { 0, 0 },
+};
+MODULE_DEVICE_TABLE(amba, pl353_ids);
+
+static struct amba_driver pl353_smc_driver = {
+       .drv = {
+               .owner = THIS_MODULE,
+               .name = "pl353-smc",
+               .pm = &pl353_smc_dev_pm_ops,
+       },
+       .id_table = pl353_ids,
+       .probe = pl353_smc_probe,
+       .remove = pl353_smc_remove,
+};
+
+module_amba_driver(pl353_smc_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("ARM PL353 SMC Driver");
+MODULE_LICENSE("GPL");
index c9bdbb463a7ee36b8115820a7e5b2db83f82c98d..fab92ba8e56622360bb718cdd48f18831475856f 100644 (file)
@@ -64,6 +64,9 @@ config CARDBUS
 
          If unsure, say Y.
 
+config PCMCIA_MAX1600
+       tristate
+
 comment "PC-card bridges"
 
 config YENTA
@@ -192,6 +195,8 @@ config PCMCIA_SA1111
        select PCMCIA_SOC_COMMON
        select PCMCIA_SA11XX_BASE if ARCH_SA1100
        select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
+       select PCMCIA_MAX1600 if ASSABET_NEPONSET
+       select PCMCIA_MAX1600 if ARCH_LUBBOCK && SA1111
        help
          Say Y  here to include support for SA1111-based PCMCIA or CF
          sockets, found on the Jornada 720, Graphicsmaster and other
@@ -208,6 +213,7 @@ config PCMCIA_PXA2XX
                    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
                    || MACH_COLIBRI320 || MACH_H4700)
        select PCMCIA_SOC_COMMON
+       select PCMCIA_MAX1600 if MACH_MAINSTONE
        help
          Say Y here to include support for the PXA2xx PCMCIA controller
 
index 28502bd159e07bca8ea8f215008808ab2a709753..01779c5c45f35dfd056e872d9101d13f4c3e9561 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_OMAP_CF)                         += omap_cf.o
 obj-$(CONFIG_AT91_CF)                          += at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)                       += electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)          += db1xxx_ss.o
+obj-$(CONFIG_PCMCIA_MAX1600)                   += max1600.o
 
 sa1111_cs-y                                    += sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)           += sa1111_neponset.o
diff --git a/drivers/pcmcia/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644 (file)
index 0000000..379875a
--- /dev/null
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MAX1600 PCMCIA power switch library
+ *
+ * Copyright (C) 2016 Russell King
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include "max1600.h"
+
+static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
+       { "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
+       { "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+       unsigned int channel, unsigned int code)
+{
+       struct max1600 *m;
+       int chan;
+       int i;
+
+       switch (channel) {
+       case MAX1600_CHAN_A:
+               chan = 0;
+               break;
+       case MAX1600_CHAN_B:
+               chan = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
+               return -EINVAL;
+
+       m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
+       if (!m)
+               return -ENOMEM;
+
+       m->dev = dev;
+       m->code = code;
+
+       for (i = 0; i < MAX1600_GPIO_MAX; i++) {
+               const char *name;
+
+               name = max1600_gpio_name[chan][i];
+               if (i != MAX1600_GPIO_0VPP) {
+                       m->gpio[i] = devm_gpiod_get(dev, name, GPIOD_OUT_LOW);
+               } else {
+                       m->gpio[i] = devm_gpiod_get_optional(dev, name,
+                                                            GPIOD_OUT_LOW);
+                       if (!m->gpio[i])
+                               break;
+               }
+               if (IS_ERR(m->gpio[i]))
+                       return PTR_ERR(m->gpio[i]);
+       }
+
+       *ptr = m;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_init);
+
+int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
+{
+       DECLARE_BITMAP(values, MAX1600_GPIO_MAX) = { 0, };
+       int n = MAX1600_GPIO_0VPP;
+
+       if (m->gpio[MAX1600_GPIO_0VPP]) {
+               if (vpp == 0) {
+                       __assign_bit(MAX1600_GPIO_0VPP, values, 0);
+                       __assign_bit(MAX1600_GPIO_1VPP, values, 0);
+               } else if (vpp == 120) {
+                       __assign_bit(MAX1600_GPIO_0VPP, values, 0);
+                       __assign_bit(MAX1600_GPIO_1VPP, values, 1);
+               } else if (vpp == vcc) {
+                       __assign_bit(MAX1600_GPIO_0VPP, values, 1);
+                       __assign_bit(MAX1600_GPIO_1VPP, values, 0);
+               } else {
+                       dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
+                               vpp / 10, vpp % 10);
+                       return -EINVAL;
+               }
+               n = MAX1600_GPIO_MAX;
+       } else if (vpp != vcc && vpp != 0) {
+               dev_err(m->dev, "no VPP control\n");
+               return -EINVAL;
+       }
+
+       if (vcc == 0) {
+               __assign_bit(MAX1600_GPIO_0VCC, values, 0);
+               __assign_bit(MAX1600_GPIO_1VCC, values, 0);
+       } else if (vcc == 33) { /* VY */
+               __assign_bit(MAX1600_GPIO_0VCC, values, 1);
+               __assign_bit(MAX1600_GPIO_1VCC, values, 0);
+       } else if (vcc == 50) { /* VX */
+               __assign_bit(MAX1600_GPIO_0VCC, values, 0);
+               __assign_bit(MAX1600_GPIO_1VCC, values, 1);
+       } else {
+               dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
+                       vcc / 10, vcc % 10);
+               return -EINVAL;
+       }
+
+       if (m->code == MAX1600_CODE_HIGH) {
+               /*
+                * Cirrus mode appears to be the same as Intel mode,
+                * except the VCC pins are inverted.
+                */
+               __change_bit(MAX1600_GPIO_0VCC, values);
+               __change_bit(MAX1600_GPIO_1VCC, values);
+       }
+
+       return gpiod_set_array_value_cansleep(n, m->gpio, NULL, values);
+}
+EXPORT_SYMBOL_GPL(max1600_configure);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pcmcia/max1600.h b/drivers/pcmcia/max1600.h
new file mode 100644 (file)
index 0000000..00bf1a0
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef MAX1600_H
+#define MAX1600_H
+
+struct gpio_desc;
+
+enum {
+       MAX1600_GPIO_0VCC = 0,
+       MAX1600_GPIO_1VCC,
+       MAX1600_GPIO_0VPP,
+       MAX1600_GPIO_1VPP,
+       MAX1600_GPIO_MAX,
+
+       MAX1600_CHAN_A,
+       MAX1600_CHAN_B,
+
+       MAX1600_CODE_LOW,
+       MAX1600_CODE_HIGH,
+};
+
+struct max1600 {
+       struct gpio_desc *gpio[MAX1600_GPIO_MAX];
+       struct device *dev;
+       unsigned int code;
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+       unsigned int channel, unsigned int code);
+
+int max1600_configure(struct max1600 *, unsigned int vcc, unsigned int vpp);
+
+#endif
index 7e32e25cdcb29d20965d2e7843bf0a8d3b8bf8a2..770c7bf0171dfd0fea504f3b3f2203b58af7b7c9 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
 #include <pcmcia/ss.h>
 
 #include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <mach/pxa2xx-regs.h>
-#include <mach/mainstone.h>
 
 #include "soc_common.h"
-
+#include "max1600.h"
 
 static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       /*
-        * Setup default state of GPIO outputs
-        * before we enable them as outputs.
-        */
-       if (skt->nr == 0) {
-               skt->socket.pci_irq = MAINSTONE_S0_IRQ;
-               skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
-               skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
-               skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
-               skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
-       } else {
-               skt->socket.pci_irq = MAINSTONE_S1_IRQ;
-               skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
-               skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
-               skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
-               skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
-       }
-       return 0;
+       struct device *dev = skt->socket.dev.parent;
+       struct max1600 *m;
+       int ret;
+
+       skt->stat[SOC_STAT_CD].name = skt->nr ? "bdetect" : "adetect";
+       skt->stat[SOC_STAT_BVD1].name = skt->nr ? "bbvd1" : "abvd1";
+       skt->stat[SOC_STAT_BVD2].name = skt->nr ? "bbvd2" : "abvd2";
+       skt->stat[SOC_STAT_RDY].name = skt->nr ? "bready" : "aready";
+       skt->stat[SOC_STAT_VS1].name = skt->nr ? "bvs1" : "avs1";
+       skt->stat[SOC_STAT_VS2].name = skt->nr ? "bvs2" : "avs2";
+
+       skt->gpio_reset = devm_gpiod_get(dev, skt->nr ? "breset" : "areset",
+                                        GPIOD_OUT_HIGH);
+       if (IS_ERR(skt->gpio_reset))
+               return PTR_ERR(skt->gpio_reset);
+
+       ret = max1600_init(dev, &m, skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+                          MAX1600_CODE_HIGH);
+       if (ret)
+               return ret;
+
+       skt->driver_data = m;
+
+       return soc_pcmcia_request_gpiods(skt);
 }
 
-static unsigned long mst_pcmcia_status[2];
+static unsigned int mst_pcmcia_bvd1_status[2];
 
 static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                    struct pcmcia_state *state)
 {
-       unsigned long status, flip;
-
-       status = (skt->nr == 0) ? MST_PCMCIA0 : MST_PCMCIA1;
-       flip = (status ^ mst_pcmcia_status[skt->nr]) & MST_PCMCIA_nSTSCHG_BVD1;
+       unsigned int flip = mst_pcmcia_bvd1_status[skt->nr] ^ state->bvd1;
 
        /*
         * Workaround for STSCHG which can't be deasserted:
@@ -68,62 +67,18 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
         * as needed to avoid IRQ locks.
         */
        if (flip) {
-               mst_pcmcia_status[skt->nr] = status;
-               if (status & MST_PCMCIA_nSTSCHG_BVD1)
-                       enable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ
-                                                  : MAINSTONE_S1_STSCHG_IRQ );
+               mst_pcmcia_bvd1_status[skt->nr] = state->bvd1;
+               if (state->bvd1)
+                       enable_irq(skt->stat[SOC_STAT_BVD1].irq);
                else
-                       disable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ
-                                                   : MAINSTONE_S1_STSCHG_IRQ );
+                       disable_irq(skt->stat[SOC_STAT_BVD2].irq);
        }
-
-       state->detect = (status & MST_PCMCIA_nCD) ? 0 : 1;
-       state->ready  = (status & MST_PCMCIA_nIRQ) ? 1 : 0;
-       state->bvd1   = (status & MST_PCMCIA_nSTSCHG_BVD1) ? 1 : 0;
-       state->bvd2   = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
-       state->vs_3v  = (status & MST_PCMCIA_nVS1) ? 0 : 1;
-       state->vs_Xv  = (status & MST_PCMCIA_nVS2) ? 0 : 1;
 }
 
 static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                       const socket_state_t *state)
 {
-       unsigned long power = 0;
-       int ret = 0;
-
-       switch (state->Vcc) {
-       case 0:  power |= MST_PCMCIA_PWR_VCC_0;  break;
-       case 33: power |= MST_PCMCIA_PWR_VCC_33; break;
-       case 50: power |= MST_PCMCIA_PWR_VCC_50; break;
-       default:
-                printk(KERN_ERR "%s(): bad Vcc %u\n",
-                                __func__, state->Vcc);
-                ret = -1;
-       }
-
-       switch (state->Vpp) {
-       case 0:   power |= MST_PCMCIA_PWR_VPP_0;   break;
-       case 120: power |= MST_PCMCIA_PWR_VPP_120; break;
-       default:
-                 if(state->Vpp == state->Vcc) {
-                         power |= MST_PCMCIA_PWR_VPP_VCC;
-                 } else {
-                         printk(KERN_ERR "%s(): bad Vpp %u\n",
-                                         __func__, state->Vpp);
-                         ret = -1;
-                 }
-       }
-
-       if (state->flags & SS_RESET)
-              power |= MST_PCMCIA_RESET;
-
-       switch (skt->nr) {
-       case 0:  MST_PCMCIA0 = power; break;
-       case 1:  MST_PCMCIA1 = power; break;
-       default: ret = -1;
-       }
-
-       return ret;
+       return max1600_configure(skt->driver_data, state->Vcc, state->Vpp);
 }
 
 static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
index e235ee14eaa6e2565630305da21de55e9fca8e69..e2e8729afd9dc9b9e5ff822af974f26ff1926783 100644 (file)
@@ -39,8 +39,8 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
        long cs3reg = simpad_get_cs3_ro();
 
-       state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
-       state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
+       /* bvd1 might be cs3reg & PCMCIA_BVD1 */
+       /* bvd2 might be cs3reg & PCMCIA_BVD2 */
 
        if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
                        (PCMCIA_VS1|PCMCIA_VS2)) {
index 3d4ca87ca76cd58871f4aa33ab72134843baa143..1083e1b4f25dbbaa85ccea6d02fc008e4b84a57c 100644 (file)
@@ -6,29 +6,62 @@
  *
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
 
 #include "sa1111_generic.h"
 
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER  GPIO_GPIO0
-#define SOCKET0_3V     GPIO_GPIO2
-#define SOCKET1_POWER  (GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V     GPIO_GPIO3
+/*
+ * Socket 0 power: GPIO A0
+ * Socket 0 3V: GPIO A2
+ * Socket 1 power: GPIO A1 & GPIO A3
+ * Socket 1 3V: GPIO A3
+ * Does Socket 1 3V actually do anything?
+ */
+enum {
+       J720_GPIO_PWR,
+       J720_GPIO_3V,
+       J720_GPIO_MAX,
+};
+struct jornada720_data {
+       struct gpio_desc *gpio[J720_GPIO_MAX];
+};
+
+static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       struct device *dev = skt->socket.dev.parent;
+       struct jornada720_data *j;
+
+       j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL);
+       if (!j)
+               return -ENOMEM;
+
+       j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" :
+                                               "s0-power", GPIOD_OUT_LOW);
+       if (IS_ERR(j->gpio[J720_GPIO_PWR]))
+               return PTR_ERR(j->gpio[J720_GPIO_PWR]);
+
+       j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" :
+                                              "s0-3v", GPIOD_OUT_LOW);
+       if (IS_ERR(j->gpio[J720_GPIO_3V]))
+               return PTR_ERR(j->gpio[J720_GPIO_3V]);
+
+       skt->driver_data = j;
+
+       return 0;
+}
 
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int pa_dwr_mask, pa_dwr_set;
+       struct jornada720_data *j = skt->driver_data;
+       DECLARE_BITMAP(values, J720_GPIO_MAX) = { 0, };
        int ret;
 
        printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
@@ -36,35 +69,34 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
        switch (skt->nr) {
        case 0:
-               pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
                switch (state->Vcc) {
                default:
                case  0:
-                       pa_dwr_set = 0;
+                       __assign_bit(J720_GPIO_PWR, values, 0);
+                       __assign_bit(J720_GPIO_3V, values, 0);
                        break;
                case 33:
-                       pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+                       __assign_bit(J720_GPIO_PWR, values, 1);
+                       __assign_bit(J720_GPIO_3V, values, 1);
                        break;
                case 50:
-                       pa_dwr_set = SOCKET0_POWER;
+                       __assign_bit(J720_GPIO_PWR, values, 1);
+                       __assign_bit(J720_GPIO_3V, values, 0);
                        break;
                }
                break;
 
        case 1:
-               pa_dwr_mask = SOCKET1_POWER;
-
                switch (state->Vcc) {
                default:
                case 0:
-                       pa_dwr_set = 0;
+                       __assign_bit(J720_GPIO_PWR, values, 0);
+                       __assign_bit(J720_GPIO_3V, values, 0);
                        break;
                case 33:
-                       pa_dwr_set = SOCKET1_POWER;
-                       break;
                case 50:
-                       pa_dwr_set = SOCKET1_POWER;
+                       __assign_bit(J720_GPIO_PWR, values, 1);
+                       __assign_bit(J720_GPIO_3V, values, 1);
                        break;
                }
                break;
@@ -81,13 +113,15 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
        ret = sa1111_pcmcia_configure_socket(skt, state);
        if (ret == 0)
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+               ret = gpiod_set_array_value_cansleep(J720_GPIO_MAX, j->gpio,
+                                                    NULL, values);
 
        return ret;
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
        .owner                  = THIS_MODULE,
+       .hw_init                = jornada720_pcmcia_hw_init,
        .configure_socket       = jornada720_pcmcia_configure_socket,
        .first                  = 0,
        .nr                     = 2,
@@ -95,16 +129,9 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
 
 int pcmcia_jornada720_init(struct sa1111_dev *sadev)
 {
-       unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
        /* Fixme: why messing around with SA11x0's GPIO1? */
        GRER |= 0x00000002;
 
-       /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-       sa1111_set_io_dir(sadev, pin, 0, 0);
-       sa1111_set_io(sadev, pin, 0);
-       sa1111_set_sleep_io(sadev, pin, 0);
-
        sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
        return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
                                 sa11xx_drv_pcmcia_add_one);
index e741f499c875314d40855190186ee939f0dba2e7..e3fc14cfb42b33ff51ad3c88f60d4d91801894a9 100644 (file)
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
-#include <mach/lubbock.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
+
+static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       struct max1600 *m;
+       int ret;
+
+       ret = max1600_init(skt->socket.dev.parent, &m,
+                          skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+                          MAX1600_CODE_HIGH);
+       if (ret == 0)
+               skt->driver_data = m;
+
+       return ret;
+}
 
 static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                const socket_state_t *state)
 {
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+       struct max1600 *m = skt->driver_data;
        int ret = 0;
 
-       pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
        /* Lubbock uses the Maxim MAX1602, with the following connections:
         *
         * Socket 0 (PCMCIA):
@@ -71,74 +82,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  again:
        switch (skt->nr) {
        case 0:
-               pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-               switch (state->Vcc) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 33: /* VY */
-                       pa_dwr_set |= GPIO_A3;
-                       break;
-
-               case 50: /* VX */
-                       pa_dwr_set |= GPIO_A2;
-                       break;
-
-               default:
-                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __func__, state->Vcc);
-                       ret = -1;
-               }
-
-               switch (state->Vpp) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 120: /* 12IN */
-                       pa_dwr_set |= GPIO_A1;
-                       break;
-
-               default: /* VCC */
-                       if (state->Vpp == state->Vcc)
-                               pa_dwr_set |= GPIO_A0;
-                       else {
-                               printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-                                      __func__, state->Vpp);
-                               ret = -1;
-                               break;
-                       }
-               }
-               break;
-
        case 1:
-               misc_mask = (1 << 15) | (1 << 14);
-
-               switch (state->Vcc) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 33: /* VY */
-                       misc_set |= 1 << 15;
-                       break;
-
-               case 50: /* VX */
-                       misc_set |= 1 << 14;
-                       break;
-
-               default:
-                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __func__, state->Vcc);
-                       ret = -1;
-                       break;
-               }
-
-               if (state->Vpp != state->Vcc && state->Vpp != 0) {
-                       printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-                              __func__, state->Vpp);
-                       ret = -1;
-                       break;
-               }
                break;
 
        default:
@@ -147,11 +91,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
        if (ret == 0)
                ret = sa1111_pcmcia_configure_socket(skt, state);
-
-       if (ret == 0) {
-               lubbock_set_misc_wr(misc_mask, misc_set);
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-       }
+       if (ret == 0)
+               ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 #if 1
        if (ret == 0 && state->Vcc == 33) {
@@ -175,8 +116,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                        /*
                         * Switch to 5V,  Configure socket with 5V voltage
                         */
-                       lubbock_set_misc_wr(misc_mask, 0);
-                       sa1111_set_io(s->dev, pa_dwr_mask, 0);
+                       max1600_configure(m, 0, 0);
 
                        /*
                         * It takes about 100ms to turn off Vcc.
@@ -201,6 +141,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
        .owner                  = THIS_MODULE,
+       .hw_init                = lubbock_pcmcia_hw_init,
        .configure_socket       = lubbock_pcmcia_configure_socket,
        .first                  = 0,
        .nr                     = 2,
@@ -210,17 +151,6 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = {
 
 int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 {
-       /*
-        * Set GPIO_A<3:0> to be outputs for the MAX1600,
-        * and switch to standby mode.
-        */
-       sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-       sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-       sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-       /* Set CF Socket 1 power to standby mode. */
-       lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
        pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
        pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
        return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
index 0ccf05a28a4b96686d76e908b54b949c298715cb..de0ce13355b449855d7789accca7e72be8242d1e 100644 (file)
 #include <linux/errno.h>
 #include <linux/init.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
 
 /*
  * Neponset uses the Maxim MAX1600, with the following connections:
  * "Standard Intel code" mode. Refer to the Maxim data sheet for
  * the corresponding truth table.
  */
-
-static int
-neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+       struct max1600 *m;
        int ret;
 
-       switch (skt->nr) {
-       case 0:
-               pa_dwr_mask = GPIO_A0 | GPIO_A1;
-               ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-               if (state->Vpp == 0)
-                       ncr_set = 0;
-               else if (state->Vpp == 120)
-                       ncr_set = NCR_A1VPP;
-               else if (state->Vpp == state->Vcc)
-                       ncr_set = NCR_A0VPP;
-               else {
-                       printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-                              __func__, state->Vpp);
-                       return -1;
-               }
-               break;
-
-       case 1:
-               pa_dwr_mask = GPIO_A2 | GPIO_A3;
-               ncr_mask = 0;
-               ncr_set = 0;
-
-               if (state->Vpp != state->Vcc && state->Vpp != 0) {
-                       printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-                              __func__, state->Vpp);
-                       return -1;
-               }
-               break;
+       ret = max1600_init(skt->socket.dev.parent, &m,
+                          skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+                          MAX1600_CODE_LOW);
+       if (ret == 0)
+               skt->driver_data = m;
 
-       default:
-               return -1;
-       }
+       return ret;
+}
 
-       /*
-        * pa_dwr_set is the mask for selecting Vcc on both sockets.
-        * pa_dwr_mask selects which bits (and therefore socket) we change.
-        */
-       switch (state->Vcc) {
-       default:
-       case 0:  pa_dwr_set = 0;                break;
-       case 33: pa_dwr_set = GPIO_A1|GPIO_A2;  break;
-       case 50: pa_dwr_set = GPIO_A0|GPIO_A3;  break;
-       }
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+       struct max1600 *m = skt->driver_data;
+       int ret;
 
        ret = sa1111_pcmcia_configure_socket(skt, state);
-       if (ret == 0) {
-               neponset_ncr_frob(ncr_mask, ncr_set);
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-       }
+       if (ret == 0)
+               ret = max1600_configure(m, state->Vcc, state->Vpp);
 
        return ret;
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
        .owner                  = THIS_MODULE,
+       .hw_init                = neponset_pcmcia_hw_init,
        .configure_socket       = neponset_pcmcia_configure_socket,
        .first                  = 0,
        .nr                     = 2,
@@ -111,13 +75,6 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
 
 int pcmcia_neponset_init(struct sa1111_dev *sadev)
 {
-       /*
-        * Set GPIO_A<3:0> to be outputs for the MAX1600,
-        * and switch to standby mode.
-        */
-       sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-       sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-       sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
        sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
        return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
                                 sa11xx_drv_pcmcia_add_one);
index 1b10ea05a914903ca1a22233356fc7410b28d6b1..69372e2bc93c7df0ce3921d6b9666773d80bbef2 100644 (file)
@@ -30,8 +30,8 @@
 #define DDRC_FLUX_RCMD          0x38c
 #define DDRC_PRE_CMD            0x3c0
 #define DDRC_ACT_CMD            0x3c4
-#define DDRC_BNK_CHG            0x3c8
 #define DDRC_RNK_CHG            0x3cc
+#define DDRC_RW_CHG             0x3d0
 #define DDRC_EVENT_CTRL         0x6C0
 #define DDRC_INT_MASK          0x6c8
 #define DDRC_INT_STATUS                0x6cc
@@ -51,7 +51,7 @@
 
 static const u32 ddrc_reg_off[] = {
        DDRC_FLUX_WR, DDRC_FLUX_RD, DDRC_FLUX_WCMD, DDRC_FLUX_RCMD,
-       DDRC_PRE_CMD, DDRC_ACT_CMD, DDRC_BNK_CHG, DDRC_RNK_CHG
+       DDRC_PRE_CMD, DDRC_ACT_CMD, DDRC_RNK_CHG, DDRC_RW_CHG
 };
 
 /*
index 34dce850067b9e9c379274ef8b3c91da4bb42ef0..e5efce3c08e2eee08c3a3bc6fb330da07df5c4b8 100644 (file)
@@ -631,6 +631,9 @@ static struct optee *optee_probe(struct device_node *np)
 
        optee_enable_shm_cache(optee);
 
+       if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+               pr_info("dynamic shared memory is enabled\n");
+
        pr_info("initialized driver\n");
        return optee;
 err:
index df35fc01fd3e5eec43088112ac7976f72c69164f..43626e15703a80ddf48360c0622f37b813b76809 100644 (file)
@@ -19,7 +19,7 @@
 struct optee_supp_req {
        struct list_head link;
 
-       bool busy;
+       bool in_queue;
        u32 func;
        u32 ret;
        size_t num_params;
@@ -54,7 +54,6 @@ void optee_supp_release(struct optee_supp *supp)
 
        /* Abort all request retrieved by supplicant */
        idr_for_each_entry(&supp->idr, req, id) {
-               req->busy = false;
                idr_remove(&supp->idr, id);
                req->ret = TEEC_ERROR_COMMUNICATION;
                complete(&req->c);
@@ -63,6 +62,7 @@ void optee_supp_release(struct optee_supp *supp)
        /* Abort all queued requests */
        list_for_each_entry_safe(req, req_tmp, &supp->reqs, link) {
                list_del(&req->link);
+               req->in_queue = false;
                req->ret = TEEC_ERROR_COMMUNICATION;
                complete(&req->c);
        }
@@ -103,6 +103,7 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
        /* Insert the request in the request list */
        mutex_lock(&supp->mutex);
        list_add_tail(&req->link, &supp->reqs);
+       req->in_queue = true;
        mutex_unlock(&supp->mutex);
 
        /* Tell an eventual waiter there's a new request */
@@ -130,9 +131,10 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
                         * will serve all requests in a timely manner and
                         * interrupting then wouldn't make sense.
                         */
-                       interruptable = !req->busy;
-                       if (!req->busy)
+                       if (req->in_queue) {
                                list_del(&req->link);
+                               req->in_queue = false;
+                       }
                }
                mutex_unlock(&supp->mutex);
 
@@ -176,7 +178,7 @@ static struct optee_supp_req  *supp_pop_entry(struct optee_supp *supp,
                return ERR_PTR(-ENOMEM);
 
        list_del(&req->link);
-       req->busy = true;
+       req->in_queue = false;
 
        return req;
 }
@@ -318,7 +320,6 @@ static struct optee_supp_req *supp_pop_req(struct optee_supp *supp,
        if ((num_params - nm) != req->num_params)
                return ERR_PTR(-EINVAL);
 
-       req->busy = false;
        idr_remove(&supp->idr, id);
        supp->req_id = -1;
        *num_meta = nm;
index 32886c3046413a466c5ebf1b457f7c71f57db781..67b9bf3b500e9e55a0922c82eae289e305cdd075 100644 (file)
@@ -1529,6 +1529,25 @@ config SERIAL_OWL_CONSOLE
          Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART
          as the system console.
 
+config SERIAL_RDA
+       bool "RDA Micro serial port support"
+       depends on ARCH_RDA || COMPILE_TEST
+       select SERIAL_CORE
+       help
+         This driver is for RDA8810PL SoC's UART.
+         Say 'Y' here if you wish to use the on-board serial port.
+         Otherwise, say 'N'.
+
+config SERIAL_RDA_CONSOLE
+       bool "Console on RDA Micro serial port"
+       depends on SERIAL_RDA=y
+       select SERIAL_CORE_CONSOLE
+       select SERIAL_EARLYCON
+       default y
+       help
+         Say 'Y' here if you wish to use the RDA8810PL UART as the system
+         console. Only earlycon is implemented currently.
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
index daac675612dff4804869460e7946210dd1eb7466..8c303736b7e8490a463d035e465d68b47638b5b4 100644 (file)
@@ -89,6 +89,7 @@ obj-$(CONFIG_SERIAL_MVEBU_UART)       += mvebu-uart.o
 obj-$(CONFIG_SERIAL_PIC32)     += pic32_uart.o
 obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o
 obj-$(CONFIG_SERIAL_OWL)       += owl-uart.o
+obj-$(CONFIG_SERIAL_RDA)       += rda-uart.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)        += serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/rda-uart.c b/drivers/tty/serial/rda-uart.c
new file mode 100644 (file)
index 0000000..284623e
--- /dev/null
@@ -0,0 +1,831 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * RDA8810PL serial device driver
+ *
+ * Copyright RDA Microelectronics Company Limited
+ * Copyright (c) 2017 Andreas Färber
+ * Copyright (c) 2018 Manivannan Sadhasivam
+ */
+
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#define RDA_UART_PORT_NUM 3
+#define RDA_UART_DEV_NAME "ttyRDA"
+
+#define RDA_UART_CTRL          0x00
+#define RDA_UART_STATUS                0x04
+#define RDA_UART_RXTX_BUFFER   0x08
+#define RDA_UART_IRQ_MASK      0x0c
+#define RDA_UART_IRQ_CAUSE     0x10
+#define RDA_UART_IRQ_TRIGGERS  0x14
+#define RDA_UART_CMD_SET       0x18
+#define RDA_UART_CMD_CLR       0x1c
+
+/* UART_CTRL Bits */
+#define RDA_UART_ENABLE                        BIT(0)
+#define RDA_UART_DBITS_8               BIT(1)
+#define RDA_UART_TX_SBITS_2            BIT(2)
+#define RDA_UART_PARITY_EN             BIT(3)
+#define RDA_UART_PARITY(x)             (((x) & 0x3) << 4)
+#define RDA_UART_PARITY_ODD            RDA_UART_PARITY(0)
+#define RDA_UART_PARITY_EVEN           RDA_UART_PARITY(1)
+#define RDA_UART_PARITY_SPACE          RDA_UART_PARITY(2)
+#define RDA_UART_PARITY_MARK           RDA_UART_PARITY(3)
+#define RDA_UART_DIV_MODE              BIT(20)
+#define RDA_UART_IRDA_EN               BIT(21)
+#define RDA_UART_DMA_EN                        BIT(22)
+#define RDA_UART_FLOW_CNT_EN           BIT(23)
+#define RDA_UART_LOOP_BACK_EN          BIT(24)
+#define RDA_UART_RX_LOCK_ERR           BIT(25)
+#define RDA_UART_RX_BREAK_LEN(x)       (((x) & 0xf) << 28)
+
+/* UART_STATUS Bits */
+#define RDA_UART_RX_FIFO(x)            (((x) & 0x7f) << 0)
+#define RDA_UART_RX_FIFO_MASK          (0x7f << 0)
+#define RDA_UART_TX_FIFO(x)            (((x) & 0x1f) << 8)
+#define RDA_UART_TX_FIFO_MASK          (0x1f << 8)
+#define RDA_UART_TX_ACTIVE             BIT(14)
+#define RDA_UART_RX_ACTIVE             BIT(15)
+#define RDA_UART_RX_OVERFLOW_ERR       BIT(16)
+#define RDA_UART_TX_OVERFLOW_ERR       BIT(17)
+#define RDA_UART_RX_PARITY_ERR         BIT(18)
+#define RDA_UART_RX_FRAMING_ERR                BIT(19)
+#define RDA_UART_RX_BREAK_INT          BIT(20)
+#define RDA_UART_DCTS                  BIT(24)
+#define RDA_UART_CTS                   BIT(25)
+#define RDA_UART_DTR                   BIT(28)
+#define RDA_UART_CLK_ENABLED           BIT(31)
+
+/* UART_RXTX_BUFFER Bits */
+#define RDA_UART_RX_DATA(x)            (((x) & 0xff) << 0)
+#define RDA_UART_TX_DATA(x)            (((x) & 0xff) << 0)
+
+/* UART_IRQ_MASK Bits */
+#define RDA_UART_TX_MODEM_STATUS       BIT(0)
+#define RDA_UART_RX_DATA_AVAILABLE     BIT(1)
+#define RDA_UART_TX_DATA_NEEDED                BIT(2)
+#define RDA_UART_RX_TIMEOUT            BIT(3)
+#define RDA_UART_RX_LINE_ERR           BIT(4)
+#define RDA_UART_TX_DMA_DONE           BIT(5)
+#define RDA_UART_RX_DMA_DONE           BIT(6)
+#define RDA_UART_RX_DMA_TIMEOUT                BIT(7)
+#define RDA_UART_DTR_RISE              BIT(8)
+#define RDA_UART_DTR_FALL              BIT(9)
+
+/* UART_IRQ_CAUSE Bits */
+#define RDA_UART_TX_MODEM_STATUS_U     BIT(16)
+#define RDA_UART_RX_DATA_AVAILABLE_U   BIT(17)
+#define RDA_UART_TX_DATA_NEEDED_U      BIT(18)
+#define RDA_UART_RX_TIMEOUT_U          BIT(19)
+#define RDA_UART_RX_LINE_ERR_U         BIT(20)
+#define RDA_UART_TX_DMA_DONE_U         BIT(21)
+#define RDA_UART_RX_DMA_DONE_U         BIT(22)
+#define RDA_UART_RX_DMA_TIMEOUT_U      BIT(23)
+#define RDA_UART_DTR_RISE_U            BIT(24)
+#define RDA_UART_DTR_FALL_U            BIT(25)
+
+/* UART_TRIGGERS Bits */
+#define RDA_UART_RX_TRIGGER(x)         (((x) & 0x1f) << 0)
+#define RDA_UART_TX_TRIGGER(x)         (((x) & 0xf) << 8)
+#define RDA_UART_AFC_LEVEL(x)          (((x) & 0x1f) << 16)
+
+/* UART_CMD_SET Bits */
+#define RDA_UART_RI                    BIT(0)
+#define RDA_UART_DCD                   BIT(1)
+#define RDA_UART_DSR                   BIT(2)
+#define RDA_UART_TX_BREAK_CONTROL      BIT(3)
+#define RDA_UART_TX_FINISH_N_WAIT      BIT(4)
+#define RDA_UART_RTS                   BIT(5)
+#define RDA_UART_RX_FIFO_RESET         BIT(6)
+#define RDA_UART_TX_FIFO_RESET         BIT(7)
+
+#define RDA_UART_TX_FIFO_SIZE  16
+
+static struct uart_driver rda_uart_driver;
+
+struct rda_uart_port {
+       struct uart_port port;
+       struct clk *clk;
+};
+
+#define to_rda_uart_port(port) container_of(port, struct rda_uart_port, port)
+
+static struct rda_uart_port *rda_uart_ports[RDA_UART_PORT_NUM];
+
+static inline void rda_uart_write(struct uart_port *port, u32 val,
+                                 unsigned int off)
+{
+       writel(val, port->membase + off);
+}
+
+static inline u32 rda_uart_read(struct uart_port *port, unsigned int off)
+{
+       return readl(port->membase + off);
+}
+
+static unsigned int rda_uart_tx_empty(struct uart_port *port)
+{
+       unsigned long flags;
+       unsigned int ret;
+       u32 val;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       val = rda_uart_read(port, RDA_UART_STATUS);
+       ret = (val & RDA_UART_TX_FIFO_MASK) ? TIOCSER_TEMT : 0;
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return ret;
+}
+
+static unsigned int rda_uart_get_mctrl(struct uart_port *port)
+{
+       unsigned int mctrl = 0;
+       u32 cmd_set, status;
+
+       cmd_set = rda_uart_read(port, RDA_UART_CMD_SET);
+       status = rda_uart_read(port, RDA_UART_STATUS);
+       if (cmd_set & RDA_UART_RTS)
+               mctrl |= TIOCM_RTS;
+       if (!(status & RDA_UART_CTS))
+               mctrl |= TIOCM_CTS;
+
+       return mctrl;
+}
+
+static void rda_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+       u32 val;
+
+       if (mctrl & TIOCM_RTS) {
+               val = rda_uart_read(port, RDA_UART_CMD_SET);
+               rda_uart_write(port, (val | RDA_UART_RTS), RDA_UART_CMD_SET);
+       } else {
+               /* Clear RTS to stop to receive. */
+               val = rda_uart_read(port, RDA_UART_CMD_CLR);
+               rda_uart_write(port, (val | RDA_UART_RTS), RDA_UART_CMD_CLR);
+       }
+
+       val = rda_uart_read(port, RDA_UART_CTRL);
+
+       if (mctrl & TIOCM_LOOP)
+               val |= RDA_UART_LOOP_BACK_EN;
+       else
+               val &= ~RDA_UART_LOOP_BACK_EN;
+
+       rda_uart_write(port, val, RDA_UART_CTRL);
+}
+
+static void rda_uart_stop_tx(struct uart_port *port)
+{
+       u32 val;
+
+       val = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       val &= ~RDA_UART_TX_DATA_NEEDED;
+       rda_uart_write(port, val, RDA_UART_IRQ_MASK);
+
+       val = rda_uart_read(port, RDA_UART_CMD_SET);
+       val |= RDA_UART_TX_FIFO_RESET;
+       rda_uart_write(port, val, RDA_UART_CMD_SET);
+}
+
+static void rda_uart_stop_rx(struct uart_port *port)
+{
+       u32 val;
+
+       val = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       val &= ~(RDA_UART_RX_DATA_AVAILABLE | RDA_UART_RX_TIMEOUT);
+       rda_uart_write(port, val, RDA_UART_IRQ_MASK);
+
+       /* Read Rx buffer before reset to avoid Rx timeout interrupt */
+       val = rda_uart_read(port, RDA_UART_RXTX_BUFFER);
+
+       val = rda_uart_read(port, RDA_UART_CMD_SET);
+       val |= RDA_UART_RX_FIFO_RESET;
+       rda_uart_write(port, val, RDA_UART_CMD_SET);
+}
+
+static void rda_uart_start_tx(struct uart_port *port)
+{
+       u32 val;
+
+       if (uart_tx_stopped(port)) {
+               rda_uart_stop_tx(port);
+               return;
+       }
+
+       val = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       val |= RDA_UART_TX_DATA_NEEDED;
+       rda_uart_write(port, val, RDA_UART_IRQ_MASK);
+}
+
+static void rda_uart_change_baudrate(struct rda_uart_port *rda_port,
+                                    unsigned long baud)
+{
+       clk_set_rate(rda_port->clk, baud * 8);
+}
+
+static void rda_uart_set_termios(struct uart_port *port,
+                                struct ktermios *termios,
+                                struct ktermios *old)
+{
+       struct rda_uart_port *rda_port = to_rda_uart_port(port);
+       unsigned long flags;
+       unsigned int ctrl, cmd_set, cmd_clr, triggers;
+       unsigned int baud;
+       u32 irq_mask;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       baud = uart_get_baud_rate(port, termios, old, 9600, port->uartclk / 4);
+       rda_uart_change_baudrate(rda_port, baud);
+
+       ctrl = rda_uart_read(port, RDA_UART_CTRL);
+       cmd_set = rda_uart_read(port, RDA_UART_CMD_SET);
+       cmd_clr = rda_uart_read(port, RDA_UART_CMD_CLR);
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+       case CS6:
+               dev_warn(port->dev, "bit size not supported, using 7 bits\n");
+               /* Fall through */
+       case CS7:
+               ctrl &= ~RDA_UART_DBITS_8;
+               break;
+       default:
+               ctrl |= RDA_UART_DBITS_8;
+               break;
+       }
+
+       /* stop bits */
+       if (termios->c_cflag & CSTOPB)
+               ctrl |= RDA_UART_TX_SBITS_2;
+       else
+               ctrl &= ~RDA_UART_TX_SBITS_2;
+
+       /* parity check */
+       if (termios->c_cflag & PARENB) {
+               ctrl |= RDA_UART_PARITY_EN;
+
+               /* Mark or Space parity */
+               if (termios->c_cflag & CMSPAR) {
+                       if (termios->c_cflag & PARODD)
+                               ctrl |= RDA_UART_PARITY_MARK;
+                       else
+                               ctrl |= RDA_UART_PARITY_SPACE;
+               } else if (termios->c_cflag & PARODD) {
+                       ctrl |= RDA_UART_PARITY_ODD;
+               } else {
+                       ctrl |= RDA_UART_PARITY_EVEN;
+               }
+       } else {
+               ctrl &= ~RDA_UART_PARITY_EN;
+       }
+
+       /* Hardware handshake (RTS/CTS) */
+       if (termios->c_cflag & CRTSCTS) {
+               ctrl   |= RDA_UART_FLOW_CNT_EN;
+               cmd_set |= RDA_UART_RTS;
+       } else {
+               ctrl   &= ~RDA_UART_FLOW_CNT_EN;
+               cmd_clr |= RDA_UART_RTS;
+       }
+
+       ctrl |= RDA_UART_ENABLE;
+       ctrl &= ~RDA_UART_DMA_EN;
+
+       triggers  = (RDA_UART_AFC_LEVEL(20) | RDA_UART_RX_TRIGGER(16));
+       irq_mask = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       rda_uart_write(port, 0, RDA_UART_IRQ_MASK);
+
+       rda_uart_write(port, triggers, RDA_UART_IRQ_TRIGGERS);
+       rda_uart_write(port, ctrl, RDA_UART_CTRL);
+       rda_uart_write(port, cmd_set, RDA_UART_CMD_SET);
+       rda_uart_write(port, cmd_clr, RDA_UART_CMD_CLR);
+
+       rda_uart_write(port, irq_mask, RDA_UART_IRQ_MASK);
+
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
+
+       /* update the per-port timeout */
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void rda_uart_send_chars(struct uart_port *port)
+{
+       struct circ_buf *xmit = &port->state->xmit;
+       unsigned int ch;
+       u32 val;
+
+       if (uart_tx_stopped(port))
+               return;
+
+       if (port->x_char) {
+               while (!(rda_uart_read(port, RDA_UART_STATUS) &
+                        RDA_UART_TX_FIFO_MASK))
+                       cpu_relax();
+
+               rda_uart_write(port, port->x_char, RDA_UART_RXTX_BUFFER);
+               port->icount.tx++;
+               port->x_char = 0;
+       }
+
+       while (rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK) {
+               if (uart_circ_empty(xmit))
+                       break;
+
+               ch = xmit->buf[xmit->tail];
+               rda_uart_write(port, ch, RDA_UART_RXTX_BUFFER);
+               xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1);
+               port->icount.tx++;
+       }
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+
+       if (!uart_circ_empty(xmit)) {
+               /* Re-enable Tx FIFO interrupt */
+               val = rda_uart_read(port, RDA_UART_IRQ_MASK);
+               val |= RDA_UART_TX_DATA_NEEDED;
+               rda_uart_write(port, val, RDA_UART_IRQ_MASK);
+       }
+}
+
+static void rda_uart_receive_chars(struct uart_port *port)
+{
+       u32 status, val;
+
+       status = rda_uart_read(port, RDA_UART_STATUS);
+       while ((status & RDA_UART_RX_FIFO_MASK)) {
+               char flag = TTY_NORMAL;
+
+               if (status & RDA_UART_RX_PARITY_ERR) {
+                       port->icount.parity++;
+                       flag = TTY_PARITY;
+               }
+
+               if (status & RDA_UART_RX_FRAMING_ERR) {
+                       port->icount.frame++;
+                       flag = TTY_FRAME;
+               }
+
+               if (status & RDA_UART_RX_OVERFLOW_ERR) {
+                       port->icount.overrun++;
+                       flag = TTY_OVERRUN;
+               }
+
+               val = rda_uart_read(port, RDA_UART_RXTX_BUFFER);
+               val &= 0xff;
+
+               port->icount.rx++;
+               tty_insert_flip_char(&port->state->port, val, flag);
+
+               status = rda_uart_read(port, RDA_UART_STATUS);
+       }
+
+       spin_unlock(&port->lock);
+       tty_flip_buffer_push(&port->state->port);
+       spin_lock(&port->lock);
+}
+
+static irqreturn_t rda_interrupt(int irq, void *dev_id)
+{
+       struct uart_port *port = dev_id;
+       unsigned long flags;
+       u32 val, irq_mask;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       /* Clear IRQ cause */
+       val = rda_uart_read(port, RDA_UART_IRQ_CAUSE);
+       rda_uart_write(port, val, RDA_UART_IRQ_CAUSE);
+
+       if (val & (RDA_UART_RX_DATA_AVAILABLE | RDA_UART_RX_TIMEOUT))
+               rda_uart_receive_chars(port);
+
+       if (val & (RDA_UART_TX_DATA_NEEDED)) {
+               irq_mask = rda_uart_read(port, RDA_UART_IRQ_MASK);
+               irq_mask &= ~RDA_UART_TX_DATA_NEEDED;
+               rda_uart_write(port, irq_mask, RDA_UART_IRQ_MASK);
+
+               rda_uart_send_chars(port);
+       }
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+static int rda_uart_startup(struct uart_port *port)
+{
+       unsigned long flags;
+       int ret;
+       u32 val;
+
+       spin_lock_irqsave(&port->lock, flags);
+       rda_uart_write(port, 0, RDA_UART_IRQ_MASK);
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       ret = request_irq(port->irq, rda_interrupt, IRQF_NO_SUSPEND,
+                         "rda-uart", port);
+       if (ret)
+               return ret;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       val = rda_uart_read(port, RDA_UART_CTRL);
+       val |= RDA_UART_ENABLE;
+       rda_uart_write(port, val, RDA_UART_CTRL);
+
+       /* enable rx interrupt */
+       val = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       val |= (RDA_UART_RX_DATA_AVAILABLE | RDA_UART_RX_TIMEOUT);
+       rda_uart_write(port, val, RDA_UART_IRQ_MASK);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return 0;
+}
+
+static void rda_uart_shutdown(struct uart_port *port)
+{
+       unsigned long flags;
+       u32 val;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       rda_uart_stop_tx(port);
+       rda_uart_stop_rx(port);
+
+       val = rda_uart_read(port, RDA_UART_CTRL);
+       val &= ~RDA_UART_ENABLE;
+       rda_uart_write(port, val, RDA_UART_CTRL);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *rda_uart_type(struct uart_port *port)
+{
+       return (port->type == PORT_RDA) ? "rda-uart" : NULL;
+}
+
+static int rda_uart_request_port(struct uart_port *port)
+{
+       struct platform_device *pdev = to_platform_device(port->dev);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
+       if (!devm_request_mem_region(port->dev, port->mapbase,
+                                    resource_size(res), dev_name(port->dev)))
+               return -EBUSY;
+
+       if (port->flags & UPF_IOREMAP) {
+               port->membase = devm_ioremap_nocache(port->dev, port->mapbase,
+                                                    resource_size(res));
+               if (!port->membase)
+                       return -EBUSY;
+       }
+
+       return 0;
+}
+
+static void rda_uart_config_port(struct uart_port *port, int flags)
+{
+       unsigned long irq_flags;
+
+       if (flags & UART_CONFIG_TYPE) {
+               port->type = PORT_RDA;
+               rda_uart_request_port(port);
+       }
+
+       spin_lock_irqsave(&port->lock, irq_flags);
+
+       /* Clear mask, so no surprise interrupts. */
+       rda_uart_write(port, 0, RDA_UART_IRQ_MASK);
+
+       /* Clear status register */
+       rda_uart_write(port, 0, RDA_UART_STATUS);
+
+       spin_unlock_irqrestore(&port->lock, irq_flags);
+}
+
+static void rda_uart_release_port(struct uart_port *port)
+{
+       struct platform_device *pdev = to_platform_device(port->dev);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return;
+
+       if (port->flags & UPF_IOREMAP) {
+               devm_release_mem_region(port->dev, port->mapbase,
+                                       resource_size(res));
+               devm_iounmap(port->dev, port->membase);
+               port->membase = NULL;
+       }
+}
+
+static int rda_uart_verify_port(struct uart_port *port,
+                               struct serial_struct *ser)
+{
+       if (port->type != PORT_RDA)
+               return -EINVAL;
+
+       if (port->irq != ser->irq)
+               return -EINVAL;
+
+       return 0;
+}
+
+static const struct uart_ops rda_uart_ops = {
+       .tx_empty       = rda_uart_tx_empty,
+       .get_mctrl      = rda_uart_get_mctrl,
+       .set_mctrl      = rda_uart_set_mctrl,
+       .start_tx       = rda_uart_start_tx,
+       .stop_tx        = rda_uart_stop_tx,
+       .stop_rx        = rda_uart_stop_rx,
+       .startup        = rda_uart_startup,
+       .shutdown       = rda_uart_shutdown,
+       .set_termios    = rda_uart_set_termios,
+       .type           = rda_uart_type,
+       .request_port   = rda_uart_request_port,
+       .release_port   = rda_uart_release_port,
+       .config_port    = rda_uart_config_port,
+       .verify_port    = rda_uart_verify_port,
+};
+
+#ifdef CONFIG_SERIAL_RDA_CONSOLE
+
+static void rda_console_putchar(struct uart_port *port, int ch)
+{
+       if (!port->membase)
+               return;
+
+       while (!(rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK))
+               cpu_relax();
+
+       rda_uart_write(port, ch, RDA_UART_RXTX_BUFFER);
+}
+
+static void rda_uart_port_write(struct uart_port *port, const char *s,
+                               u_int count)
+{
+       u32 old_irq_mask;
+       unsigned long flags;
+       int locked;
+
+       local_irq_save(flags);
+
+       if (port->sysrq) {
+               locked = 0;
+       } else if (oops_in_progress) {
+               locked = spin_trylock(&port->lock);
+       } else {
+               spin_lock(&port->lock);
+               locked = 1;
+       }
+
+       old_irq_mask = rda_uart_read(port, RDA_UART_IRQ_MASK);
+       rda_uart_write(port, 0, RDA_UART_IRQ_MASK);
+
+       uart_console_write(port, s, count, rda_console_putchar);
+
+       /* wait until all contents have been sent out */
+       while (!(rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK))
+               cpu_relax();
+
+       rda_uart_write(port, old_irq_mask, RDA_UART_IRQ_MASK);
+
+       if (locked)
+               spin_unlock(&port->lock);
+
+       local_irq_restore(flags);
+}
+
+static void rda_uart_console_write(struct console *co, const char *s,
+                                  u_int count)
+{
+       struct rda_uart_port *rda_port;
+
+       rda_port = rda_uart_ports[co->index];
+       if (!rda_port)
+               return;
+
+       rda_uart_port_write(&rda_port->port, s, count);
+}
+
+static int rda_uart_console_setup(struct console *co, char *options)
+{
+       struct rda_uart_port *rda_port;
+       int baud = 921600;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       if (co->index < 0 || co->index >= RDA_UART_PORT_NUM)
+               return -EINVAL;
+
+       rda_port = rda_uart_ports[co->index];
+       if (!rda_port || !rda_port->port.membase)
+               return -ENODEV;
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+       return uart_set_options(&rda_port->port, co, baud, parity, bits, flow);
+}
+
+static struct console rda_uart_console = {
+       .name = RDA_UART_DEV_NAME,
+       .write = rda_uart_console_write,
+       .device = uart_console_device,
+       .setup = rda_uart_console_setup,
+       .flags = CON_PRINTBUFFER,
+       .index = -1,
+       .data = &rda_uart_driver,
+};
+
+static int __init rda_uart_console_init(void)
+{
+       register_console(&rda_uart_console);
+
+       return 0;
+}
+console_initcall(rda_uart_console_init);
+
+static void rda_uart_early_console_write(struct console *co,
+                                        const char *s,
+                                        u_int count)
+{
+       struct earlycon_device *dev = co->data;
+
+       rda_uart_port_write(&dev->port, s, count);
+}
+
+static int __init
+rda_uart_early_console_setup(struct earlycon_device *device, const char *opt)
+{
+       if (!device->port.membase)
+               return -ENODEV;
+
+       device->con->write = rda_uart_early_console_write;
+
+       return 0;
+}
+
+OF_EARLYCON_DECLARE(rda, "rda,8810pl-uart",
+                   rda_uart_early_console_setup);
+
+#define RDA_UART_CONSOLE (&rda_uart_console)
+#else
+#define RDA_UART_CONSOLE NULL
+#endif /* CONFIG_SERIAL_RDA_CONSOLE */
+
+static struct uart_driver rda_uart_driver = {
+       .owner = THIS_MODULE,
+       .driver_name = "rda-uart",
+       .dev_name = RDA_UART_DEV_NAME,
+       .nr = RDA_UART_PORT_NUM,
+       .cons = RDA_UART_CONSOLE,
+};
+
+static const struct of_device_id rda_uart_dt_matches[] = {
+       { .compatible = "rda,8810pl-uart" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, rda_uart_dt_matches);
+
+static int rda_uart_probe(struct platform_device *pdev)
+{
+       struct resource *res_mem;
+       struct rda_uart_port *rda_port;
+       int ret, irq;
+
+       if (pdev->dev.of_node)
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+
+       if (pdev->id < 0 || pdev->id >= RDA_UART_PORT_NUM) {
+               dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+               return -EINVAL;
+       }
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res_mem) {
+               dev_err(&pdev->dev, "could not get mem\n");
+               return -ENODEV;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "could not get irq\n");
+               return irq;
+       }
+
+       if (rda_uart_ports[pdev->id]) {
+               dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+               return -EBUSY;
+       }
+
+       rda_port = devm_kzalloc(&pdev->dev, sizeof(*rda_port), GFP_KERNEL);
+       if (!rda_port)
+               return -ENOMEM;
+
+       rda_port->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(rda_port->clk)) {
+               dev_err(&pdev->dev, "could not get clk\n");
+               return PTR_ERR(rda_port->clk);
+       }
+
+       rda_port->port.dev = &pdev->dev;
+       rda_port->port.regshift = 0;
+       rda_port->port.line = pdev->id;
+       rda_port->port.type = PORT_RDA;
+       rda_port->port.iotype = UPIO_MEM;
+       rda_port->port.mapbase = res_mem->start;
+       rda_port->port.irq = irq;
+       rda_port->port.uartclk = clk_get_rate(rda_port->clk);
+       if (rda_port->port.uartclk == 0) {
+               dev_err(&pdev->dev, "clock rate is zero\n");
+               return -EINVAL;
+       }
+       rda_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+                              UPF_LOW_LATENCY;
+       rda_port->port.x_char = 0;
+       rda_port->port.fifosize = RDA_UART_TX_FIFO_SIZE;
+       rda_port->port.ops = &rda_uart_ops;
+
+       rda_uart_ports[pdev->id] = rda_port;
+       platform_set_drvdata(pdev, rda_port);
+
+       ret = uart_add_one_port(&rda_uart_driver, &rda_port->port);
+       if (ret)
+               rda_uart_ports[pdev->id] = NULL;
+
+       return ret;
+}
+
+static int rda_uart_remove(struct platform_device *pdev)
+{
+       struct rda_uart_port *rda_port = platform_get_drvdata(pdev);
+
+       uart_remove_one_port(&rda_uart_driver, &rda_port->port);
+       rda_uart_ports[pdev->id] = NULL;
+
+       return 0;
+}
+
+static struct platform_driver rda_uart_platform_driver = {
+       .probe = rda_uart_probe,
+       .remove = rda_uart_remove,
+       .driver = {
+               .name = "rda-uart",
+               .of_match_table = rda_uart_dt_matches,
+       },
+};
+
+static int __init rda_uart_init(void)
+{
+       int ret;
+
+       ret = uart_register_driver(&rda_uart_driver);
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&rda_uart_platform_driver);
+       if (ret)
+               uart_unregister_driver(&rda_uart_driver);
+
+       return ret;
+}
+
+static void __init rda_uart_exit(void)
+{
+       platform_driver_unregister(&rda_uart_platform_driver);
+       uart_unregister_driver(&rda_uart_driver);
+}
+
+module_init(rda_uart_init);
+module_exit(rda_uart_exit);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("RDA8810PL serial device driver");
+MODULE_LICENSE("GPL");
index d6bc3f5d784b5676185070ae208345dd2eef3325..323ae99122039944a3df2a36a126748fafcd2529 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/writeback.h>
 #include <linux/gfp.h>
 #include <linux/task_io_accounting_ops.h>
+#include <linux/mm.h>
 #include "internal.h"
 
 static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
@@ -441,7 +442,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
        /* Count the number of contiguous pages at the front of the list.  Note
         * that the list goes prev-wards rather than next-wards.
         */
-       first = list_entry(pages->prev, struct page, lru);
+       first = lru_to_page(pages);
        index = first->index + 1;
        n = 1;
        for (p = first->lru.prev; p != pages; p = p->prev) {
@@ -473,7 +474,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
         * page at the end of the file.
         */
        do {
-               page = list_entry(pages->prev, struct page, lru);
+               page = lru_to_page(pages);
                list_del(&page->lru);
                index = page->index;
                if (add_to_page_cache_lru(page, mapping, index,
index fde6b4d4121e38532ea9ade21feb40b0a2bd09c6..3a9eaec06756998875f94a474bd6a75cb1ef5cf3 100644 (file)
@@ -247,7 +247,7 @@ int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried)
                        }
                }
 
-               if (!still_probing || unlikely(signal_pending(current)))
+               if (!still_probing || signal_pending(current))
                        goto stop;
                schedule();
        }
index f0b032976487cd5bde632b171ebaf858eb11a52c..f402ee8171a1d7cda8b8da05253408003c7f29f7 100644 (file)
@@ -248,7 +248,7 @@ int afs_wait_for_vl_probes(struct afs_vlserver_list *vllist,
                        }
                }
 
-               if (!still_probing || unlikely(signal_pending(current)))
+               if (!still_probing || signal_pending(current))
                        goto stop;
                schedule();
        }
index 9f9cadbfbd7a34f8005fafb0960b3c60e4848c60..3e59f0ed777bff66542a32cda86e2f90b1a821ef 100644 (file)
@@ -42,6 +42,8 @@
 #endif
 #define pr_fmt(fmt) KBUILD_MODNAME ":pid:%d:%s: " fmt, current->pid, __func__
 
+extern struct file_system_type autofs_fs_type;
+
 /*
  * Unified info structure.  This is pointed to by both the dentry and
  * inode structures.  Each file in the filesystem has an instance of this
@@ -101,16 +103,19 @@ struct autofs_wait_queue {
 
 #define AUTOFS_SBI_MAGIC 0x6d4a556d
 
+#define AUTOFS_SBI_CATATONIC   0x0001
+#define AUTOFS_SBI_STRICTEXPIRE 0x0002
+
 struct autofs_sb_info {
        u32 magic;
        int pipefd;
        struct file *pipe;
        struct pid *oz_pgrp;
-       int catatonic;
        int version;
        int sub_version;
        int min_proto;
        int max_proto;
+       unsigned int flags;
        unsigned long exp_timeout;
        unsigned int type;
        struct super_block *sb;
@@ -126,8 +131,7 @@ struct autofs_sb_info {
 
 static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
 {
-       return sb->s_magic != AUTOFS_SUPER_MAGIC ?
-               NULL : (struct autofs_sb_info *)(sb->s_fs_info);
+       return (struct autofs_sb_info *)(sb->s_fs_info);
 }
 
 static inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry)
@@ -141,7 +145,8 @@ static inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry)
  */
 static inline int autofs_oz_mode(struct autofs_sb_info *sbi)
 {
-       return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
+       return ((sbi->flags & AUTOFS_SBI_CATATONIC) ||
+                task_pgrp(current) == sbi->oz_pgrp);
 }
 
 struct inode *autofs_get_inode(struct super_block *, umode_t);
index 86eafda4a65226ef292f8713c2a86dee48e831ff..e9fe74d1541bbab6c9bf062b9b5bd268b5055c3e 100644 (file)
@@ -151,22 +151,6 @@ out:
        return err;
 }
 
-/*
- * Get the autofs super block info struct from the file opened on
- * the autofs mount point.
- */
-static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)
-{
-       struct autofs_sb_info *sbi = NULL;
-       struct inode *inode;
-
-       if (f) {
-               inode = file_inode(f);
-               sbi = autofs_sbi(inode->i_sb);
-       }
-       return sbi;
-}
-
 /* Return autofs dev ioctl version */
 static int autofs_dev_ioctl_version(struct file *fp,
                                    struct autofs_sb_info *sbi,
@@ -366,7 +350,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
        pipefd = param->setpipefd.pipefd;
 
        mutex_lock(&sbi->wq_mutex);
-       if (!sbi->catatonic) {
+       if (!(sbi->flags & AUTOFS_SBI_CATATONIC)) {
                mutex_unlock(&sbi->wq_mutex);
                return -EBUSY;
        } else {
@@ -393,7 +377,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
                swap(sbi->oz_pgrp, new_pid);
                sbi->pipefd = pipefd;
                sbi->pipe = pipe;
-               sbi->catatonic = 0;
+               sbi->flags &= ~AUTOFS_SBI_CATATONIC;
        }
 out:
        put_pid(new_pid);
@@ -658,6 +642,8 @@ static int _autofs_dev_ioctl(unsigned int command,
        if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD &&
            cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
            cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
+               struct super_block *sb;
+
                fp = fget(param->ioctlfd);
                if (!fp) {
                        if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
@@ -666,12 +652,13 @@ static int _autofs_dev_ioctl(unsigned int command,
                        goto out;
                }
 
-               sbi = autofs_dev_ioctl_sbi(fp);
-               if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
+               sb = file_inode(fp)->i_sb;
+               if (sb->s_type != &autofs_fs_type) {
                        err = -EINVAL;
                        fput(fp);
                        goto out;
                }
+               sbi = autofs_sbi(sb);
 
                /*
                 * Admin needs to be able to set the mount catatonic in
index 79ae07d9592f55cc06a10086cf45453250637d30..c0c1db2cc6ea7aa12ed64b8415b9558b884a0051 100644 (file)
@@ -16,7 +16,7 @@ static struct dentry *autofs_mount(struct file_system_type *fs_type,
        return mount_nodev(fs_type, flags, data, autofs_fill_super);
 }
 
-static struct file_system_type autofs_fs_type = {
+struct file_system_type autofs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "autofs",
        .mount          = autofs_mount,
index 846c052569dd4913e1aea268ad88a0521251002e..0e8ea2d9a2bba20b185ffee82aff9652d1012d0f 100644 (file)
@@ -87,6 +87,8 @@ static int autofs_show_options(struct seq_file *m, struct dentry *root)
                seq_printf(m, ",direct");
        else
                seq_printf(m, ",indirect");
+       if (sbi->flags & AUTOFS_SBI_STRICTEXPIRE)
+               seq_printf(m, ",strictexpire");
 #ifdef CONFIG_CHECKPOINT_RESTORE
        if (sbi->pipe)
                seq_printf(m, ",pipe_ino=%ld", file_inode(sbi->pipe)->i_ino);
@@ -109,7 +111,7 @@ static const struct super_operations autofs_sops = {
 };
 
 enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto,
-       Opt_indirect, Opt_direct, Opt_offset};
+       Opt_indirect, Opt_direct, Opt_offset, Opt_strictexpire};
 
 static const match_table_t tokens = {
        {Opt_fd, "fd=%u"},
@@ -121,24 +123,28 @@ static const match_table_t tokens = {
        {Opt_indirect, "indirect"},
        {Opt_direct, "direct"},
        {Opt_offset, "offset"},
+       {Opt_strictexpire, "strictexpire"},
        {Opt_err, NULL}
 };
 
-static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
-                        int *pgrp, bool *pgrp_set, unsigned int *type,
-                        int *minproto, int *maxproto)
+static int parse_options(char *options,
+                        struct inode *root, int *pgrp, bool *pgrp_set,
+                        struct autofs_sb_info *sbi)
 {
        char *p;
        substring_t args[MAX_OPT_ARGS];
        int option;
+       int pipefd = -1;
+       kuid_t uid;
+       kgid_t gid;
 
-       *uid = current_uid();
-       *gid = current_gid();
+       root->i_uid = current_uid();
+       root->i_gid = current_gid();
 
-       *minproto = AUTOFS_MIN_PROTO_VERSION;
-       *maxproto = AUTOFS_MAX_PROTO_VERSION;
+       sbi->min_proto = AUTOFS_MIN_PROTO_VERSION;
+       sbi->max_proto = AUTOFS_MAX_PROTO_VERSION;
 
-       *pipefd = -1;
+       sbi->pipefd = -1;
 
        if (!options)
                return 1;
@@ -152,22 +158,25 @@ static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
                token = match_token(p, tokens, args);
                switch (token) {
                case Opt_fd:
-                       if (match_int(args, pipefd))
+                       if (match_int(args, &pipefd))
                                return 1;
+                       sbi->pipefd = pipefd;
                        break;
                case Opt_uid:
                        if (match_int(args, &option))
                                return 1;
-                       *uid = make_kuid(current_user_ns(), option);
-                       if (!uid_valid(*uid))
+                       uid = make_kuid(current_user_ns(), option);
+                       if (!uid_valid(uid))
                                return 1;
+                       root->i_uid = uid;
                        break;
                case Opt_gid:
                        if (match_int(args, &option))
                                return 1;
-                       *gid = make_kgid(current_user_ns(), option);
-                       if (!gid_valid(*gid))
+                       gid = make_kgid(current_user_ns(), option);
+                       if (!gid_valid(gid))
                                return 1;
+                       root->i_gid = gid;
                        break;
                case Opt_pgrp:
                        if (match_int(args, &option))
@@ -178,27 +187,30 @@ static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
                case Opt_minproto:
                        if (match_int(args, &option))
                                return 1;
-                       *minproto = option;
+                       sbi->min_proto = option;
                        break;
                case Opt_maxproto:
                        if (match_int(args, &option))
                                return 1;
-                       *maxproto = option;
+                       sbi->max_proto = option;
                        break;
                case Opt_indirect:
-                       set_autofs_type_indirect(type);
+                       set_autofs_type_indirect(&sbi->type);
                        break;
                case Opt_direct:
-                       set_autofs_type_direct(type);
+                       set_autofs_type_direct(&sbi->type);
                        break;
                case Opt_offset:
-                       set_autofs_type_offset(type);
+                       set_autofs_type_offset(&sbi->type);
+                       break;
+               case Opt_strictexpire:
+                       sbi->flags |= AUTOFS_SBI_STRICTEXPIRE;
                        break;
                default:
                        return 1;
                }
        }
-       return (*pipefd < 0);
+       return (sbi->pipefd < 0);
 }
 
 int autofs_fill_super(struct super_block *s, void *data, int silent)
@@ -206,7 +218,6 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
        struct inode *root_inode;
        struct dentry *root;
        struct file *pipe;
-       int pipefd;
        struct autofs_sb_info *sbi;
        struct autofs_info *ino;
        int pgrp = 0;
@@ -222,12 +233,12 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
        sbi->magic = AUTOFS_SBI_MAGIC;
        sbi->pipefd = -1;
        sbi->pipe = NULL;
-       sbi->catatonic = 1;
        sbi->exp_timeout = 0;
        sbi->oz_pgrp = NULL;
        sbi->sb = s;
        sbi->version = 0;
        sbi->sub_version = 0;
+       sbi->flags = AUTOFS_SBI_CATATONIC;
        set_autofs_type_indirect(&sbi->type);
        sbi->min_proto = 0;
        sbi->max_proto = 0;
@@ -262,9 +273,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
        root->d_fsdata = ino;
 
        /* Can this call block? */
-       if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
-                         &pgrp, &pgrp_set, &sbi->type, &sbi->min_proto,
-                         &sbi->max_proto)) {
+       if (parse_options(data, root_inode, &pgrp, &pgrp_set, sbi)) {
                pr_err("called with bogus options\n");
                goto fail_dput;
        }
@@ -303,8 +312,9 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
        root_inode->i_fop = &autofs_root_operations;
        root_inode->i_op = &autofs_dir_inode_operations;
 
-       pr_debug("pipe fd = %d, pgrp = %u\n", pipefd, pid_nr(sbi->oz_pgrp));
-       pipe = fget(pipefd);
+       pr_debug("pipe fd = %d, pgrp = %u\n",
+                sbi->pipefd, pid_nr(sbi->oz_pgrp));
+       pipe = fget(sbi->pipefd);
 
        if (!pipe) {
                pr_err("could not open pipe file descriptor\n");
@@ -314,8 +324,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
        if (ret < 0)
                goto fail_fput;
        sbi->pipe = pipe;
-       sbi->pipefd = pipefd;
-       sbi->catatonic = 0;
+       sbi->flags &= ~AUTOFS_SBI_CATATONIC;
 
        /*
         * Success! Install the root dentry now to indicate completion.
index 782e57b911abcf0cd1d7aae2095333554e1f1d74..1246f396bf0e9dbffca16c6f8b856e43a9b8e05f 100644 (file)
@@ -275,8 +275,11 @@ static int autofs_mount_wait(const struct path *path, bool rcu_walk)
                pr_debug("waiting for mount name=%pd\n", path->dentry);
                status = autofs_wait(sbi, path, NFY_MOUNT);
                pr_debug("mount wait done status=%d\n", status);
+               ino->last_used = jiffies;
+               return status;
        }
-       ino->last_used = jiffies;
+       if (!(sbi->flags & AUTOFS_SBI_STRICTEXPIRE))
+               ino->last_used = jiffies;
        return status;
 }
 
@@ -510,7 +513,8 @@ static struct dentry *autofs_lookup(struct inode *dir,
        sbi = autofs_sbi(dir->i_sb);
 
        pr_debug("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
-                current->pid, task_pgrp_nr(current), sbi->catatonic,
+                current->pid, task_pgrp_nr(current),
+                sbi->flags & AUTOFS_SBI_CATATONIC,
                 autofs_oz_mode(sbi));
 
        active = autofs_lookup_active(dentry);
@@ -563,7 +567,7 @@ static int autofs_dir_symlink(struct inode *dir,
         * autofs mount is catatonic but the state of an autofs
         * file system needs to be preserved over restarts.
         */
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
        BUG_ON(!ino);
@@ -626,7 +630,7 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
         * autofs mount is catatonic but the state of an autofs
         * file system needs to be preserved over restarts.
         */
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
        if (atomic_dec_and_test(&ino->count)) {
@@ -714,7 +718,7 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
         * autofs mount is catatonic but the state of an autofs
         * file system needs to be preserved over restarts.
         */
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
        spin_lock(&sbi->lookup_lock);
@@ -759,7 +763,7 @@ static int autofs_dir_mkdir(struct inode *dir,
         * autofs mount is catatonic but the state of an autofs
         * file system needs to be preserved over restarts.
         */
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -EACCES;
 
        pr_debug("dentry %p, creating %pd\n", dentry, dentry);
index f6385c6ef0a56afe90dee6f14dd9329ee62818c2..15a3e31d09045aef788b69f6f32e4e9f28ae672f 100644 (file)
@@ -20,14 +20,14 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi)
        struct autofs_wait_queue *wq, *nwq;
 
        mutex_lock(&sbi->wq_mutex);
-       if (sbi->catatonic) {
+       if (sbi->flags & AUTOFS_SBI_CATATONIC) {
                mutex_unlock(&sbi->wq_mutex);
                return;
        }
 
        pr_debug("entering catatonic mode\n");
 
-       sbi->catatonic = 1;
+       sbi->flags |= AUTOFS_SBI_CATATONIC;
        wq = sbi->queues;
        sbi->queues = NULL;     /* Erase all wait queues */
        while (wq) {
@@ -255,7 +255,7 @@ static int validate_request(struct autofs_wait_queue **wait,
        struct autofs_wait_queue *wq;
        struct autofs_info *ino;
 
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -ENOENT;
 
        /* Wait in progress, continue; */
@@ -290,7 +290,7 @@ static int validate_request(struct autofs_wait_queue **wait,
                        if (mutex_lock_interruptible(&sbi->wq_mutex))
                                return -EINTR;
 
-                       if (sbi->catatonic)
+                       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                                return -ENOENT;
 
                        wq = autofs_find_wait(sbi, qstr);
@@ -359,7 +359,7 @@ int autofs_wait(struct autofs_sb_info *sbi,
        pid_t tgid;
 
        /* In catatonic mode, we don't wait for nobody */
-       if (sbi->catatonic)
+       if (sbi->flags & AUTOFS_SBI_CATATONIC)
                return -ENOENT;
 
        /*
index 67aef3bb89e4c491b84691089020ecb15b00fdbf..606f9378b2f03d17c3f5abefd36ecb96c57c0773 100644 (file)
@@ -1,13 +1,20 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  *     fs/bfs/bfs.h
- *     Copyright (C) 1999 Tigran Aivazian <tigran@veritas.com>
+ *     Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
  */
 #ifndef _FS_BFS_BFS_H
 #define _FS_BFS_BFS_H
 
 #include <linux/bfs_fs.h>
 
+/* In theory BFS supports up to 512 inodes, numbered from 2 (for /) up to 513 inclusive.
+   In actual fact, attempting to create the 512th inode (i.e. inode No. 513 or file No. 511)
+   will fail with ENOSPC in bfs_add_entry(): the root directory cannot contain so many entries, counting '..'.
+   So, mkfs.bfs(8) should really limit its -N option to 511 and not 512. For now, we just print a warning
+   if a filesystem is mounted with such "impossible to fill up" number of inodes */
+#define BFS_MAX_LASTI  513
+
 /*
  * BFS file system in-core superblock info
  */
@@ -17,7 +24,7 @@ struct bfs_sb_info {
        unsigned long si_freei;
        unsigned long si_lf_eblk;
        unsigned long si_lasti;
-       unsigned long *si_imap;
+       DECLARE_BITMAP(si_imap, BFS_MAX_LASTI+1);
        struct mutex bfs_lock;
 };
 
index f32f21c3bbc7b0fcdfb73b11193d3f1e52feb861..d8dfe3a0cb390db6639ad59836af75f1548aafbe 100644 (file)
@@ -2,8 +2,8 @@
 /*
  *     fs/bfs/dir.c
  *     BFS directory operations.
- *     Copyright (C) 1999,2000  Tigran Aivazian <tigran@veritas.com>
- *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
+ *     Copyright (C) 1999-2018  Tigran Aivazian <aivazian.tigran@gmail.com>
+ *  Made endianness-clean by Andrew Stribblehill <ads@wompom.org> 2005
  */
 
 #include <linux/time.h>
index 1476cdd90cfbb14a1d53b131ec7bef84b40b1c3b..0dceefc54b48abd99bfb766355ddf3e5666643ce 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *     fs/bfs/file.c
  *     BFS file operations.
- *     Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
+ *     Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
  *
  *     Make the file block allocation algorithm understand the size
  *     of the underlying block device.
index d81c148682e715a9f0ed4937185dd3b5538a9603..d136b2aaafb3a931922d912a4f836ef6536a3352 100644 (file)
@@ -1,10 +1,9 @@
 /*
  *     fs/bfs/inode.c
  *     BFS superblock and inode operations.
- *     Copyright (C) 1999-2006 Tigran Aivazian <aivazian.tigran@gmail.com>
+ *     Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
  *     From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
- *
- *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
+ *     Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
  */
 
 #include <linux/module.h>
@@ -118,12 +117,12 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        struct bfs_sb_info *info = BFS_SB(inode->i_sb);
        unsigned int ino = (u16)inode->i_ino;
-        unsigned long i_sblock;
+       unsigned long i_sblock;
        struct bfs_inode *di;
        struct buffer_head *bh;
        int err = 0;
 
-        dprintf("ino=%08x\n", ino);
+       dprintf("ino=%08x\n", ino);
 
        di = find_inode(inode->i_sb, ino, &bh);
        if (IS_ERR(di))
@@ -144,7 +143,7 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
        di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
        di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
        di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
-        i_sblock = BFS_I(inode)->i_sblock;
+       i_sblock = BFS_I(inode)->i_sblock;
        di->i_sblock = cpu_to_le32(i_sblock);
        di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
        di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
@@ -188,13 +187,13 @@ static void bfs_evict_inode(struct inode *inode)
        mark_buffer_dirty(bh);
        brelse(bh);
 
-        if (bi->i_dsk_ino) {
+       if (bi->i_dsk_ino) {
                if (bi->i_sblock)
                        info->si_freeb += bi->i_eblock + 1 - bi->i_sblock;
                info->si_freei++;
                clear_bit(ino, info->si_imap);
-               bfs_dump_imap("delete_inode", s);
-        }
+               bfs_dump_imap("evict_inode", s);
+       }
 
        /*
         * If this was the last file, make the previous block
@@ -214,7 +213,6 @@ static void bfs_put_super(struct super_block *s)
                return;
 
        mutex_destroy(&info->bfs_lock);
-       kfree(info->si_imap);
        kfree(info);
        s->s_fs_info = NULL;
 }
@@ -311,8 +309,7 @@ void bfs_dump_imap(const char *prefix, struct super_block *s)
                else
                        strcat(tmpbuf, "0");
        }
-       printf("BFS-fs: %s: lasti=%08lx <%s>\n",
-                               prefix, BFS_SB(s)->si_lasti, tmpbuf);
+       printf("%s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf);
        free_page((unsigned long)tmpbuf);
 #endif
 }
@@ -322,7 +319,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
        struct buffer_head *bh, *sbh;
        struct bfs_super_block *bfs_sb;
        struct inode *inode;
-       unsigned i, imap_len;
+       unsigned i;
        struct bfs_sb_info *info;
        int ret = -EINVAL;
        unsigned long i_sblock, i_eblock, i_eoff, s_size;
@@ -341,8 +338,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
        bfs_sb = (struct bfs_super_block *)sbh->b_data;
        if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
                if (!silent)
-                       printf("No BFS filesystem on %s (magic=%08x)\n", 
-                               s->s_id,  le32_to_cpu(bfs_sb->s_magic));
+                       printf("No BFS filesystem on %s (magic=%08x)\n", s->s_id,  le32_to_cpu(bfs_sb->s_magic));
                goto out1;
        }
        if (BFS_UNCLEAN(bfs_sb, s) && !silent)
@@ -351,18 +347,16 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
        s->s_magic = BFS_MAGIC;
 
        if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) ||
-           le32_to_cpu(bfs_sb->s_start) < BFS_BSIZE) {
-               printf("Superblock is corrupted\n");
+           le32_to_cpu(bfs_sb->s_start) < sizeof(struct bfs_super_block) + sizeof(struct bfs_dirent)) {
+               printf("Superblock is corrupted on %s\n", s->s_id);
                goto out1;
        }
 
-       info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) /
-                                       sizeof(struct bfs_inode)
-                                       + BFS_ROOT_INO - 1;
-       imap_len = (info->si_lasti / 8) + 1;
-       info->si_imap = kzalloc(imap_len, GFP_KERNEL | __GFP_NOWARN);
-       if (!info->si_imap) {
-               printf("Cannot allocate %u bytes\n", imap_len);
+       info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / sizeof(struct bfs_inode) + BFS_ROOT_INO - 1;
+       if (info->si_lasti == BFS_MAX_LASTI)
+               printf("WARNING: filesystem %s was created with 512 inodes, the real maximum is 511, mounting anyway\n", s->s_id);
+       else if (info->si_lasti > BFS_MAX_LASTI) {
+               printf("Impossible last inode number %lu > %d on %s\n", info->si_lasti, BFS_MAX_LASTI, s->s_id);
                goto out1;
        }
        for (i = 0; i < BFS_ROOT_INO; i++)
@@ -372,26 +366,25 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
        inode = bfs_iget(s, BFS_ROOT_INO);
        if (IS_ERR(inode)) {
                ret = PTR_ERR(inode);
-               goto out2;
+               goto out1;
        }
        s->s_root = d_make_root(inode);
        if (!s->s_root) {
                ret = -ENOMEM;
-               goto out2;
+               goto out1;
        }
 
        info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
-       info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1
-                       - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
+       info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
        info->si_freei = 0;
        info->si_lf_eblk = 0;
 
        /* can we read the last block? */
        bh = sb_bread(s, info->si_blocks - 1);
        if (!bh) {
-               printf("Last block not available: %lu\n", info->si_blocks - 1);
+               printf("Last block not available on %s: %lu\n", s->s_id, info->si_blocks - 1);
                ret = -EIO;
-               goto out3;
+               goto out2;
        }
        brelse(bh);
 
@@ -425,11 +418,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
                        (i_eoff != le32_to_cpu(-1) && i_eoff > s_size) ||
                        i_sblock * BFS_BSIZE > i_eoff) {
 
-                       printf("Inode 0x%08x corrupted\n", i);
+                       printf("Inode 0x%08x corrupted on %s\n", i, s->s_id);
 
                        brelse(bh);
                        ret = -EIO;
-                       goto out3;
+                       goto out2;
                }
 
                if (!di->i_ino) {
@@ -445,14 +438,12 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
        }
        brelse(bh);
        brelse(sbh);
-       bfs_dump_imap("read_super", s);
+       bfs_dump_imap("fill_super", s);
        return 0;
 
-out3:
+out2:
        dput(s->s_root);
        s->s_root = NULL;
-out2:
-       kfree(info->si_imap);
 out1:
        brelse(sbh);
 out:
@@ -482,7 +473,7 @@ static int __init init_bfs_fs(void)
        int err = init_inodecache();
        if (err)
                goto out1;
-        err = register_filesystem(&bfs_fs_type);
+       err = register_filesystem(&bfs_fs_type);
        if (err)
                goto out;
        return 0;
index 7cde3f46ad263ab084aafaefa14161902f33d4f1..d0078cbb718b4855dc520dbfae91223d499da81a 100644 (file)
@@ -42,10 +42,14 @@ static int load_script(struct linux_binprm *bprm)
        fput(bprm->file);
        bprm->file = NULL;
 
-       bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
-       if ((cp = strchr(bprm->buf, '\n')) == NULL)
-               cp = bprm->buf+BINPRM_BUF_SIZE-1;
+       for (cp = bprm->buf+2;; cp++) {
+               if (cp >= bprm->buf + BINPRM_BUF_SIZE)
+                       return -ENOEXEC;
+               if (!*cp || (*cp == '\n'))
+                       break;
+       }
        *cp = '\0';
+
        while (cp > bprm->buf) {
                cp--;
                if ((*cp == ' ') || (*cp == '\t'))
index fc126b92ea5961bd05c5447fddd3b6a3f271a02e..52abe408268088575db22ce79b851ee2f529a0c0 100644 (file)
@@ -4103,8 +4103,7 @@ int extent_readpages(struct address_space *mapping, struct list_head *pages,
 
        while (!list_empty(pages)) {
                for (nr = 0; nr < ARRAY_SIZE(pagepool) && !list_empty(pages);) {
-                       struct page *page = list_entry(pages->prev,
-                                                      struct page, lru);
+                       struct page *page = lru_to_page(pages);
 
                        prefetchw(&page->flags);
                        list_del(&page->lru);
index d60d61e8ed7de495bddd0bc799f16c2606a4c68b..52d024bfdbc12142a97ff8ec204ce4b658df6fe6 100644 (file)
@@ -2366,7 +2366,7 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
 
                balance_dirty_pages_ratelimited(mapping);
 
-               if (unlikely(fatal_signal_pending(current))) {
+               if (fatal_signal_pending(current)) {
                        err = -EINTR;
                        goto out;
                }
index 8eade7a993c1f5f120908849a38a0c80537cf505..5d0c05e288ccb3bcfc09db85b3ef949711292ad1 100644 (file)
@@ -306,7 +306,7 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
        struct ceph_osd_client *osdc =
                &ceph_inode_to_client(inode)->client->osdc;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct page *page = list_entry(page_list->prev, struct page, lru);
+       struct page *page = lru_to_page(page_list);
        struct ceph_vino vino;
        struct ceph_osd_request *req;
        u64 off;
@@ -333,8 +333,7 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
                        if (got)
                                ceph_put_cap_refs(ci, got);
                        while (!list_empty(page_list)) {
-                               page = list_entry(page_list->prev,
-                                                 struct page, lru);
+                               page = lru_to_page(page_list);
                                list_del(&page->lru);
                                put_page(page);
                        }
index 5e405164394a1c0287d8a6b7e348fe1292bccec3..e3e3a755020561d71394f328a600910e4120ca0c 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/mount.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
+#include <linux/mm.h>
 #include <asm/div64.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
@@ -3964,7 +3965,7 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
 
        INIT_LIST_HEAD(tmplist);
 
-       page = list_entry(page_list->prev, struct page, lru);
+       page = lru_to_page(page_list);
 
        /*
         * Lock the page and put it in the cache. Since no one else
index 7ebae39fbcb3750a6cb264c2e84b844ddba7e7da..a5d219d920e755aa7761253c87a1da6470f26782 100644 (file)
@@ -381,7 +381,8 @@ static void ep_nested_calls_init(struct nested_calls *ncalls)
  */
 static inline int ep_events_available(struct eventpoll *ep)
 {
-       return !list_empty(&ep->rdllist) || ep->ovflist != EP_UNACTIVE_PTR;
+       return !list_empty_careful(&ep->rdllist) ||
+               READ_ONCE(ep->ovflist) != EP_UNACTIVE_PTR;
 }
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
@@ -471,7 +472,6 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
  *                  no re-entered.
  *
  * @ncalls: Pointer to the nested_calls structure to be used for this call.
- * @max_nests: Maximum number of allowed nesting calls.
  * @nproc: Nested call core function pointer.
  * @priv: Opaque data to be passed to the @nproc callback.
  * @cookie: Cookie to be used to identify this nested call.
@@ -480,7 +480,7 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
  * Returns: Returns the code returned by the @nproc callback, or -1 if
  *          the maximum recursion limit has been exceeded.
  */
-static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+static int ep_call_nested(struct nested_calls *ncalls,
                          int (*nproc)(void *, void *, int), void *priv,
                          void *cookie, void *ctx)
 {
@@ -499,7 +499,7 @@ static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
         */
        list_for_each_entry(tncur, lsthead, llink) {
                if (tncur->ctx == ctx &&
-                   (tncur->cookie == cookie || ++call_nests > max_nests)) {
+                   (tncur->cookie == cookie || ++call_nests > EP_MAX_NESTS)) {
                        /*
                         * Ops ... loop detected or maximum nest level reached.
                         * We abort this wake by breaking the cycle itself.
@@ -573,7 +573,7 @@ static void ep_poll_safewake(wait_queue_head_t *wq)
 {
        int this_cpu = get_cpu();
 
-       ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS,
+       ep_call_nested(&poll_safewake_ncalls,
                       ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu);
 
        put_cpu();
@@ -699,7 +699,7 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
         */
        spin_lock_irq(&ep->wq.lock);
        list_splice_init(&ep->rdllist, &txlist);
-       ep->ovflist = NULL;
+       WRITE_ONCE(ep->ovflist, NULL);
        spin_unlock_irq(&ep->wq.lock);
 
        /*
@@ -713,7 +713,7 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
         * other events might have been queued by the poll callback.
         * We re-insert them inside the main ready-list here.
         */
-       for (nepi = ep->ovflist; (epi = nepi) != NULL;
+       for (nepi = READ_ONCE(ep->ovflist); (epi = nepi) != NULL;
             nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
                /*
                 * We need to check if the item is already in the list.
@@ -731,7 +731,7 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
         * releasing the lock, events will be queued in the normal way inside
         * ep->rdllist.
         */
-       ep->ovflist = EP_UNACTIVE_PTR;
+       WRITE_ONCE(ep->ovflist, EP_UNACTIVE_PTR);
 
        /*
         * Quickly re-inject items left on "txlist".
@@ -1154,10 +1154,10 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
         * semantics). All the events that happen during that period of time are
         * chained in ep->ovflist and requeued later on.
         */
-       if (unlikely(ep->ovflist != EP_UNACTIVE_PTR)) {
+       if (READ_ONCE(ep->ovflist) != EP_UNACTIVE_PTR) {
                if (epi->next == EP_UNACTIVE_PTR) {
-                       epi->next = ep->ovflist;
-                       ep->ovflist = epi;
+                       epi->next = READ_ONCE(ep->ovflist);
+                       WRITE_ONCE(ep->ovflist, epi);
                        if (epi->ws) {
                                /*
                                 * Activate ep->ws since epi->ws may get
@@ -1333,7 +1333,6 @@ static int reverse_path_check_proc(void *priv, void *cookie, int call_nests)
                                }
                        } else {
                                error = ep_call_nested(&poll_loop_ncalls,
-                                                       EP_MAX_NESTS,
                                                        reverse_path_check_proc,
                                                        child_file, child_file,
                                                        current);
@@ -1367,7 +1366,7 @@ static int reverse_path_check(void)
        /* let's call this for all tfiles */
        list_for_each_entry(current_file, &tfile_check_list, f_tfile_llink) {
                path_count_init();
-               error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
+               error = ep_call_nested(&poll_loop_ncalls,
                                        reverse_path_check_proc, current_file,
                                        current_file, current);
                if (error)
@@ -1626,21 +1625,24 @@ static __poll_t ep_send_events_proc(struct eventpoll *ep, struct list_head *head
 {
        struct ep_send_events_data *esed = priv;
        __poll_t revents;
-       struct epitem *epi;
-       struct epoll_event __user *uevent;
+       struct epitem *epi, *tmp;
+       struct epoll_event __user *uevent = esed->events;
        struct wakeup_source *ws;
        poll_table pt;
 
        init_poll_funcptr(&pt, NULL);
+       esed->res = 0;
 
        /*
         * We can loop without lock because we are passed a task private list.
         * Items cannot vanish during the loop because ep_scan_ready_list() is
         * holding "mtx" during this call.
         */
-       for (esed->res = 0, uevent = esed->events;
-            !list_empty(head) && esed->res < esed->maxevents;) {
-               epi = list_first_entry(head, struct epitem, rdllink);
+       lockdep_assert_held(&ep->mtx);
+
+       list_for_each_entry_safe(epi, tmp, head, rdllink) {
+               if (esed->res >= esed->maxevents)
+                       break;
 
                /*
                 * Activate ep->ws before deactivating epi->ws to prevent
@@ -1660,42 +1662,42 @@ static __poll_t ep_send_events_proc(struct eventpoll *ep, struct list_head *head
 
                list_del_init(&epi->rdllink);
 
-               revents = ep_item_poll(epi, &pt, 1);
-
                /*
                 * If the event mask intersect the caller-requested one,
                 * deliver the event to userspace. Again, ep_scan_ready_list()
-                * is holding "mtx", so no operations coming from userspace
+                * is holding ep->mtx, so no operations coming from userspace
                 * can change the item.
                 */
-               if (revents) {
-                       if (__put_user(revents, &uevent->events) ||
-                           __put_user(epi->event.data, &uevent->data)) {
-                               list_add(&epi->rdllink, head);
-                               ep_pm_stay_awake(epi);
-                               if (!esed->res)
-                                       esed->res = -EFAULT;
-                               return 0;
-                       }
-                       esed->res++;
-                       uevent++;
-                       if (epi->event.events & EPOLLONESHOT)
-                               epi->event.events &= EP_PRIVATE_BITS;
-                       else if (!(epi->event.events & EPOLLET)) {
-                               /*
-                                * If this file has been added with Level
-                                * Trigger mode, we need to insert back inside
-                                * the ready list, so that the next call to
-                                * epoll_wait() will check again the events
-                                * availability. At this point, no one can insert
-                                * into ep->rdllist besides us. The epoll_ctl()
-                                * callers are locked out by
-                                * ep_scan_ready_list() holding "mtx" and the
-                                * poll callback will queue them in ep->ovflist.
-                                */
-                               list_add_tail(&epi->rdllink, &ep->rdllist);
-                               ep_pm_stay_awake(epi);
-                       }
+               revents = ep_item_poll(epi, &pt, 1);
+               if (!revents)
+                       continue;
+
+               if (__put_user(revents, &uevent->events) ||
+                   __put_user(epi->event.data, &uevent->data)) {
+                       list_add(&epi->rdllink, head);
+                       ep_pm_stay_awake(epi);
+                       if (!esed->res)
+                               esed->res = -EFAULT;
+                       return 0;
+               }
+               esed->res++;
+               uevent++;
+               if (epi->event.events & EPOLLONESHOT)
+                       epi->event.events &= EP_PRIVATE_BITS;
+               else if (!(epi->event.events & EPOLLET)) {
+                       /*
+                        * If this file has been added with Level
+                        * Trigger mode, we need to insert back inside
+                        * the ready list, so that the next call to
+                        * epoll_wait() will check again the events
+                        * availability. At this point, no one can insert
+                        * into ep->rdllist besides us. The epoll_ctl()
+                        * callers are locked out by
+                        * ep_scan_ready_list() holding "mtx" and the
+                        * poll callback will queue them in ep->ovflist.
+                        */
+                       list_add_tail(&epi->rdllink, &ep->rdllist);
+                       ep_pm_stay_awake(epi);
                }
        }
 
@@ -1747,6 +1749,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
 {
        int res = 0, eavail, timed_out = 0;
        u64 slack = 0;
+       bool waiter = false;
        wait_queue_entry_t wait;
        ktime_t expires, *to = NULL;
 
@@ -1761,11 +1764,18 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
        } else if (timeout == 0) {
                /*
                 * Avoid the unnecessary trip to the wait queue loop, if the
-                * caller specified a non blocking operation.
+                * caller specified a non blocking operation. We still need
+                * lock because we could race and not see an epi being added
+                * to the ready list while in irq callback. Thus incorrectly
+                * returning 0 back to userspace.
                 */
                timed_out = 1;
+
                spin_lock_irq(&ep->wq.lock);
-               goto check_events;
+               eavail = ep_events_available(ep);
+               spin_unlock_irq(&ep->wq.lock);
+
+               goto send_events;
        }
 
 fetch_events:
@@ -1773,64 +1783,66 @@ fetch_events:
        if (!ep_events_available(ep))
                ep_busy_loop(ep, timed_out);
 
-       spin_lock_irq(&ep->wq.lock);
+       eavail = ep_events_available(ep);
+       if (eavail)
+               goto send_events;
 
-       if (!ep_events_available(ep)) {
-               /*
-                * Busy poll timed out.  Drop NAPI ID for now, we can add
-                * it back in when we have moved a socket with a valid NAPI
-                * ID onto the ready list.
-                */
-               ep_reset_busy_poll_napi_id(ep);
+       /*
+        * Busy poll timed out.  Drop NAPI ID for now, we can add
+        * it back in when we have moved a socket with a valid NAPI
+        * ID onto the ready list.
+        */
+       ep_reset_busy_poll_napi_id(ep);
 
-               /*
-                * We don't have any available event to return to the caller.
-                * We need to sleep here, and we will be wake up by
-                * ep_poll_callback() when events will become available.
-                */
+       /*
+        * We don't have any available event to return to the caller.  We need
+        * to sleep here, and we will be woken by ep_poll_callback() when events
+        * become available.
+        */
+       if (!waiter) {
+               waiter = true;
                init_waitqueue_entry(&wait, current);
-               __add_wait_queue_exclusive(&ep->wq, &wait);
 
-               for (;;) {
-                       /*
-                        * We don't want to sleep if the ep_poll_callback() sends us
-                        * a wakeup in between. That's why we set the task state
-                        * to TASK_INTERRUPTIBLE before doing the checks.
-                        */
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       /*
-                        * Always short-circuit for fatal signals to allow
-                        * threads to make a timely exit without the chance of
-                        * finding more events available and fetching
-                        * repeatedly.
-                        */
-                       if (fatal_signal_pending(current)) {
-                               res = -EINTR;
-                               break;
-                       }
-                       if (ep_events_available(ep) || timed_out)
-                               break;
-                       if (signal_pending(current)) {
-                               res = -EINTR;
-                               break;
-                       }
+               spin_lock_irq(&ep->wq.lock);
+               __add_wait_queue_exclusive(&ep->wq, &wait);
+               spin_unlock_irq(&ep->wq.lock);
+       }
 
-                       spin_unlock_irq(&ep->wq.lock);
-                       if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
-                               timed_out = 1;
+       for (;;) {
+               /*
+                * We don't want to sleep if the ep_poll_callback() sends us
+                * a wakeup in between. That's why we set the task state
+                * to TASK_INTERRUPTIBLE before doing the checks.
+                */
+               set_current_state(TASK_INTERRUPTIBLE);
+               /*
+                * Always short-circuit for fatal signals to allow
+                * threads to make a timely exit without the chance of
+                * finding more events available and fetching
+                * repeatedly.
+                */
+               if (fatal_signal_pending(current)) {
+                       res = -EINTR;
+                       break;
+               }
 
-                       spin_lock_irq(&ep->wq.lock);
+               eavail = ep_events_available(ep);
+               if (eavail)
+                       break;
+               if (signal_pending(current)) {
+                       res = -EINTR;
+                       break;
                }
 
-               __remove_wait_queue(&ep->wq, &wait);
-               __set_current_state(TASK_RUNNING);
+               if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) {
+                       timed_out = 1;
+                       break;
+               }
        }
-check_events:
-       /* Is it worth to try to dig for events ? */
-       eavail = ep_events_available(ep);
 
-       spin_unlock_irq(&ep->wq.lock);
+       __set_current_state(TASK_RUNNING);
 
+send_events:
        /*
         * Try to transfer events to user space. In case we get 0 events and
         * there's still timeout left over, we go trying again in search of
@@ -1840,6 +1852,12 @@ check_events:
            !(res = ep_send_events(ep, events, maxevents)) && !timed_out)
                goto fetch_events;
 
+       if (waiter) {
+               spin_lock_irq(&ep->wq.lock);
+               __remove_wait_queue(&ep->wq, &wait);
+               spin_unlock_irq(&ep->wq.lock);
+       }
+
        return res;
 }
 
@@ -1876,7 +1894,7 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
                        ep_tovisit = epi->ffd.file->private_data;
                        if (ep_tovisit->visited)
                                continue;
-                       error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
+                       error = ep_call_nested(&poll_loop_ncalls,
                                        ep_loop_check_proc, epi->ffd.file,
                                        ep_tovisit, current);
                        if (error != 0)
@@ -1916,7 +1934,7 @@ static int ep_loop_check(struct eventpoll *ep, struct file *file)
        int ret;
        struct eventpoll *ep_cur, *ep_next;
 
-       ret = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
+       ret = ep_call_nested(&poll_loop_ncalls,
                              ep_loop_check_proc, file, ep, current);
        /* clear visited list */
        list_for_each_entry_safe(ep_cur, ep_next, &visited_list,
index fc281b738a9822a652f7d19bb60ae15acd7a7ebf..44320d893f1a38db0a37364a997c81b714cbebe6 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -218,55 +218,10 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
        if (ret <= 0)
                return NULL;
 
-       if (write) {
-               unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
-               unsigned long ptr_size, limit;
-
-               /*
-                * Since the stack will hold pointers to the strings, we
-                * must account for them as well.
-                *
-                * The size calculation is the entire vma while each arg page is
-                * built, so each time we get here it's calculating how far it
-                * is currently (rather than each call being just the newly
-                * added size from the arg page).  As a result, we need to
-                * always add the entire size of the pointers, so that on the
-                * last call to get_arg_page() we'll actually have the entire
-                * correct size.
-                */
-               ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
-               if (ptr_size > ULONG_MAX - size)
-                       goto fail;
-               size += ptr_size;
-
-               acct_arg_size(bprm, size / PAGE_SIZE);
-
-               /*
-                * We've historically supported up to 32 pages (ARG_MAX)
-                * of argument strings even with small stacks
-                */
-               if (size <= ARG_MAX)
-                       return page;
-
-               /*
-                * Limit to 1/4 of the max stack size or 3/4 of _STK_LIM
-                * (whichever is smaller) for the argv+env strings.
-                * This ensures that:
-                *  - the remaining binfmt code will not run out of stack space,
-                *  - the program will have a reasonable amount of stack left
-                *    to work from.
-                */
-               limit = _STK_LIM / 4 * 3;
-               limit = min(limit, bprm->rlim_stack.rlim_cur / 4);
-               if (size > limit)
-                       goto fail;
-       }
+       if (write)
+               acct_arg_size(bprm, vma_pages(bprm->vma));
 
        return page;
-
-fail:
-       put_page(page);
-       return NULL;
 }
 
 static void put_arg_page(struct page *page)
@@ -492,6 +447,50 @@ static int count(struct user_arg_ptr argv, int max)
        return i;
 }
 
+static int prepare_arg_pages(struct linux_binprm *bprm,
+                       struct user_arg_ptr argv, struct user_arg_ptr envp)
+{
+       unsigned long limit, ptr_size;
+
+       bprm->argc = count(argv, MAX_ARG_STRINGS);
+       if (bprm->argc < 0)
+               return bprm->argc;
+
+       bprm->envc = count(envp, MAX_ARG_STRINGS);
+       if (bprm->envc < 0)
+               return bprm->envc;
+
+       /*
+        * Limit to 1/4 of the max stack size or 3/4 of _STK_LIM
+        * (whichever is smaller) for the argv+env strings.
+        * This ensures that:
+        *  - the remaining binfmt code will not run out of stack space,
+        *  - the program will have a reasonable amount of stack left
+        *    to work from.
+        */
+       limit = _STK_LIM / 4 * 3;
+       limit = min(limit, bprm->rlim_stack.rlim_cur / 4);
+       /*
+        * We've historically supported up to 32 pages (ARG_MAX)
+        * of argument strings even with small stacks
+        */
+       limit = max_t(unsigned long, limit, ARG_MAX);
+       /*
+        * We must account for the size of all the argv and envp pointers to
+        * the argv and envp strings, since they will also take up space in
+        * the stack. They aren't stored until much later when we can't
+        * signal to the parent that the child has run out of stack space.
+        * Instead, calculate it here so it's possible to fail gracefully.
+        */
+       ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
+       if (limit <= ptr_size)
+               return -E2BIG;
+       limit -= ptr_size;
+
+       bprm->argmin = bprm->p - limit;
+       return 0;
+}
+
 /*
  * 'copy_strings()' copies argument/environment strings from the old
  * processes's memory to the new process's stack.  The call to get_user_pages()
@@ -527,6 +526,10 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
                pos = bprm->p;
                str += len;
                bprm->p -= len;
+#ifdef CONFIG_MMU
+               if (bprm->p < bprm->argmin)
+                       goto out;
+#endif
 
                while (len > 0) {
                        int offset, bytes_to_copy;
@@ -1084,7 +1087,7 @@ static int de_thread(struct task_struct *tsk)
                __set_current_state(TASK_KILLABLE);
                spin_unlock_irq(lock);
                schedule();
-               if (unlikely(__fatal_signal_pending(tsk)))
+               if (__fatal_signal_pending(tsk))
                        goto killed;
                spin_lock_irq(lock);
        }
@@ -1112,7 +1115,7 @@ static int de_thread(struct task_struct *tsk)
                        write_unlock_irq(&tasklist_lock);
                        cgroup_threadgroup_change_end(tsk);
                        schedule();
-                       if (unlikely(__fatal_signal_pending(tsk)))
+                       if (__fatal_signal_pending(tsk))
                                goto killed;
                }
 
@@ -1789,12 +1792,8 @@ static int __do_execve_file(int fd, struct filename *filename,
        if (retval)
                goto out_unmark;
 
-       bprm->argc = count(argv, MAX_ARG_STRINGS);
-       if ((retval = bprm->argc) < 0)
-               goto out;
-
-       bprm->envc = count(envp, MAX_ARG_STRINGS);
-       if ((retval = bprm->envc) < 0)
+       retval = prepare_arg_pages(bprm, argv, envp);
+       if (retval < 0)
                goto out;
 
        retval = prepare_binprm(bprm);
index f461d75ac049f04e2a180228530c507902269df0..6aa282ee455a929aa2b5927e39d0f20c7bd33acd 100644 (file)
@@ -128,7 +128,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
 
                prefetchw(&page->flags);
                if (pages) {
-                       page = list_entry(pages->prev, struct page, lru);
+                       page = lru_to_page(pages);
                        list_del(&page->lru);
                        if (add_to_page_cache_lru(page, mapping, page->index,
                                  readahead_gfp_mask(mapping)))
index 78d501c1fb658f153a9683a95c560a3483c70cd7..738e427e2d2150e83b67de7c272ca474cb299920 100644 (file)
@@ -363,7 +363,7 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
 
        *phys = 0;
        *mapped_blocks = 0;
-       if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) {
+       if (!is_fat32(sbi) && (inode->i_ino == MSDOS_ROOT_INO)) {
                if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) {
                        *phys = sector + sbi->dir_start;
                        *mapped_blocks = 1;
index 0295a095b9205352c6c993edf58f51a4147c1aea..9d01db37183f2616feec648fd63c9ab292a45b8f 100644 (file)
@@ -57,7 +57,7 @@ static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
        if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1)
                return;
        /* root dir of FAT12/FAT16 */
-       if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
+       if (!is_fat32(sbi) && (dir->i_ino == MSDOS_ROOT_INO))
                return;
 
        bh = sb_find_get_block(sb, phys);
@@ -1313,7 +1313,7 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
                }
        }
        if (dir->i_ino == MSDOS_ROOT_INO) {
-               if (sbi->fat_bits != 32)
+               if (!is_fat32(sbi))
                        goto error;
        } else if (MSDOS_I(dir)->i_start == 0) {
                fat_msg(sb, KERN_ERR, "Corrupted directory (i_pos %lld)",
index 4e1b2f6df5e6a63f7db7f5b92d96c443de915171..922a0c6ba46c49d45c6d019b71ef5f0c2c61b583 100644 (file)
@@ -142,6 +142,34 @@ static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb)
        return sb->s_fs_info;
 }
 
+/*
+ * Functions that determine the variant of the FAT file system (i.e.,
+ * whether this is FAT12, FAT16 or FAT32.
+ */
+static inline bool is_fat12(const struct msdos_sb_info *sbi)
+{
+       return sbi->fat_bits == 12;
+}
+
+static inline bool is_fat16(const struct msdos_sb_info *sbi)
+{
+       return sbi->fat_bits == 16;
+}
+
+static inline bool is_fat32(const struct msdos_sb_info *sbi)
+{
+       return sbi->fat_bits == 32;
+}
+
+/* Maximum number of clusters */
+static inline u32 max_fat(struct super_block *sb)
+{
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+
+       return is_fat32(sbi) ? MAX_FAT32 :
+               is_fat16(sbi) ? MAX_FAT16 : MAX_FAT12;
+}
+
 static inline struct msdos_inode_info *MSDOS_I(struct inode *inode)
 {
        return container_of(inode, struct msdos_inode_info, vfs_inode);
@@ -257,7 +285,7 @@ static inline int fat_get_start(const struct msdos_sb_info *sbi,
                                const struct msdos_dir_entry *de)
 {
        int cluster = le16_to_cpu(de->start);
-       if (sbi->fat_bits == 32)
+       if (is_fat32(sbi))
                cluster |= (le16_to_cpu(de->starthi) << 16);
        return cluster;
 }
index f58c0cacc531df1c6c439325cb6c574cd704486d..495edeafd60a0c073be86829489a0b8ae58d8ff9 100644 (file)
@@ -290,19 +290,17 @@ void fat_ent_access_init(struct super_block *sb)
 
        mutex_init(&sbi->fat_lock);
 
-       switch (sbi->fat_bits) {
-       case 32:
+       if (is_fat32(sbi)) {
                sbi->fatent_shift = 2;
                sbi->fatent_ops = &fat32_ops;
-               break;
-       case 16:
+       } else if (is_fat16(sbi)) {
                sbi->fatent_shift = 1;
                sbi->fatent_ops = &fat16_ops;
-               break;
-       case 12:
+       } else if (is_fat12(sbi)) {
                sbi->fatent_shift = -1;
                sbi->fatent_ops = &fat12_ops;
-               break;
+       } else {
+               fat_fs_error(sb, "invalid FAT variant, %u bits", sbi->fat_bits);
        }
 }
 
@@ -310,7 +308,7 @@ static void mark_fsinfo_dirty(struct super_block *sb)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
 
-       if (sb_rdonly(sb) || sbi->fat_bits != 32)
+       if (sb_rdonly(sb) || !is_fat32(sbi))
                return;
 
        __mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC);
@@ -327,7 +325,7 @@ static inline int fat_ent_update_ptr(struct super_block *sb,
        /* Is this fatent's blocks including this entry? */
        if (!fatent->nr_bhs || bhs[0]->b_blocknr != blocknr)
                return 0;
-       if (sbi->fat_bits == 12) {
+       if (is_fat12(sbi)) {
                if ((offset + 1) < sb->s_blocksize) {
                        /* This entry is on bhs[0]. */
                        if (fatent->nr_bhs == 2) {
index c0b5b5c3373bd967f86697f9aa39b75942399877..79bb0e73a65f48b2de5f7e3645748b535e81b6d1 100644 (file)
@@ -686,7 +686,7 @@ static void fat_set_state(struct super_block *sb,
 
        b = (struct fat_boot_sector *) bh->b_data;
 
-       if (sbi->fat_bits == 32) {
+       if (is_fat32(sbi)) {
                if (set)
                        b->fat32.state |= FAT_STATE_DIRTY;
                else
@@ -1396,7 +1396,7 @@ static int fat_read_root(struct inode *inode)
        inode->i_mode = fat_make_mode(sbi, ATTR_DIR, S_IRWXUGO);
        inode->i_op = sbi->dir_ops;
        inode->i_fop = &fat_dir_operations;
-       if (sbi->fat_bits == 32) {
+       if (is_fat32(sbi)) {
                MSDOS_I(inode)->i_start = sbi->root_cluster;
                error = fat_calc_dir_size(inode);
                if (error < 0)
@@ -1423,7 +1423,7 @@ static unsigned long calc_fat_clusters(struct super_block *sb)
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
 
        /* Divide first to avoid overflow */
-       if (sbi->fat_bits != 12) {
+       if (!is_fat12(sbi)) {
                unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
                return ent_per_sec * sbi->fat_length;
        }
@@ -1743,7 +1743,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
        }
 
        /* interpret volume ID as a little endian 32 bit integer */
-       if (sbi->fat_bits == 32)
+       if (is_fat32(sbi))
                sbi->vol_id = bpb.fat32_vol_id;
        else /* fat 16 or 12 */
                sbi->vol_id = bpb.fat16_vol_id;
@@ -1769,11 +1769,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
 
        total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
 
-       if (sbi->fat_bits != 32)
+       if (!is_fat32(sbi))
                sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
 
        /* some OSes set FAT_STATE_DIRTY and clean it on unmount. */
-       if (sbi->fat_bits == 32)
+       if (is_fat32(sbi))
                sbi->dirty = bpb.fat32_state & FAT_STATE_DIRTY;
        else /* fat 16 or 12 */
                sbi->dirty = bpb.fat16_state & FAT_STATE_DIRTY;
@@ -1781,7 +1781,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
        /* check that FAT table does not overflow */
        fat_clusters = calc_fat_clusters(sb);
        total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
-       if (total_clusters > MAX_FAT(sb)) {
+       if (total_clusters > max_fat(sb)) {
                if (!silent)
                        fat_msg(sb, KERN_ERR, "count of clusters too big (%u)",
                               total_clusters);
@@ -1803,11 +1803,15 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
        fat_ent_access_init(sb);
 
        /*
-        * The low byte of FAT's first entry must have same value with
-        * media-field.  But in real world, too many devices is
-        * writing wrong value.  So, removed that validity check.
+        * The low byte of the first FAT entry must have the same value as
+        * the media field of the boot sector. But in real world, too many
+        * devices are writing wrong values. So, removed that validity check.
         *
-        * if (FAT_FIRST_ENT(sb, media) != first)
+        * The removed check compared the first FAT entry to a value dependent
+        * on the media field like this:
+        * == (0x0F00 | media), for FAT12
+        * == (0XFF00 | media), for FAT16
+        * == (0x0FFFFF | media), for FAT32
         */
 
        error = -EINVAL;
index fce0a76f3f1e4c2617934a93c027d0af0d074b45..4fc950bb64335c6be4881223afef072794d043e5 100644 (file)
@@ -64,7 +64,7 @@ int fat_clusters_flush(struct super_block *sb)
        struct buffer_head *bh;
        struct fat_boot_fsinfo *fsinfo;
 
-       if (sbi->fat_bits != 32)
+       if (!is_fat32(sbi))
                return 0;
 
        bh = sb_bread(sb, sbi->fsinfo_sector);
index f37662675c3a3467e36510d087833236415dbf67..29a9dcfbe81f72e24efea8f683fed86b955123b3 100644 (file)
@@ -565,6 +565,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
        .symlink                = hfsplus_symlink,
        .mknod                  = hfsplus_mknod,
        .rename                 = hfsplus_rename,
+       .getattr                = hfsplus_getattr,
        .listxattr              = hfsplus_listxattr,
 };
 
index dd7ad9f13e3aad58f9cd1552b08a67f95def09bc..b8471bf05def9581e39a4aeb8424824e2773be14 100644 (file)
@@ -488,6 +488,8 @@ void hfsplus_inode_write_fork(struct inode *inode,
                              struct hfsplus_fork_raw *fork);
 int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd);
 int hfsplus_cat_write_inode(struct inode *inode);
+int hfsplus_getattr(const struct path *path, struct kstat *stat,
+                   u32 request_mask, unsigned int query_flags);
 int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
                       int datasync);
 
index d7ab9d8c4b674380f6aa9470910e860dd61cc87a..d131c8ea7eb616708e26ff55eca114772d25dd9d 100644 (file)
@@ -270,6 +270,26 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
        return 0;
 }
 
+int hfsplus_getattr(const struct path *path, struct kstat *stat,
+                   u32 request_mask, unsigned int query_flags)
+{
+       struct inode *inode = d_inode(path->dentry);
+       struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+
+       if (inode->i_flags & S_APPEND)
+               stat->attributes |= STATX_ATTR_APPEND;
+       if (inode->i_flags & S_IMMUTABLE)
+               stat->attributes |= STATX_ATTR_IMMUTABLE;
+       if (hip->userflags & HFSPLUS_FLG_NODUMP)
+               stat->attributes |= STATX_ATTR_NODUMP;
+
+       stat->attributes_mask |= STATX_ATTR_APPEND | STATX_ATTR_IMMUTABLE |
+                                STATX_ATTR_NODUMP;
+
+       generic_fillattr(inode, stat);
+       return 0;
+}
+
 int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
                       int datasync)
 {
@@ -329,6 +349,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
 
 static const struct inode_operations hfsplus_file_inode_operations = {
        .setattr        = hfsplus_setattr,
+       .getattr        = hfsplus_getattr,
        .listxattr      = hfsplus_listxattr,
 };
 
index eb1ce30412dc3e09d1fbd4c8e890d86c2d0a4c9f..832c1759a09af49b029bfa49583fcda2d791ad95 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/quotaops.h>
 #include <linux/blkdev.h>
 #include <linux/uio.h>
+#include <linux/mm.h>
 
 #include <cluster/masklog.h>
 
@@ -397,7 +398,7 @@ static int ocfs2_readpages(struct file *filp, struct address_space *mapping,
         * Check whether a remote node truncated this file - we just
         * drop out in that case as it's not worth handling here.
         */
-       last = list_entry(pages->prev, struct page, lru);
+       last = lru_to_page(pages);
        start = (loff_t)last->index << PAGE_SHIFT;
        if (start >= i_size_read(inode))
                goto out_unlock;
index fe53381b26b1841c3cae47dbe630d400e6021af8..f038235c64bdf6d840f0d37fde29818ffa5c6e65 100644 (file)
@@ -77,7 +77,7 @@ static int orangefs_readpages(struct file *file,
        for (page_idx = 0; page_idx < nr_pages; page_idx++) {
                struct page *page;
 
-               page = list_entry(pages->prev, struct page, lru);
+               page = lru_to_page(pages);
                list_del(&page->lru);
                if (!add_to_page_cache(page,
                                       mapping,
index c4e98c9c16217b85c6b97afc8e829130205cfede..443bcd8c3c1991d2d9160ef3a94622b283e8b349 100644 (file)
@@ -105,7 +105,7 @@ static int wait_for_free(struct slot_map *m)
                        left = t;
                else
                        left = t + (left - n);
-               if (unlikely(signal_pending(current)))
+               if (signal_pending(current))
                        left = -EINTR;
        } while (left > 0);
 
index d7fd1ca807d2c32ca28c78bd852d50b66e001822..633a6346257346595a71843092fb79efd71c14f8 100644 (file)
@@ -581,8 +581,10 @@ static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
        /*
         * print the file header
         */
-       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
-                 "Limit", "Soft Limit", "Hard Limit", "Units");
+       seq_puts(m, "Limit                     "
+               "Soft Limit           "
+               "Hard Limit           "
+               "Units     \n");
 
        for (i = 0; i < RLIM_NLIMITS; i++) {
                if (rlim[i].rlim_cur == RLIM_INFINITY)
@@ -2356,10 +2358,13 @@ static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
                return -ESRCH;
 
        if (p != current) {
-               if (!capable(CAP_SYS_NICE)) {
+               rcu_read_lock();
+               if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
+                       rcu_read_unlock();
                        count = -EPERM;
                        goto out;
                }
+               rcu_read_unlock();
 
                err = security_task_setscheduler(p);
                if (err) {
@@ -2392,11 +2397,14 @@ static int timerslack_ns_show(struct seq_file *m, void *v)
                return -ESRCH;
 
        if (p != current) {
-
-               if (!capable(CAP_SYS_NICE)) {
+               rcu_read_lock();
+               if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
+                       rcu_read_unlock();
                        err = -EPERM;
                        goto out;
                }
+               rcu_read_unlock();
+
                err = security_task_getscheduler(p);
                if (err)
                        goto out;
index 5792f9e39466ef4420720c737b3a010da17a986f..da649ccd680431424c2d5ec82f6fa2487f5a0c30 100644 (file)
@@ -59,7 +59,6 @@ static struct kmem_cache *pde_opener_cache __ro_after_init;
 static struct inode *proc_alloc_inode(struct super_block *sb)
 {
        struct proc_inode *ei;
-       struct inode *inode;
 
        ei = kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL);
        if (!ei)
@@ -71,8 +70,7 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
        ei->sysctl = NULL;
        ei->sysctl_entry = NULL;
        ei->ns_ops = NULL;
-       inode = &ei->vfs_inode;
-       return inode;
+       return &ei->vfs_inode;
 }
 
 static void proc_i_callback(struct rcu_head *head)
index b161cfa0f9fa15dce4e2afdc7d71bd0b3925ba3c..98f8adc17345311c25a18708079d554e833e894c 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/dcache.h>
+#include "internal.h"
 
 unsigned name_to_int(const struct qstr *qstr)
 {
index 62daf940989df977d94be029beafcca21a777338..c8455cc28841afe18cfa24f7c24280836bfc58b7 100644 (file)
@@ -9,7 +9,7 @@
  * This is defined the same way as ffs.
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
-static __always_inline int fls(int x)
+static __always_inline int fls(unsigned int x)
 {
        return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
 }
index 753aecaab641a82d7f218988fcebe0751f7149ff..b168bb10e1be17bb6394e749c238da3940ea3a01 100644 (file)
@@ -10,7 +10,7 @@
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 
-static __always_inline int fls(int x)
+static __always_inline int fls(unsigned int x)
 {
        int r = 32;
 
index e9f5fe69df312d022648dd69e21ca00d2daf45a5..03200a8c01787c68abcb63c1d8ea267de40a8093 100644 (file)
@@ -25,6 +25,7 @@ struct linux_binprm {
 #endif
        struct mm_struct *mm;
        unsigned long p; /* current top of mem */
+       unsigned long argmin; /* rlimit marker for copy_strings() */
        unsigned int
                /*
                 * True after the bprm_set_creds hook has been called once
index 43d1fd50d433d3a62cd428d0ea1d0ef7e4bd4366..faeec7433aab024bf00e6e7108f4bc461afbc26b 100644 (file)
@@ -5,21 +5,8 @@
 #include <linux/compiler.h>
 
 #ifdef __CHECKER__
-#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
-#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
 #define BUILD_BUG_ON_ZERO(e) (0)
-#define BUILD_BUG_ON_INVALID(e) (0)
-#define BUILD_BUG_ON_MSG(cond, msg) (0)
-#define BUILD_BUG_ON(condition) (0)
-#define BUILD_BUG() (0)
 #else /* __CHECKER__ */
-
-/* Force a compilation error if a constant expression is not a power of 2 */
-#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)       \
-       BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
-#define BUILD_BUG_ON_NOT_POWER_OF_2(n)                 \
-       BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
-
 /*
  * Force a compilation error if condition is true, but also produce a
  * result (of value 0 and type size_t), so the expression can be used
  * aren't permitted).
  */
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#endif /* __CHECKER__ */
+
+/* Force a compilation error if a constant expression is not a power of 2 */
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)       \
+       BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n)                 \
+       BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
 
 /*
  * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
  * If you have some code which relies on certain constants being equal, or
  * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
  * detect if someone changes it.
- *
- * The implementation uses gcc's reluctance to create a negative array, but gcc
- * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
- * inline functions).  Luckily, in 4.3 they added the "error" function
- * attribute just for this type of case.  Thus, we use a negative sized array
- * (should always create an error on gcc versions older than 4.4) and then call
- * an undefined function with the error attribute (should always create an
- * error on gcc 4.3 and later).  If for some reason, neither creates a
- * compile-time error, we'll still have a link-time error, which is harder to
- * track down.
  */
-#ifndef __OPTIMIZE__
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-#else
 #define BUILD_BUG_ON(condition) \
        BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
-#endif
 
 /**
  * BUILD_BUG - break compile if used.
@@ -78,6 +58,4 @@
  */
 #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
 
-#endif /* __CHECKER__ */
-
 #endif /* _LINUX_BUILD_BUG_H */
index 872f930f1b06d4bbb21f1d371a1d63d306d695dd..dd0a452373e71541c670c916ac886183582b517e 100644 (file)
@@ -51,7 +51,8 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map,
                        unsigned long size,
                        unsigned long start,
                        unsigned int nr,
-                       void *data, struct gen_pool *pool);
+                       void *data, struct gen_pool *pool,
+                       unsigned long start_addr);
 
 /*
  *  General purpose special memory pool descriptor.
@@ -131,24 +132,24 @@ extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo,
 
 extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool);
+               struct gen_pool *pool, unsigned long start_addr);
 
 extern unsigned long gen_pool_fixed_alloc(unsigned long *map,
                unsigned long size, unsigned long start, unsigned int nr,
-               void *data, struct gen_pool *pool);
+               void *data, struct gen_pool *pool, unsigned long start_addr);
 
 extern unsigned long gen_pool_first_fit_align(unsigned long *map,
                unsigned long size, unsigned long start, unsigned int nr,
-               void *data, struct gen_pool *pool);
+               void *data, struct gen_pool *pool, unsigned long start_addr);
 
 
 extern unsigned long gen_pool_first_fit_order_align(unsigned long *map,
                unsigned long size, unsigned long start, unsigned int nr,
-               void *data, struct gen_pool *pool);
+               void *data, struct gen_pool *pool, unsigned long start_addr);
 
 extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool);
+               struct gen_pool *pool, unsigned long start_addr);
 
 
 extern struct gen_pool *devm_gen_pool_create(struct device *dev,
index d6aac75b51baab469d05ad6ca816b46bcd590906..8f0e68e250a760abbc2dc134c7c3b76760a2c764 100644 (file)
@@ -527,6 +527,7 @@ static inline u32 int_sqrt64(u64 x)
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;           /* If set, an oops, panic(), BUG() or die() is in progress */
 extern int panic_timeout;
+extern unsigned long panic_print;
 extern int panic_on_oops;
 extern int panic_on_unrecovered_nmi;
 extern int panic_on_io_nmi;
index ea1f12d15365bd8517f2b57f7bf3ab35a289bae6..80bb6408fe73a8744c733362abf5446b237156ab 100644 (file)
@@ -171,6 +171,8 @@ extern int overcommit_kbytes_handler(struct ctl_table *, int, void __user *,
 /* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */
 #define PAGE_ALIGNED(addr)     IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
 
+#define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
+
 /*
  * Linux kernel virtual memory manager primitives.
  * The idea being to have a "virtual" mm in the same way
@@ -1873,8 +1875,8 @@ static inline void mm_inc_nr_ptes(struct mm_struct *mm) {}
 static inline void mm_dec_nr_ptes(struct mm_struct *mm) {}
 #endif
 
-int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
-int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd);
+int __pte_alloc_kernel(pmd_t *pmd);
 
 /*
  * The following ifdef needed to get the 4level-fixup.h header to work.
@@ -2005,18 +2007,17 @@ static inline void pgtable_page_dtor(struct page *page)
        pte_unmap(pte);                                 \
 } while (0)
 
-#define pte_alloc(mm, pmd, address)                    \
-       (unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, pmd, address))
+#define pte_alloc(mm, pmd) (unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, pmd))
 
 #define pte_alloc_map(mm, pmd, address)                        \
-       (pte_alloc(mm, pmd, address) ? NULL : pte_offset_map(pmd, address))
+       (pte_alloc(mm, pmd) ? NULL : pte_offset_map(pmd, address))
 
 #define pte_alloc_map_lock(mm, pmd, address, ptlp)     \
-       (pte_alloc(mm, pmd, address) ?                  \
+       (pte_alloc(mm, pmd) ?                   \
                 NULL : pte_offset_map_lock(mm, pmd, address, ptlp))
 
 #define pte_alloc_kernel(pmd, address)                 \
-       ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
+       ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd))? \
                NULL: pte_offset_kernel(pmd, address))
 
 #if USE_SPLIT_PMD_PTLOCKS
index 10191c28fc04ce22c605d54a87257ee5ff427651..04ec454d44cefd0dbd2ffb1b82842b220a14d2cf 100644 (file)
@@ -124,7 +124,4 @@ static __always_inline enum lru_list page_lru(struct page *page)
        }
        return lru;
 }
-
-#define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
-
 #endif
diff --git a/include/linux/pl353-smc.h b/include/linux/pl353-smc.h
new file mode 100644 (file)
index 0000000..0e0d3df
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ARM PL353 SMC Driver Header
+ *
+ * Copyright (C) 2012 - 2018 Xilinx, Inc
+ */
+
+#ifndef __LINUX_PL353_SMC_H
+#define __LINUX_PL353_SMC_H
+
+enum pl353_smc_ecc_mode {
+       PL353_SMC_ECCMODE_BYPASS = 0,
+       PL353_SMC_ECCMODE_APB = 1,
+       PL353_SMC_ECCMODE_MEM = 2
+};
+
+enum pl353_smc_mem_width {
+       PL353_SMC_MEM_WIDTH_8 = 0,
+       PL353_SMC_MEM_WIDTH_16 = 1
+};
+
+u32 pl353_smc_get_ecc_val(int ecc_reg);
+bool pl353_smc_ecc_is_busy(void);
+int pl353_smc_get_nand_int_status_raw(void);
+void pl353_smc_clr_nand_int(void);
+int pl353_smc_set_ecc_mode(enum pl353_smc_ecc_mode mode);
+int pl353_smc_set_ecc_pg_size(unsigned int pg_sz);
+int pl353_smc_set_buswidth(unsigned int bw);
+void pl353_smc_set_cycles(u32 timings[]);
+#endif
index 55aa96975fa268081df984fc5103d6e6c467f0bc..77740a506ebbb96cb31aeec9bce44a33f73e23e7 100644 (file)
@@ -264,7 +264,7 @@ static inline void show_regs_print_info(const char *log_lvl)
 {
 }
 
-static inline asmlinkage void dump_stack(void)
+static inline void dump_stack(void)
 {
 }
 
index 06996ad4f2bc1d2e075f65d492beb734828c9149..1637385bcc171a8476fb24b908bd87925fffba52 100644 (file)
@@ -67,6 +67,9 @@ extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
 extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
 extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
 #else
+
+#include <linux/errno.h>
+
 static inline
 int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 {
index 108ede99e5335033526f754ba640f8fd0205f457..44c6f15800ff554ebc36994106e482bb62e2bb4b 100644 (file)
@@ -39,6 +39,8 @@ void __noreturn do_task_dead(void);
 
 extern void proc_caches_init(void);
 
+extern void fork_init(void);
+
 extern void release_task(struct task_struct * p);
 
 #ifdef CONFIG_HAVE_COPY_THREAD_TLS
index bf2523867a02a549197060100b32492a245d09ca..37b226e8df13f3b6235277485519b5de37cf6fe2 100644 (file)
@@ -264,7 +264,7 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
        probe_kernel_read(&retval, addr, sizeof(retval))
 
 #ifndef user_access_begin
-#define user_access_begin() do { } while (0)
+#define user_access_begin(ptr,len) access_ok(ptr, len)
 #define user_access_end() do { } while (0)
 #define unsafe_get_user(x, ptr, err) do { if (unlikely(__get_user(x, ptr))) goto err; } while (0)
 #define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
index 9e67fd359d589934b331679ae08bf6aa8157bb11..36a7e3f18e6999b56d02585d6f774463ee0d41d6 100644 (file)
@@ -378,6 +378,7 @@ enum {
 #define AUDIT_ARCH_ARM         (EM_ARM|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_ARMEB       (EM_ARM)
 #define AUDIT_ARCH_CRIS                (EM_CRIS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_CSKY                (EM_CSKY|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_FRV         (EM_FRV)
 #define AUDIT_ARCH_I386                (EM_386|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_IA64                (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
index df31aa9c9a8c3abe699e5875d814eb354257bd25..082119630b49c2575512f7c7a876b4feff67c10b 100644 (file)
@@ -23,7 +23,7 @@
 #define AUTOFS_MIN_PROTO_VERSION       3
 #define AUTOFS_MAX_PROTO_VERSION       5
 
-#define AUTOFS_PROTO_SUBVERSION                3
+#define AUTOFS_PROTO_SUBVERSION                4
 
 /*
  * The wait_queue_token (autofs_wqt_t) is part of a structure which is passed
index 940b04772af801345a07687c0f920a5dd9ce4cfb..08f6b495635982cfbd33963e136ed889c5b7d1e3 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
  *     include/linux/bfs_fs.h - BFS data structures on disk.
- *     Copyright (C) 1999 Tigran Aivazian <tigran@veritas.com>
+ *     Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
  */
 
 #ifndef _LINUX_BFS_FS_H
index d2fb964432f335f95c27b9574ea3c22980c2200b..0c3000faedbae3f831c5e62c4cd0676e1a71ead5 100644 (file)
@@ -44,6 +44,7 @@
 #define EM_TILEGX      191     /* Tilera TILE-Gx */
 #define EM_RISCV       243     /* RISC-V */
 #define EM_BPF         247     /* Linux BPF - in-kernel virtual machine */
+#define EM_CSKY                252     /* C-SKY */
 #define EM_FRV         0x5441  /* Fujitsu FR-V */
 
 /*
index fde753735abaecacf6c4765218a0ac4686c28b61..a5773899f4d910a8f9eee1e6bacd5b0ea1cfba48 100644 (file)
@@ -58,9 +58,6 @@
 #define MSDOS_DOT      ".          "   /* ".", padded to MSDOS_NAME chars */
 #define MSDOS_DOTDOT   "..         "   /* "..", padded to MSDOS_NAME chars */
 
-#define FAT_FIRST_ENT(s, x)    ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
-       MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
-
 /* start of data cluster's entry (number of reserved clusters) */
 #define FAT_START_ENT  2
 
@@ -68,8 +65,6 @@
 #define MAX_FAT12      0xFF4
 #define MAX_FAT16      0xFFF4
 #define MAX_FAT32      0x0FFFFFF6
-#define MAX_FAT(s)     (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
-       MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
 
 /* bad cluster mark */
 #define BAD_FAT12      0xFF7
@@ -135,7 +130,7 @@ struct fat_boot_sector {
                                                   for mount state. */
                        __u8    signature;  /* extended boot signature */
                        __u8    vol_id[4];      /* volume ID */
-                       __u8    vol_label[11];  /* volume label */
+                       __u8    vol_label[MSDOS_NAME];  /* volume label */
                        __u8    fs_type[8];             /* file system type */
                        /* other fields are not added here */
                } fat16;
@@ -158,7 +153,7 @@ struct fat_boot_sector {
                                                   for mount state. */
                        __u8    signature;  /* extended boot signature */
                        __u8    vol_id[4];      /* volume ID */
-                       __u8    vol_label[11];  /* volume label */
+                       __u8    vol_label[MSDOS_NAME];  /* volume label */
                        __u8    fs_type[8];             /* file system type */
                        /* other fields are not added here */
                } fat32;
index dce5f9dae1210455734e555044749f94d399594e..df4a7534e23986dbd1a5ba354a418ea55f929e9e 100644 (file)
 /* MediaTek BTIF */
 #define PORT_MTK_BTIF  117
 
+/* RDA UART */
+#define PORT_RDA       118
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
index d71013fffaf65b520420a4d04d2347f450c2f598..87aa2a6d91256654cacc38c98658ff908ab4e86c 100644 (file)
@@ -153,6 +153,7 @@ enum
        KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
        KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
        KERN_PANIC_ON_WARN=77, /* int: call panic() in WARN() functions */
+       KERN_PANIC_PRINT=78, /* ulong: bitmask to print system info on panic */
 };
 
 
index fca899622937f48be0b47b25479fe3bff2252fcf..7cea802d00efa3bd7c676af35b7ab676dd1a00a6 100644 (file)
@@ -550,7 +550,6 @@ skip:
        initrd_end = 0;
 }
 
-#ifdef CONFIG_BLK_DEV_RAM
 #define BUF_SIZE 1024
 static void __init clean_rootfs(void)
 {
@@ -597,7 +596,6 @@ static void __init clean_rootfs(void)
        ksys_close(fd);
        kfree(buf);
 }
-#endif
 
 static int __init populate_rootfs(void)
 {
@@ -640,8 +638,10 @@ static int __init populate_rootfs(void)
                printk(KERN_INFO "Unpacking initramfs...\n");
                err = unpack_to_rootfs((char *)initrd_start,
                        initrd_end - initrd_start);
-               if (err)
+               if (err) {
                        printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
+                       clean_rootfs();
+               }
                free_initrd();
 #endif
        }
index 86d894852bef8b4e25cddde0967d4f08a86ab269..e2e80ca3165a8726c8f13cbd6d62dcadbefb5abc 100644 (file)
 static int kernel_init(void *);
 
 extern void init_IRQ(void);
-extern void fork_init(void);
 extern void radix_tree_init(void);
 
 /*
@@ -930,7 +929,7 @@ static initcall_entry_t *initcall_levels[] __initdata = {
 };
 
 /* Keep these in sync with initcalls in include/linux/init.h */
-static char *initcall_level_names[] __initdata = {
+static const char *initcall_level_names[] __initdata = {
        "pure",
        "core",
        "postcore",
index 705d4ae6c018a4377a0f9952c562276cd6217986..f01affa17e225d29be50f58b8f9c430e971ae42a 100644 (file)
@@ -354,10 +354,9 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
        bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
        nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
-       if (!access_ok(umask, bitmap_size / 8))
+       if (!user_access_begin(umask, bitmap_size / 8))
                return -EFAULT;
 
-       user_access_begin();
        while (nr_compat_longs > 1) {
                compat_ulong_t l1, l2;
                unsafe_get_user(l1, umask++, Efault);
@@ -384,10 +383,9 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
        bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
        nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
-       if (!access_ok(umask, bitmap_size / 8))
+       if (!user_access_begin(umask, bitmap_size / 8))
                return -EFAULT;
 
-       user_access_begin();
        while (nr_compat_longs > 1) {
                unsigned long m = *mask++;
                unsafe_put_user((compat_ulong_t)m, umask++, Efault);
index 8a01b671dc1fb40a703b169937355923430ebf29..2d14979577ee1ef536bf3e554057e14dab90ce0f 100644 (file)
@@ -1604,10 +1604,9 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
        if (!infop)
                return err;
 
-       if (!access_ok(infop, sizeof(*infop)))
+       if (!user_access_begin(infop, sizeof(*infop)))
                return -EFAULT;
 
-       user_access_begin();
        unsafe_put_user(signo, &infop->si_signo, Efault);
        unsafe_put_user(0, &infop->si_errno, Efault);
        unsafe_put_user(info.cause, &infop->si_code, Efault);
@@ -1732,10 +1731,9 @@ COMPAT_SYSCALL_DEFINE5(waitid,
        if (!infop)
                return err;
 
-       if (!access_ok(infop, sizeof(*infop)))
+       if (!user_access_begin(infop, sizeof(*infop)))
                return -EFAULT;
 
-       user_access_begin();
        unsafe_put_user(signo, &infop->si_signo, Efault);
        unsafe_put_user(0, &infop->si_errno, Efault);
        unsafe_put_user(info.cause, &infop->si_code, Efault);
index d439c48ecf181c5914cbf467a1754ac355c830f9..a60459947f186ded8a074d49c45634cacb3b8525 100644 (file)
@@ -164,10 +164,6 @@ static inline void free_task_struct(struct task_struct *tsk)
 }
 #endif
 
-void __weak arch_release_thread_stack(unsigned long *stack)
-{
-}
-
 #ifndef CONFIG_ARCH_THREAD_STACK_ALLOCATOR
 
 /*
@@ -422,7 +418,6 @@ static void release_task_stack(struct task_struct *tsk)
                return;  /* Better to leak the stack than to free prematurely */
 
        account_kernel_stack(tsk, -1);
-       arch_release_thread_stack(tsk->stack);
        free_thread_stack(tsk);
        tsk->stack = NULL;
 #ifdef CONFIG_VMAP_STACK
index cb8e3e8ac7b90b14b2bb0dd97dcdc7c5d02c3afe..4a9191617076fae367a77e75400208839a9c8ef8 100644 (file)
@@ -34,7 +34,7 @@ int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;
  * is disabled during the critical section. It also controls the size of
  * the RCU grace period. So it needs to be upper-bound.
  */
-#define HUNG_TASK_BATCHING 1024
+#define HUNG_TASK_LOCK_BREAK (HZ / 10)
 
 /*
  * Zero means infinite timeout - no checking done:
@@ -112,8 +112,11 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
 
        trace_sched_process_hang(t);
 
-       if (!sysctl_hung_task_warnings && !sysctl_hung_task_panic)
-               return;
+       if (sysctl_hung_task_panic) {
+               console_verbose();
+               hung_task_show_lock = true;
+               hung_task_call_panic = true;
+       }
 
        /*
         * Ok, the task did not get scheduled for more than 2 minutes,
@@ -135,11 +138,6 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
        }
 
        touch_nmi_watchdog();
-
-       if (sysctl_hung_task_panic) {
-               hung_task_show_lock = true;
-               hung_task_call_panic = true;
-       }
 }
 
 /*
@@ -173,7 +171,7 @@ static bool rcu_lock_break(struct task_struct *g, struct task_struct *t)
 static void check_hung_uninterruptible_tasks(unsigned long timeout)
 {
        int max_count = sysctl_hung_task_check_count;
-       int batch_count = HUNG_TASK_BATCHING;
+       unsigned long last_break = jiffies;
        struct task_struct *g, *t;
 
        /*
@@ -188,10 +186,10 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
        for_each_process_thread(g, t) {
                if (!max_count--)
                        goto unlock;
-               if (!--batch_count) {
-                       batch_count = HUNG_TASK_BATCHING;
+               if (time_after(jiffies, last_break + HUNG_TASK_LOCK_BREAK)) {
                        if (!rcu_lock_break(g, t))
                                goto unlock;
+                       last_break = jiffies;
                }
                /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
                if (t->state == TASK_UNINTERRUPTIBLE)
index 97959d7b77e2a9f535af0eda0c9e41fac1fbe798..c2277dbdbfb148842b855a942678e1218d891e07 100644 (file)
@@ -112,7 +112,7 @@ void notrace __sanitizer_cov_trace_pc(void)
 EXPORT_SYMBOL(__sanitizer_cov_trace_pc);
 
 #ifdef CONFIG_KCOV_ENABLE_COMPARISONS
-static void write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip)
+static void notrace write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip)
 {
        struct task_struct *t;
        u64 *area;
index 3f8a35104285ab29fe2e9992430e75b6aefbff89..db578783dd36a3efc87b2bd052ba1353438850ed 100644 (file)
@@ -987,7 +987,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
                 * wait_lock. This ensures the lock cancellation is ordered
                 * against mutex_unlock() and wake-ups do not go missing.
                 */
-               if (unlikely(signal_pending_state(state, current))) {
+               if (signal_pending_state(state, current)) {
                        ret = -EINTR;
                        goto err;
                }
index d10c340c43b0e169c42255b826c22d6ec3068637..f121e6ba7e114e10e7e11ac3fa1cd24ab8fef0c1 100644 (file)
@@ -46,6 +46,13 @@ int panic_on_warn __read_mostly;
 int panic_timeout = CONFIG_PANIC_TIMEOUT;
 EXPORT_SYMBOL_GPL(panic_timeout);
 
+#define PANIC_PRINT_TASK_INFO          0x00000001
+#define PANIC_PRINT_MEM_INFO           0x00000002
+#define PANIC_PRINT_TIMER_INFO         0x00000004
+#define PANIC_PRINT_LOCK_INFO          0x00000008
+#define PANIC_PRINT_FTRACE_INFO                0x00000010
+unsigned long panic_print;
+
 ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
 
 EXPORT_SYMBOL(panic_notifier_list);
@@ -125,6 +132,24 @@ void nmi_panic(struct pt_regs *regs, const char *msg)
 }
 EXPORT_SYMBOL(nmi_panic);
 
+static void panic_print_sys_info(void)
+{
+       if (panic_print & PANIC_PRINT_TASK_INFO)
+               show_state();
+
+       if (panic_print & PANIC_PRINT_MEM_INFO)
+               show_mem(0, NULL);
+
+       if (panic_print & PANIC_PRINT_TIMER_INFO)
+               sysrq_timer_list_show();
+
+       if (panic_print & PANIC_PRINT_LOCK_INFO)
+               debug_show_all_locks();
+
+       if (panic_print & PANIC_PRINT_FTRACE_INFO)
+               ftrace_dump(DUMP_ALL);
+}
+
 /**
  *     panic - halt the system
  *     @fmt: The text string to print
@@ -254,6 +279,8 @@ void panic(const char *fmt, ...)
        debug_locks_off();
        console_flush_on_panic();
 
+       panic_print_sys_info();
+
        if (!panic_blink)
                panic_blink = no_blink;
 
@@ -658,6 +685,7 @@ void refcount_error_report(struct pt_regs *regs, const char *err)
 #endif
 
 core_param(panic, panic_timeout, int, 0644);
+core_param(panic_print, panic_print, ulong, 0644);
 core_param(pause_on_oops, pause_on_oops, int, 0644);
 core_param(panic_on_warn, panic_on_warn, int, 0644);
 core_param(crash_kexec_post_notifiers, crash_kexec_post_notifiers, bool, 0644);
index 1f3e19fd6dc6c7cf09790732c4873d92d43eeec9..223f78d5c1110d90d7d64e0ee55d1efb99f0ec6a 100644 (file)
@@ -3416,7 +3416,7 @@ static void __sched notrace __schedule(bool preempt)
 
        switch_count = &prev->nivcsw;
        if (!preempt && prev->state) {
-               if (unlikely(signal_pending_state(prev->state, prev))) {
+               if (signal_pending_state(prev->state, prev)) {
                        prev->state = TASK_RUNNING;
                } else {
                        deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
index 66b59ac77c2209fd9fccd92c8ae0c660e7428e4d..e83a3f8449f653475f27e2770e9b55f21223cd4c 100644 (file)
@@ -93,7 +93,7 @@ long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait
        long ret = 0;
 
        raw_spin_lock_irqsave(&q->lock, flags);
-       if (unlikely(signal_pending_state(state, current))) {
+       if (signal_pending_state(state, current)) {
                /*
                 * See prepare_to_wait_event(). TL;DR, subsequent swake_up_one()
                 * must not see us.
index 5dd47f1103d18bd769cace68b753088574e02f27..6eb1f8efd221c5fd9b590014e5e51cb0e479356a 100644 (file)
@@ -264,7 +264,7 @@ long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_en
        long ret = 0;
 
        spin_lock_irqsave(&wq_head->lock, flags);
-       if (unlikely(signal_pending_state(state, current))) {
+       if (signal_pending_state(state, current)) {
                /*
                 * Exclusive waiter must not fail if it was selected by wakeup,
                 * it should "consume" the condition we were waiting for.
index 1825f712e73bb74809e921503622dd5511b94923..ba4d9e85feb8ca69fb533049ab8a3a4a556bec9d 100644 (file)
@@ -807,6 +807,13 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "panic_print",
+               .data           = &panic_print,
+               .maxlen         = sizeof(unsigned long),
+               .mode           = 0644,
+               .proc_handler   = proc_doulongvec_minmax,
+       },
 #if defined CONFIG_PRINTK
        {
                .procname       = "printk",
@@ -2787,6 +2794,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
                        bool neg;
 
                        left -= proc_skip_spaces(&p);
+                       if (!left)
+                               break;
 
                        err = proc_get_long(&p, &left, &val, &neg,
                                             proc_wspace_sep,
index 07148b4974516cec45b934e5ed5881e1554e7af0..73c132095a7bd4330813eb741c2f9630086e6c8f 100644 (file)
@@ -140,6 +140,7 @@ static const struct bin_table bin_kern_table[] = {
        { CTL_INT,      KERN_MAX_LOCK_DEPTH,            "max_lock_depth" },
        { CTL_INT,      KERN_PANIC_ON_NMI,              "panic_on_unrecovered_nmi" },
        { CTL_INT,      KERN_PANIC_ON_WARN,             "panic_on_warn" },
+       { CTL_ULONG,    KERN_PANIC_PRINT,               "panic_print" },
        {}
 };
 
index 5367ffa5c18f9cf98a811dc0e1a2fa15433fa401..f0e394dd2beba0bbd5c016c2a6e4c32ebdf25afe 100644 (file)
@@ -108,14 +108,13 @@ static int __init test_find_next_and_bit(const void *bitmap,
                const void *bitmap2, unsigned long len)
 {
        unsigned long i, cnt;
-       cycles_t cycles;
+       ktime_t time;
 
-       cycles = get_cycles();
+       time = ktime_get();
        for (cnt = i = 0; i < BITMAP_LEN; cnt++)
-               i = find_next_and_bit(bitmap, bitmap2, BITMAP_LEN, i+1);
-       cycles = get_cycles() - cycles;
-       pr_err("find_next_and_bit:\t\t%llu cycles, %ld iterations\n",
-               (u64)cycles, cnt);
+               i = find_next_and_bit(bitmap, bitmap2, BITMAP_LEN, i + 1);
+       time = ktime_get() - time;
+       pr_err("find_next_and_bit:  %18llu ns, %6ld iterations\n", time, cnt);
 
        return 0;
 }
index ca06adc4f44510d816ddc9911a1ff38f04cd497b..f365d71cdc774c089cfdce89b1aec1facb3a0b05 100644 (file)
@@ -187,7 +187,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy
        int nbytes = sizeof(struct gen_pool_chunk) +
                                BITS_TO_LONGS(nbits) * sizeof(long);
 
-       chunk = kzalloc_node(nbytes, GFP_KERNEL, nid);
+       chunk = vzalloc_node(nbytes, nid);
        if (unlikely(chunk == NULL))
                return -ENOMEM;
 
@@ -251,7 +251,7 @@ void gen_pool_destroy(struct gen_pool *pool)
                bit = find_next_bit(chunk->bits, end_bit, 0);
                BUG_ON(bit < end_bit);
 
-               kfree(chunk);
+               vfree(chunk);
        }
        kfree_const(pool->name);
        kfree(pool);
@@ -311,7 +311,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
                end_bit = chunk_size(chunk) >> order;
 retry:
                start_bit = algo(chunk->bits, end_bit, start_bit,
-                                nbits, data, pool);
+                                nbits, data, pool, chunk->start_addr);
                if (start_bit >= end_bit)
                        continue;
                remain = bitmap_set_ll(chunk->bits, start_bit, nbits);
@@ -525,7 +525,7 @@ EXPORT_SYMBOL(gen_pool_set_algo);
  */
 unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool)
+               struct gen_pool *pool, unsigned long start_addr)
 {
        return bitmap_find_next_zero_area(map, size, start, nr, 0);
 }
@@ -543,16 +543,19 @@ EXPORT_SYMBOL(gen_pool_first_fit);
  */
 unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool)
+               struct gen_pool *pool, unsigned long start_addr)
 {
        struct genpool_data_align *alignment;
-       unsigned long align_mask;
+       unsigned long align_mask, align_off;
        int order;
 
        alignment = data;
        order = pool->min_alloc_order;
        align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1;
-       return bitmap_find_next_zero_area(map, size, start, nr, align_mask);
+       align_off = (start_addr & (alignment->align - 1)) >> order;
+
+       return bitmap_find_next_zero_area_off(map, size, start, nr,
+                                             align_mask, align_off);
 }
 EXPORT_SYMBOL(gen_pool_first_fit_align);
 
@@ -567,7 +570,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_align);
  */
 unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool)
+               struct gen_pool *pool, unsigned long start_addr)
 {
        struct genpool_data_fixed *fixed_data;
        int order;
@@ -601,7 +604,8 @@ EXPORT_SYMBOL(gen_pool_fixed_alloc);
  */
 unsigned long gen_pool_first_fit_order_align(unsigned long *map,
                unsigned long size, unsigned long start,
-               unsigned int nr, void *data, struct gen_pool *pool)
+               unsigned int nr, void *data, struct gen_pool *pool,
+               unsigned long start_addr)
 {
        unsigned long align_mask = roundup_pow_of_two(nr) - 1;
 
@@ -624,7 +628,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align);
  */
 unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
                unsigned long start, unsigned int nr, void *data,
-               struct gen_pool *pool)
+               struct gen_pool *pool, unsigned long start_addr)
 {
        unsigned long start_bit = size;
        unsigned long len = size + 1;
index b53e1b5d80f429e611cd0be58e9ec1079fb68ead..58eacd41526c58339a7cb35ef92a618f0f3517e4 100644 (file)
@@ -114,10 +114,11 @@ long strncpy_from_user(char *dst, const char __user *src, long count)
 
                kasan_check_write(dst, count);
                check_object_size(dst, count, false);
-               user_access_begin();
-               retval = do_strncpy_from_user(dst, src, count, max);
-               user_access_end();
-               return retval;
+               if (user_access_begin(src, max)) {
+                       retval = do_strncpy_from_user(dst, src, count, max);
+                       user_access_end();
+                       return retval;
+               }
        }
        return -EFAULT;
 }
index 60d0bbda8f5e581178719e9122b0e9f19b0876a5..1c1a1b0e38a5f5c853cf935ed06eb9abb2b56ef2 100644 (file)
@@ -114,10 +114,11 @@ long strnlen_user(const char __user *str, long count)
                unsigned long max = max_addr - src_addr;
                long retval;
 
-               user_access_begin();
-               retval = do_strnlen_user(str, count, max);
-               user_access_end();
-               return retval;
+               if (user_access_begin(str, max)) {
+                       retval = do_strnlen_user(str, count, max);
+                       user_access_end();
+                       return retval;
+               }
        }
        return 0;
 }
index 29655fb47a2c4b2cf61e1c61e5b06d6f51e537a8..9f5e323e883e6f0921bf9cdbfb81c6cf698064a4 100644 (file)
@@ -1125,7 +1125,7 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q,
                                break;
                }
 
-               if (unlikely(signal_pending_state(state, current))) {
+               if (signal_pending_state(state, current)) {
                        ret = -EINTR;
                        break;
                }
index 6f591ccb8eca74282049fdefaadcd0c9dacb1e71..05acd7e2eb22e0849c5125d0cabc671fdc58f71f 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -727,7 +727,7 @@ retry:
                 * If we have a pending SIGKILL, don't keep faulting pages and
                 * potentially allocating memory.
                 */
-               if (unlikely(fatal_signal_pending(current))) {
+               if (fatal_signal_pending(current)) {
                        ret = -ERESTARTSYS;
                        goto out;
                }
index cbd977b1d60d4006d854c92f3e79141bdb7f4493..faf357eaf0cee5aa6ea0d9c562a24bde2d1bbd15 100644 (file)
@@ -568,7 +568,7 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf,
                return VM_FAULT_FALLBACK;
        }
 
-       pgtable = pte_alloc_one(vma->vm_mm, haddr);
+       pgtable = pte_alloc_one(vma->vm_mm);
        if (unlikely(!pgtable)) {
                ret = VM_FAULT_OOM;
                goto release;
@@ -702,7 +702,7 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf)
                struct page *zero_page;
                bool set;
                vm_fault_t ret;
-               pgtable = pte_alloc_one(vma->vm_mm, haddr);
+               pgtable = pte_alloc_one(vma->vm_mm);
                if (unlikely(!pgtable))
                        return VM_FAULT_OOM;
                zero_page = mm_get_huge_zero_page(vma->vm_mm);
@@ -791,7 +791,7 @@ vm_fault_t vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
                return VM_FAULT_SIGBUS;
 
        if (arch_needs_pgtable_deposit()) {
-               pgtable = pte_alloc_one(vma->vm_mm, addr);
+               pgtable = pte_alloc_one(vma->vm_mm);
                if (!pgtable)
                        return VM_FAULT_OOM;
        }
@@ -927,7 +927,7 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
        if (!vma_is_anonymous(vma))
                return 0;
 
-       pgtable = pte_alloc_one(dst_mm, addr);
+       pgtable = pte_alloc_one(dst_mm);
        if (unlikely(!pgtable))
                goto out;
 
index e37efd5d831830123ca117a0efec6eead901eaa7..7450888109651f8974de4c04cab9a91ef7309932 100644 (file)
@@ -4231,7 +4231,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                 * If we have a pending SIGKILL, don't keep faulting pages and
                 * potentially allocating memory.
                 */
-               if (unlikely(fatal_signal_pending(current))) {
+               if (fatal_signal_pending(current)) {
                        remainder = 0;
                        break;
                }
index 34afad56497bd37a1d2b100295a3852652b2d7c0..45a1b5e38e1e2415ad39113a6504ead9fa949dbc 100644 (file)
@@ -123,7 +123,7 @@ static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
                        pte_t *p;
 
                        if (slab_is_available())
-                               p = pte_alloc_one_kernel(&init_mm, addr);
+                               p = pte_alloc_one_kernel(&init_mm);
                        else
                                p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
                        if (!p)
index 2dd2f9ab57f4656c7dd0e06411a6416b8964922d..a52663c0612d4d1fb58a5be5ad34f4985ca80a89 100644 (file)
@@ -400,10 +400,10 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
        }
 }
 
-int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd)
 {
        spinlock_t *ptl;
-       pgtable_t new = pte_alloc_one(mm, address);
+       pgtable_t new = pte_alloc_one(mm);
        if (!new)
                return -ENOMEM;
 
@@ -434,9 +434,9 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
        return 0;
 }
 
-int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+int __pte_alloc_kernel(pmd_t *pmd)
 {
-       pte_t *new = pte_alloc_one_kernel(&init_mm, address);
+       pte_t *new = pte_alloc_one_kernel(&init_mm);
        if (!new)
                return -ENOMEM;
 
@@ -2896,7 +2896,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
         *
         * Here we only have down_read(mmap_sem).
         */
-       if (pte_alloc(vma->vm_mm, vmf->pmd, vmf->address))
+       if (pte_alloc(vma->vm_mm, vmf->pmd))
                return VM_FAULT_OOM;
 
        /* See the comment in pte_alloc_one_map() */
@@ -3043,7 +3043,7 @@ static vm_fault_t pte_alloc_one_map(struct vm_fault *vmf)
                pmd_populate(vma->vm_mm, vmf->pmd, vmf->prealloc_pte);
                spin_unlock(vmf->ptl);
                vmf->prealloc_pte = NULL;
-       } else if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd, vmf->address))) {
+       } else if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd))) {
                return VM_FAULT_OOM;
        }
 map_pte:
@@ -3122,7 +3122,7 @@ static vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
         * related to pte entry. Use the preallocated table for that.
         */
        if (arch_needs_pgtable_deposit() && !vmf->prealloc_pte) {
-               vmf->prealloc_pte = pte_alloc_one(vma->vm_mm, vmf->address);
+               vmf->prealloc_pte = pte_alloc_one(vma->vm_mm);
                if (!vmf->prealloc_pte)
                        return VM_FAULT_OOM;
                smp_wmb(); /* See comment in __pte_alloc() */
@@ -3360,8 +3360,7 @@ static vm_fault_t do_fault_around(struct vm_fault *vmf)
                        start_pgoff + nr_pages - 1);
 
        if (pmd_none(*vmf->pmd)) {
-               vmf->prealloc_pte = pte_alloc_one(vmf->vma->vm_mm,
-                                                 vmf->address);
+               vmf->prealloc_pte = pte_alloc_one(vmf->vma->vm_mm);
                if (!vmf->prealloc_pte)
                        goto out;
                smp_wmb(); /* See comment in __pte_alloc() */
index 5d1839a9148df0d98f4183dbe931b3abe7541f68..ccf8966caf6fe1b36bfa7c02ea8cac91999f8f34 100644 (file)
@@ -2636,7 +2636,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
         *
         * Here we only have down_read(mmap_sem).
         */
-       if (pte_alloc(mm, pmdp, addr))
+       if (pte_alloc(mm, pmdp))
                goto abort;
 
        /* See the comment in pte_alloc_one_map() */
index def01d86e36fd370f9764a9cdb746f3925fbbf8e..3320616ed93f4bb56ced4ad7bc9f6af9be4ebd31 100644 (file)
@@ -191,6 +191,52 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
                drop_rmap_locks(vma);
 }
 
+#ifdef CONFIG_HAVE_MOVE_PMD
+static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
+                 unsigned long new_addr, unsigned long old_end,
+                 pmd_t *old_pmd, pmd_t *new_pmd)
+{
+       spinlock_t *old_ptl, *new_ptl;
+       struct mm_struct *mm = vma->vm_mm;
+       pmd_t pmd;
+
+       if ((old_addr & ~PMD_MASK) || (new_addr & ~PMD_MASK)
+           || old_end - old_addr < PMD_SIZE)
+               return false;
+
+       /*
+        * The destination pmd shouldn't be established, free_pgtables()
+        * should have release it.
+        */
+       if (WARN_ON(!pmd_none(*new_pmd)))
+               return false;
+
+       /*
+        * We don't have to worry about the ordering of src and dst
+        * ptlocks because exclusive mmap_sem prevents deadlock.
+        */
+       old_ptl = pmd_lock(vma->vm_mm, old_pmd);
+       new_ptl = pmd_lockptr(mm, new_pmd);
+       if (new_ptl != old_ptl)
+               spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+
+       /* Clear the pmd */
+       pmd = *old_pmd;
+       pmd_clear(old_pmd);
+
+       VM_BUG_ON(!pmd_none(*new_pmd));
+
+       /* Set the new pmd */
+       set_pmd_at(mm, new_addr, new_pmd, pmd);
+       flush_tlb_range(vma, old_addr, old_addr + PMD_SIZE);
+       if (new_ptl != old_ptl)
+               spin_unlock(new_ptl);
+       spin_unlock(old_ptl);
+
+       return true;
+}
+#endif
+
 unsigned long move_page_tables(struct vm_area_struct *vma,
                unsigned long old_addr, struct vm_area_struct *new_vma,
                unsigned long new_addr, unsigned long len,
@@ -235,8 +281,26 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
                        split_huge_pmd(vma, old_pmd, old_addr);
                        if (pmd_trans_unstable(old_pmd))
                                continue;
+               } else if (extent == PMD_SIZE) {
+#ifdef CONFIG_HAVE_MOVE_PMD
+                       /*
+                        * If the extent is PMD-sized, try to speed the move by
+                        * moving at the PMD level if possible.
+                        */
+                       bool moved;
+
+                       if (need_rmap_locks)
+                               take_rmap_locks(vma);
+                       moved = move_normal_pmd(vma, old_addr, new_addr,
+                                       old_end, old_pmd, new_pmd);
+                       if (need_rmap_locks)
+                               drop_rmap_locks(vma);
+                       if (moved)
+                               continue;
+#endif
                }
-               if (pte_alloc(new_vma->vm_mm, new_pmd, new_addr))
+
+               if (pte_alloc(new_vma->vm_mm, new_pmd))
                        break;
                next = (new_addr + PMD_SIZE) & PMD_MASK;
                if (extent > next - new_addr)
index d975fa3f02aa565c1bd050b0e2a70e6bedc3af2e..2e8019d0e048dde3ea8a7507f085bb1570553604 100644 (file)
@@ -401,6 +401,8 @@ int swap_readpage(struct page *page, bool synchronous)
        get_task_struct(current);
        bio->bi_private = current;
        bio_set_op_attrs(bio, REQ_OP_READ, 0);
+       if (synchronous)
+               bio->bi_opf |= REQ_HIPRI;
        count_vm_event(PSWPIN);
        bio_get(bio);
        qc = submit_bio(bio);
@@ -410,7 +412,7 @@ int swap_readpage(struct page *page, bool synchronous)
                        break;
 
                if (!blk_poll(disk->queue, qc, true))
-                       break;
+                       io_schedule();
        }
        __set_current_state(TASK_RUNNING);
        bio_put(bio);
index 4d8a1f1afaab44976ce3f4bb1e9efd690276e819..4929bc1be60efaac6276288540cd61c244244753 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -126,7 +126,7 @@ void put_pages_list(struct list_head *pages)
        while (!list_empty(pages)) {
                struct page *victim;
 
-               victim = list_entry(pages->prev, struct page, lru);
+               victim = lru_to_page(pages);
                list_del(&victim->lru);
                put_page(victim);
        }
index 48368589f51990a6ed43a02d49a0d80532a5deb0..065c1ce191c47f65c49b031e9d7b318afc051492 100644 (file)
@@ -550,7 +550,7 @@ retry:
                        break;
                }
                if (unlikely(pmd_none(dst_pmdval)) &&
-                   unlikely(__pte_alloc(dst_mm, dst_pmd, dst_addr))) {
+                   unlikely(__pte_alloc(dst_mm, dst_pmd))) {
                        err = -ENOMEM;
                        break;
                }
index 377f373db6c002ab87ce739be7f87f1d19bbe0cc..b737ca9d720441989b52d066130db5157a4172f7 100755 (executable)
@@ -468,6 +468,7 @@ our $logFunctions = qr{(?x:
 
 our $signature_tags = qr{(?xi:
        Signed-off-by:|
+       Co-developed-by:|
        Acked-by:|
        Tested-by:|
        Reviewed-by:|
@@ -3890,14 +3891,23 @@ sub process {
                        WARN("STATIC_CONST_CHAR_ARRAY",
                             "static const char * array should probably be static const char * const\n" .
                                $herecurr);
-               }
+               }
+
+# check for initialized const char arrays that should be static const
+               if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
+                       if (WARN("STATIC_CONST_CHAR_ARRAY",
+                                "const array should probably be static const\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
+                       }
+               }
 
 # check for static char foo[] = "bar" declarations.
                if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
                        WARN("STATIC_CONST_CHAR_ARRAY",
                             "static char array declaration should probably be static const char\n" .
                                $herecurr);
-               }
+               }
 
 # check for const <foo> const where <foo> is not a pointer or array type
                if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
index 086d27223c0cf3451105fad63fd5cb46e4f3bc7d..0aebd7565b032f9f7598f6867164e0d488d70926 100644 (file)
@@ -41,7 +41,7 @@ class LxVersion(gdb.Command):
 
     def invoke(self, arg, from_tty):
         # linux_banner should contain a newline
-        gdb.write(gdb.parse_and_eval("linux_banner").string())
+        gdb.write(gdb.parse_and_eval("(char *)linux_banner").string())
 
 LxVersion()
 
index 753aecaab641a82d7f218988fcebe0751f7149ff..b168bb10e1be17bb6394e749c238da3940ea3a01 100644 (file)
@@ -10,7 +10,7 @@
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 
-static __always_inline int fls(int x)
+static __always_inline int fls(unsigned int x)
 {
        int r = 32;
 
index 3053bf2584f899fed547b5a53d56f053b344ba0a..fbdf3ac2f001069f35c92e6ef4c6be878e01221d 100644 (file)
@@ -647,7 +647,7 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
                BUG_ON(pmd_sect(*pmd));
 
                if (pmd_none(*pmd)) {
-                       pte = pte_alloc_one_kernel(NULL, addr);
+                       pte = pte_alloc_one_kernel(NULL);
                        if (!pte) {
                                kvm_err("Cannot allocate Hyp pte\n");
                                return -ENOMEM;