summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/shmobile.txt2
-rw-r--r--Documentation/devicetree/bindings/bus/ti-sysc.txt6
-rw-r--r--Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt2
-rw-r--r--Documentation/devicetree/bindings/reset/renesas,rst.txt2
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Kconfig.debug13
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/secure_cntvoff.S32
-rw-r--r--arch/arm/configs/bcm2835_defconfig2
-rw-r--r--arch/arm/configs/davinci_all_defconfig4
-rw-r--r--arch/arm/configs/exynos_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig9
-rw-r--r--arch/arm/configs/multi_v7_defconfig12
-rw-r--r--arch/arm/configs/shmobile_defconfig3
-rw-r--r--arch/arm/include/asm/cputype.h14
-rw-r--r--arch/arm/include/asm/secure_cntvoff.h8
-rw-r--r--arch/arm/include/debug/brcmstb.S21
-rw-r--r--arch/arm/mach-berlin/Kconfig6
-rw-r--r--arch/arm/mach-berlin/berlin.c5
-rw-r--r--arch/arm/mach-berlin/headsmp.S5
-rw-r--r--arch/arm/mach-berlin/platsmp.c6
-rw-r--r--arch/arm/mach-davinci/aemif.c8
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c1
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c3
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c1
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c3
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c2
-rw-r--r--arch/arm/mach-davinci/davinci.h1
-rw-r--r--arch/arm/mach-davinci/dm644x.c13
-rw-r--r--arch/arm/mach-exynos/Kconfig12
-rw-r--r--arch/arm/mach-exynos/common.h17
-rw-r--r--arch/arm/mach-exynos/exynos.c37
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h2
-rw-r--r--arch/arm/mach-exynos/platsmp.c27
-rw-r--r--arch/arm/mach-exynos/pm.c4
-rw-r--r--arch/arm/mach-exynos/suspend.c4
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c18
-rw-r--r--arch/arm/mach-imx/mach-mx31lilly.c12
-rw-r--r--arch/arm/mach-imx/mach-mx31lite.c16
-rw-r--r--arch/arm/mach-imx/mach-mx31moboard.c17
-rw-r--r--arch/arm/mach-imx/mach-pca100.c13
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c13
-rw-r--r--arch/arm/mach-imx/mach-pcm037_eet.c5
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c13
-rw-r--r--arch/arm/mach-imx/mach-vpr200.c9
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c107
-rw-r--r--arch/arm/mach-omap1/board-osk.c10
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/clockdomain.c73
-rw-r--r--arch/arm/mach-omap2/clockdomain.h8
-rw-r--r--arch/arm/mach-omap2/cm33xx.c53
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c43
-rw-r--r--arch/arm/mach-omap2/common.h18
-rw-r--r--arch/arm/mach-omap2/control.c112
-rw-r--r--arch/arm/mach-omap2/control.h61
-rw-r--r--arch/arm/mach-omap2/display.c10
-rw-r--r--arch/arm/mach-omap2/hsmmc.c1
-rw-r--r--arch/arm/mach-omap2/i2c.c1
-rw-r--r--arch/arm/mach-omap2/io.c70
-rw-r--r--arch/arm/mach-omap2/omap-pm-noop.c176
-rw-r--r--arch/arm/mach-omap2/omap-pm.h161
-rw-r--r--arch/arm/mach-omap2/omap_device.c22
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c21
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h6
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c6
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c1
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c15
-rw-r--r--arch/arm/mach-omap2/pm-debug.c5
-rw-r--r--arch/arm/mach-omap2/pm.c21
-rw-r--r--arch/arm/mach-omap2/pm33xx-core.c4
-rw-r--r--arch/arm/mach-omap2/pm44xx.c13
-rw-r--r--arch/arm/mach-omap2/powerdomain.c87
-rw-r--r--arch/arm/mach-omap2/powerdomain.h7
-rw-r--r--arch/arm/mach-omap2/prm33xx.c31
-rw-r--r--arch/arm/mach-omap2/prm44xx.c104
-rw-r--r--arch/arm/mach-omap2/timer.c100
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c4
-rw-r--r--arch/arm/mach-pxa/stargate2.c10
-rw-r--r--arch/arm/mach-s3c24xx/h1940-bluetooth.c2
-rw-r--r--arch/arm/mach-s3c24xx/mach-mini2440.c10
-rw-r--r--arch/arm/mach-shmobile/Kconfig13
-rw-r--r--arch/arm/mach-shmobile/common.h1
-rw-r--r--arch/arm/mach-shmobile/headsmp-apmu.S22
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c5
-rw-r--r--arch/arm/mach-sunxi/Kconfig2
-rw-r--r--arch/arm/mach-sunxi/Makefile2
-rw-r--r--arch/arm/mach-sunxi/headsmp.S81
-rw-r--r--arch/arm/mach-sunxi/mc_smp.c239
-rw-r--r--arch/arm/mach-sunxi/sunxi.c20
-rw-r--r--arch/arm/mach-tegra/tegra.c4
-rw-r--r--arch/arm/mach-ux500/Kconfig53
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c16
-rw-r--r--arch/arm/mach-ux500/db8500-regs.h4
-rw-r--r--arch/arm/mm/cache-b15-rac.c30
-rw-r--r--arch/arm/plat-omap/Kconfig10
-rw-r--r--arch/arm/plat-samsung/adc.c3
-rw-r--r--arch/arm/plat-samsung/include/plat/map-s5p.h4
-rw-r--r--arch/arm64/configs/defconfig43
-rw-r--r--drivers/bus/ti-sysc.c388
-rw-r--r--drivers/media/rc/ir-rx51.c17
-rw-r--r--drivers/mtd/nand/raw/davinci_nand.c6
-rw-r--r--drivers/soc/renesas/Kconfig13
-rw-r--r--drivers/soc/renesas/Makefile2
-rw-r--r--drivers/soc/renesas/r8a77470-sysc.c29
-rw-r--r--drivers/soc/renesas/r8a77990-sysc.c68
-rw-r--r--drivers/soc/renesas/r8a77995-sysc.c3
-rw-r--r--drivers/soc/renesas/rcar-rst.c2
-rw-r--r--drivers/soc/renesas/rcar-sysc.c6
-rw-r--r--drivers/soc/renesas/rcar-sysc.h2
-rw-r--r--drivers/soc/renesas/renesas-soc.c16
-rw-r--r--include/dt-bindings/power/r8a77470-sysc.h22
-rw-r--r--include/dt-bindings/power/r8a77990-sysc.h26
-rw-r--r--include/linux/platform_data/media/ir-rx51.h9
-rw-r--r--include/linux/platform_data/mtd-davinci.h10
-rw-r--r--include/linux/platform_data/spi-imx.h29
-rw-r--r--include/linux/platform_data/ti-sysc.h1
-rw-r--r--sound/soc/omap/ams-delta.c38
131 files changed, 2038 insertions, 1006 deletions
diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
index d3d1df97834f..86ac320323a7 100644
--- a/Documentation/devicetree/bindings/arm/shmobile.txt
+++ b/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -21,6 +21,8 @@ SoCs:
compatible = "renesas,r8a7744"
- RZ/G1E (R8A77450)
compatible = "renesas,r8a7745"
+ - RZ/G1C (R8A77470)
+ compatible = "renesas,r8a77470"
- R-Car M1A (R8A77781)
compatible = "renesas,r8a7778"
- R-Car H1 (R8A77790)
diff --git a/Documentation/devicetree/bindings/bus/ti-sysc.txt b/Documentation/devicetree/bindings/bus/ti-sysc.txt
index 2957a9ae291f..d8ed5b780ed9 100644
--- a/Documentation/devicetree/bindings/bus/ti-sysc.txt
+++ b/Documentation/devicetree/bindings/bus/ti-sysc.txt
@@ -79,7 +79,11 @@ Optional properties:
mode as for example omap4 L4_CFG_CLKCTRL
- clock-names should contain at least "fck", and optionally also "ick"
- depending on the SoC and the interconnect target module
+ depending on the SoC and the interconnect target module,
+ some interconnect target modules also need additional
+ optional clocks that can be specified as listed in TRM
+ for the related CLKCTRL register bits 8 to 15 such as
+ "dbclk" or "clk32k" depending on their role
- ti,hwmods optional TI interconnect module name to use legacy
hwmod platform data
diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
index ab399e559257..180ae65be753 100644
--- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
+++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
@@ -9,6 +9,7 @@ Required properties:
- compatible: Must contain exactly one of the following:
- "renesas,r8a7743-sysc" (RZ/G1M)
- "renesas,r8a7745-sysc" (RZ/G1E)
+ - "renesas,r8a77470-sysc" (RZ/G1C)
- "renesas,r8a7779-sysc" (R-Car H1)
- "renesas,r8a7790-sysc" (R-Car H2)
- "renesas,r8a7791-sysc" (R-Car M2-W)
@@ -20,6 +21,7 @@ Required properties:
- "renesas,r8a77965-sysc" (R-Car M3-N)
- "renesas,r8a77970-sysc" (R-Car V3M)
- "renesas,r8a77980-sysc" (R-Car V3H)
+ - "renesas,r8a77990-sysc" (R-Car E3)
- "renesas,r8a77995-sysc" (R-Car D3)
- reg: Address start and address range for the device.
- #power-domain-cells: Must be 1.
diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt
index 294a0dae106a..67e83b02e10b 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rst.txt
+++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt
@@ -17,6 +17,7 @@ Required properties:
Examples with soctypes are:
- "renesas,r8a7743-rst" (RZ/G1M)
- "renesas,r8a7745-rst" (RZ/G1E)
+ - "renesas,r8a77470-rst" (RZ/G1C)
- "renesas,r8a7778-reset-wdt" (R-Car M1A)
- "renesas,r8a7779-reset-wdt" (R-Car H1)
- "renesas,r8a7790-rst" (R-Car H2)
@@ -29,6 +30,7 @@ Required properties:
- "renesas,r8a77965-rst" (R-Car M3-N)
- "renesas,r8a77970-rst" (R-Car V3M)
- "renesas,r8a77980-rst" (R-Car V3H)
+ - "renesas,r8a77990-rst" (R-Car E3)
- "renesas,r8a77995-rst" (R-Car D3)
- reg: Address start and address range for the device.
diff --git a/MAINTAINERS b/MAINTAINERS
index 868be4ab62db..0ee6fe90a52b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1419,6 +1419,7 @@ M: Shawn Guo <shawnguo@kernel.org>
M: Sascha Hauer <s.hauer@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
R: Fabio Estevam <fabio.estevam@nxp.com>
+R: NXP Linux Team <linux-imx@nxp.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 94d222545920..2a78bdef9a24 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1463,7 +1463,7 @@ config ARM_PSCI
config ARCH_NR_GPIO
int
default 2048 if ARCH_SOCFPGA
- default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
+ default 1024 if ARCH_BRCMSTB || ARCH_RENESAS || ARCH_TEGRA || \
ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 199ebc1c4538..693f84392f1b 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -942,6 +942,13 @@ choice
via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790),
M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793).
+ config DEBUG_RCAR_GEN2_SCIF1
+ bool "Kernel low-level debugging messages via SCIF1 on R8A77470"
+ depends on ARCH_R8A77470
+ help
+ Say Y here if you want kernel low-level debugging support
+ via SCIF1 on Renesas RZ/G1C (R8A77470).
+
config DEBUG_RCAR_GEN2_SCIF2
bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
depends on ARCH_R8A7794
@@ -1495,6 +1502,7 @@ config DEBUG_LL_INCLUDE
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
+ default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF1
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF4
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
@@ -1617,6 +1625,7 @@ config DEBUG_UART_PHYS
default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
+ default 0xe6e68000 if DEBUG_RCAR_GEN2_SCIF1
default 0xe6ee0000 if DEBUG_RCAR_GEN2_SCIF4
default 0xe8008000 if DEBUG_R7S72100_SCIF2
default 0xf0000be0 if ARCH_EBSA110
@@ -1651,8 +1660,8 @@ config DEBUG_UART_PHYS
DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
- DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
- DEBUG_RCAR_GEN2_SCIF4 || \
+ DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF1 || \
+ DEBUG_RCAR_GEN2_SCIF2 || DEBUG_RCAR_GEN2_SCIF4 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
DEBUG_S3C64XX_UART || \
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1dc4045e1af6..fc26c3d7b9b6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -212,7 +212,7 @@ machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx
machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx
machine-$(CONFIG_ARCH_S5PV210) += s5pv210
machine-$(CONFIG_ARCH_SA1100) += sa1100
-machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
+machine-$(CONFIG_ARCH_RENESAS) += shmobile
machine-$(CONFIG_ARCH_SIRF) += prima2
machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 70b4a14ed993..1e9f7af8f70f 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
+obj-$(CONFIG_SMP) += secure_cntvoff.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
CFLAGS_REMOVE_mcpm_entry.o = -pg
diff --git a/arch/arm/common/secure_cntvoff.S b/arch/arm/common/secure_cntvoff.S
new file mode 100644
index 000000000000..53fc7bdb6c2e
--- /dev/null
+++ b/arch/arm/common/secure_cntvoff.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ *
+ * Initialization of CNTVOFF register from secure mode
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(secure_cntvoff_init)
+ .arch armv7-a
+ /*
+ * CNTVOFF has to be initialized either from non-secure Hypervisor
+ * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
+ * then it should be handled by the secure code. The CPU must implement
+ * the virtualization extensions.
+ */
+ cps #MON_MODE
+ mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
+ orr r0, r1, #1
+ mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
+ isb
+ mov r0, #0
+ mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
+ isb
+ mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
+ isb
+ cps #SVC_MODE
+ ret lr
+ENDPROC(secure_cntvoff_init)
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 8682b15336b9..e4d188f0a4b4 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -64,6 +64,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
+CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_BRCMFMAC=m
@@ -127,6 +128,7 @@ CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=y
CONFIG_STAGING=y
+CONFIG_BCM2835_VCHIQ=m
CONFIG_MAILBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index c302a04e8cbc..21b2d7791df4 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -56,7 +56,7 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_NETFILTER=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
CONFIG_DMA_CMA=y
CONFIG_DA8XX_MSTPRI=y
CONFIG_MTD=m
@@ -212,6 +212,8 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_OMAP=m
CONFIG_DMADEVICES=y
CONFIG_TI_EDMA=y
+CONFIG_REMOTEPROC=m
+CONFIG_DA8XX_REMOTEPROC=m
CONFIG_MEMORY=y
CONFIG_TI_AEMIF=m
CONFIG_DA8XX_DDRCTL=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 629189c62fd1..85b2369d6b20 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -208,6 +208,7 @@ CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
+CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
CONFIG_DRM_NXP_PTN3460=y
CONFIG_DRM_PARADE_PS8622=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 3a308437b088..f70507ab91ee 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -38,6 +38,7 @@ CONFIG_SOC_IMX51=y
CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_IMX6SLL=y
CONFIG_SOC_IMX6SX=y
CONFIG_SOC_IMX6UL=y
CONFIG_SOC_IMX7D=y
@@ -153,6 +154,9 @@ CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_CDC_EEM=m
CONFIG_BRCMFMAC=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_PCIE=m
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SDIO=m
@@ -199,6 +203,7 @@ CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
CONFIG_SPI_FSL_DSPI=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MC9S08DZ60=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_STMPE=y
@@ -214,11 +219,13 @@ CONFIG_CPU_THERMAL=y
CONFIG_IMX_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DA9062_WATCHDOG=y
+CONFIG_RN5T618_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_DA9052_I2C=y
CONFIG_MFD_DA9062=y
CONFIG_MFD_MC13XXX_SPI=y
CONFIG_MFD_MC13XXX_I2C=y
+CONFIG_MFD_RN5T618=y
CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -229,6 +236,7 @@ CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
CONFIG_REGULATOR_PFUZE100=y
+CONFIG_REGULATOR_RN5T618=y
CONFIG_RC_CORE=y
CONFIG_RC_DEVICES=y
CONFIG_IR_GPIO_CIR=y
@@ -374,6 +382,7 @@ CONFIG_PWM=y
CONFIG_PWM_FSL_FTM=y
CONFIG_PWM_IMX=y
CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_NVMEM_VF610_OCOTP=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_MUX_MMIO=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index e6b3c96d4c09..7e1c543162c3 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -90,6 +90,7 @@ CONFIG_ARCH_R8A73A4=y
CONFIG_ARCH_R8A7740=y
CONFIG_ARCH_R8A7743=y
CONFIG_ARCH_R8A7745=y
+CONFIG_ARCH_R8A77470=y
CONFIG_ARCH_R8A7778=y
CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
@@ -187,6 +188,8 @@ CONFIG_B53_MMAP_DRIVER=m
CONFIG_B53_SRAB_DRIVER=m
CONFIG_CAN_SUN4I=y
CONFIG_BT=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_CFG80211=m
@@ -280,6 +283,7 @@ CONFIG_FIXED_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
+CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
@@ -360,10 +364,12 @@ CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DAVINCI=y
+CONFIG_I2C_MESON=y
CONFIG_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_PCA954x=y
@@ -385,6 +391,7 @@ CONFIG_I2C_S3C2410=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_I2C_SIRF=y
CONFIG_I2C_ST=y
+CONFIG_I2C_STM32F7=y
CONFIG_I2C_SUN6I_P2WI=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_UNIPHIER=y
@@ -497,6 +504,7 @@ CONFIG_TEGRA_WATCHDOG=m
CONFIG_MESON_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
+CONFIG_RENESAS_WDT=m
CONFIG_BCM2835_WDT=y
CONFIG_BCM47XX_WDT=y
CONFIG_BCM7038_WDT=m
@@ -638,6 +646,7 @@ CONFIG_DRM_SUN4I=m
CONFIG_DRM_FSL_DCU=m
CONFIG_DRM_TEGRA=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
+CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_SII9234=m
@@ -650,7 +659,6 @@ CONFIG_FB_EFI=y
CONFIG_FB_WM8505=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FB_SIMPLE=y
-CONFIG_FB_SH_MOBILE_MERAM=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=m
@@ -947,6 +955,7 @@ CONFIG_PWM_ATMEL=m
CONFIG_PWM_ATMEL_HLCDC_PWM=m
CONFIG_PWM_ATMEL_TCB=m
CONFIG_PWM_FSL_FTM=m
+CONFIG_PWM_MESON=m
CONFIG_PWM_RCAR=m
CONFIG_PWM_RENESAS_TPU=y
CONFIG_PWM_ROCKCHIP=m
@@ -972,6 +981,7 @@ CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_STIH407_USB=y
+CONFIG_PHY_STM32_USBPHYC=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SAMSUNG_USB2=m
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index a701601fbd76..b49887e86a3d 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -14,6 +14,7 @@ CONFIG_ARCH_R8A73A4=y
CONFIG_ARCH_R8A7740=y
CONFIG_ARCH_R8A7743=y
CONFIG_ARCH_R8A7745=y
+CONFIG_ARCH_R8A77470=y
CONFIG_ARCH_R8A7778=y
CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
@@ -127,6 +128,7 @@ CONFIG_CPU_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DA9063_WATCHDOG=y
+CONFIG_RENESAS_WDT=y
CONFIG_MFD_AS3711=y
CONFIG_MFD_DA9063=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -156,7 +158,6 @@ CONFIG_DRM_DUMB_VGA_DAC=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_FB_SH_MOBILE_LCDC=y
-CONFIG_FB_SH_MOBILE_MERAM=y
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PWM=y
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 26021980504d..0d289240b6ca 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -2,9 +2,6 @@
#ifndef __ASM_ARM_CPUTYPE_H
#define __ASM_ARM_CPUTYPE_H
-#include <linux/stringify.h>
-#include <linux/kernel.h>
-
#define CPUID_ID 0
#define CPUID_CACHETYPE 1
#define CPUID_TCM 2
@@ -62,6 +59,7 @@
((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
#define ARM_CPU_IMP_ARM 0x41
+#define ARM_CPU_IMP_BRCM 0x42
#define ARM_CPU_IMP_DEC 0x44
#define ARM_CPU_IMP_INTEL 0x69
@@ -84,8 +82,9 @@
#define ARM_CPU_PART_CORTEX_A75 0x4100d0a0
#define ARM_CPU_PART_MASK 0xff00fff0
-/* Broadcom cores */
+/* Broadcom implemented processors */
#define ARM_CPU_PART_BRAHMA_B15 0x420000f0
+#define ARM_CPU_PART_BRAHMA_B53 0x42001000
/* DEC implemented cores */
#define ARM_CPU_PART_SA1100 0x4400a110
@@ -106,6 +105,11 @@
/* Qualcomm implemented cores */
#define ARM_CPU_PART_SCORPION 0x510002d0
+#ifndef __ASSEMBLY__
+
+#include <linux/stringify.h>
+#include <linux/kernel.h>
+
extern unsigned int processor_id;
#ifdef CONFIG_CPU_CP15
@@ -334,4 +338,6 @@ static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
#define cpuid_feature_extract(reg, field) \
cpuid_feature_extract_field(read_cpuid_ext(reg), field)
+#endif /* __ASSEMBLY__ */
+
#endif
diff --git a/arch/arm/include/asm/secure_cntvoff.h b/arch/arm/include/asm/secure_cntvoff.h
new file mode 100644
index 000000000000..1f93aee1f630
--- /dev/null
+++ b/arch/arm/include/asm/secure_cntvoff.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASMARM_ARCH_CNTVOFF_H
+#define __ASMARM_ARCH_CNTVOFF_H
+
+extern void secure_cntvoff_init(void);
+
+#endif
diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S
index c826f15d2f80..0f580caa81e5 100644
--- a/arch/arm/include/debug/brcmstb.S
+++ b/arch/arm/include/debug/brcmstb.S
@@ -11,20 +11,25 @@
* GNU General Public License for more details.
*/
#include <linux/serial_reg.h>
+#include <asm/cputype.h>
/* Physical register offset and virtual register offset */
#define REG_PHYS_BASE 0xf0000000
+#define REG_PHYS_BASE_V7 0x08000000
#define REG_VIRT_BASE 0xfc000000
#define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE)
+#define REG_PHYS_ADDR_V7(x) ((x) + REG_PHYS_BASE_V7)
/* Product id can be read from here */
#define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000)
+#define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000)
#define UARTA_3390 REG_PHYS_ADDR(0x40a900)
#define UARTA_7250 REG_PHYS_ADDR(0x40b400)
#define UARTA_7260 REG_PHYS_ADDR(0x40c000)
#define UARTA_7268 UARTA_7260
#define UARTA_7271 UARTA_7268
+#define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000)
#define UARTA_7364 REG_PHYS_ADDR(0x40b000)
#define UARTA_7366 UARTA_7364
#define UARTA_74371 REG_PHYS_ADDR(0x406b00)
@@ -55,8 +60,21 @@
mov \rv, #0 @ yes; record init is done
str \rv, [\tmp]
+ /* Check for V7 memory map if B53 */
+ mrc p15, 0, \rv, c0, c0, 0 @ get Main ID register
+ ldr \rp, =ARM_CPU_PART_MASK
+ and \rv, \rv, \rp
+ ldr \rp, =ARM_CPU_PART_BRAHMA_B53 @ check for B53 CPU
+ cmp \rv, \rp
+ bne 10f
+
+ /* if PERIPHBASE doesn't overlap REG_PHYS_BASE use V7 map */
+ mrc p15, 1, \rv, c15, c3, 0 @ get PERIPHBASE from CBAR
+ ands \rv, \rv, #REG_PHYS_BASE
+ ldreq \rp, =SUN_TOP_CTRL_BASE_V7
+
/* Check SUN_TOP_CTRL base */
- ldr \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
+10: ldrne \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
ldr \rv, [\rp, #0] @ get register contents
ARM_BE8( rev \rv, \rv )
and \rv, \rv, #0xffffff00 @ strip revision bits [7:0]
@@ -72,6 +90,7 @@ ARM_BE8( rev \rv, \rv )
27: checkuart(\rp, \rv, 0x07437100, 74371)
28: checkuart(\rp, \rv, 0x74390000, 7439)
29: checkuart(\rp, \rv, 0x74450000, 7445)
+30: checkuart(\rp, \rv, 0x72780000, 7278)
/* No valid UART found */
90: mov \rp, #0
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
index 63ab1d368625..3d719cf645e3 100644
--- a/arch/arm/mach-berlin/Kconfig
+++ b/arch/arm/mach-berlin/Kconfig
@@ -23,8 +23,12 @@ config MACH_BERLIN_BG2
config MACH_BERLIN_BG2CD
bool "Marvell Armada 1500-mini (BG2CD)"
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_775420
+ select ARM_GLOBAL_TIMER
select CACHE_L2X0
- select HAVE_ARM_TWD if SMP
+ select HAVE_ARM_SCU
+ select HAVE_ARM_TWD
select PINCTRL_BERLIN_BG2CD
config MACH_BERLIN_BG2Q
diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
index ac181c6797ee..2424ad40190c 100644
--- a/arch/arm/mach-berlin/berlin.c
+++ b/arch/arm/mach-berlin/berlin.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Device Tree support for Marvell Berlin SoCs.
*
@@ -5,10 +6,6 @@
*
* based on GPL'ed 2.6 kernel sources
* (c) Marvell International Ltd.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/init.h>
diff --git a/arch/arm/mach-berlin/headsmp.S b/arch/arm/mach-berlin/headsmp.S
index dc82a3486b05..3057885d9772 100644
--- a/arch/arm/mach-berlin/headsmp.S
+++ b/arch/arm/mach-berlin/headsmp.S
@@ -1,11 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
* Antoine Ténart <antoine.tenart@free-electrons.com>
- *
- * 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>
diff --git a/arch/arm/mach-berlin/platsmp.c b/arch/arm/mach-berlin/platsmp.c
index 7586b7aec272..593fc4a69d84 100644
--- a/arch/arm/mach-berlin/platsmp.c
+++ b/arch/arm/mach-berlin/platsmp.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
* Antoine Ténart <antoine.tenart@free-electrons.com>
- *
- * 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/io.h>
@@ -81,7 +78,6 @@ static void __init berlin_smp_prepare_cpus(unsigned int max_cpus)
goto unmap_scu;
scu_enable(scu_base);
- flush_cache_all();
/*
* Write the first instruction the CPU will execute after being reset
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
index ff8b7e76b6e9..e4ab3f3a2a1f 100644
--- a/arch/arm/mach-davinci/aemif.c
+++ b/arch/arm/mach-davinci/aemif.c
@@ -189,7 +189,7 @@ int davinci_aemif_setup(struct platform_device *pdev)
* Setup Async configuration register in case we did not boot
* from NAND and so bootloader did not bother to set it up.
*/
- val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
+ val = davinci_aemif_readl(base, A1CR_OFFSET + pdata->core_chipsel * 4);
/*
* Extended Wait is not valid and Select Strobe mode is not
* used
@@ -198,13 +198,13 @@ int davinci_aemif_setup(struct platform_device *pdev)
if (pdata->options & NAND_BUSWIDTH_16)
val |= 0x1;
- davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
+ davinci_aemif_writel(base, A1CR_OFFSET + pdata->core_chipsel * 4, val);
clkrate = clk_get_rate(clk);
if (pdata->timing)
- ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
- clkrate);
+ ret = davinci_aemif_setup_timing(pdata->timing, base,
+ pdata->core_chipsel, clkrate);
if (ret < 0)
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index d1e8ce7b4bd2..14a6fc061744 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -315,6 +315,7 @@ static struct davinci_aemif_timing da830_evm_nandflash_timing = {
};
static struct davinci_nand_pdata da830_evm_nand_pdata = {
+ .core_chipsel = 1,
.parts = da830_evm_nand_partitions,
.nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
.ecc_mode = NAND_ECC_HW,
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 158ed9a1483f..e22fb40e34bc 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -244,6 +244,7 @@ static struct davinci_aemif_timing da850_evm_nandflash_timing = {
};
static struct davinci_nand_pdata da850_evm_nandflash_data = {
+ .core_chipsel = 1,
.parts = da850_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 23ab9e8bc04c..a3377f959444 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -78,6 +78,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
+ .core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 59743bd76793..8249a0bf69f0 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -72,6 +72,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
+ .core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 0ac085b58a2b..435f7ec7d9af 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -138,6 +138,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
+ .core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 509e64ab1994..48436f74fd71 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -153,6 +153,7 @@ static struct davinci_aemif_timing davinci_evm_nandflash_timing = {
};
static struct davinci_nand_pdata davinci_evm_nandflash_data = {
+ .core_chipsel = 0,
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
@@ -772,6 +773,8 @@ static __init void davinci_evm_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_init_devices();
+
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index a3c0d1e87647..584064fdabf5 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -84,6 +84,7 @@ static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
};
static struct davinci_nand_pdata davinci_nand_data = {
+ .core_chipsel = 0,
.mask_cle = 0x80000,
.mask_ale = 0x40000,
.parts = davinci_nand_partitions,
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index d1c85484c2e2..37b3e48a21d1 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -400,6 +400,7 @@ static struct mtd_partition mityomapl138_nandflash_partition[] = {
};
static struct davinci_nand_pdata mityomapl138_nandflash_data = {
+ .core_chipsel = 1,
.parts = mityomapl138_nandflash_partition,
.nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index f2875770fbff..25ad9b0612be 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -87,6 +87,7 @@ static struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
};
static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
+ .core_chipsel = 0,
.parts = davinci_ntosd2_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
@@ -174,6 +175,8 @@ static __init void davinci_ntosd2_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_init_devices();
+
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 2922da9d1684..e7c1728b0833 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
+ dm644x_init_devices();
+
platform_add_devices(davinci_sffsdr_devices,
ARRAY_SIZE(davinci_sffsdr_devices));
sffsdr_init_i2c();
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index 270cef85750a..376cdd51ce9d 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -104,6 +104,7 @@ int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
+void dm644x_init_devices(void);
void dm644x_init_time(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index b409801649e1..a2e8586c8a6d 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -961,19 +961,14 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
return 0;
}
-static int __init dm644x_init_devices(void)
+void __init dm644x_init_devices(void)
{
struct platform_device *edma_pdev;
- int ret = 0;
-
- if (!cpu_is_davinci_dm644x())
- return 0;
+ int ret;
edma_pdev = platform_device_register_full(&dm644x_edma_device);
- if (IS_ERR(edma_pdev)) {
+ if (IS_ERR(edma_pdev))
pr_warn("%s: Failed to register eDMA\n", __func__);
- return PTR_ERR(edma_pdev);
- }
platform_device_register(&dm644x_mdio_device);
platform_device_register(&dm644x_emac_device);
@@ -982,6 +977,4 @@ static int __init dm644x_init_devices(void)
if (ret)
pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
- return ret;
}
-postcore_initcall(dm644x_init_devices);
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 2ca405816846..b40963cf91c7 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -8,7 +8,6 @@
menuconfig ARCH_EXYNOS
bool "Samsung EXYNOS"
depends on ARCH_MULTI_V7
- select ARCH_HAS_BANDGAP
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
@@ -108,17 +107,6 @@ config SOC_EXYNOS5420
default y
depends on ARCH_EXYNOS5
-config SOC_EXYNOS5440
- bool "SAMSUNG EXYNOS5440"
- default y
- depends on ARCH_EXYNOS5
- select HAVE_ARM_ARCH_TIMER
- select AUTO_ZRELADDR
- select PINCTRL_EXYNOS5440
- select PM_OPP
- help
- Enable EXYNOS5440 SoC support
-
config SOC_EXYNOS5800
bool "SAMSUNG EXYNOS5800"
default y
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 098f84a149a3..dcd21bb95e3b 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -21,7 +21,6 @@
#define EXYNOS5250_SOC_ID 0x43520000
#define EXYNOS5410_SOC_ID 0xE5410000
#define EXYNOS5420_SOC_ID 0xE5420000
-#define EXYNOS5440_SOC_ID 0xE5440000
#define EXYNOS5800_SOC_ID 0xE5422000
#define EXYNOS5_SOC_MASK 0xFFFFF000
@@ -39,7 +38,6 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
#if defined(CONFIG_SOC_EXYNOS3250)
@@ -82,22 +80,12 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
# define soc_is_exynos5420() 0
#endif
-#if defined(CONFIG_SOC_EXYNOS5440)
-# define soc_is_exynos5440() is_samsung_exynos5440()
-#else
-# define soc_is_exynos5440() 0
-#endif
-
#if defined(CONFIG_SOC_EXYNOS5800)
# define soc_is_exynos5800() is_samsung_exynos5800()
#else
# define soc_is_exynos5800() 0
#endif
-#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4412())
-#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
- soc_is_exynos5420() || soc_is_exynos5800())
-
extern u32 cp15_save_diag;
extern u32 cp15_save_power;
@@ -149,6 +137,11 @@ extern void exynos_cpu_restore_register(void);
extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void);
+#ifdef CONFIG_SMP
+extern void exynos_scu_enable(void);
+#else
+static inline void exynos_scu_enable(void) { }
+#endif
extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 8c4f5e342dc1..f4b6c93a7fd0 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -24,15 +24,6 @@
#include "common.h"
-static struct map_desc exynos4_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
- .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
- .length = SZ_8K,
- .type = MT_DEVICE,
- },
-};
-
static struct platform_device exynos_cpuidle = {
.name = "exynos_cpuidle",
#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -63,15 +54,6 @@ void __init exynos_sysram_init(void)
}
}
-static void __init exynos_init_late(void)
-{
- if (of_machine_is_compatible("samsung,exynos5440"))
- /* to be supported later */
- return;
-
- exynos_pm_init();
-}
-
static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
int depth, void *data)
{
@@ -79,8 +61,7 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
const __be32 *reg;
int len;
- if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
- !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
+ if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid"))
return 0;
reg = of_get_flat_dt_prop(node, "reg", &len);
@@ -95,17 +76,6 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
return 1;
}
-/*
- * exynos_map_io
- *
- * register the standard cpu IO areas
- */
-static void __init exynos_map_io(void)
-{
- if (soc_is_exynos4())
- iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-}
-
static void __init exynos_init_io(void)
{
debug_ll_io_init();
@@ -114,8 +84,6 @@ static void __init exynos_init_io(void)
/* detect cpu id and rev. */
s5p_init_cpu(S5P_VA_CHIPID);
-
- exynos_map_io();
}
/*
@@ -209,7 +177,6 @@ static char const *const exynos_dt_compat[] __initconst = {
"samsung,exynos5250",
"samsung,exynos5260",
"samsung,exynos5420",
- "samsung,exynos5440",
NULL
};
@@ -232,7 +199,7 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
.init_early = exynos_firmware_init,
.init_irq = exynos_init_irq,
.init_machine = exynos_dt_machine_init,
- .init_late = exynos_init_late,
+ .init_late = exynos_pm_init,
.dt_compat = exynos_dt_compat,
.dt_fixup = exynos_dt_fixup,
MACHINE_END
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 37a5ea5e2602..22ebe3654633 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -15,6 +15,4 @@
#define EXYNOS_PA_CHIPID 0x10000000
-#define EXYNOS4_PA_COREPERI 0x10500000
-
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 5156fe70e030..6a1e682371b3 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -163,6 +163,26 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
+/**
+ * exynos_scu_enable : enables SCU for Cortex-A9 based system
+ */
+void exynos_scu_enable(void)
+{
+ struct device_node *np;
+ static void __iomem *scu_base;
+
+ if (!scu_base) {
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ if (np) {
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ } else {
+ scu_base = ioremap(scu_a9_get_base(), SZ_4K);
+ }
+ }
+ scu_enable(scu_base);
+}
+
static void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
@@ -219,11 +239,6 @@ static void write_pen_release(int val)
sync_cache_w(&pen_release);
}
-static void __iomem *scu_base_addr(void)
-{
- return (void __iomem *)(S5P_VA_SCU);
-}
-
static DEFINE_SPINLOCK(boot_lock);
static void exynos_secondary_init(unsigned int cpu)
@@ -389,7 +404,7 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
exynos_set_delayed_reset_assertion(true);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
- scu_enable(scu_base_addr());
+ exynos_scu_enable();
/*
* Write the address of secondary startup into the
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index a822c5073715..48e7fb38613e 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -22,8 +22,6 @@
#include <asm/suspend.h>
#include <asm/cacheflush.h>
-#include <mach/map.h>
-
#include "common.h"
static inline void __iomem *exynos_boot_vector_addr(void)
@@ -172,7 +170,7 @@ void exynos_enter_aftr(void)
cpu_suspend(0, exynos_aftr_finisher);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
- scu_enable(S5P_VA_SCU);
+ exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS)
exynos_cpu_restore_register();
}
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index c2ed997fedef..d3db306a5a70 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -30,8 +30,6 @@
#include <asm/smp_scu.h>
#include <asm/suspend.h>
-#include <mach/map.h>
-
#include <plat/pm-common.h>
#include "common.h"
@@ -401,7 +399,7 @@ static void exynos_pm_resume(void)
goto early_wakeup;
if (cpuid == ARM_CPU_PART_CORTEX_A9)
- scu_enable(S5P_VA_SCU);
+ exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS
&& cpuid == ARM_CPU_PART_CORTEX_A9)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index e47fa13f4b0c..6f4232384774 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -501,6 +501,7 @@ config SOC_IMX6SL
config SOC_IMX6SLL
bool "i.MX6 SoloLiteLite support"
+ select PINCTRL_IMX6SLL
select SOC_IMX6
help
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 68c3f0799d5b..9d87f1dcf7bb 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -374,26 +374,12 @@ static struct imx_ssi_platform_data mx31_3ds_ssi_pdata = {
};
/* SPI */
-static int spi0_internal_chipselect[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(1),
- MXC_SPI_CS(2),
-};
-
static const struct spi_imx_master spi0_pdata __initconst = {
- .chipselect = spi0_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi0_internal_chipselect),
-};
-
-static int spi1_internal_chipselect[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(1),
- MXC_SPI_CS(2),
+ .num_chipselect = 3,
};
static const struct spi_imx_master spi1_pdata __initconst = {
- .chipselect = spi1_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+ .num_chipselect = 3,
};
static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c
index 6fd463642954..8bf52819d4d9 100644
--- a/arch/arm/mach-imx/mach-mx31lilly.c
+++ b/arch/arm/mach-imx/mach-mx31lilly.c
@@ -226,20 +226,12 @@ static void __init lilly1131_usb_init(void)
/* SPI */
-static int spi_internal_chipselect[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(1),
- MXC_SPI_CS(2),
-};
-
static const struct spi_imx_master spi0_pdata __initconst = {
- .chipselect = spi_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+ .num_chipselect = 3,
};
static const struct spi_imx_master spi1_pdata __initconst = {
- .chipselect = spi_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+ .num_chipselect = 3,
};
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c
index a3250bc7f114..a3cbba6c955b 100644
--- a/arch/arm/mach-imx/mach-mx31lite.c
+++ b/arch/arm/mach-imx/mach-mx31lite.c
@@ -83,15 +83,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
};
/* SPI */
-static int spi0_internal_chipselect[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(1),
- MXC_SPI_CS(2),
-};
-
static const struct spi_imx_master spi0_pdata __initconst = {
- .chipselect = spi0_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi0_internal_chipselect),
+ .num_chipselect = 3,
};
static const struct mxc_nand_platform_data
@@ -133,13 +126,8 @@ static struct platform_device smsc911x_device = {
* The MC13783 is the only hard-wired SPI device on the module.
*/
-static int spi1_internal_chipselect[] = {
- MXC_SPI_CS(0),
-};
-
static const struct spi_imx_master spi1_pdata __initconst = {
- .chipselect = spi1_internal_chipselect,
- .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+ .num_chipselect = 1,
};
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index 7716f83aecdd..643a3d749703 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -152,14 +152,8 @@ static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
.bitrate = 100000,
};
-static int moboard_spi1_cs[] = {
- MXC_SPI_CS(0),
- MXC_SPI_CS(2),
-};
-
static const struct spi_imx_master moboard_spi1_pdata __initconst = {
- .chipselect = moboard_spi1_cs,
- .num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
+ .num_chipselect = 3,
};
static struct regulator_consumer_supply sdhc_consumers[] = {
@@ -296,19 +290,14 @@ static struct spi_board_info moboard_spi_board_info[] __initdata = {
/* irq number is run-time assigned */
.max_speed_hz = 300000,
.bus_num = 1,
- .chip_select = 1,
+ .chip_select = 0,
.platform_data = &moboard_pmic,
.mode = SPI_CS_HIGH,
},
};
-static int moboard_spi2_cs[] = {
- MXC_SPI_CS(0), MXC_SPI_CS(1),
-};
-
static const struct spi_imx_master moboard_spi2_pdata __initconst = {
- .chipselect = moboard_spi2_cs,
- .num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
+ .num_chipselect = 2,
};
#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index ed675863655b..5714e2f1b106 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
@@ -168,16 +168,15 @@ static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
.bitrate = 100000,
};
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
+static const struct property_entry board_eeprom_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 32),
+ { }
};
static struct i2c_board_info pca100_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
+ I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
+ .properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
}, {
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index b787ba6897e4..004737c40fda 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -23,7 +23,7 @@
#include <linux/smsc911x.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/irq.h>
@@ -263,16 +263,15 @@ static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
.bitrate = 20000,
};
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
+static const struct property_entry board_eeprom_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 32),
+ { }
};
static struct i2c_board_info pcm037_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
+ I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
+ .properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
}
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c
index 95bd97710494..15bc956d466b 100644
--- a/arch/arm/mach-imx/mach-pcm037_eet.c
+++ b/arch/arm/mach-imx/mach-pcm037_eet.c
@@ -56,11 +56,8 @@ static struct spi_board_info pcm037_spi_dev[] = {
};
/* Platform Data for MXC CSPI */
-static int pcm037_spi1_cs[] = { MXC_SPI_CS(0), MXC_SPI_CS(1), };
-
static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
- .chipselect = pcm037_spi1_cs,
- .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
+ .num_chipselect = 2,
};
/* GPIO-keys input device */
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index 78e2bf8dcd96..e595e5368676 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -24,7 +24,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
@@ -110,16 +110,15 @@ static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
.bitrate = 50000,
};
-static struct at24_platform_data board_eeprom = {
- .byte_len = 4096,
- .page_size = 32,
- .flags = AT24_FLAG_ADDR16,
+static const struct property_entry board_eeprom_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 32),
+ { }
};
static struct i2c_board_info pcm043_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
- .platform_data = &board_eeprom,
+ I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
+ .properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
},
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
index 5ff154c9a086..da3336aaa4c5 100644
--- a/arch/arm/mach-imx/mach-vpr200.c
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -29,7 +29,6 @@
#include <asm/mach/time.h>
#include <linux/i2c.h>
-#include <linux/platform_data/at24.h>
#include <linux/mfd/mc13xxx.h>
#include "common.h"
@@ -145,15 +144,9 @@ static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
.bitrate = 50000,
};
-static struct at24_platform_data vpr200_eeprom = {
- .byte_len = 2048 / 8,
- .page_size = 1,
-};
-
static struct i2c_board_info vpr200_i2c_devices[] = {
{
- I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
- .platform_data = &vpr200_eeprom,
+ I2C_BOARD_INFO("24c02", 0x50), /* E0=0, E1=0, E2=0 */
}, {
I2C_BOARD_INFO("mc13892", 0x08),
.platform_data = &vpr200_pmic,
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 52e8e53ca154..80f54cb54276 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
#include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -202,7 +203,10 @@ static struct resource latch2_resources[] = {
},
};
+#define LATCH2_LABEL "latch2"
+
static struct bgpio_pdata latch2_pdata = {
+ .label = LATCH2_LABEL,
.base = AMS_DELTA_LATCH2_GPIO_BASE,
.ngpio = AMS_DELTA_LATCH2_NGPIO,
};
@@ -217,6 +221,23 @@ static struct platform_device latch2_gpio_device = {
},
};
+#define LATCH2_PIN_LCD_VBLEN 0
+#define LATCH2_PIN_LCD_NDISP 1
+#define LATCH2_PIN_NAND_NCE 2
+#define LATCH2_PIN_NAND_NRE 3
+#define LATCH2_PIN_NAND_NWP 4
+#define LATCH2_PIN_NAND_NWE 5
+#define LATCH2_PIN_NAND_ALE 6
+#define LATCH2_PIN_NAND_CLE 7
+#define LATCH2_PIN_KEYBRD_PWR 8
+#define LATCH2_PIN_KEYBRD_DATAOUT 9
+#define LATCH2_PIN_SCARD_RSTIN 10
+#define LATCH2_PIN_SCARD_CMDVCC 11
+#define LATCH2_PIN_MODEM_NRESET 12
+#define LATCH2_PIN_MODEM_CODEC 13
+#define LATCH2_PIN_HOOKFLASH1 14
+#define LATCH2_PIN_HOOKFLASH2 15
+
static const struct gpio latch_gpios[] __initconst = {
{
.gpio = LATCH1_GPIO_BASE + 6,
@@ -239,11 +260,6 @@ static const struct gpio latch_gpios[] __initconst = {
.label = "scard_cmdvcc",
},
{
- .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC,
- .flags = GPIOF_OUT_INIT_LOW,
- .label = "modem_codec",
- },
- {
.gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14,
.flags = GPIOF_OUT_INIT_LOW,
.label = "hookflash1",
@@ -323,6 +339,22 @@ static struct platform_device ams_delta_nand_device = {
.resource = ams_delta_nand_resources,
};
+#define OMAP_GPIO_LABEL "gpio-0-15"
+
+static struct gpiod_lookup_table ams_delta_nand_gpio_table = {
+ .table = {
+ GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_NAND_RB, "rdy",
+ 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0),
+ { },
+ },
+};
+
static struct resource ams_delta_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
@@ -358,6 +390,14 @@ static struct platform_device ams_delta_lcd_device = {
.id = -1,
};
+static struct gpiod_lookup_table ams_delta_lcd_gpio_table = {
+ .table = {
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_VBLEN, "vblen", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_NDISP, "ndisp", 0),
+ { },
+ },
+};
+
static const struct gpio_led gpio_leds[] __initconst = {
{
.name = "camera",
@@ -449,11 +489,35 @@ static struct platform_device ams_delta_audio_device = {
.id = -1,
};
+static struct gpiod_lookup_table ams_delta_audio_gpio_table = {
+ .table = {
+ GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_HOOK_SWITCH,
+ "hook_switch", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC,
+ "modem_codec", 0),
+ { },
+ },
+};
+
static struct platform_device cx20442_codec_device = {
.name = "cx20442-codec",
.id = -1,
};
+static struct gpiod_lookup_table ams_delta_serio_gpio_table = {
+ .table = {
+ GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
+ "data", 0),
+ GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
+ "clock", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR,
+ "power", 0),
+ GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT,
+ "dataout", 0),
+ { },
+ },
+};
+
static struct platform_device *ams_delta_devices[] __initdata = {
&latch1_gpio_device,
&latch2_gpio_device,
@@ -468,6 +532,16 @@ static struct platform_device *late_devices[] __initdata = {
&cx20442_codec_device,
};
+static struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = {
+ &ams_delta_audio_gpio_table,
+ &ams_delta_serio_gpio_table,
+};
+
+static struct gpiod_lookup_table *late_gpio_tables[] __initdata = {
+ &ams_delta_lcd_gpio_table,
+ &ams_delta_nand_gpio_table,
+};
+
static void __init ams_delta_init(void)
{
/* mux pins for uarts */
@@ -500,6 +574,20 @@ static void __init ams_delta_init(void)
gpio_led_register_device(-1, &leds_pdata);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
+ /*
+ * As soon as devices have been registered, assign their dev_names
+ * to respective GPIO lookup tables before they are added.
+ */
+ ams_delta_audio_gpio_table.dev_id =
+ dev_name(&ams_delta_audio_device.dev);
+ /*
+ * No device name is assigned to GPIO lookup table for serio device
+ * as long as serio driver is not converted to platform device driver.
+ */
+
+ gpiod_add_lookup_tables(ams_delta_gpio_tables,
+ ARRAY_SIZE(ams_delta_gpio_tables));
+
ams_delta_init_fiq();
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
@@ -570,6 +658,15 @@ static int __init late_init(void)
platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
+ /*
+ * As soon as devices have been registered, assign their dev_names
+ * to respective GPIO lookup tables before they are added.
+ */
+ ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
+ ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
+
+ gpiod_add_lookup_tables(late_gpio_tables, ARRAY_SIZE(late_gpio_tables));
+
err = platform_device_register(&modem_nreset_device);
if (err) {
pr_err("Couldn't register the modem regulator device\n");
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index c66372ed29e2..9ffa8d755a59 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -303,22 +303,22 @@ static const struct omap_lcd_config osk_lcd_config __initconst = {
#ifdef CONFIG_OMAP_OSK_MISTRAL
#include <linux/input.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/platform_data/keypad-omap.h>
-static struct at24_platform_data at24c04 = {
- .byte_len = SZ_4K / 8,
- .page_size = 16,
+static const struct property_entry mistral_at24_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 16),
+ { }
};
static struct i2c_board_info __initdata mistral_i2c_board_info[] = {
{
/* NOTE: powered from LCD supply */
I2C_BOARD_INFO("24c04", 0x50),
- .platform_data = &at24c04,
+ .properties = mistral_at24_properties,
},
/* TODO when driver support is ready:
* - optionally ov9640 camera sensor at 0x30
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 0d9ce58bc464..01377c292db4 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -78,7 +78,6 @@ endif
omap-4-5-pm-common = omap-mpuss-lowpower.o
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common)
-obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 6c61ecc62905..6b4f4975cf7a 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -31,8 +31,6 @@ static const struct of_device_id omap_dt_match_table[] __initconst = {
static void __init __maybe_unused omap_generic_init(void)
{
pdata_quirks_init(omap_dt_match_table);
-
- omapdss_init_of();
omap_soc_device_init();
}
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b79b1ca9aee9..6d44fe05a3fe 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -23,6 +23,7 @@
#include <linux/limits.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
+#include <linux/cpu_pm.h>
#include <linux/io.h>
@@ -31,6 +32,7 @@
#include "soc.h"
#include "clock.h"
#include "clockdomain.h"
+#include "pm.h"
/* clkdm_list contains all registered struct clockdomains */
static LIST_HEAD(clkdm_list);
@@ -39,6 +41,8 @@ static LIST_HEAD(clkdm_list);
static struct clkdm_autodep *autodeps;
static struct clkdm_ops *arch_clkdm;
+void clkdm_save_context(void);
+void clkdm_restore_context(void);
/* Private functions */
@@ -449,6 +453,22 @@ int clkdm_register_autodeps(struct clkdm_autodep *ia)
return 0;
}
+static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (enable_off_mode)
+ clkdm_save_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (enable_off_mode)
+ clkdm_restore_context();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
/**
* clkdm_complete_init - set up the clockdomain layer
*
@@ -460,6 +480,7 @@ int clkdm_register_autodeps(struct clkdm_autodep *ia)
int clkdm_complete_init(void)
{
struct clockdomain *clkdm;
+ static struct notifier_block nb;
if (list_empty(&clkdm_list))
return -EACCES;
@@ -474,6 +495,12 @@ int clkdm_complete_init(void)
clkdm_clear_all_sleepdeps(clkdm);
}
+ /* Only AM43XX can lose clkdm context during rtc-ddr suspend */
+ if (soc_is_am43xx()) {
+ nb.notifier_call = cpu_notifier;
+ cpu_pm_register_notifier(&nb);
+ }
+
return 0;
}
@@ -1307,3 +1334,49 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
return 0;
}
+/**
+ * _clkdm_save_context - save the context for the control of this clkdm
+ *
+ * Due to a suspend or hibernation operation, the state of the registers
+ * controlling this clkdm will be lost, save their context.
+ */
+static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed)
+{
+ if (!arch_clkdm || !arch_clkdm->clkdm_save_context)
+ return -EINVAL;
+
+ return arch_clkdm->clkdm_save_context(clkdm);
+}
+
+/**
+ * _clkdm_restore_context - restore context for control of this clkdm
+ *
+ * Restore the register values for this clockdomain.
+ */
+static int _clkdm_restore_context(struct clockdomain *clkdm, void *ununsed)
+{
+ if (!arch_clkdm || !arch_clkdm->clkdm_restore_context)
+ return -EINVAL;
+
+ return arch_clkdm->clkdm_restore_context(clkdm);
+}
+
+/**
+ * clkdm_save_context - Saves the context for each registered clkdm
+ *
+ * Save the context for each registered clockdomain.
+ */
+void clkdm_save_context(void)
+{
+ clkdm_for_each(_clkdm_save_context, NULL);
+}
+
+/**
+ * clkdm_restore_context - Restores the context for each registered clkdm
+ *
+ * Restore the context for each registered clockdomain.
+ */
+void clkdm_restore_context(void)
+{
+ clkdm_for_each(_clkdm_restore_context, NULL);
+}
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 24667a5a9dc0..c7d0953e4aa2 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -141,6 +141,7 @@ struct clockdomain {
int usecount;
int forcewake_count;
struct list_head node;
+ u32 context;
};
/**
@@ -159,6 +160,8 @@ struct clockdomain {
* @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
* @clkdm_clk_enable: Put the clkdm in right state for a clock enable
* @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ * @clkdm_save_context: Save the current clkdm context
+ * @clkdm_restore_context: Restore the clkdm context
*/
struct clkdm_ops {
int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
@@ -175,6 +178,8 @@ struct clkdm_ops {
void (*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
+ int (*clkdm_save_context)(struct clockdomain *clkdm);
+ int (*clkdm_restore_context)(struct clockdomain *clkdm);
};
int clkdm_register_platform_funcs(struct clkdm_ops *co);
@@ -214,6 +219,9 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
+void clkdm_save_context(void);
+void clkdm_restore_context(void);
+
extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index 1cc0247a2cb5..084d454f6074 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -72,6 +72,17 @@ static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
return v;
}
+static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = am33xx_cm_read_reg(inst, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @inst: CM instance register offset (*_INST macro)
@@ -338,6 +349,46 @@ static u32 am33xx_cm_xlate_clkctrl(u8 part, u16 inst, u16 offset)
return cm_base.pa + inst + offset;
}
+/**
+ * am33xx_clkdm_save_context - Save the clockdomain transition context
+ * @clkdm: The clockdomain pointer whose context needs to be saved
+ *
+ * Save the clockdomain transition context.
+ */
+static int am33xx_clkdm_save_context(struct clockdomain *clkdm)
+{
+ clkdm->context = am33xx_cm_read_reg_bits(clkdm->cm_inst,
+ clkdm->clkdm_offs,
+ AM33XX_CLKTRCTRL_MASK);
+
+ return 0;
+}
+
+/**
+ * am33xx_restore_save_context - Restore the clockdomain transition context
+ * @clkdm: The clockdomain pointer whose context needs to be restored
+ *
+ * Restore the clockdomain transition context.
+ */
+static int am33xx_clkdm_restore_context(struct clockdomain *clkdm)
+{
+ switch (clkdm->context) {
+ case OMAP34XX_CLKSTCTRL_DISABLE_AUTO:
+ am33xx_clkdm_deny_idle(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_FORCE_SLEEP:
+ am33xx_clkdm_sleep(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_FORCE_WAKEUP:
+ am33xx_clkdm_wakeup(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_ENABLE_AUTO:
+ am33xx_clkdm_allow_idle(clkdm);
+ break;
+ }
+ return 0;
+}
+
struct clkdm_ops am33xx_clkdm_operations = {
.clkdm_sleep = am33xx_clkdm_sleep,
.clkdm_wakeup = am33xx_clkdm_wakeup,
@@ -345,6 +396,8 @@ struct clkdm_ops am33xx_clkdm_operations = {
.clkdm_deny_idle = am33xx_clkdm_deny_idle,
.clkdm_clk_enable = am33xx_clkdm_clk_enable,
.clkdm_clk_disable = am33xx_clkdm_clk_disable,
+ .clkdm_save_context = am33xx_clkdm_save_context,
+ .clkdm_restore_context = am33xx_clkdm_restore_context,
};
static const struct cm_ll_data am33xx_cm_ll_data = {
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 7deefee49fc3..c11ac492b626 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -481,6 +481,47 @@ static u32 omap4_cminst_xlate_clkctrl(u8 part, u16 inst, u16 offset)
return _cm_bases[part].pa + inst + offset;
}
+/**
+ * omap4_clkdm_save_context - Save the clockdomain modulemode context
+ * @clkdm: The clockdomain pointer whose context needs to be saved
+ *
+ * Save the clockdomain modulemode context.
+ */
+static int omap4_clkdm_save_context(struct clockdomain *clkdm)
+{
+ clkdm->context = omap4_cminst_read_inst_reg(clkdm->prcm_partition,
+ clkdm->cm_inst,
+ clkdm->clkdm_offs +
+ OMAP4_CM_CLKSTCTRL);
+ clkdm->context &= OMAP4430_MODULEMODE_MASK;
+ return 0;
+}
+
+/**
+ * omap4_clkdm_restore_context - Restore the clockdomain modulemode context
+ * @clkdm: The clockdomain pointer whose context needs to be restored
+ *
+ * Restore the clockdomain modulemode context.
+ */
+static int omap4_clkdm_restore_context(struct clockdomain *clkdm)
+{
+ switch (clkdm->context) {
+ case OMAP34XX_CLKSTCTRL_DISABLE_AUTO:
+ omap4_clkdm_deny_idle(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_FORCE_SLEEP:
+ omap4_clkdm_sleep(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_FORCE_WAKEUP:
+ omap4_clkdm_wakeup(clkdm);
+ break;
+ case OMAP34XX_CLKSTCTRL_ENABLE_AUTO:
+ omap4_clkdm_allow_idle(clkdm);
+ break;
+ }
+ return 0;
+}
+
struct clkdm_ops omap4_clkdm_operations = {
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
@@ -496,6 +537,8 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable,
+ .clkdm_save_context = omap4_clkdm_save_context,
+ .clkdm_restore_context = omap4_clkdm_restore_context,
};
struct clkdm_ops am43xx_clkdm_operations = {
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index fbe0b78bf489..dff3750e432f 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -44,6 +44,9 @@
#define OMAP_INTC_START NR_IRQS
+extern int (*omap_pm_soc_init)(void);
+int omap_pm_nop_init(void);
+
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
int omap2_pm_init(void);
#else
@@ -79,9 +82,12 @@ static inline int omap4_pm_init_early(void)
#if defined(CONFIG_PM) && (defined(CONFIG_SOC_AM33XX) || \
defined(CONFIG_SOC_AM43XX))
-void amx3_common_pm_init(void);
+int amx3_common_pm_init(void);
#else
-static inline void amx3_common_pm_init(void) { }
+static inline int amx3_common_pm_init(void)
+{
+ return 0;
+}
#endif
extern void omap2_init_common_infrastructure(void);
@@ -122,14 +128,10 @@ void am43xx_init_early(void);
void am43xx_init_late(void);
void omap4430_init_early(void);
void omap5_init_early(void);
-void omap3_init_late(void); /* Do not use this one */
+void omap3_init_late(void);
void omap4430_init_late(void);
void omap2420_init_late(void);
void omap2430_init_late(void);
-void omap3430_init_late(void);
-void omap35xx_init_late(void);
-void omap3630_init_late(void);
-void am35xx_init_late(void);
void ti81xx_init_late(void);
void am33xx_init_late(void);
void omap5_init_late(void);
@@ -350,7 +352,5 @@ extern int omap_dss_reset(struct omap_hwmod *);
/* SoC specific clock initializer */
int omap_clk_init(void);
-int __init omapdss_init_of(void);
-
#endif /* __ASSEMBLER__ */
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 180da403639e..0bbfb20e193f 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -17,6 +17,7 @@
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/cpu_pm.h>
#include "soc.h"
#include "iomap.h"
@@ -621,6 +622,110 @@ void __init omap3_ctrl_init(void)
}
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+static unsigned long am43xx_control_reg_offsets[] = {
+ AM33XX_CONTROL_SYSCONFIG_OFFSET,
+ AM33XX_CONTROL_STATUS_OFFSET,
+ AM43XX_CONTROL_MPU_L2_CTRL_OFFSET,
+ AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET,
+ AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET,
+ AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET,
+ AM33XX_CONTROL_BANDGAP_CTRL_OFFSET,
+ AM33XX_CONTROL_BANDGAP_TRIM_OFFSET,
+ AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET,
+ AM33XX_CONTROL_MOSC_CTRL_OFFSET,
+ AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET,
+ AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET,
+ AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET,
+ AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET,
+ AM33XX_CONTROL_TPTC_CFG_OFFSET,
+ AM33XX_CONTROL_USB_CTRL0_OFFSET,
+ AM33XX_CONTROL_USB_CTRL1_OFFSET,
+ AM43XX_CONTROL_USB_CTRL2_OFFSET,
+ AM43XX_CONTROL_GMII_SEL_OFFSET,
+ AM43XX_CONTROL_MPUSS_CTRL_OFFSET,
+ AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET,
+ AM43XX_CONTROL_PWMSS_CTRL_OFFSET,
+ AM33XX_CONTROL_MREQPRIO_0_OFFSET,
+ AM33XX_CONTROL_MREQPRIO_1_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET,
+ AM33XX_CONTROL_SMRT_CTRL_OFFSET,
+ AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET,
+ AM43XX_CONTROL_CQDETECT_STS_OFFSET,
+ AM43XX_CONTROL_CQDETECT_STS2_OFFSET,
+ AM43XX_CONTROL_VTP_CTRL_OFFSET,
+ AM33XX_CONTROL_VREF_CTRL_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET,
+ AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET,
+ AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_RESET_ISO_OFFSET,
+};
+
+static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
+
+/**
+ * am43xx_control_save_context - Save the wakeup domain registers
+ *
+ * Save the wkup domain registers
+ */
+void am43xx_control_save_context(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+ am33xx_control_vals[i] =
+ omap_ctrl_readl(am43xx_control_reg_offsets[i]);
+}
+
+/**
+ * am43xx_control_restore_context - Restore the wakeup domain registers
+ *
+ * Restore the wkup domain registers
+ */
+void am43xx_control_restore_context(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+ omap_ctrl_writel(am33xx_control_vals[i],
+ am43xx_control_reg_offsets[i]);
+}
+
+static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (enable_off_mode)
+ am43xx_control_save_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (enable_off_mode)
+ am43xx_control_restore_context();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
struct control_init_data {
int index;
void __iomem *mem;
@@ -699,6 +804,7 @@ int __init omap_control_init(void)
const struct omap_prcm_init_data *data;
int ret;
struct regmap *syscon;
+ static struct notifier_block nb;
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
data = match->data;
@@ -731,6 +837,12 @@ int __init omap_control_init(void)
}
}
+ /* Only AM43XX can lose ctrl registers context during rtc-ddr suspend */
+ if (soc_is_am43xx()) {
+ nb.notifier_call = cpu_notifier;
+ cpu_pm_register_notifier(&nb);
+ }
+
return 0;
}
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index ec406bc2c6d4..393b42110511 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -409,6 +409,67 @@
#define AM33XX_DEV_FEATURE 0x604
#define AM33XX_SGX_MASK BIT(29)
+/* Additional AM33XX/AM43XX CONTROL registers */
+#define AM33XX_CONTROL_SYSCONFIG_OFFSET 0x0010
+#define AM33XX_CONTROL_STATUS_OFFSET 0x0040
+#define AM43XX_CONTROL_MPU_L2_CTRL_OFFSET 0x01e0
+#define AM33XX_CONTROL_CORTEX_VBBLDO_CTRL_OFFSET 0x041c
+#define AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET 0x0428
+#define AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET 0x042c
+#define AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET 0x0444
+#define AM33XX_CONTROL_BANDGAP_CTRL_OFFSET 0x0448
+#define AM33XX_CONTROL_BANDGAP_TRIM_OFFSET 0x044c
+#define AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET 0x0458
+#define AM33XX_CONTROL_MOSC_CTRL_OFFSET 0x0468
+#define AM33XX_CONTROL_RCOSC_CTRL_OFFSET 0x046c
+#define AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET 0x0470
+#define AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET 0x0534
+#define AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET 0x0608
+#define AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET 0x060c
+#define AM33XX_CONTROL_MMU_CFG_OFFSET 0x0610
+#define AM33XX_CONTROL_TPTC_CFG_OFFSET 0x0614
+#define AM33XX_CONTROL_USB_CTRL0_OFFSET 0x0620
+#define AM33XX_CONTROL_USB_CTRL1_OFFSET 0x0628
+#define AM33XX_CONTROL_USB_WKUP_CTRL_OFFSET 0x0648
+#define AM43XX_CONTROL_USB_CTRL2_OFFSET 0x064c
+#define AM43XX_CONTROL_GMII_SEL_OFFSET 0x0650
+#define AM43XX_CONTROL_MPUSS_CTRL_OFFSET 0x0654
+#define AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET 0x0658
+#define AM43XX_CONTROL_PWMSS_CTRL_OFFSET 0x0664
+#define AM33XX_CONTROL_MREQPRIO_0_OFFSET 0x0670
+#define AM33XX_CONTROL_MREQPRIO_1_OFFSET 0x0674
+#define AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET 0x0690
+#define AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET 0x0694
+#define AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET 0x0698
+#define AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET 0x069c
+#define AM33XX_CONTROL_SMRT_CTRL_OFFSET 0x06a0
+#define AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET 0x06a4
+#define AM43XX_CONTROL_CQDETECT_STS_OFFSET 0x0e00
+#define AM43XX_CONTROL_CQDETECT_STS2_OFFSET 0x0e08
+#define AM43XX_CONTROL_VTP_CTRL_OFFSET 0x0e0c
+#define AM33XX_CONTROL_VREF_CTRL_OFFSET 0x0e14
+#define AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET 0x0f90
+#define AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET 0x0f94
+#define AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET 0x0f98
+#define AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET 0x0f9c
+#define AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET 0x0fa0
+#define AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET 0x0fa4
+#define AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET 0x0fa8
+#define AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET 0x0fac
+#define AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET 0x0fb0
+#define AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET 0x0fb4
+#define AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET 0x0fb8
+#define AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET 0x0fbc
+#define AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET 0x0fc0
+#define AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET 0x0fc4
+#define AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET 0x0fc8
+#define AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET 0x0fcc
+#define AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET 0x0fd0
+#define AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET 0x0fd4
+#define AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET 0x0fd8
+#define AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET 0x0fdc
+#define AM33XX_CONTROL_RESET_ISO_OFFSET 0x1000
+
/* CONTROL OMAP STATUS register to identify OMAP3 features */
#define OMAP3_CONTROL_OMAP_STATUS 0x044c
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index b3f6eb5d04a2..9500b6e27380 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -32,7 +32,6 @@
#include <linux/platform_data/omapdss.h>
#include "omap_hwmod.h"
#include "omap_device.h"
-#include "omap-pm.h"
#include "common.h"
#include "soc.h"
@@ -126,11 +125,6 @@ static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
omap4_dsi_mux_pads(dsi_id, 0);
}
-static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
-{
- return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput);
-}
-
static enum omapdss_version __init omap_display_get_version(void)
{
if (cpu_is_omap24xx())
@@ -169,7 +163,6 @@ static int __init omapdss_init_fbdev(void)
static struct omap_dss_board_info board_data = {
.dsi_enable_pads = omap_dsi_enable_pads,
.dsi_disable_pads = omap_dsi_disable_pads,
- .set_min_bus_tput = omap_dss_set_min_bus_tput,
};
struct device_node *node;
int r;
@@ -392,7 +385,7 @@ static struct device_node * __init omapdss_find_dss_of_node(void)
return NULL;
}
-int __init omapdss_init_of(void)
+static int __init omapdss_init_of(void)
{
int r;
struct device_node *node;
@@ -422,3 +415,4 @@ int __init omapdss_init_of(void)
return omapdss_init_fbdev();
}
+omap_device_initcall(omapdss_init_of);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b064066d431c..0103548b0b15 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -18,7 +18,6 @@
#include "soc.h"
#include "omap_device.h"
-#include "omap-pm.h"
#include "hsmmc.h"
#include "control.h"
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
index 91a21c3923b2..37ff25ee3d89 100644
--- a/arch/arm/mach-omap2/i2c.c
+++ b/arch/arm/mach-omap2/i2c.c
@@ -22,7 +22,6 @@
#include "soc.h"
#include "omap_hwmod.h"
#include "omap_device.h"
-#include "omap-pm.h"
#include "prm.h"
#include "common.h"
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index cf546dfe3b32..bb8e0bb7ef5d 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -37,7 +37,6 @@
#include "clock.h"
#include "clock2xxx.h"
#include "clock3xxx.h"
-#include "omap-pm.h"
#include "sdrc.h"
#include "control.h"
#include "serial.h"
@@ -421,13 +420,6 @@ static void __init __maybe_unused omap_hwmod_init_postsetup(void)
postsetup_state = _HWMOD_STATE_ENABLED;
#endif
omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
-
- omap_pm_if_early_init();
-}
-
-static void __init __maybe_unused omap_common_late_init(void)
-{
- omap2_common_pm_late_init();
}
#ifdef CONFIG_SOC_OMAP2420
@@ -450,9 +442,7 @@ void __init omap2420_init_early(void)
void __init omap2420_init_late(void)
{
- omap_common_late_init();
- omap2_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap2_pm_init;
}
#endif
@@ -476,9 +466,7 @@ void __init omap2430_init_early(void)
void __init omap2430_init_late(void)
{
- omap_common_late_init();
- omap2_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap2_pm_init;
}
#endif
@@ -529,43 +517,12 @@ void __init am35xx_init_early(void)
void __init omap3_init_late(void)
{
- omap_common_late_init();
- omap3_pm_init();
- omap2_clk_enable_autoidle_all();
-}
-
-void __init omap3430_init_late(void)
-{
- omap_common_late_init();
- omap3_pm_init();
- omap2_clk_enable_autoidle_all();
-}
-
-void __init omap35xx_init_late(void)
-{
- omap_common_late_init();
- omap3_pm_init();
- omap2_clk_enable_autoidle_all();
-}
-
-void __init omap3630_init_late(void)
-{
- omap_common_late_init();
- omap3_pm_init();
- omap2_clk_enable_autoidle_all();
-}
-
-void __init am35xx_init_late(void)
-{
- omap_common_late_init();
- omap3_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap3_pm_init;
}
void __init ti81xx_init_late(void)
{
- omap_common_late_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap_pm_nop_init;
}
#endif
@@ -621,8 +578,7 @@ void __init am33xx_init_early(void)
void __init am33xx_init_late(void)
{
- omap_common_late_init();
- amx3_common_pm_init();
+ omap_pm_soc_init = amx3_common_pm_init;
}
#endif
@@ -645,9 +601,7 @@ void __init am43xx_init_early(void)
void __init am43xx_init_late(void)
{
- omap_common_late_init();
- omap2_clk_enable_autoidle_all();
- amx3_common_pm_init();
+ omap_pm_soc_init = amx3_common_pm_init;
}
#endif
@@ -675,9 +629,7 @@ void __init omap4430_init_early(void)
void __init omap4430_init_late(void)
{
- omap_common_late_init();
- omap4_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap4_pm_init;
}
#endif
@@ -703,9 +655,7 @@ void __init omap5_init_early(void)
void __init omap5_init_late(void)
{
- omap_common_late_init();
- omap4_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap4_pm_init;
}
#endif
@@ -728,9 +678,7 @@ void __init dra7xx_init_early(void)
void __init dra7xx_init_late(void)
{
- omap_common_late_init();
- omap4_pm_init();
- omap2_clk_enable_autoidle_all();
+ omap_pm_soc_init = omap4_pm_init;
}
#endif
diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c
deleted file mode 100644
index 4ead077ea4e7..000000000000
--- a/arch/arm/mach-omap2/omap-pm-noop.c
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * omap-pm-noop.c - OMAP power management interface - dummy version
- *
- * This code implements the OMAP power management interface to
- * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for
- * debug/demonstration use, as it does nothing but printk() whenever a
- * function is called (when DEBUG is defined, below)
- *
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
- * Paul Walmsley
- *
- * Interface developed by (in alphabetical order):
- * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
- * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
- */
-
-#undef DEBUG
-
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-
-#include "omap_device.h"
-#include "omap-pm.h"
-
-static bool off_mode_enabled;
-static int dummy_context_loss_counter;
-
-/*
- * Device-driver-originated constraints (via board-*.c files)
- */
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (t == -1)
- pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n",
- dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the MPU to a
- * powerdomain, then go through the list of current max lat
- * constraints on the MPU and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
-{
- if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
- agent_id != OCP_TARGET_AGENT)) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (r == 0)
- pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n",
- dev_name(dev), agent_id);
- else
- pr_debug("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n",
- dev_name(dev), agent_id, r);
-
- /*
- * This code should model the interconnect and compute the
- * required clock frequency, convert that to a VDD2 OPP ID, then
- * set the VDD2 OPP appropriately.
- *
- * TI CDP code can call constraint_set here on the VDD2 OPP.
- */
-
- return 0;
-}
-
-/*
- * DSP Bridge-specific constraints
- */
-
-
-/**
- * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
- *
- * Intended for use only by OMAP PM core code to notify this layer
- * that off mode has been enabled.
- */
-void omap_pm_enable_off_mode(void)
-{
- off_mode_enabled = true;
-}
-
-/**
- * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
- *
- * Intended for use only by OMAP PM core code to notify this layer
- * that off mode has been disabled.
- */
-void omap_pm_disable_off_mode(void)
-{
- off_mode_enabled = false;
-}
-
-/*
- * Device context loss tracking
- */
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
-int omap_pm_get_dev_context_loss_count(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- int count;
-
- if (WARN_ON(!dev))
- return -ENODEV;
-
- if (dev->pm_domain == &omap_device_pm_domain) {
- count = omap_device_get_context_loss_count(pdev);
- } else {
- WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
- dev_name(dev));
-
- count = dummy_context_loss_counter;
-
- if (off_mode_enabled) {
- count++;
- /*
- * Context loss count has to be a non-negative value.
- * Clear the sign bit to get a value range from 0 to
- * INT_MAX.
- */
- count &= INT_MAX;
- dummy_context_loss_counter = count;
- }
- }
-
- pr_debug("OMAP PM: context loss count for dev %s = %d\n",
- dev_name(dev), count);
-
- return count;
-}
-
-#else
-
-int omap_pm_get_dev_context_loss_count(struct device *dev)
-{
- return dummy_context_loss_counter;
-}
-
-#endif
-
-/* Should be called before clk framework init */
-int __init omap_pm_if_early_init(void)
-{
- return 0;
-}
-
-/* Must be called after clock framework is initialized */
-int __init omap_pm_if_init(void)
-{
- return 0;
-}
diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h
deleted file mode 100644
index 5ba5df47f91b..000000000000
--- a/arch/arm/mach-omap2/omap-pm.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * omap-pm.h - OMAP power management interface
- *
- * Copyright (C) 2008-2010 Texas Instruments, Inc.
- * Copyright (C) 2008-2010 Nokia Corporation
- * Paul Walmsley
- *
- * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
- * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
- * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
- * Richard Woodruff
- */
-
-#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
-#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
-
-#include <linux/device.h>
-#include <linux/cpufreq.h>
-#include <linux/clk.h>
-#include <linux/pm_opp.h>
-
-/*
- * agent_id values for use with omap_pm_set_min_bus_tput():
- *
- * OCP_INITIATOR_AGENT is only valid for devices that can act as
- * initiators -- it represents the device's L3 interconnect
- * connection. OCP_TARGET_AGENT represents the device's L4
- * interconnect connection.
- */
-#define OCP_TARGET_AGENT 1
-#define OCP_INITIATOR_AGENT 2
-
-/**
- * omap_pm_if_early_init - OMAP PM init code called before clock fw init
- * @mpu_opp_table: array ptr to struct omap_opp for MPU
- * @dsp_opp_table: array ptr to struct omap_opp for DSP
- * @l3_opp_table : array ptr to struct omap_opp for CORE
- *
- * Initialize anything that must be configured before the clock
- * framework starts. The "_if_" is to avoid name collisions with the
- * PM idle-loop code.
- */
-int __init omap_pm_if_early_init(void);
-
-/**
- * omap_pm_if_init - OMAP PM init code called after clock fw init
- *
- * The main initialization code. OPP tables are passed in here. The
- * "_if_" is to avoid name collisions with the PM idle-loop code.
- */
-int __init omap_pm_if_init(void);
-
-/*
- * Device-driver-originated constraints (via board-*.c files, platform_data)
- */
-
-
-/**
- * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
- * @t: maximum MPU wakeup latency in microseconds
- *
- * Request that the maximum interrupt latency for the MPU to be no
- * greater than @t microseconds. "Interrupt latency" in this case is
- * defined as the elapsed time from the occurrence of a hardware or
- * timer interrupt to the time when the device driver's interrupt
- * service routine has been entered by the MPU.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the MPU powerdomain into, and
- * possibly the CORE powerdomain as well, since interrupt handling
- * code currently runs from SDRAM. Advanced PM or board*.c code may
- * also configure interrupt controller priorities, OCP bus priorities,
- * CPU speed(s), etc.
- *
- * This function will not affect device wakeup latency, e.g., time
- * elapsed from when a device driver enables a hardware device with
- * clk_enable(), to when the device is ready for register access or
- * other use. To control this device wakeup latency, use
- * omap_pm_set_max_dev_wakeup_lat()
- *
- * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
- * previous t value. To remove the latency target for the MPU, call
- * with t = -1.
- *
- * XXX This constraint will be deprecated soon in favor of the more
- * general omap_pm_set_max_dev_wakeup_lat()
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
- * @dev: struct device * requesting the constraint
- * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
- * @r: minimum throughput (in KiB/s)
- *
- * Request that the minimum data throughput on the OCP interconnect
- * attached to device @dev interconnect agent @tbus_id be no less
- * than @r KiB/s.
- *
- * It is expected that the OMAP PM or bus code will use this
- * information to set the interconnect clock to run at the lowest
- * possible speed that satisfies all current system users. The PM or
- * bus code will adjust the estimate based on its model of the bus, so
- * device driver authors should attempt to specify an accurate
- * quantity for their device use case, and let the PM or bus code
- * overestimate the numbers as necessary to handle request/response
- * latency, other competing users on the system, etc. On OMAP2/3, if
- * a driver requests a minimum L4 interconnect speed constraint, the
- * code will also need to add an minimum L3 interconnect speed
- * constraint,
- *
- * Multiple calls to omap_pm_set_min_bus_tput() will replace the
- * previous rate value for this device. To remove the interconnect
- * throughput restriction for this device, call with r = 0.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
-
-
-/*
- * CPUFreq-originated constraint
- *
- * In the future, this should be handled by custom OPP clocktype
- * functions.
- */
-
-
-/*
- * Device context loss tracking
- */
-
-/**
- * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
- * @dev: struct device *
- *
- * This function returns the number of times that the device @dev has
- * lost its internal context. This generally occurs on a powerdomain
- * transition to OFF. Drivers use this as an optimization to avoid restoring
- * context if the device hasn't lost it. To use, drivers should initially
- * call this in their context save functions and store the result. Early in
- * the driver's context restore function, the driver should call this function
- * again, and compare the result to the stored counter. If they differ, the
- * driver must restore device context. If the number of context losses
- * exceeds the maximum positive integer, the function will wrap to 0 and
- * continue counting. Returns the number of context losses for this device,
- * or negative value upon error.
- */
-int omap_pm_get_dev_context_loss_count(struct device *dev);
-
-void omap_pm_enable_off_mode(void);
-void omap_pm_disable_off_mode(void);
-
-#endif
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 3b829a50d1db..ac219b9e6a4c 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -143,7 +143,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
struct resource res;
const char *oh_name;
int oh_cnt, i, ret = 0;
- bool device_active = false;
+ bool device_active = false, skip_pm_domain = false;
oh_cnt = of_property_count_strings(node, "ti,hwmods");
if (oh_cnt <= 0) {
@@ -151,8 +151,15 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
return -ENODEV;
}
+ /* SDMA still needs special handling for omap_device_build() */
+ ret = of_property_read_string_index(node, "ti,hwmods", 0, &oh_name);
+ if (!ret && (!strncmp("dma_system", oh_name, 10) ||
+ !strncmp("dma", oh_name, 3)))
+ skip_pm_domain = true;
+
/* Use ti-sysc driver instead of omap_device? */
- if (!omap_hwmod_parse_module_range(NULL, node, &res))
+ if (!skip_pm_domain &&
+ !omap_hwmod_parse_module_range(NULL, node, &res))
return -ENODEV;
hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
@@ -191,11 +198,12 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
r->name = dev_name(&pdev->dev);
}
- dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
-
- if (device_active) {
- omap_device_enable(pdev);
- pm_runtime_set_active(&pdev->dev);
+ if (!skip_pm_domain) {
+ dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
+ if (device_active) {
+ omap_device_enable(pdev);
+ pm_runtime_set_active(&pdev->dev);
+ }
}
odbfd_exit1:
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e7d23e200ecc..2ceffd85dd3d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -481,7 +481,7 @@ static int _wait_softreset_complete(struct omap_hwmod *oh)
sysc = oh->class->sysc;
- if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS && sysc->syss_offs > 0)
omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
@@ -3171,19 +3171,19 @@ static int omap_hwmod_init_regbits(struct device *dev,
*/
int omap_hwmod_init_reg_offs(struct device *dev,
const struct ti_sysc_module_data *data,
- u32 *rev_offs, u32 *sysc_offs, u32 *syss_offs)
+ s32 *rev_offs, s32 *sysc_offs, s32 *syss_offs)
{
- *rev_offs = 0;
+ *rev_offs = -ENODEV;
*sysc_offs = 0;
*syss_offs = 0;
- if (data->offsets[SYSC_REVISION] > 0)
+ if (data->offsets[SYSC_REVISION] >= 0)
*rev_offs = data->offsets[SYSC_REVISION];
- if (data->offsets[SYSC_SYSCONFIG] > 0)
+ if (data->offsets[SYSC_SYSCONFIG] >= 0)
*sysc_offs = data->offsets[SYSC_SYSCONFIG];
- if (data->offsets[SYSC_SYSSTATUS] > 0)
+ if (data->offsets[SYSC_SYSSTATUS] >= 0)
*syss_offs = data->offsets[SYSC_SYSSTATUS];
return 0;
@@ -3312,8 +3312,8 @@ static int omap_hwmod_check_module(struct device *dev,
struct omap_hwmod *oh,
const struct ti_sysc_module_data *data,
struct sysc_regbits *sysc_fields,
- u32 rev_offs, u32 sysc_offs,
- u32 syss_offs, u32 sysc_flags,
+ s32 rev_offs, s32 sysc_offs,
+ s32 syss_offs, u32 sysc_flags,
u32 idlemodes)
{
if (!oh->class->sysc)
@@ -3365,7 +3365,7 @@ static int omap_hwmod_check_module(struct device *dev,
int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
const struct ti_sysc_module_data *data,
struct sysc_regbits *sysc_fields,
- u32 rev_offs, u32 sysc_offs, u32 syss_offs,
+ s32 rev_offs, s32 sysc_offs, s32 syss_offs,
u32 sysc_flags, u32 idlemodes)
{
struct omap_hwmod_class_sysconfig *sysc;
@@ -3425,7 +3425,8 @@ int omap_hwmod_init_module(struct device *dev,
{
struct omap_hwmod *oh;
struct sysc_regbits *sysc_fields;
- u32 rev_offs, sysc_offs, syss_offs, sysc_flags, idlemodes;
+ s32 rev_offs, sysc_offs, syss_offs;
+ u32 sysc_flags, idlemodes;
int error;
if (!dev || !data)
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index c7122abbf977..b70cdc21f8a2 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -317,9 +317,9 @@ struct omap_hwmod_ocp_if {
* then this field has to be populated with the correct offset structure.
*/
struct omap_hwmod_class_sysconfig {
- u32 rev_offs;
- u32 sysc_offs;
- u32 syss_offs;
+ s32 rev_offs;
+ s32 sysc_offs;
+ s32 syss_offs;
u16 sysc_flags;
struct sysc_regbits *sysc_fields;
u8 srst_udelay;
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
index 5efe91c6e95b..9ded7bf972e7 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
@@ -629,6 +629,7 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
/* 'i2c' class */
static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 23336b6c7125..d93f9ea4119e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -885,6 +885,7 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
@@ -990,6 +991,7 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
/* 'mcbsp sidetone' class */
static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_AUTOIDLE,
.sysc_fields = &omap_hwmod_sysc_type1,
@@ -1018,6 +1020,7 @@ static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
/* SR common */
static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x24,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
.sysc_fields = &omap34xx_sr_sysc_fields,
@@ -1030,6 +1033,7 @@ static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
};
static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x38,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index 5f73b730d4fc..aa271ac5ebac 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -378,6 +378,7 @@ static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = {
};
static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index e4f8ae9cd637..234ee0eec815 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1360,6 +1360,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -1634,6 +1635,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0004,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1667,6 +1669,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
@@ -2353,6 +2356,7 @@ static struct omap_hwmod omap44xx_slimbus2_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x0038,
.sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index c72cd84b07ec..887a30fa775b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -804,6 +804,7 @@ static struct omap_hwmod omap54xx_gpio8_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -974,6 +975,7 @@ static struct omap_hwmod omap54xx_mailbox_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
@@ -1997,6 +1999,7 @@ static struct omap_hwmod omap54xx_ocp2scp3_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = {
+ .rev_offs = 0x00fc,
.sysc_offs = 0x0000,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 62352d1e6361..a27c2fed298c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -1070,6 +1070,7 @@ static struct omap_hwmod dra7xx_hdq1w_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_i2c_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -1440,6 +1441,7 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
*
*/
static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0004,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
@@ -1898,6 +1900,7 @@ static struct omap_hwmod dra7xx_pciess2_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_qspi_sysc = {
+ .rev_offs = 0,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1930,6 +1933,7 @@ static struct omap_hwmod dra7xx_qspi_hwmod = {
*
*/
static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = {
+ .rev_offs = 0x0074,
.sysc_offs = 0x0078,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1965,6 +1969,7 @@ static struct omap_hwmod dra7xx_rtcss_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_sata_sysc = {
+ .rev_offs = 0x00fc,
.sysc_offs = 0x0000,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -2003,6 +2008,7 @@ static struct omap_hwmod dra7xx_sata_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig dra7xx_smartreflex_sysc = {
+ .rev_offs = -ENODEV,
.sysc_offs = 0x0038,
.sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 686655f884c1..8e44e2728620 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -954,6 +954,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
};
static struct omap_hwmod_class_sysconfig dm81xx_sata_sysc = {
+ .rev_offs = 0x00fc,
.sysc_offs = 0x1100,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = SIDLE_FORCE,
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 6459816c2879..7f02743edbe4 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -26,14 +26,12 @@
#include <linux/platform_data/iommu-omap.h>
#include <linux/platform_data/ti-sysc.h>
#include <linux/platform_data/wkup_m3.h>
-#include <linux/platform_data/media/ir-rx51.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "common.h"
#include "common-board-devices.h"
#include "control.h"
#include "omap_device.h"
-#include "omap-pm.h"
#include "omap-secure.h"
#include "soc.h"
#include "hsmmc.h"
@@ -514,18 +512,6 @@ void omap_auxdata_legacy_init(struct device *dev)
dev->platform_data = &twl_gpio_auxdata;
}
-static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
- .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
-};
-
-static struct platform_device __maybe_unused rx51_ir_device = {
- .name = "ir_rx51",
- .id = -1,
- .dev = {
- .platform_data = &rx51_ir_data,
- },
-};
-
#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP)
static struct omap_mcbsp_platform_data mcbsp_pdata;
static void __init omap3_mcbsp_init(void)
@@ -569,7 +555,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
"480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),
OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]),
OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]),
- OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_ir_data),
/* Only on am3517 */
OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 5c46ea6756d7..acb698d5780f 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -31,7 +31,6 @@
#include "clock.h"
#include "powerdomain.h"
#include "clockdomain.h"
-#include "omap-pm.h"
#include "soc.h"
#include "cm2xxx_3xxx.h"
@@ -240,10 +239,6 @@ static int option_set(void *data, u64 val)
*option = val;
if (option == &enable_off_mode) {
- if (val)
- omap_pm_enable_off_mode();
- else
- omap_pm_disable_off_mode();
if (cpu_is_omap34xx())
omap3_pm_off_mode_enable(val);
}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 6f68576e5695..ca03af8fe43f 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -16,11 +16,11 @@
#include <linux/pm_opp.h>
#include <linux/export.h>
#include <linux/suspend.h>
+#include <linux/clk.h>
#include <linux/cpu.h>
#include <asm/system_misc.h>
-#include "omap-pm.h"
#include "omap_device.h"
#include "common.h"
@@ -230,16 +230,20 @@ static void __init omap4_init_voltages(void)
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
}
-static int __init omap2_common_pm_init(void)
+int __maybe_unused omap_pm_nop_init(void)
{
- omap_pm_if_init();
-
return 0;
}
-omap_postcore_initcall(omap2_common_pm_init);
+
+int (*omap_pm_soc_init)(void);
int __init omap2_common_pm_late_init(void)
{
+ int error;
+
+ if (!omap_pm_soc_init)
+ return 0;
+
/* Init the voltage layer */
omap3_twl_init();
omap4_twl_init();
@@ -252,5 +256,12 @@ int __init omap2_common_pm_late_init(void)
/* Smartreflex device init */
omap_devinit_smartreflex();
+ error = omap_pm_soc_init();
+ if (error)
+ pr_warn("%s: pm soc init failed: %i\n", __func__, error);
+
+ omap2_clk_enable_autoidle_all();
+
return 0;
}
+omap_late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c
index 93c0b5ba9f09..9b3755a2e2ec 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -173,7 +173,7 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
return NULL;
}
-void __init amx3_common_pm_init(void)
+int __init amx3_common_pm_init(void)
{
struct am33xx_pm_platform_data *pdata;
struct platform_device_info devinfo;
@@ -186,4 +186,6 @@ void __init amx3_common_pm_init(void)
devinfo.size_data = sizeof(*pdata);
devinfo.id = -1;
platform_device_register_full(&devinfo);
+
+ return 0;
}
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index b3870220612e..78e1ace7d17d 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -131,6 +131,19 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
return 0;
}
+ /*
+ * Bootloader or kexec boot may have LOGICRETSTATE cleared
+ * for some domains. This is the case when kexec booting from
+ * Android kernels that support off mode for example.
+ * Make sure it's set at least for core and per, otherwise
+ * we currently will see lost GPIO interrupts for wlcore and
+ * smsc911x at least if per hits retention during idle.
+ */
+ if (!strncmp(pwrdm->name, "core", 4) ||
+ !strncmp(pwrdm->name, "l4per", 5) ||
+ !strncmp(pwrdm->name, "wkup", 4))
+ pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
+
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
if (!pwrst)
return -ENOMEM;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 1e6a967cd2d5..1a0f69c0a376 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -14,6 +14,7 @@
*/
#undef DEBUG
+#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/list.h>
@@ -39,6 +40,9 @@
#define PWRDM_TRACE_STATES_FLAG (1<<31)
+void pwrdms_save_context(void);
+void pwrdms_restore_context(void);
+
enum {
PWRDM_STATE_NOW = 0,
PWRDM_STATE_PREV,
@@ -333,6 +337,22 @@ int pwrdm_register_pwrdms(struct powerdomain **ps)
return 0;
}
+static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (enable_off_mode)
+ pwrdms_save_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (enable_off_mode)
+ pwrdms_restore_context();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
/**
* pwrdm_complete_init - set up the powerdomain layer
*
@@ -347,6 +367,7 @@ int pwrdm_register_pwrdms(struct powerdomain **ps)
int pwrdm_complete_init(void)
{
struct powerdomain *temp_p;
+ static struct notifier_block nb;
if (list_empty(&pwrdm_list))
return -EACCES;
@@ -354,6 +375,12 @@ int pwrdm_complete_init(void)
list_for_each_entry(temp_p, &pwrdm_list, node)
pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
+ /* Only AM43XX can lose pwrdm context during rtc-ddr suspend */
+ if (soc_is_am43xx()) {
+ nb.notifier_call = cpu_notifier;
+ cpu_pm_register_notifier(&nb);
+ }
+
return 0;
}
@@ -1199,3 +1226,63 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
return 0;
}
+
+/**
+ * pwrdm_save_context - save powerdomain registers
+ *
+ * Register state is going to be lost due to a suspend or hibernate
+ * event. Save the powerdomain registers.
+ */
+static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused)
+{
+ if (arch_pwrdm && arch_pwrdm->pwrdm_save_context)
+ arch_pwrdm->pwrdm_save_context(pwrdm);
+ return 0;
+}
+
+/**
+ * pwrdm_save_context - restore powerdomain registers
+ *
+ * Restore powerdomain control registers after a suspend or resume
+ * event.
+ */
+static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused)
+{
+ if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context)
+ arch_pwrdm->pwrdm_restore_context(pwrdm);
+ return 0;
+}
+
+static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused)
+{
+ int state;
+
+ /*
+ * Power has been lost across all powerdomains, increment the
+ * counter.
+ */
+
+ state = pwrdm_read_pwrst(pwrdm);
+ if (state != PWRDM_POWER_OFF) {
+ pwrdm->state_counter[state]++;
+ pwrdm->state_counter[PWRDM_POWER_OFF]++;
+ }
+ pwrdm->state = state;
+
+ return 0;
+}
+
+void pwrdms_save_context(void)
+{
+ pwrdm_for_each(pwrdm_save_context, NULL);
+}
+
+void pwrdms_restore_context(void)
+{
+ pwrdm_for_each(pwrdm_restore_context, NULL);
+}
+
+void pwrdms_lost_power(void)
+{
+ pwrdm_for_each(pwrdm_lost_power, NULL);
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 28a796ce07d7..9a907fb14044 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -144,6 +144,7 @@ struct powerdomain {
s64 timer;
s64 state_timer[PWRDM_MAX_PWRSTS];
#endif
+ u32 context;
};
/**
@@ -198,6 +199,8 @@ struct pwrdm_ops {
int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
int (*pwrdm_has_voltdm)(void);
+ void (*pwrdm_save_context)(struct powerdomain *pwrdm);
+ void (*pwrdm_restore_context)(struct powerdomain *pwrdm);
};
int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
@@ -273,4 +276,8 @@ extern struct powerdomain gfx_omap2_pwrdm;
extern void pwrdm_lock(struct powerdomain *pwrdm);
extern void pwrdm_unlock(struct powerdomain *pwrdm);
+extern void pwrdms_save_context(void);
+extern void pwrdms_restore_context(void);
+
+extern void pwrdms_lost_power(void);
#endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index ebaf80d72a10..d5141669c28d 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -342,6 +342,35 @@ static void am33xx_prm_global_warm_sw_reset(void)
AM33XX_PRM_RSTCTRL_OFFSET);
}
+static void am33xx_pwrdm_save_context(struct powerdomain *pwrdm)
+{
+ pwrdm->context = am33xx_prm_read_reg(pwrdm->prcm_offs,
+ pwrdm->pwrstctrl_offs);
+ /*
+ * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
+ * reading back a 1 indicates a request in progress.
+ */
+ pwrdm->context &= ~AM33XX_LOWPOWERSTATECHANGE_MASK;
+}
+
+static void am33xx_pwrdm_restore_context(struct powerdomain *pwrdm)
+{
+ int st, ctrl;
+
+ st = am33xx_prm_read_reg(pwrdm->prcm_offs,
+ pwrdm->pwrstst_offs);
+
+ am33xx_prm_write_reg(pwrdm->context, pwrdm->prcm_offs,
+ pwrdm->pwrstctrl_offs);
+
+ /* Make sure we only wait for a transition if there is one */
+ st &= OMAP_POWERSTATEST_MASK;
+ ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
+
+ if (st != ctrl)
+ am33xx_pwrdm_wait_transition(pwrdm);
+}
+
struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
@@ -357,6 +386,8 @@ struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
.pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
.pwrdm_has_voltdm = am33xx_check_vcvp,
+ .pwrdm_save_context = am33xx_pwrdm_save_context,
+ .pwrdm_restore_context = am33xx_pwrdm_restore_context,
};
static struct prm_ll_data am33xx_prm_ll_data = {
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index acb95936dfe7..7b95729e8359 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -30,6 +31,7 @@
#include "prcm44xx.h"
#include "prminst44xx.h"
#include "powerdomain.h"
+#include "pm.h"
/* Static data */
@@ -57,6 +59,13 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
.reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain,
};
+struct omap_prm_irq_context {
+ unsigned long irq_enable;
+ unsigned long pm_ctrl;
+};
+
+static struct omap_prm_irq_context omap_prm_context;
+
/*
* omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
* hardware register (which are specific to OMAP44xx SoCs) to reset
@@ -667,6 +676,54 @@ static int omap4_check_vcvp(void)
return 0;
}
+/**
+ * omap4_pwrdm_save_context - Saves the powerdomain state
+ * @pwrdm: pointer to individual powerdomain
+ *
+ * The function saves the powerdomain state control information.
+ * This is needed in rtc+ddr modes where we lose powerdomain context.
+ */
+static void omap4_pwrdm_save_context(struct powerdomain *pwrdm)
+{
+ pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ pwrdm->pwrstctrl_offs);
+
+ /*
+ * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
+ * reading back a 1 indicates a request in progress.
+ */
+ pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK;
+}
+
+/**
+ * omap4_pwrdm_restore_context - Restores the powerdomain state
+ * @pwrdm: pointer to individual powerdomain
+ *
+ * The function restores the powerdomain state control information.
+ * This is needed in rtc+ddr modes where we lose powerdomain context.
+ */
+static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm)
+{
+ int st, ctrl;
+
+ st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ pwrdm->pwrstctrl_offs);
+
+ omap4_prminst_write_inst_reg(pwrdm->context,
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ pwrdm->pwrstctrl_offs);
+
+ /* Make sure we only wait for a transition if there is one */
+ st &= OMAP_POWERSTATEST_MASK;
+ ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
+
+ if (st != ctrl)
+ omap4_pwrdm_wait_transition(pwrdm);
+}
+
struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
@@ -685,10 +742,50 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
.pwrdm_wait_transition = omap4_pwrdm_wait_transition,
.pwrdm_has_voltdm = omap4_check_vcvp,
+ .pwrdm_save_context = omap4_pwrdm_save_context,
+ .pwrdm_restore_context = omap4_pwrdm_restore_context,
};
static int omap44xx_prm_late_init(void);
+void prm_save_context(void)
+{
+ omap_prm_context.irq_enable =
+ omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
+ omap4_prcm_irq_setup.mask);
+
+ omap_prm_context.pm_ctrl =
+ omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
+ omap4_prcm_irq_setup.pm_ctrl);
+}
+
+void prm_restore_context(void)
+{
+ omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ omap4_prcm_irq_setup.mask);
+
+ omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
+ AM43XX_PRM_DEVICE_INST,
+ omap4_prcm_irq_setup.pm_ctrl);
+}
+
+static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (enable_off_mode)
+ prm_save_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (enable_off_mode)
+ prm_restore_context();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
/*
* XXX document
*/
@@ -709,6 +806,7 @@ static const struct omap_prcm_init_data *prm_init_data;
int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
{
+ static struct notifier_block nb;
omap_prm_base_init();
prm_init_data = data;
@@ -730,6 +828,12 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
}
+ /* Only AM43XX can lose prm context during rtc-ddr suspend */
+ if (soc_is_am43xx()) {
+ nb.notifier_call = cpu_notifier;
+ cpu_pm_register_notifier(&nb);
+ }
+
return prm_register(&omap44xx_prm_ll_data);
}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 4fb4dc24e5e9..98ed5ac073bc 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -50,7 +50,6 @@
#include "omap_device.h"
#include <plat/counter-32k.h>
#include <clocksource/timer-ti-dm.h>
-#include "omap-pm.h"
#include "soc.h"
#include "common.h"
@@ -71,6 +70,9 @@ static struct clock_event_device clockevent_gpt;
/* Clockevent hwmod for am335x and am437x suspend */
static struct omap_hwmod *clockevent_gpt_hwmod;
+/* Clockesource hwmod for am437x suspend */
+static struct omap_hwmod *clocksource_gpt_hwmod;
+
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
static unsigned long arch_timer_freq;
@@ -168,6 +170,43 @@ static const struct of_device_id omap_timer_match[] __initconst = {
{ }
};
+static int omap_timer_add_disabled_property(struct device_node *np)
+{
+ struct property *prop;
+
+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+ if (!prop)
+ return -ENOMEM;
+
+ prop->name = "status";
+ prop->value = "disabled";
+ prop->length = strlen(prop->value);
+
+ return of_add_property(np, prop);
+}
+
+static int omap_timer_update_dt(struct device_node *np)
+{
+ int error = 0;
+
+ if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
+ error = omap_timer_add_disabled_property(np);
+ if (error)
+ return error;
+ }
+
+ /* No parent interconnect target module configured? */
+ if (of_get_property(np, "ti,hwmods", NULL))
+ return error;
+
+ /* Tag parent interconnect target module disabled */
+ error = omap_timer_add_disabled_property(np->parent);
+ if (error)
+ return error;
+
+ return 0;
+}
+
/**
* omap_get_timer_dt - get a timer using device-tree
* @match - device-tree match structure for matching a device type
@@ -183,6 +222,7 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
const char *property)
{
struct device_node *np;
+ int error;
for_each_matching_node(np, match) {
if (!of_device_is_available(np))
@@ -197,17 +237,9 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
of_get_property(np, "ti,timer-secure", NULL)))
continue;
- if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
- struct property *prop;
+ error = omap_timer_update_dt(np);
+ WARN(error, "%s: Could not update dt: %i\n", __func__, error);
- prop = kzalloc(sizeof(*prop), GFP_KERNEL);
- if (!prop)
- return NULL;
- prop->name = "status";
- prop->value = "disabled";
- prop->length = strlen(prop->value);
- of_add_property(np, prop);
- }
return np;
}
@@ -266,8 +298,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
return -ENODEV;
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
- if (!oh_name)
- return -ENODEV;
+ if (!oh_name) {
+ of_property_read_string_index(np->parent, "ti,hwmods", 0,
+ &oh_name);
+ if (!oh_name)
+ return -ENODEV;
+ }
timer->irq = irq_of_parse_and_map(np, 0);
if (!timer->irq)
@@ -419,9 +455,12 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
if (!np)
return -ENODEV;
- of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
- if (!oh_name)
- return -ENODEV;
+ of_property_read_string_index(np->parent, "ti,hwmods", 0, &oh_name);
+ if (!oh_name) {
+ of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
+ if (!oh_name)
+ return -ENODEV;
+ }
/*
* First check hwmod data is available for sync32k counter
@@ -442,6 +481,26 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
return ret;
}
+static unsigned int omap2_gptimer_clksrc_load;
+
+static void omap2_gptimer_clksrc_suspend(struct clocksource *unused)
+{
+ omap2_gptimer_clksrc_load =
+ __omap_dm_timer_read_counter(&clksrc, OMAP_TIMER_NONPOSTED);
+
+ omap_hwmod_idle(clocksource_gpt_hwmod);
+}
+
+static void omap2_gptimer_clksrc_resume(struct clocksource *unused)
+{
+ omap_hwmod_enable(clocksource_gpt_hwmod);
+
+ __omap_dm_timer_load_start(&clksrc,
+ OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR,
+ omap2_gptimer_clksrc_load,
+ OMAP_TIMER_NONPOSTED);
+}
+
static void __init omap2_gptimer_clocksource_init(int gptimer_id,
const char *fck_source,
const char *property)
@@ -454,6 +513,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
res = omap_dm_timer_init_one(&clksrc, fck_source, property,
&clocksource_gpt.name,
OMAP_TIMER_NONPOSTED);
+
+ if (soc_is_am43xx()) {
+ clocksource_gpt.suspend = omap2_gptimer_clksrc_suspend;
+ clocksource_gpt.resume = omap2_gptimer_clksrc_resume;
+
+ clocksource_gpt_hwmod =
+ omap_hwmod_lookup(clocksource_gpt.name);
+ }
+
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4b8a0df8ea57..8c64f93b669b 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -446,6 +446,10 @@ static int __init pxa3xx_init(void)
pxa3xx_init_pm();
+ enable_irq_wake(IRQ_WAKEUP0);
+ if (cpu_is_pxa320())
+ enable_irq_wake(IRQ_WAKEUP1);
+
register_syscore_ops(&pxa_irq_syscore_ops);
register_syscore_ops(&pxa3xx_mfp_syscore_ops);
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index df62bb23dbee..bbea5fa9a140 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -27,11 +27,11 @@
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/pcf857x.h>
-#include <linux/platform_data/at24.h>
#include <linux/smc91x.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/leds.h>
+#include <linux/property.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -795,9 +795,9 @@ static struct pcf857x_platform_data platform_data_pcf857x = {
.context = NULL,
};
-static struct at24_platform_data pca9500_eeprom_pdata = {
- .byte_len = 256,
- .page_size = 4,
+static const struct property_entry pca9500_eeprom_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 4),
+ { }
};
/**
@@ -935,7 +935,7 @@ static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
}, {
.type = "24c02",
.addr = 0x57,
- .platform_data = &pca9500_eeprom_pdata,
+ .properties = pca9500_eeprom_properties,
}, {
.type = "max1238",
.addr = 0x35,
diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
index 46ad20ea87d1..186b5321658e 100644
--- a/arch/arm/mach-s3c24xx/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-1.0
+// SPDX-License-Identifier: GPL-1.0+
//
// Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
//
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
index 95753e0bc073..f9fc1f8d2b28 100644
--- a/arch/arm/mach-s3c24xx/mach-mini2440.c
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -20,7 +20,7 @@
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/dm9000.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>
@@ -481,15 +481,15 @@ static struct platform_device mini2440_audio = {
/*
* I2C devices
*/
-static struct at24_platform_data at24c08 = {
- .byte_len = SZ_8K / 8,
- .page_size = 16,
+static const struct property_entry mini2440_at24_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 16),
+ { }
};
static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
{
I2C_BOARD_INFO("24c08", 0x50),
- .platform_data = &at24c08,
+ .properties = mini2440_at24_properties,
},
};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index fe60cd09a5ca..0b67254eabb2 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -74,6 +74,10 @@ config ARCH_R8A7745
bool "RZ/G1E (R8A77450)"
select ARCH_RCAR_GEN2
+config ARCH_R8A77470
+ bool "RZ/G1C (R8A77470)"
+ select ARCH_RCAR_GEN2
+
config ARCH_R8A7778
bool "R-Car M1A (R8A77781)"
select ARCH_RCAR_GEN1
@@ -109,6 +113,15 @@ config ARCH_R8A7794
bool "R-Car E2 (R8A77940)"
select ARCH_RCAR_GEN2
+config ARCH_R9A06G032
+ bool "RZ/N1D (R9A06G032)"
+ select ARCH_RZN1
+
+config ARCH_RZN1
+ bool "RZ/N1 (R9A06G0xx) Family"
+ select ARM_AMBA
+ select CPU_V7
+
config ARCH_SH73A0
bool "SH-Mobile AG5 (R8A73A00)"
select ARCH_RMOBILE
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 43c1ac696274..2109f123bdfb 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -2,7 +2,6 @@
#ifndef __ARCH_MACH_COMMON_H
#define __ARCH_MACH_COMMON_H
-extern void shmobile_init_cntvoff(void);
extern void shmobile_init_delay(void);
extern void shmobile_boot_vector(void);
extern unsigned long shmobile_boot_fn;
diff --git a/arch/arm/mach-shmobile/headsmp-apmu.S b/arch/arm/mach-shmobile/headsmp-apmu.S
index 5672b5849401..d49ab194766a 100644
--- a/arch/arm/mach-shmobile/headsmp-apmu.S
+++ b/arch/arm/mach-shmobile/headsmp-apmu.S
@@ -11,29 +11,9 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-ENTRY(shmobile_init_cntvoff)
- /*
- * CNTVOFF has to be initialized either from non-secure Hypervisor
- * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
- * then it should be handled by the secure code
- */
- cps #MON_MODE
- mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
- orr r0, r1, #1
- mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
- instr_sync
- mov r0, #0
- mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
- instr_sync
- mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
- instr_sync
- cps #SVC_MODE
- ret lr
-ENDPROC(shmobile_init_cntvoff)
-
#ifdef CONFIG_SMP
ENTRY(shmobile_boot_apmu)
- bl shmobile_init_cntvoff
+ bl secure_cntvoff_init
b secondary_startup
ENDPROC(shmobile_boot_apmu)
#endif
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index 5561dbed7a33..88fdc1801d90 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -26,6 +26,7 @@
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
+#include <asm/secure_cntvoff.h>
#include "common.h"
#include "rcar-gen2.h"
@@ -70,9 +71,10 @@ void __init rcar_gen2_timer_init(void)
void __iomem *base;
u32 freq;
- shmobile_init_cntvoff();
+ secure_cntvoff_init();
if (of_machine_is_compatible("renesas,r8a7745") ||
+ of_machine_is_compatible("renesas,r8a77470") ||
of_machine_is_compatible("renesas,r8a7792") ||
of_machine_is_compatible("renesas,r8a7794")) {
freq = 260000000 / 8; /* ZS / 8 */
@@ -205,6 +207,7 @@ MACHINE_END
static const char * const rz_g1_boards_compat_dt[] __initconst = {
"renesas,r8a7743",
"renesas,r8a7745",
+ "renesas,r8a77470",
NULL,
};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index ce53ceaf4cc5..d9c8ecf88ec6 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -51,7 +51,7 @@ config MACH_SUN9I
config ARCH_SUNXI_MC_SMP
bool
depends on SMP
- default MACH_SUN9I
+ default MACH_SUN9I || MACH_SUN8I
select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 7de9cc286d53..71429aa85143 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,5 +1,5 @@
CFLAGS_mc_smp.o += -march=armv7-a
obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
-obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o
+obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o headsmp.o
obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
new file mode 100644
index 000000000000..32d76be98541
--- /dev/null
+++ b/arch/arm/mach-sunxi/headsmp.S
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 Chen-Yu Tsai
+ * Copyright (c) 2018 Bootlin
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ * Mylène Josserand <mylene.josserand@bootlin.com>
+ *
+ * SMP support for sunxi based systems with Cortex A7/A15
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/cputype.h>
+
+ENTRY(sunxi_mc_smp_cluster_cache_enable)
+ .arch armv7-a
+ /*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ *
+ * Also enable regional clock gating and L2 data latency settings for
+ * Cortex-A15. These settings are from the vendor kernel.
+ */
+ mrc p15, 0, r1, c0, c0, 0
+ movw r2, #(ARM_CPU_PART_MASK & 0xffff)
+ movt r2, #(ARM_CPU_PART_MASK >> 16)
+ and r1, r1, r2
+ movw r2, #(ARM_CPU_PART_CORTEX_A15 & 0xffff)
+ movt r2, #(ARM_CPU_PART_CORTEX_A15 >> 16)
+ cmp r1, r2
+ bne not_a15
+
+ /* The following is Cortex-A15 specific */
+
+ /* ACTLR2: Enable CPU regional clock gates */
+ mrc p15, 1, r1, c15, c0, 4
+ orr r1, r1, #(0x1 << 31)
+ mcr p15, 1, r1, c15, c0, 4
+
+ /* L2ACTLR */
+ mrc p15, 1, r1, c15, c0, 0
+ /* Enable L2, GIC, and Timer regional clock gates */
+ orr r1, r1, #(0x1 << 26)
+ /* Disable clean/evict from being pushed to external */
+ orr r1, r1, #(0x1<<3)
+ mcr p15, 1, r1, c15, c0, 0
+
+ /* L2CTRL: L2 data RAM latency */
+ mrc p15, 1, r1, c9, c0, 2
+ bic r1, r1, #(0x7 << 0)
+ orr r1, r1, #(0x3 << 0)
+ mcr p15, 1, r1, c9, c0, 2
+
+ /* End of Cortex-A15 specific setup */
+ not_a15:
+
+ /* Get value of sunxi_mc_smp_first_comer */
+ adr r1, first
+ ldr r0, [r1]
+ ldr r0, [r1, r0]
+
+ /* Skip cci_enable_port_for_self if not first comer */
+ cmp r0, #0
+ bxeq lr
+ b cci_enable_port_for_self
+
+ .align 2
+ first: .word sunxi_mc_smp_first_comer - .
+ENDPROC(sunxi_mc_smp_cluster_cache_enable)
+
+ENTRY(sunxi_mc_smp_secondary_startup)
+ bl sunxi_mc_smp_cluster_cache_enable
+ bl secure_cntvoff_init
+ b secondary_startup
+ENDPROC(sunxi_mc_smp_secondary_startup)
+
+ENTRY(sunxi_mc_smp_resume)
+ bl sunxi_mc_smp_cluster_cache_enable
+ b cpu_resume
+ENDPROC(sunxi_mc_smp_resume)
diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
index c0246ec54a0a..b4037b603897 100644
--- a/arch/arm/mach-sunxi/mc_smp.c
+++ b/arch/arm/mach-sunxi/mc_smp.c
@@ -55,22 +55,35 @@
#define CPUCFG_CX_RST_CTRL_L2_RST BIT(8)
#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n))
#define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n)
+#define CPUCFG_CX_RST_CTRL_CORE_RST_ALL (0xf << 0)
#define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c))
#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n)
#define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf
#define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c))
-#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4)
+/* The power off register for clusters are different from a80 and a83t */
+#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I BIT(0)
+#define PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I BIT(4)
#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n)
#define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu))
#define PRCM_CPU_SOFT_ENTRY_REG 0x164
+/* R_CPUCFG registers, specific to sun8i-a83t */
+#define R_CPUCFG_CLUSTER_PO_RST_CTRL(c) (0x30 + (c) * 0x4)
+#define R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(n) BIT(n)
+#define R_CPUCFG_CPU_SOFT_ENTRY_REG 0x01a4
+
#define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F
#define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A
static void __iomem *cpucfg_base;
static void __iomem *prcm_base;
static void __iomem *sram_b_smp_base;
+static void __iomem *r_cpucfg_base;
+
+extern void sunxi_mc_smp_secondary_startup(void);
+extern void sunxi_mc_smp_resume(void);
+static bool is_a83t;
static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster)
{
@@ -157,6 +170,16 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster)
reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu);
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ if (is_a83t) {
+ /* assert cpu power-on reset */
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg &= ~(R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu));
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* Cortex-A7: hold L1 reset disable signal low */
if (!sunxi_core_is_cortex_a15(cpu, cluster)) {
reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster));
@@ -180,17 +203,38 @@ static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster)
/* open power switch */
sunxi_cpu_power_switch_set(cpu, cluster, true);
+ /* Handle A83T bit swap */
+ if (is_a83t) {
+ if (cpu == 0)
+ cpu = 4;
+ }
+
/* clear processor power gate */
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu);
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
+ /* Handle A83T bit swap */
+ if (is_a83t) {
+ if (cpu == 4)
+ cpu = 0;
+ }
+
/* de-assert processor power-on reset */
reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu);
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ if (is_a83t) {
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg |= R_CPUCFG_CLUSTER_PO_RST_CTRL_CORE(cpu);
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* de-assert all processor resets */
reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu);
@@ -212,6 +256,14 @@ static int sunxi_cluster_powerup(unsigned int cluster)
if (cluster >= SUNXI_NR_CLUSTERS)
return -EINVAL;
+ /* For A83T, assert cluster cores resets */
+ if (is_a83t) {
+ reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+ reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL; /* Core Reset */
+ writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* assert ACINACTM */
reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster));
reg |= CPUCFG_CX_CTRL_REG1_ACINACTM;
@@ -222,6 +274,16 @@ static int sunxi_cluster_powerup(unsigned int cluster)
reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL;
writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster));
+ /* assert cluster cores resets */
+ if (is_a83t) {
+ reg = readl(r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ reg &= ~CPUCFG_CX_RST_CTRL_CORE_RST_ALL;
+ writel(reg, r_cpucfg_base +
+ R_CPUCFG_CLUSTER_PO_RST_CTRL(cluster));
+ udelay(10);
+ }
+
/* assert cluster resets */
reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster));
reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST;
@@ -252,7 +314,10 @@ static int sunxi_cluster_powerup(unsigned int cluster)
/* clear cluster power gate */
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER;
+ if (is_a83t)
+ reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I;
+ else
+ reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
@@ -300,74 +365,7 @@ static void sunxi_cluster_cache_disable_without_axi(void)
}
static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER];
-static int sunxi_mc_smp_first_comer;
-
-/*
- * Enable cluster-level coherency, in preparation for turning on the MMU.
- *
- * Also enable regional clock gating and L2 data latency settings for
- * Cortex-A15. These settings are from the vendor kernel.
- */
-static void __naked sunxi_mc_smp_cluster_cache_enable(void)
-{
- asm volatile (
- "mrc p15, 0, r1, c0, c0, 0\n"
- "movw r2, #" __stringify(ARM_CPU_PART_MASK & 0xffff) "\n"
- "movt r2, #" __stringify(ARM_CPU_PART_MASK >> 16) "\n"
- "and r1, r1, r2\n"
- "movw r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 & 0xffff) "\n"
- "movt r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 >> 16) "\n"
- "cmp r1, r2\n"
- "bne not_a15\n"
-
- /* The following is Cortex-A15 specific */
-
- /* ACTLR2: Enable CPU regional clock gates */
- "mrc p15, 1, r1, c15, c0, 4\n"
- "orr r1, r1, #(0x1<<31)\n"
- "mcr p15, 1, r1, c15, c0, 4\n"
-
- /* L2ACTLR */
- "mrc p15, 1, r1, c15, c0, 0\n"
- /* Enable L2, GIC, and Timer regional clock gates */
- "orr r1, r1, #(0x1<<26)\n"
- /* Disable clean/evict from being pushed to external */
- "orr r1, r1, #(0x1<<3)\n"
- "mcr p15, 1, r1, c15, c0, 0\n"
-
- /* L2CTRL: L2 data RAM latency */
- "mrc p15, 1, r1, c9, c0, 2\n"
- "bic r1, r1, #(0x7<<0)\n"
- "orr r1, r1, #(0x3<<0)\n"
- "mcr p15, 1, r1, c9, c0, 2\n"
-
- /* End of Cortex-A15 specific setup */
- "not_a15:\n"
-
- /* Get value of sunxi_mc_smp_first_comer */
- "adr r1, first\n"
- "ldr r0, [r1]\n"
- "ldr r0, [r1, r0]\n"
-
- /* Skip cci_enable_port_for_self if not first comer */
- "cmp r0, #0\n"
- "bxeq lr\n"
- "b cci_enable_port_for_self\n"
-
- ".align 2\n"
- "first: .word sunxi_mc_smp_first_comer - .\n"
- );
-}
-
-static void __naked sunxi_mc_smp_secondary_startup(void)
-{
- asm volatile(
- "bl sunxi_mc_smp_cluster_cache_enable\n"
- "b secondary_startup"
- /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
- :: "i" (sunxi_mc_smp_cluster_cache_enable)
- );
-}
+int sunxi_mc_smp_first_comer;
static DEFINE_SPINLOCK(boot_lock);
@@ -516,7 +514,10 @@ static int sunxi_cluster_powerdown(unsigned int cluster)
/* gate cluster power */
pr_debug("%s: gate cluster power\n", __func__);
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
- reg |= PRCM_PWROFF_GATING_REG_CLUSTER;
+ if (is_a83t)
+ reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN8I;
+ else
+ reg |= PRCM_PWROFF_GATING_REG_CLUSTER_SUN9I;
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
udelay(20);
@@ -598,8 +599,12 @@ out:
return !ret;
}
-static bool sunxi_mc_smp_cpu_can_disable(unsigned int __unused)
+static bool sunxi_mc_smp_cpu_can_disable(unsigned int cpu)
{
+ /* CPU0 hotplug not handled for sun8i-a83t */
+ if (is_a83t)
+ if (cpu == 0)
+ return false;
return true;
}
#endif
@@ -637,16 +642,6 @@ static bool __init sunxi_mc_smp_cpu_table_init(void)
*/
typedef typeof(cpu_reset) phys_reset_t;
-static void __init __naked sunxi_mc_smp_resume(void)
-{
- asm volatile(
- "bl sunxi_mc_smp_cluster_cache_enable\n"
- "b cpu_resume"
- /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */
- :: "i" (sunxi_mc_smp_cluster_cache_enable)
- );
-}
-
static int __init nocache_trampoline(unsigned long __unused)
{
phys_reset_t phys_reset;
@@ -692,12 +687,14 @@ struct sunxi_mc_smp_nodes {
struct device_node *prcm_node;
struct device_node *cpucfg_node;
struct device_node *sram_node;
+ struct device_node *r_cpucfg_node;
};
/* This structure holds SoC-specific bits tied to an enable-method string. */
struct sunxi_mc_smp_data {
const char *enable_method;
int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes);
+ bool is_a83t;
};
static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
@@ -705,6 +702,7 @@ static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes)
of_node_put(nodes->prcm_node);
of_node_put(nodes->cpucfg_node);
of_node_put(nodes->sram_node);
+ of_node_put(nodes->r_cpucfg_node);
memset(nodes, 0, sizeof(*nodes));
}
@@ -734,11 +732,42 @@ static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
return 0;
}
+static int __init sun8i_a83t_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes)
+{
+ nodes->prcm_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-r-ccu");
+ if (!nodes->prcm_node) {
+ pr_err("%s: PRCM not available\n", __func__);
+ return -ENODEV;
+ }
+
+ nodes->cpucfg_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-cpucfg");
+ if (!nodes->cpucfg_node) {
+ pr_err("%s: CPUCFG not available\n", __func__);
+ return -ENODEV;
+ }
+
+ nodes->r_cpucfg_node = of_find_compatible_node(NULL, NULL,
+ "allwinner,sun8i-a83t-r-cpucfg");
+ if (!nodes->r_cpucfg_node) {
+ pr_err("%s: RCPUCFG not available\n", __func__);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = {
{
.enable_method = "allwinner,sun9i-a80-smp",
.get_smp_nodes = sun9i_a80_get_smp_nodes,
},
+ {
+ .enable_method = "allwinner,sun8i-a83t-smp",
+ .get_smp_nodes = sun8i_a83t_get_smp_nodes,
+ .is_a83t = true,
+ },
};
static int __init sunxi_mc_smp_init(void)
@@ -746,6 +775,7 @@ static int __init sunxi_mc_smp_init(void)
struct sunxi_mc_smp_nodes nodes = { 0 };
struct device_node *node;
struct resource res;
+ void __iomem *addr;
int i, ret;
/*
@@ -771,6 +801,8 @@ static int __init sunxi_mc_smp_init(void)
break;
}
+ is_a83t = sunxi_mc_smp_data[i].is_a83t;
+
of_node_put(node);
if (ret)
return -ENODEV;
@@ -808,12 +840,23 @@ static int __init sunxi_mc_smp_init(void)
goto err_unmap_prcm;
}
- sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
- "sunxi-mc-smp");
- if (IS_ERR(sram_b_smp_base)) {
- ret = PTR_ERR(sram_b_smp_base);
- pr_err("%s: failed to map secure SRAM\n", __func__);
- goto err_unmap_release_cpucfg;
+ if (is_a83t) {
+ r_cpucfg_base = of_io_request_and_map(nodes.r_cpucfg_node,
+ 0, "sunxi-mc-smp");
+ if (IS_ERR(r_cpucfg_base)) {
+ ret = PTR_ERR(r_cpucfg_base);
+ pr_err("%s: failed to map R-CPUCFG registers\n",
+ __func__);
+ goto err_unmap_release_cpucfg;
+ }
+ } else {
+ sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0,
+ "sunxi-mc-smp");
+ if (IS_ERR(sram_b_smp_base)) {
+ ret = PTR_ERR(sram_b_smp_base);
+ pr_err("%s: failed to map secure SRAM\n", __func__);
+ goto err_unmap_release_cpucfg;
+ }
}
/* Configure CCI-400 for boot cluster */
@@ -821,15 +864,18 @@ static int __init sunxi_mc_smp_init(void)
if (ret) {
pr_err("%s: failed to configure boot cluster: %d\n",
__func__, ret);
- goto err_unmap_release_secure_sram;
+ goto err_unmap_release_sram_rcpucfg;
}
/* We don't need the device nodes anymore */
sunxi_mc_smp_put_nodes(&nodes);
/* Set the hardware entry point address */
- writel(__pa_symbol(sunxi_mc_smp_secondary_startup),
- prcm_base + PRCM_CPU_SOFT_ENTRY_REG);
+ if (is_a83t)
+ addr = r_cpucfg_base + R_CPUCFG_CPU_SOFT_ENTRY_REG;
+ else
+ addr = prcm_base + PRCM_CPU_SOFT_ENTRY_REG;
+ writel(__pa_symbol(sunxi_mc_smp_secondary_startup), addr);
/* Actually enable multi cluster SMP */
smp_set_ops(&sunxi_mc_smp_smp_ops);
@@ -838,9 +884,14 @@ static int __init sunxi_mc_smp_init(void)
return 0;
-err_unmap_release_secure_sram:
- iounmap(sram_b_smp_base);
- of_address_to_resource(nodes.sram_node, 0, &res);
+err_unmap_release_sram_rcpucfg:
+ if (is_a83t) {
+ iounmap(r_cpucfg_base);
+ of_address_to_resource(nodes.r_cpucfg_node, 0, &res);
+ } else {
+ iounmap(sram_b_smp_base);
+ of_address_to_resource(nodes.sram_node, 0, &res);
+ }
release_mem_region(res.start, resource_size(&res));
err_unmap_release_cpucfg:
iounmap(cpucfg_base);
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 5e9602ce1573..de4b0e932f22 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
+#include <asm/secure_cntvoff.h>
static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
@@ -62,7 +63,6 @@ MACHINE_END
static const char * const sun8i_board_dt_compat[] = {
"allwinner,sun8i-a23",
"allwinner,sun8i-a33",
- "allwinner,sun8i-a83t",
"allwinner,sun8i-h2-plus",
"allwinner,sun8i-h3",
"allwinner,sun8i-r40",
@@ -75,6 +75,24 @@ DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i Family")
.dt_compat = sun8i_board_dt_compat,
MACHINE_END
+static void __init sun8i_a83t_cntvoff_init(void)
+{
+#ifdef CONFIG_SMP
+ secure_cntvoff_init();
+#endif
+}
+
+static const char * const sun8i_a83t_cntvoff_board_dt_compat[] = {
+ "allwinner,sun8i-a83t",
+ NULL,
+};
+
+DT_MACHINE_START(SUN8I_A83T_CNTVOFF_DT, "Allwinner A83t board")
+ .init_early = sun8i_a83t_cntvoff_init,
+ .init_time = sun6i_timer_init,
+ .dt_compat = sun8i_a83t_cntvoff_board_dt_compat,
+MACHINE_END
+
static const char * const sun9i_board_dt_compat[] = {
"allwinner,sun9i-a80",
NULL,
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index 02e712d2ea30..f9587be48235 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -97,6 +97,10 @@ static void __init tegra_dt_init_late(void)
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
of_machine_is_compatible("compal,paz00"))
tegra_paz00_wifikill_init();
+
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
+ of_machine_is_compatible("nvidia,tegra20"))
+ platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0);
}
static const char * const tegra_dt_board_compat[] = {
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index f98332ea2ef2..c1086ebe0050 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -9,64 +9,33 @@ menuconfig ARCH_U8500
select ARM_ERRATA_764369 if SMP
select ARM_GIC
select CACHE_L2X0
+ select CLKSRC_DBX500_PRCMU
select CLKSRC_NOMADIK_MTU
select GPIOLIB
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
+ select I2C
+ select I2C_NOMADIK
+ select MFD_DB8500_PRCMU
select PINCTRL
+ select PINCTRL_AB8500
+ select PINCTRL_AB8505
select PINCTRL_ABX500
+ select PINCTRL_DB8500
select PINCTRL_NOMADIK
select PL310_ERRATA_753970 if CACHE_L2X0
- help
- Support for ST-Ericsson's Ux500 architecture
-
-if ARCH_U8500
-
-config UX500_SOC_DB8500
- bool
- select MFD_DB8500_PRCMU
- select PINCTRL_DB8500
- select PINCTRL_DB8540
- select PINCTRL_AB8500
- select PINCTRL_AB8505
- select PINCTRL_AB9540
- select PINCTRL_AB8540
- select REGULATOR
- select REGULATOR_DB8500_PRCMU
- select CLKSRC_DBX500_PRCMU
select PM_GENERIC_DOMAINS if PM
-
-config MACH_MOP500
- bool "U8500 Development platform, MOP500 versions"
- select I2C
- select I2C_NOMADIK
select REGULATOR
+ select REGULATOR_DB8500_PRCMU
select REGULATOR_FIXED_VOLTAGE
select SOC_BUS
- select UX500_SOC_DB8500
help
- Include support for the MOP500 development platform.
-
-config MACH_HREFV60
- bool "U8500 Development platform, HREFv60 version"
- select MACH_MOP500
- help
- Include support for the HREFv60 new development platform.
- Includes HREFv70, v71 etc.
+ Support for ST-Ericsson's Ux500 architecture
-config MACH_SNOWBALL
- bool "U8500 Snowball platform"
- select MACH_MOP500
- help
- Include support for the snowball development platform.
+if ARCH_U8500
-config UX500_AUTO_PLATFORM
+config UX500_SOC_DB8500
def_bool y
- select MACH_MOP500
- help
- At least one platform needs to be selected in order to build
- a working kernel. If everything else is disabled, this
- automatically enables MACH_MOP500.
config UX500_DEBUG_UART
int "Ux500 UART to use for low-level debug"
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 36cd23c8be9b..389ecf6faa00 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -111,11 +111,6 @@ static void ux500_restart(enum reboot_mode mode, const char *cmd)
prcmu_system_reset(0);
}
-static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", NULL),
- {},
-};
-
static const struct of_device_id u8500_local_bus_nodes[] = {
/* only create devices below soc node */
{ .compatible = "stericsson,db8500", },
@@ -129,20 +124,13 @@ static void __init u8500_init_machine(void)
/* Initialize ux500 power domains */
ux500_pm_domains_init();
- /* automatically probe child nodes of dbx5x0 devices */
- if (of_machine_is_compatible("st-ericsson,u8540"))
- of_platform_populate(NULL, u8500_local_bus_nodes,
- u8540_auxdata_lookup, NULL);
- else
- of_platform_populate(NULL, u8500_local_bus_nodes,
- NULL, NULL);
+ of_platform_populate(NULL, u8500_local_bus_nodes,
+ NULL, NULL);
}
static const char * stericsson_dt_platform_compat[] = {
"st-ericsson,u8500",
- "st-ericsson,u8540",
"st-ericsson,u9500",
- "st-ericsson,u9540",
NULL,
};
diff --git a/arch/arm/mach-ux500/db8500-regs.h b/arch/arm/mach-ux500/db8500-regs.h
index 27399553c841..3d6e1955119a 100644
--- a/arch/arm/mach-ux500/db8500-regs.h
+++ b/arch/arm/mach-ux500/db8500-regs.h
@@ -41,10 +41,6 @@
/* ASIC ID is at 0xbf4 offset within this region */
#define U8500_ASIC_ID_BASE 0x9001D000
-#define U9540_BOOT_ROM_BASE 0xFFFE0000
-/* ASIC ID is at 0xbf4 offset within this region */
-#define U9540_ASIC_ID_BASE 0xFFFFD000
-
#define U8500_PER6_BASE 0xa03c0000
#define U8500_PER7_BASE 0xa03d0000
#define U8500_PER5_BASE 0xa03e0000
diff --git a/arch/arm/mm/cache-b15-rac.c b/arch/arm/mm/cache-b15-rac.c
index d9586ba2e63c..c6ed14840c3c 100644
--- a/arch/arm/mm/cache-b15-rac.c
+++ b/arch/arm/mm/cache-b15-rac.c
@@ -33,7 +33,10 @@ extern void v7_flush_kern_cache_all(void);
#define RAC_CPU_SHIFT (8)
#define RACCFG_MASK (0xff)
#define RAC_CONFIG1_REG (0x7c)
-#define RAC_FLUSH_REG (0x80)
+/* Brahma-B15 is a quad-core only design */
+#define B15_RAC_FLUSH_REG (0x80)
+/* Brahma-B53 is an octo-core design */
+#define B53_RAC_FLUSH_REG (0x84)
#define FLUSH_RAC (1 << 0)
/* Bitmask to enable instruction and data prefetching with a 256-bytes stride */
@@ -52,6 +55,7 @@ static void __iomem *b15_rac_base;
static DEFINE_SPINLOCK(rac_lock);
static u32 rac_config0_reg;
+static u32 rac_flush_offset;
/* Initialization flag to avoid checking for b15_rac_base, and to prevent
* multi-platform kernels from crashing here as well.
@@ -70,14 +74,14 @@ static inline void __b15_rac_flush(void)
{
u32 reg;
- __raw_writel(FLUSH_RAC, b15_rac_base + RAC_FLUSH_REG);
+ __raw_writel(FLUSH_RAC, b15_rac_base + rac_flush_offset);
do {
/* This dmb() is required to force the Bus Interface Unit
* to clean oustanding writes, and forces an idle cycle
* to be inserted.
*/
dmb();
- reg = __raw_readl(b15_rac_base + RAC_FLUSH_REG);
+ reg = __raw_readl(b15_rac_base + rac_flush_offset);
} while (reg & FLUSH_RAC);
}
@@ -287,7 +291,7 @@ static struct syscore_ops b15_rac_syscore_ops = {
static int __init b15_rac_init(void)
{
- struct device_node *dn;
+ struct device_node *dn, *cpu_dn;
int ret = 0, cpu;
u32 reg, en_mask = 0;
@@ -305,6 +309,24 @@ static int __init b15_rac_init(void)
goto out;
}
+ cpu_dn = of_get_cpu_node(0, NULL);
+ if (!cpu_dn) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (of_device_is_compatible(cpu_dn, "brcm,brahma-b15"))
+ rac_flush_offset = B15_RAC_FLUSH_REG;
+ else if (of_device_is_compatible(cpu_dn, "brcm,brahma-b53"))
+ rac_flush_offset = B53_RAC_FLUSH_REG;
+ else {
+ pr_err("Unsupported CPU\n");
+ of_node_put(cpu_dn);
+ ret = -EINVAL;
+ goto out;
+ }
+ of_node_put(cpu_dn);
+
ret = register_reboot_notifier(&b15_rac_reboot_nb);
if (ret) {
pr_err("failed to register reboot notifier\n");
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index afc1a1d4f7a5..c0a242cae79a 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -115,16 +115,6 @@ config OMAP_SERIAL_WAKE
to data on the serial RX line. This allows you to wake the
system from serial console.
-choice
- prompt "OMAP PM layer selection"
- depends on ARCH_OMAP
- default OMAP_PM_NOOP
-
-config OMAP_PM_NOOP
- bool "No-op/debug PM layer"
-
-endchoice
-
endmenu
endif
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index 42bac8d5ab5d..2da35735fa38 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -413,8 +413,7 @@ static int s3c_adc_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int s3c_adc_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct adc_device *adc = platform_get_drvdata(pdev);
+ struct adc_device *adc = dev_get_drvdata(dev);
unsigned long flags;
u32 con;
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index f5769e93544a..d69a0ca09fb5 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -11,10 +11,6 @@
#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
-#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
-#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
-#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
-
#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0 VA_VIC(0)
#define VA_VIC1 VA_VIC(1)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 17ea72b1b389..3cfa8ca26738 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -53,6 +53,7 @@ CONFIG_ARCH_R8A7796=y
CONFIG_ARCH_R8A77965=y
CONFIG_ARCH_R8A77970=y
CONFIG_ARCH_R8A77980=y
+CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77995=y
CONFIG_ARCH_STRATIX10=y
CONFIG_ARCH_TEGRA=y
@@ -75,6 +76,7 @@ CONFIG_PCI_HISI=y
CONFIG_PCIE_QCOM=y
CONFIG_PCIE_KIRIN=y
CONFIG_PCIE_ARMADA_8K=y
+CONFIG_PCIE_HISI_STB=y
CONFIG_PCI_AARDVARK=y
CONFIG_PCI_TEGRA=y
CONFIG_PCIE_RCAR=y
@@ -158,8 +160,10 @@ CONFIG_BT_HIDP=m
# CONFIG_BT_LE is not set
CONFIG_BT_LEDS=y
# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIBTUSB=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_BCM=y
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_MAC80211_LEDS=y
@@ -170,6 +174,9 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_HISILICON_LPC=y
+CONFIG_SIMPLE_PM_BUS=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y
@@ -188,6 +195,9 @@ CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_SAS_ATA=y
CONFIG_SCSI_HISI_SAS=y
CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_SCSI_UFSHCD=m
+CONFIG_SCSI_UFSHCD_PLATFORM=m
+CONFIG_SCSI_UFS_QCOM=m
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
@@ -207,8 +217,10 @@ CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
CONFIG_AMD_XGBE=y
CONFIG_NET_XGENE=y
+CONFIG_ATL1C=m
CONFIG_MACB=y
CONFIG_THUNDER_NIC_PF=y
+CONFIG_HIX5HD2_GMAC=y
CONFIG_HNS_DSAF=y
CONFIG_HNS_ENET=y
CONFIG_E1000E=y
@@ -240,6 +252,7 @@ CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
+CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SR9800=m
@@ -247,13 +260,19 @@ CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
+CONFIG_ATH10K=m
+CONFIG_ATH10K_PCI=m
CONFIG_BRCMFMAC=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_PCIE=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SDIO=m
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_ADC=m
CONFIG_KEYBOARD_CROS_EC=y
CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_HISI_POWERKEY=y
@@ -287,6 +306,7 @@ CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
CONFIG_VIRTIO_CONSOLE=y
+CONFIG_I2C_HID=m
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_PCA954x=y
@@ -304,6 +324,7 @@ CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SPI=y
+CONFIG_SPI_ARMADA_3700=y
CONFIG_SPI_MESON_SPICC=m
CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_BCM2835=m
@@ -321,6 +342,7 @@ CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_MSM8994=y
CONFIG_PINCTRL_MSM8996=y
+CONFIG_PINCTRL_MT7622=y
CONFIG_PINCTRL_QDF2XXX=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIO_DWAPB=y
@@ -333,6 +355,8 @@ CONFIG_GPIO_XGENE_SB=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_MAX77620=y
+CONFIG_POWER_AVS=y
+CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_POWER_RESET_MSM=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
@@ -344,6 +368,7 @@ CONFIG_SENSORS_INA2XX=m
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_CPU_THERMAL=y
CONFIG_THERMAL_EMULATION=y
+CONFIG_ARMADA_THERMAL=y
CONFIG_BRCMSTB_THERMAL=m
CONFIG_EXYNOS_THERMAL=y
CONFIG_RCAR_GEN3_THERMAL=y
@@ -362,6 +387,7 @@ CONFIG_MFD_AXP20X_RSB=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_CROS_EC_CHARDEV=m
CONFIG_MFD_EXYNOS_LPASS=m
CONFIG_MFD_HI6421_PMIC=y
CONFIG_MFD_HI655X_PMIC=y
@@ -440,7 +466,8 @@ CONFIG_SND_BCM2835_SOC_I2S=m
CONFIG_SND_SOC_SAMSUNG=y
CONFIG_SND_SOC_RCAR=m
CONFIG_SND_SOC_AK4613=m
-CONFIG_SND_SIMPLE_CARD=y
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
CONFIG_USB=y
CONFIG_USB_OTG=y
CONFIG_USB_XHCI_HCD=y
@@ -486,6 +513,7 @@ CONFIG_MMC_SPI=y
CONFIG_MMC_SDHI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_EXYNOS=y
+CONFIG_MMC_DW_HI3798CV200=y
CONFIG_MMC_DW_K3=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SUNXI=y
@@ -515,6 +543,7 @@ CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_ARMADA38X=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_XGENE=y
+CONFIG_RTC_DRV_CROS_EC=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=m
CONFIG_K3_DMA=y
@@ -557,6 +586,7 @@ CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_ARM_SMMU=y
CONFIG_ARM_SMMU_V3=y
CONFIG_QCOM_IOMMU=y
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
CONFIG_RPMSG_QCOM_SMD=y
CONFIG_RASPBERRYPI_POWER=y
CONFIG_QCOM_SMEM=y
@@ -568,12 +598,18 @@ CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
CONFIG_ARCH_TEGRA_186_SOC=y
CONFIG_ARCH_TEGRA_194_SOC=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_EXTCON_USB_GPIO=y
+CONFIG_EXTCON_USBC_CROS_EC=y
CONFIG_MEMORY=y
CONFIG_TEGRA_MC=y
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
CONFIG_ROCKCHIP_SARADC=m
+CONFIG_IIO_CROS_EC_SENSORS_CORE=m
+CONFIG_IIO_CROS_EC_SENSORS=m
+CONFIG_IIO_CROS_EC_LIGHT_PROX=m
+CONFIG_IIO_CROS_EC_BARO=m
CONFIG_PWM=y
CONFIG_PWM_BCM2835=m
CONFIG_PWM_CROS_EC=m
@@ -582,21 +618,26 @@ CONFIG_PWM_RCAR=m
CONFIG_PWM_ROCKCHIP=y
CONFIG_PWM_SAMSUNG=y
CONFIG_PWM_TEGRA=m
+CONFIG_PHY_HISTB_COMBPHY=y
+CONFIG_PHY_HISI_INNO_USB2=y
CONFIG_PHY_RCAR_GEN3_USB2=y
CONFIG_PHY_RCAR_GEN3_USB3=m
CONFIG_PHY_HI6220_USB=y
CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_MVEBU_CP110_COMPHY=y
+CONFIG_PHY_QCOM_QMP=m
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_EMMC=y
CONFIG_PHY_ROCKCHIP_PCIE=m
+CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PHY_XGENE=y
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_QCOM_L2_PMU=y
CONFIG_QCOM_L3_PMU=y
CONFIG_MESON_EFUSE=m
CONFIG_QCOM_QFPROM=y
+CONFIG_ROCKCHIP_EFUSE=y
CONFIG_UNIPHIER_EFUSE=y
CONFIG_TEE=y
CONFIG_OPTEE=y
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index 7cd2fd04b212..1cc29629d238 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
+#include <linux/reset.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
@@ -32,10 +33,18 @@ static const char * const reg_names[] = { "rev", "sysc", "syss", };
enum sysc_clocks {
SYSC_FCK,
SYSC_ICK,
+ SYSC_OPTFCK0,
+ SYSC_OPTFCK1,
+ SYSC_OPTFCK2,
+ SYSC_OPTFCK3,
+ SYSC_OPTFCK4,
+ SYSC_OPTFCK5,
+ SYSC_OPTFCK6,
+ SYSC_OPTFCK7,
SYSC_MAX_CLOCKS,
};
-static const char * const clock_names[] = { "fck", "ick", };
+static const char * const clock_names[SYSC_ICK + 1] = { "fck", "ick", };
#define SYSC_IDLEMODE_MASK 3
#define SYSC_CLOCKACTIVITY_MASK 3
@@ -48,6 +57,8 @@ static const char * const clock_names[] = { "fck", "ick", };
* @module_va: virtual address of the interconnect target module
* @offsets: register offsets from module base
* @clocks: clocks used by the interconnect target module
+ * @clock_roles: clock role names for the found clocks
+ * @nr_clocks: number of clocks used by the interconnect target module
* @legacy_mode: configured for legacy mode if set
* @cap: interconnect target module capabilities
* @cfg: interconnect target module configuration
@@ -61,7 +72,10 @@ struct sysc {
u32 module_size;
void __iomem *module_va;
int offsets[SYSC_MAX_REGS];
- struct clk *clocks[SYSC_MAX_CLOCKS];
+ struct clk **clocks;
+ const char **clock_roles;
+ int nr_clocks;
+ struct reset_control *rsts;
const char *legacy_mode;
const struct sysc_capabilities *cap;
struct sysc_config cfg;
@@ -88,6 +102,11 @@ static u32 sysc_read(struct sysc *ddata, int offset)
return readl_relaxed(ddata->module_va + offset);
}
+static bool sysc_opt_clks_needed(struct sysc *ddata)
+{
+ return !!(ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_NEEDED);
+}
+
static u32 sysc_read_revision(struct sysc *ddata)
{
int offset = ddata->offsets[SYSC_REVISION];
@@ -98,21 +117,28 @@ static u32 sysc_read_revision(struct sysc *ddata)
return sysc_read(ddata, offset);
}
-static int sysc_get_one_clock(struct sysc *ddata,
- enum sysc_clocks index)
+static int sysc_get_one_clock(struct sysc *ddata, const char *name)
{
- const char *name;
- int error;
+ int error, i, index = -ENODEV;
+
+ if (!strncmp(clock_names[SYSC_FCK], name, 3))
+ index = SYSC_FCK;
+ else if (!strncmp(clock_names[SYSC_ICK], name, 3))
+ index = SYSC_ICK;
+
+ if (index < 0) {
+ for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) {
+ if (!ddata->clocks[i]) {
+ index = i;
+ break;
+ }
+ }
+ }
- switch (index) {
- case SYSC_FCK:
- break;
- case SYSC_ICK:
- break;
- default:
- return -EINVAL;
+ if (index < 0) {
+ dev_err(ddata->dev, "clock %s not added\n", name);
+ return index;
}
- name = clock_names[index];
ddata->clocks[index] = devm_clk_get(ddata->dev, name);
if (IS_ERR(ddata->clocks[index])) {
@@ -138,10 +164,50 @@ static int sysc_get_one_clock(struct sysc *ddata,
static int sysc_get_clocks(struct sysc *ddata)
{
- int i, error;
+ struct device_node *np = ddata->dev->of_node;
+ struct property *prop;
+ const char *name;
+ int nr_fck = 0, nr_ick = 0, i, error = 0;
- for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
- error = sysc_get_one_clock(ddata, i);
+ ddata->clock_roles = devm_kzalloc(ddata->dev,
+ sizeof(*ddata->clock_roles) *
+ SYSC_MAX_CLOCKS,
+ GFP_KERNEL);
+ if (!ddata->clock_roles)
+ return -ENOMEM;
+
+ of_property_for_each_string(np, "clock-names", prop, name) {
+ if (!strncmp(clock_names[SYSC_FCK], name, 3))
+ nr_fck++;
+ if (!strncmp(clock_names[SYSC_ICK], name, 3))
+ nr_ick++;
+ ddata->clock_roles[ddata->nr_clocks] = name;
+ ddata->nr_clocks++;
+ }
+
+ if (ddata->nr_clocks < 1)
+ return 0;
+
+ if (ddata->nr_clocks > SYSC_MAX_CLOCKS) {
+ dev_err(ddata->dev, "too many clocks for %pOF\n", np);
+
+ return -EINVAL;
+ }
+
+ if (nr_fck > 1 || nr_ick > 1) {
+ dev_err(ddata->dev, "max one fck and ick for %pOF\n", np);
+
+ return -EINVAL;
+ }
+
+ ddata->clocks = devm_kzalloc(ddata->dev,
+ sizeof(*ddata->clocks) * ddata->nr_clocks,
+ GFP_KERNEL);
+ if (!ddata->clocks)
+ return -ENOMEM;
+
+ for (i = 0; i < ddata->nr_clocks; i++) {
+ error = sysc_get_one_clock(ddata, ddata->clock_roles[i]);
if (error && error != -ENOENT)
return error;
}
@@ -150,6 +216,42 @@ static int sysc_get_clocks(struct sysc *ddata)
}
/**
+ * sysc_init_resets - reset module on init
+ * @ddata: device driver data
+ *
+ * A module can have both OCP softreset control and external rstctrl.
+ * If more complicated rstctrl resets are needed, please handle these
+ * directly from the child device driver and map only the module reset
+ * for the parent interconnect target module device.
+ *
+ * Automatic reset of the module on init can be skipped with the
+ * "ti,no-reset-on-init" device tree property.
+ */
+static int sysc_init_resets(struct sysc *ddata)
+{
+ int error;
+
+ ddata->rsts =
+ devm_reset_control_array_get_optional_exclusive(ddata->dev);
+ if (IS_ERR(ddata->rsts))
+ return PTR_ERR(ddata->rsts);
+
+ if (ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
+ goto deassert;
+
+ error = reset_control_assert(ddata->rsts);
+ if (error)
+ return error;
+
+deassert:
+ error = reset_control_deassert(ddata->rsts);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+/**
* sysc_parse_and_check_child_range - parses module IO region from ranges
* @ddata: device driver data
*
@@ -533,9 +635,13 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
goto idled;
}
- for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
+ for (i = 0; i < ddata->nr_clocks; i++) {
if (IS_ERR_OR_NULL(ddata->clocks[i]))
continue;
+
+ if (i >= SYSC_OPTFCK0 && !sysc_opt_clks_needed(ddata))
+ break;
+
clk_disable(ddata->clocks[i]);
}
@@ -572,9 +678,13 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
goto awake;
}
- for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
+ for (i = 0; i < ddata->nr_clocks; i++) {
if (IS_ERR_OR_NULL(ddata->clocks[i]))
continue;
+
+ if (i >= SYSC_OPTFCK0 && !sysc_opt_clks_needed(ddata))
+ break;
+
error = clk_enable(ddata->clocks[i]);
if (error)
return error;
@@ -590,23 +700,103 @@ awake:
static int sysc_suspend(struct device *dev)
{
struct sysc *ddata;
+ int error;
ddata = dev_get_drvdata(dev);
+ if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
+ SYSC_QUIRK_LEGACY_IDLE))
+ return 0;
+
if (!ddata->enabled)
return 0;
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
+ error = pm_runtime_put_sync_suspend(dev);
+ if (error < 0) {
+ dev_warn(ddata->dev, "%s not idle %i %s\n",
+ __func__, error,
+ ddata->name ? ddata->name : "");
+
+ return 0;
+ }
+
ddata->needs_resume = true;
- return sysc_runtime_suspend(dev);
+ return 0;
}
static int sysc_resume(struct device *dev)
{
struct sysc *ddata;
+ int error;
+
+ ddata = dev_get_drvdata(dev);
+
+ if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
+ SYSC_QUIRK_LEGACY_IDLE))
+ return 0;
+
+ if (ddata->needs_resume) {
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
+ error = pm_runtime_get_sync(dev);
+ if (error < 0) {
+ dev_err(ddata->dev, "%s error %i %s\n",
+ __func__, error,
+ ddata->name ? ddata->name : "");
+
+ return error;
+ }
+
+ ddata->needs_resume = false;
+ }
+
+ return 0;
+}
+
+static int sysc_noirq_suspend(struct device *dev)
+{
+ struct sysc *ddata;
ddata = dev_get_drvdata(dev);
+
+ if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
+ return 0;
+
+ if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
+ return 0;
+
+ if (!ddata->enabled)
+ return 0;
+
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
+ ddata->needs_resume = true;
+
+ return sysc_runtime_suspend(dev);
+}
+
+static int sysc_noirq_resume(struct device *dev)
+{
+ struct sysc *ddata;
+
+ ddata = dev_get_drvdata(dev);
+
+ if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
+ return 0;
+
+ if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
+ return 0;
+
if (ddata->needs_resume) {
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
ddata->needs_resume = false;
return sysc_runtime_resume(dev);
@@ -618,6 +808,7 @@ static int sysc_resume(struct device *dev)
static const struct dev_pm_ops sysc_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_noirq_suspend, sysc_noirq_resume)
SET_RUNTIME_PM_OPS(sysc_runtime_suspend,
sysc_runtime_resume,
NULL)
@@ -649,9 +840,29 @@ struct sysc_revision_quirk {
}
static const struct sysc_revision_quirk sysc_revision_quirks[] = {
+ /* These need to use noirq_suspend */
+ SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+ SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff,
+ SYSC_QUIRK_RESOURCE_PROVIDER),
+
/* These drivers need to be fixed to not use pm_runtime_irq_safe() */
SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff,
- SYSC_QUIRK_LEGACY_IDLE),
+ SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET),
SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
SYSC_QUIRK_LEGACY_IDLE),
SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000030, 0xffffffff,
@@ -664,8 +875,40 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK_LEGACY_IDLE),
SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff,
SYSC_QUIRK_LEGACY_IDLE),
+ /* Some timers on omap4 and later */
+ SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffffffff,
+ SYSC_QUIRK_LEGACY_IDLE),
SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
SYSC_QUIRK_LEGACY_IDLE),
+ /* Uarts on omap4 and later */
+ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffffffff,
+ SYSC_QUIRK_LEGACY_IDLE),
+
+ /* These devices don't yet suspend properly without legacy setting */
+ SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffffffff,
+ SYSC_QUIRK_LEGACY_IDLE),
+ SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xffffffff,
+ SYSC_QUIRK_LEGACY_IDLE),
+ SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0d00, 0xffffffff,
+ SYSC_QUIRK_LEGACY_IDLE),
+
+#ifdef DEBUG
+ SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff, 0),
+ SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0),
+ SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, 0),
+ SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
+ SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0),
+ SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0),
+ SYSC_QUIRK("mcbsp", 0, -1, 0x8c, -1, 0, 0, 0),
+ SYSC_QUIRK("mailbox", 0, 0, 0x10, -1, 0x00000400, 0xffffffff, 0),
+ SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40000902, 0xffffffff, 0),
+ SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40002903, 0xffffffff, 0),
+ SYSC_QUIRK("spinlock", 0, 0, 0x10, -1, 0x50020000, 0xffffffff, 0),
+ SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
+ SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
+ SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
+ 0xffffffff, 0),
+#endif
};
static void sysc_init_revision_quirks(struct sysc *ddata)
@@ -716,6 +959,7 @@ static int sysc_init_module(struct sysc *ddata)
return 0;
}
+
ddata->revision = sysc_read_revision(ddata);
pm_runtime_put_sync(ddata->dev);
@@ -811,29 +1055,58 @@ static int sysc_init_syss_mask(struct sysc *ddata)
}
/*
- * Many child device drivers need to have fck available to get the clock
- * rate for device internal configuration.
+ * Many child device drivers need to have fck and opt clocks available
+ * to get the clock rate for device internal configuration etc.
*/
-static int sysc_child_add_fck(struct sysc *ddata,
- struct device *child)
+static int sysc_child_add_named_clock(struct sysc *ddata,
+ struct device *child,
+ const char *name)
{
- struct clk *fck;
+ struct clk *clk;
struct clk_lookup *l;
- const char *name = clock_names[SYSC_FCK];
+ int error = 0;
- if (IS_ERR_OR_NULL(ddata->clocks[SYSC_FCK]))
+ if (!name)
return 0;
- fck = clk_get(child, name);
- if (!IS_ERR(fck)) {
- clk_put(fck);
+ clk = clk_get(child, name);
+ if (!IS_ERR(clk)) {
+ clk_put(clk);
return -EEXIST;
}
- l = clkdev_create(ddata->clocks[SYSC_FCK], name, dev_name(child));
+ clk = clk_get(ddata->dev, name);
+ if (IS_ERR(clk))
+ return -ENODEV;
+
+ l = clkdev_create(clk, name, dev_name(child));
+ if (!l)
+ error = -ENOMEM;
+
+ clk_put(clk);
+
+ return error;
+}
+
+static int sysc_child_add_clocks(struct sysc *ddata,
+ struct device *child)
+{
+ int i, error;
+
+ for (i = 0; i < ddata->nr_clocks; i++) {
+ error = sysc_child_add_named_clock(ddata,
+ child,
+ ddata->clock_roles[i]);
+ if (error && error != -EEXIST) {
+ dev_err(ddata->dev, "could not add child clock %s: %i\n",
+ ddata->clock_roles[i], error);
+
+ return error;
+ }
+ }
- return l ? 0 : -ENODEV;
+ return 0;
}
static struct device_type sysc_device_type = {
@@ -891,18 +1164,33 @@ static int sysc_child_suspend_noirq(struct device *dev)
ddata = sysc_child_to_parent(dev);
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
error = pm_generic_suspend_noirq(dev);
- if (error)
+ if (error) {
+ dev_err(dev, "%s error at %i: %i\n",
+ __func__, __LINE__, error);
+
return error;
+ }
if (!pm_runtime_status_suspended(dev)) {
error = pm_generic_runtime_suspend(dev);
- if (error)
+ if (error) {
+ dev_err(dev, "%s error at %i: %i\n",
+ __func__, __LINE__, error);
+
return error;
+ }
error = sysc_runtime_suspend(ddata->dev);
- if (error)
+ if (error) {
+ dev_err(dev, "%s error at %i: %i\n",
+ __func__, __LINE__, error);
+
return error;
+ }
ddata->child_needs_resume = true;
}
@@ -917,6 +1205,9 @@ static int sysc_child_resume_noirq(struct device *dev)
ddata = sysc_child_to_parent(dev);
+ dev_dbg(ddata->dev, "%s %s\n", __func__,
+ ddata->name ? ddata->name : "");
+
if (ddata->child_needs_resume) {
ddata->child_needs_resume = false;
@@ -983,10 +1274,9 @@ static int sysc_notifier_call(struct notifier_block *nb,
switch (event) {
case BUS_NOTIFY_ADD_DEVICE:
- error = sysc_child_add_fck(ddata, dev);
- if (error && error != -EEXIST)
- dev_warn(ddata->dev, "could not add %s fck: %i\n",
- dev_name(dev), error);
+ error = sysc_child_add_clocks(ddata, dev);
+ if (error)
+ return error;
sysc_legacy_idle_quirk(ddata, dev);
break;
default:
@@ -1314,6 +1604,11 @@ static void ti_sysc_idle(struct work_struct *work)
pm_runtime_put_sync(ddata->dev);
}
+static const struct of_device_id sysc_match_table[] = {
+ { .compatible = "simple-bus", },
+ { /* sentinel */ },
+};
+
static int sysc_probe(struct platform_device *pdev)
{
struct ti_sysc_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -1359,8 +1654,11 @@ static int sysc_probe(struct platform_device *pdev)
if (error)
goto unprepare;
- pm_runtime_enable(ddata->dev);
+ error = sysc_init_resets(ddata);
+ if (error)
+ return error;
+ pm_runtime_enable(ddata->dev);
error = sysc_init_module(ddata);
if (error)
goto unprepare;
@@ -1375,8 +1673,8 @@ static int sysc_probe(struct platform_device *pdev)
sysc_show_registers(ddata);
ddata->dev->type = &sysc_device_type;
- error = of_platform_populate(ddata->dev->of_node,
- NULL, pdata ? pdata->auxdata : NULL,
+ error = of_platform_populate(ddata->dev->of_node, sysc_match_table,
+ pdata ? pdata->auxdata : NULL,
ddata->dev);
if (error)
goto err;
@@ -1391,6 +1689,9 @@ static int sysc_probe(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
}
+ if (!of_get_available_child_count(ddata->dev->of_node))
+ reset_control_assert(ddata->rsts);
+
return 0;
err:
@@ -1420,6 +1721,7 @@ static int sysc_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ reset_control_assert(ddata->rsts);
unprepare:
sysc_unprepare(ddata);
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c
index 49265f02e772..8a93f7468622 100644
--- a/drivers/media/rc/ir-rx51.c
+++ b/drivers/media/rc/ir-rx51.c
@@ -22,7 +22,6 @@
#include <linux/hrtimer.h>
#include <media/rc-core.h>
-#include <linux/platform_data/media/ir-rx51.h>
#define WBUF_LEN 256
@@ -31,7 +30,6 @@ struct ir_rx51 {
struct pwm_device *pwm;
struct hrtimer timer;
struct device *dev;
- struct ir_rx51_platform_data *pdata;
wait_queue_head_t wqueue;
unsigned int freq; /* carrier frequency */
@@ -130,10 +128,9 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer,
ir_rx51->wbuf[count] = -1; /* Insert termination mark */
/*
- * Adjust latency requirements so the device doesn't go in too
- * deep sleep states
+ * REVISIT: Adjust latency requirements so the device doesn't go in too
+ * deep sleep states with pm_qos_add_request().
*/
- ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, 50);
ir_rx51_on(ir_rx51);
ir_rx51->wbuf_index = 1;
@@ -146,8 +143,7 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer,
*/
wait_event_interruptible(ir_rx51->wqueue, ir_rx51->wbuf_index < 0);
- /* We can sleep again */
- ir_rx51->pdata->set_max_mpu_wakeup_lat(ir_rx51->dev, -1);
+ /* REVISIT: Remove pm_qos constraint, we can sleep again */
return count;
}
@@ -244,13 +240,6 @@ static int ir_rx51_probe(struct platform_device *dev)
struct pwm_device *pwm;
struct rc_dev *rcdev;
- ir_rx51.pdata = dev->dev.platform_data;
-
- if (!ir_rx51.pdata) {
- dev_err(&dev->dev, "Platform Data is missing\n");
- return -ENXIO;
- }
-
pwm = pwm_get(&dev->dev, NULL);
if (IS_ERR(pwm)) {
int err = PTR_ERR(pwm);
diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c
index 7255a0d94374..cd12e5abafde 100644
--- a/drivers/mtd/nand/raw/davinci_nand.c
+++ b/drivers/mtd/nand/raw/davinci_nand.c
@@ -545,7 +545,7 @@ static struct davinci_nand_pdata
return ERR_PTR(-ENOMEM);
if (!of_property_read_u32(pdev->dev.of_node,
"ti,davinci-chipselect", &prop))
- pdev->id = prop;
+ pdata->core_chipsel = prop;
else
return ERR_PTR(-EINVAL);
@@ -627,7 +627,7 @@ static int nand_davinci_probe(struct platform_device *pdev)
return -ENODEV;
/* which external chipselect will we be managing? */
- if (pdev->id < 0 || pdev->id > 3)
+ if (pdata->core_chipsel < 0 || pdata->core_chipsel > 3)
return -ENODEV;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
@@ -683,7 +683,7 @@ static int nand_davinci_probe(struct platform_device *pdev)
info->ioaddr = (uint32_t __force) vaddr;
info->current_cs = info->ioaddr;
- info->core_chipsel = pdev->id;
+ info->core_chipsel = pdata->core_chipsel;
info->mask_chipsel = pdata->mask_chipsel;
/* use nandboot-capable ALE/CLE masks by default */
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 3bbe6114a420..1d824cbd462d 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -4,9 +4,11 @@ config SOC_RENESAS
select SOC_BUS
select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
- ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77995
+ ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77990 || \
+ ARCH_R8A77995
select SYSC_R8A7743 if ARCH_R8A7743
select SYSC_R8A7745 if ARCH_R8A7745
+ select SYSC_R8A77470 if ARCH_R8A77470
select SYSC_R8A7779 if ARCH_R8A7779
select SYSC_R8A7790 if ARCH_R8A7790
select SYSC_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
@@ -17,6 +19,7 @@ config SOC_RENESAS
select SYSC_R8A77965 if ARCH_R8A77965
select SYSC_R8A77970 if ARCH_R8A77970
select SYSC_R8A77980 if ARCH_R8A77980
+ select SYSC_R8A77990 if ARCH_R8A77990
select SYSC_R8A77995 if ARCH_R8A77995
if SOC_RENESAS
@@ -30,6 +33,10 @@ config SYSC_R8A7745
bool "RZ/G1E System Controller support" if COMPILE_TEST
select SYSC_RCAR
+config SYSC_R8A77470
+ bool "RZ/G1C System Controller support" if COMPILE_TEST
+ select SYSC_RCAR
+
config SYSC_R8A7779
bool "R-Car H1 System Controller support" if COMPILE_TEST
select SYSC_RCAR
@@ -70,6 +77,10 @@ config SYSC_R8A77980
bool "R-Car V3H System Controller support" if COMPILE_TEST
select SYSC_RCAR
+config SYSC_R8A77990
+ bool "R-Car E3 System Controller support" if COMPILE_TEST
+ select SYSC_RCAR
+
config SYSC_R8A77995
bool "R-Car D3 System Controller support" if COMPILE_TEST
select SYSC_RCAR
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index ccb5ec57a262..7dc0f20d7907 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_SOC_RENESAS) += renesas-soc.o
# SoC
obj-$(CONFIG_SYSC_R8A7743) += r8a7743-sysc.o
obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o
+obj-$(CONFIG_SYSC_R8A77470) += r8a77470-sysc.o
obj-$(CONFIG_SYSC_R8A7779) += r8a7779-sysc.o
obj-$(CONFIG_SYSC_R8A7790) += r8a7790-sysc.o
obj-$(CONFIG_SYSC_R8A7791) += r8a7791-sysc.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o
obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o
obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o
obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o
+obj-$(CONFIG_SYSC_R8A77990) += r8a77990-sysc.o
obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o
# Family
diff --git a/drivers/soc/renesas/r8a77470-sysc.c b/drivers/soc/renesas/r8a77470-sysc.c
new file mode 100644
index 000000000000..cfa015e208ef
--- /dev/null
+++ b/drivers/soc/renesas/r8a77470-sysc.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G1C System Controller
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/power/r8a77470-sysc.h>
+
+#include "rcar-sysc.h"
+
+static const struct rcar_sysc_area r8a77470_areas[] __initconst = {
+ { "always-on", 0, 0, R8A77470_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca7-scu", 0x100, 0, R8A77470_PD_CA7_SCU, R8A77470_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca7-cpu0", 0x1c0, 0, R8A77470_PD_CA7_CPU0, R8A77470_PD_CA7_SCU,
+ PD_CPU_NOCR },
+ { "ca7-cpu1", 0x1c0, 1, R8A77470_PD_CA7_CPU1, R8A77470_PD_CA7_SCU,
+ PD_CPU_NOCR },
+ { "sgx", 0xc0, 0, R8A77470_PD_SGX, R8A77470_PD_ALWAYS_ON },
+};
+
+const struct rcar_sysc_info r8a77470_sysc_info __initconst = {
+ .areas = r8a77470_areas,
+ .num_areas = ARRAY_SIZE(r8a77470_areas),
+};
diff --git a/drivers/soc/renesas/r8a77990-sysc.c b/drivers/soc/renesas/r8a77990-sysc.c
new file mode 100644
index 000000000000..15579ebc5ed2
--- /dev/null
+++ b/drivers/soc/renesas/r8a77990-sysc.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas R-Car E3 System Controller
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/sys_soc.h>
+
+#include <dt-bindings/power/r8a77990-sysc.h>
+
+#include "rcar-sysc.h"
+
+static struct rcar_sysc_area r8a77990_areas[] __initdata = {
+ { "always-on", 0, 0, R8A77990_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+ { "ca53-scu", 0x140, 0, R8A77990_PD_CA53_SCU, R8A77990_PD_ALWAYS_ON,
+ PD_SCU },
+ { "ca53-cpu0", 0x200, 0, R8A77990_PD_CA53_CPU0, R8A77990_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "ca53-cpu1", 0x200, 1, R8A77990_PD_CA53_CPU1, R8A77990_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "cr7", 0x240, 0, R8A77990_PD_CR7, R8A77990_PD_ALWAYS_ON },
+ { "a3vc", 0x380, 0, R8A77990_PD_A3VC, R8A77990_PD_ALWAYS_ON },
+ { "a2vc1", 0x3c0, 1, R8A77990_PD_A2VC1, R8A77990_PD_A3VC },
+ { "3dg-a", 0x100, 0, R8A77990_PD_3DG_A, R8A77990_PD_ALWAYS_ON },
+ { "3dg-b", 0x100, 1, R8A77990_PD_3DG_B, R8A77990_PD_3DG_A },
+};
+
+static void __init rcar_sysc_fix_parent(struct rcar_sysc_area *areas,
+ unsigned int num_areas, u8 id,
+ int new_parent)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_areas; i++)
+ if (areas[i].isr_bit == id) {
+ areas[i].parent = new_parent;
+ return;
+ }
+}
+
+/* Fixups for R-Car E3 ES1.0 revision */
+static const struct soc_device_attribute r8a77990[] __initconst = {
+ { .soc_id = "r8a77990", .revision = "ES1.0" },
+ { /* sentinel */ }
+};
+
+static int __init r8a77990_sysc_init(void)
+{
+ if (soc_device_match(r8a77990)) {
+ rcar_sysc_fix_parent(r8a77990_areas,
+ ARRAY_SIZE(r8a77990_areas),
+ R8A77990_PD_3DG_A, R8A77990_PD_3DG_B);
+ rcar_sysc_fix_parent(r8a77990_areas,
+ ARRAY_SIZE(r8a77990_areas),
+ R8A77990_PD_3DG_B, R8A77990_PD_ALWAYS_ON);
+ }
+
+ return 0;
+}
+
+const struct rcar_sysc_info r8a77990_sysc_info __initconst = {
+ .init = r8a77990_sysc_init,
+ .areas = r8a77990_areas,
+ .num_areas = ARRAY_SIZE(r8a77990_areas),
+};
diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c
index f718429cab02..1b2ef415bbe1 100644
--- a/drivers/soc/renesas/r8a77995-sysc.c
+++ b/drivers/soc/renesas/r8a77995-sysc.c
@@ -10,13 +10,12 @@
#include <linux/bug.h>
#include <linux/kernel.h>
-#include <linux/sys_soc.h>
#include <dt-bindings/power/r8a77995-sysc.h>
#include "rcar-sysc.h"
-static struct rcar_sysc_area r8a77995_areas[] __initdata = {
+static const struct rcar_sysc_area r8a77995_areas[] __initconst = {
{ "always-on", 0, 0, R8A77995_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
{ "ca53-scu", 0x140, 0, R8A77995_PD_CA53_SCU, R8A77995_PD_ALWAYS_ON,
PD_SCU },
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
index 8e9cb7996ab0..d9c1034e70e9 100644
--- a/drivers/soc/renesas/rcar-rst.c
+++ b/drivers/soc/renesas/rcar-rst.c
@@ -44,6 +44,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
/* RZ/G is handled like R-Car Gen2 */
{ .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 },
{ .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 },
/* R-Car Gen1 */
{ .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 },
{ .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 },
@@ -59,6 +60,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
{ .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 },
+ { .compatible = "renesas,r8a77990-rst", .data = &rcar_rst_gen3 },
{ .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 },
{ /* sentinel */ }
};
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index faf20e719361..95120acc4d80 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -261,6 +261,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
#ifdef CONFIG_SYSC_R8A7745
{ .compatible = "renesas,r8a7745-sysc", .data = &r8a7745_sysc_info },
#endif
+#ifdef CONFIG_SYSC_R8A77470
+ { .compatible = "renesas,r8a77470-sysc", .data = &r8a77470_sysc_info },
+#endif
#ifdef CONFIG_SYSC_R8A7779
{ .compatible = "renesas,r8a7779-sysc", .data = &r8a7779_sysc_info },
#endif
@@ -293,6 +296,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = {
#ifdef CONFIG_SYSC_R8A77980
{ .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info },
#endif
+#ifdef CONFIG_SYSC_R8A77990
+ { .compatible = "renesas,r8a77990-sysc", .data = &r8a77990_sysc_info },
+#endif
#ifdef CONFIG_SYSC_R8A77995
{ .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
#endif
diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
index dcdc9ec8eba7..a22e7cf25e30 100644
--- a/drivers/soc/renesas/rcar-sysc.h
+++ b/drivers/soc/renesas/rcar-sysc.h
@@ -51,6 +51,7 @@ struct rcar_sysc_info {
extern const struct rcar_sysc_info r8a7743_sysc_info;
extern const struct rcar_sysc_info r8a7745_sysc_info;
+extern const struct rcar_sysc_info r8a77470_sysc_info;
extern const struct rcar_sysc_info r8a7779_sysc_info;
extern const struct rcar_sysc_info r8a7790_sysc_info;
extern const struct rcar_sysc_info r8a7791_sysc_info;
@@ -61,6 +62,7 @@ extern const struct rcar_sysc_info r8a7796_sysc_info;
extern const struct rcar_sysc_info r8a77965_sysc_info;
extern const struct rcar_sysc_info r8a77970_sysc_info;
extern const struct rcar_sysc_info r8a77980_sysc_info;
+extern const struct rcar_sysc_info r8a77990_sysc_info;
extern const struct rcar_sysc_info r8a77995_sysc_info;
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index ea71c413c926..d44d0e687ab8 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -100,6 +100,11 @@ static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = {
.id = 0x4c,
};
+static const struct renesas_soc soc_rz_g1c __initconst __maybe_unused = {
+ .family = &fam_rzg,
+ .id = 0x53,
+};
+
static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
.family = &fam_rcar_gen1,
};
@@ -159,6 +164,11 @@ static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = {
.id = 0x56,
};
+static const struct renesas_soc soc_rcar_e3 __initconst __maybe_unused = {
+ .family = &fam_rcar_gen3,
+ .id = 0x57,
+};
+
static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
.family = &fam_rcar_gen3,
.id = 0x58,
@@ -192,6 +202,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
#ifdef CONFIG_ARCH_R8A7745
{ .compatible = "renesas,r8a7745", .data = &soc_rz_g1e },
#endif
+#ifdef CONFIG_ARCH_R8A77470
+ { .compatible = "renesas,r8a77470", .data = &soc_rz_g1c },
+#endif
#ifdef CONFIG_ARCH_R8A7778
{ .compatible = "renesas,r8a7778", .data = &soc_rcar_m1a },
#endif
@@ -228,6 +241,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
#ifdef CONFIG_ARCH_R8A77980
{ .compatible = "renesas,r8a77980", .data = &soc_rcar_v3h },
#endif
+#ifdef CONFIG_ARCH_R8A77990
+ { .compatible = "renesas,r8a77990", .data = &soc_rcar_e3 },
+#endif
#ifdef CONFIG_ARCH_R8A77995
{ .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 },
#endif
diff --git a/include/dt-bindings/power/r8a77470-sysc.h b/include/dt-bindings/power/r8a77470-sysc.h
new file mode 100644
index 000000000000..8bf4db187c31
--- /dev/null
+++ b/include/dt-bindings/power/r8a77470-sysc.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A77470_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A77470_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A77470_PD_CA7_CPU0 5
+#define R8A77470_PD_CA7_CPU1 6
+#define R8A77470_PD_SGX 20
+#define R8A77470_PD_CA7_SCU 21
+
+/* Always-on power area */
+#define R8A77470_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A77470_SYSC_H__ */
diff --git a/include/dt-bindings/power/r8a77990-sysc.h b/include/dt-bindings/power/r8a77990-sysc.h
new file mode 100644
index 000000000000..944d85beec15
--- /dev/null
+++ b/include/dt-bindings/power/r8a77990-sysc.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A77990_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A77990_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A77990_PD_CA53_CPU0 5
+#define R8A77990_PD_CA53_CPU1 6
+#define R8A77990_PD_CR7 13
+#define R8A77990_PD_A3VC 14
+#define R8A77990_PD_3DG_A 17
+#define R8A77990_PD_3DG_B 18
+#define R8A77990_PD_CA53_SCU 21
+#define R8A77990_PD_A2VC1 26
+
+/* Always-on power area */
+#define R8A77990_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_R8A77990_SYSC_H__ */
diff --git a/include/linux/platform_data/media/ir-rx51.h b/include/linux/platform_data/media/ir-rx51.h
deleted file mode 100644
index 9d127aa648e7..000000000000
--- a/include/linux/platform_data/media/ir-rx51.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IR_RX51_H
-#define _IR_RX51_H
-
-struct ir_rx51_platform_data {
- int(*set_max_mpu_wakeup_lat)(struct device *dev, long t);
-};
-
-#endif
diff --git a/include/linux/platform_data/mtd-davinci.h b/include/linux/platform_data/mtd-davinci.h
index f1a2cf655bdb..1bbfa27cccb4 100644
--- a/include/linux/platform_data/mtd-davinci.h
+++ b/include/linux/platform_data/mtd-davinci.h
@@ -56,6 +56,16 @@ struct davinci_nand_pdata { /* platform_data */
uint32_t mask_ale;
uint32_t mask_cle;
+ /*
+ * 0-indexed chip-select number of the asynchronous
+ * interface to which the NAND device has been connected.
+ *
+ * So, if you have NAND connected to CS3 of DA850, you
+ * will pass '1' here. Since the asynchronous interface
+ * on DA850 starts from CS2.
+ */
+ uint32_t core_chipsel;
+
/* for packages using two chipselects */
uint32_t mask_chipsel;
diff --git a/include/linux/platform_data/spi-imx.h b/include/linux/platform_data/spi-imx.h
index 6f012fefa1a2..328f670d10bd 100644
--- a/include/linux/platform_data/spi-imx.h
+++ b/include/linux/platform_data/spi-imx.h
@@ -5,24 +5,29 @@
/*
* struct spi_imx_master - device.platform_data for SPI controller devices.
- * @chipselect: Array of chipselects for this master. Numbers >= 0 mean gpio
- * pins, numbers < 0 mean internal CSPI chipselects according
- * to MXC_SPI_CS(). Normally you want to use gpio based chip
- * selects as the CSPI module tries to be intelligent about
- * when to assert the chipselect: The CSPI module deasserts the
- * chipselect once it runs out of input data. The other problem
- * is that it is not possible to mix between high active and low
- * active chipselects on one single bus using the internal
- * chipselects. Unfortunately Freescale decided to put some
+ * @chipselect: Array of chipselects for this master or NULL. Numbers >= 0
+ * mean GPIO pins, -ENOENT means internal CSPI chipselect
+ * matching the position in the array. E.g., if chipselect[1] =
+ * -ENOENT then a SPI slave using chip select 1 will use the
+ * native SS1 line of the CSPI. Omitting the array will use
+ * all native chip selects.
+
+ * Normally you want to use gpio based chip selects as the CSPI
+ * module tries to be intelligent about when to assert the
+ * chipselect: The CSPI module deasserts the chipselect once it
+ * runs out of input data. The other problem is that it is not
+ * possible to mix between high active and low active chipselects
+ * on one single bus using the internal chipselects.
+ * Unfortunately, on some SoCs, Freescale decided to put some
* chipselects on dedicated pins which are not usable as gpios,
* so we have to support the internal chipselects.
- * @num_chipselect: ARRAY_SIZE(chipselect)
+ *
+ * @num_chipselect: If @chipselect is specified, ARRAY_SIZE(chipselect),
+ * otherwise the number of native chip selects.
*/
struct spi_imx_master {
int *chipselect;
int num_chipselect;
};
-#define MXC_SPI_CS(no) ((no) - 32)
-
#endif /* __MACH_SPI_H_*/
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 80ce28d40832..990aad477458 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -45,6 +45,7 @@ struct sysc_regbits {
s8 emufree_shift;
};
+#define SYSC_QUIRK_RESOURCE_PROVIDER BIT(9)
#define SYSC_QUIRK_LEGACY_IDLE BIT(8)
#define SYSC_QUIRK_RESET_STATUS BIT(7)
#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6)
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 77a30f0f0c96..4dce494dfbd3 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -22,7 +22,7 @@
*
*/
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/spinlock.h>
#include <linux/tty.h>
#include <linux/module.h>
@@ -32,7 +32,6 @@
#include <asm/mach-types.h>
-#include <mach/board-ams-delta.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "omap-mcbsp.h"
@@ -213,7 +212,6 @@ static const struct snd_kcontrol_new ams_delta_audio_controls[] = {
static struct snd_soc_jack ams_delta_hook_switch;
static struct snd_soc_jack_gpio ams_delta_hook_switch_gpios[] = {
{
- .gpio = 4,
.name = "hook_switch",
.report = SND_JACK_HEADSET,
.invert = 1,
@@ -259,6 +257,7 @@ static struct timer_list cx81801_timer;
static bool cx81801_cmd_pending;
static bool ams_delta_muted;
static DEFINE_SPINLOCK(ams_delta_lock);
+static struct gpio_desc *gpiod_modem_codec;
static void cx81801_timeout(struct timer_list *unused)
{
@@ -272,7 +271,7 @@ static void cx81801_timeout(struct timer_list *unused)
/* Reconnect the codec DAI back from the modem to the CPU DAI
* only if digital mute still off */
if (!muted)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
+ gpiod_set_value(gpiod_modem_codec, 0);
}
/* Line discipline .open() */
@@ -381,8 +380,7 @@ static void cx81801_receive(struct tty_struct *tty,
/* Apply config pulse by connecting the codec to the modem
* if not already done */
if (apply)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
- AMS_DELTA_LATCH2_MODEM_CODEC);
+ gpiod_set_value(gpiod_modem_codec, 1);
break;
}
}
@@ -432,8 +430,7 @@ static int ams_delta_digital_mute(struct snd_soc_dai *dai, int mute)
spin_unlock_bh(&ams_delta_lock);
if (apply)
- ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
- mute ? AMS_DELTA_LATCH2_MODEM_CODEC : 0);
+ gpiod_set_value(gpiod_modem_codec, !!mute);
return 0;
}
@@ -469,14 +466,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
/* Store a pointer to the codec structure for tty ldisc use */
cx20442_codec = rtd->codec_dai->component;
- /* Set up digital mute if not provided by the codec */
- if (!codec_dai->driver->ops) {
- codec_dai->driver->ops = &ams_delta_dai_ops;
- } else {
- ams_delta_ops.startup = ams_delta_startup;
- ams_delta_ops.shutdown = ams_delta_shutdown;
- }
-
/* Add hook switch - can be used to control the codec from userspace
* even if line discipline fails */
ret = snd_soc_card_jack_new(card, "hook_switch", SND_JACK_HEADSET,
@@ -486,7 +475,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
"Failed to allocate resources for hook switch, "
"will continue without one.\n");
else {
- ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch,
+ ret = snd_soc_jack_add_gpiods(card->dev, &ams_delta_hook_switch,
ARRAY_SIZE(ams_delta_hook_switch_gpios),
ams_delta_hook_switch_gpios);
if (ret)
@@ -495,6 +484,21 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
"will continue with hook switch inactive.\n");
}
+ gpiod_modem_codec = devm_gpiod_get(card->dev, "modem_codec",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(gpiod_modem_codec)) {
+ dev_warn(card->dev, "Failed to obtain modem_codec GPIO\n");
+ return 0;
+ }
+
+ /* Set up digital mute if not provided by the codec */
+ if (!codec_dai->driver->ops) {
+ codec_dai->driver->ops = &ams_delta_dai_ops;
+ } else {
+ ams_delta_ops.startup = ams_delta_startup;
+ ams_delta_ops.shutdown = ams_delta_shutdown;
+ }
+
/* Register optional line discipline for over the modem control */
ret = tty_register_ldisc(N_V253, &cx81801_ops);
if (ret) {