diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-12 03:49:09 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-12 03:49:09 +0300 |
commit | 7c00e8ae041b349992047769af741b67379ce19a (patch) | |
tree | e3d504b9523eb6b4109a1873ed804ed03762b26d /arch/arm | |
parent | a2b7ab45b8905b9c1813b0212e82a39d5c081c8a (diff) | |
parent | 958da6e3ff446fe558bdf0fd06fb2713539ebeef (diff) | |
download | linux-7c00e8ae041b349992047769af741b67379ce19a.tar.xz |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Olof Johansson:
"Here are the main updates for SoC support (besides DT additions) for
ARM 32- and 64-bit platforms. The branch also contains defconfig
updates to turn on drivers and options as needed on the various
platforms.
The largest parts of the delta are from cleanups moving platform data
and board file setup of TI platforms to ti-sysc bus drivers. There are
also some sweeping changes of eeprom and nand setup on Davinci, i.MX
and other platforms.
Samsung is removing support for Exynos5440, which was an oddball SoC
that hasn't been seen much use in designs.
Renesas is adding support for new SoCs (R-Car E3, RZ/G1C and RZ/N1D).
Linus Walleij is also removing support for ux500 (Sony Ericsson)
U8540/9540 SoCs that never made it to significant mass production and
products"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (133 commits)
MAINTAINERS: add NXP linux team maillist as i.MX reviewer
ARM: stm32: Don't select DMA unconditionally on STM32MP157C
arm64: defconfig: Enable PCIe on msm8996 and db820c
ARM: pxa3xx: enable external wakeup pins
ARM: pxa: stargate2: use device properties for at24 eeprom
arm64: defconfig: Enable HISILICON_LPC
arm64: defconfig: enable drivers for Poplar support
arm64: defconfig: Enable UFS on msm8996
ARM: berlin: switch to SPDX license identifier
arm: berlin: remove non-necessary flush_cache_all()
ARM: berlin: extend BG2CD Kconfig entry
OMAP: CLK: CLKSRC: Add suspend resume hooks
ARM: AM43XX: Add functions to save/restore am43xx control registers
ASoC: ams_delta: use GPIO lookup table
ARM: OMAP1: ams-delta: add GPIO lookup tables
bus: ti-sysc: Fix optional clocks array access
ARM: OMAP2+: Make sure LOGICRETSTATE bits are not cleared
ARM: OMAP2+: prm44xx: Inroduce cpu_pm notifiers for context save/restore
ARM: OMAP2+: prm44xx: Introduce context save/restore for am43 PRCM IO
ARM: OMAP2+: powerdomain: Introduce cpu_pm notifiers for context save/restore
...
Diffstat (limited to 'arch/arm')
106 files changed, 1398 insertions, 903 deletions
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) |