diff options
Diffstat (limited to 'arch/arm')
118 files changed, 960 insertions, 1077 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9ec5f5588dc5..14b4cf75ceec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -351,20 +351,6 @@ config ARM_SINGLE_ARMV7M select SPARSE_IRQ select USE_OF - -config ARCH_CLPS711X - bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" - select AUTO_ZRELADDR - select COMMON_CLK - select CPU_ARM720T - select GENERIC_CLOCKEVENTS - select CLPS711X_TIMER - select GPIOLIB - select MFD_SYSCON - select SOC_BUS - help - Support for Cirrus Logic 711x/721x/731x based boards. - config ARCH_GEMINI bool "Cortina Systems Gemini" select CLKSRC_MMIO diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 19a3dcf5eb2e..a9693b6987a6 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -109,23 +109,41 @@ choice 0x80020000 | 0xf0020000 | UART8 0x80024000 | 0xf0024000 | UART9 - config DEBUG_AT91_UART - bool "Kernel low-level debugging on Atmel SoCs" - depends on ARCH_AT91 + config DEBUG_AT91_RM9200_DBGU + bool "Kernel low-level debugging on AT91RM9200, AT91SAM9 DBGU" + select DEBUG_AT91_UART + depends on SOC_AT91RM9200 || SOC_AT91SAM9 help - Say Y here if you want the debug print routines to direct - their output to the serial port on atmel devices. + Say Y here if you want kernel low-level debugging support + on the DBGU port of: + at91rm9200, at91sam9260, at91sam9g20, at91sam9261, + at91sam9g10, at91sam9n12, at91sam9rl64, at91sam9x5 - SOC DEBUG_UART_PHYS DEBUG_UART_VIRT PORT - rm9200, 9260/9g20, 0xfffff200 0xfefff200 DBGU - 9261/9g10, 9rl - 9263, 9g45, sama5d3 0xffffee00 0xfeffee00 DBGU - sama5d4 0xfc00c000 0xfb00c000 USART3 - sama5d4 0xfc069000 0xfb069000 DBGU - sama5d2 0xf8020000 0xf7020000 UART1 + config DEBUG_AT91_SAM9263_DBGU + bool "Kernel low-level debugging on AT91SAM{9263,9G45,A5D3} DBGU" + select DEBUG_AT91_UART + depends on SOC_AT91SAM9 || SOC_SAMA5D3 + help + Say Y here if you want kernel low-level debugging support + on the DBGU port of: + at91sam9263, at91sam9g45, at91sam9m10, + sama5d3 - Please adjust DEBUG_UART_PHYS configuration options based on - your needs. + config DEBUG_AT91_SAMA5D2_UART1 + bool "Kernel low-level debugging on SAMA5D2 UART1" + select DEBUG_AT91_UART + depends on SOC_SAMA5D2 + help + Say Y here if you want kernel low-level debugging support + on the UART1 port of sama5d2. + + config DEBUG_AT91_SAMA5D4_USART3 + bool "Kernel low-level debugging on SAMA5D4 USART3" + select DEBUG_AT91_UART + depends on SOC_SAMA5D4 + help + Say Y here if you want kernel low-level debugging support + on the USART3 port of sama5d4. config DEBUG_BCM2835 bool "Kernel low-level debugging on BCM2835 PL011 UART" @@ -138,8 +156,8 @@ choice select DEBUG_UART_PL01X config DEBUG_BCM_5301X - bool "Kernel low-level debugging on BCM5301X UART1" - depends on ARCH_BCM_5301X + bool "Kernel low-level debugging on BCM5301X/NSP UART1" + depends on ARCH_BCM_5301X || ARCH_BCM_NSP select DEBUG_UART_8250 config DEBUG_BCM_KONA_UART @@ -1296,6 +1314,10 @@ choice endchoice +config DEBUG_AT91_UART + bool + depends on ARCH_AT91 + config DEBUG_EXYNOS_UART bool @@ -1502,8 +1524,10 @@ config DEBUG_UART_PHYS default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE default 0xf1012100 if DEBUG_MVEBU_UART1_ALTERNATE default 0xf7fc9000 if DEBUG_BERLIN_UART + default 0xf8020000 if DEBUG_AT91_SAMA5D2_UART1 default 0xf8b00000 if DEBUG_HIX5HD2_UART default 0xf991e000 if DEBUG_QCOM_UARTDM + default 0xfc00c000 if DEBUG_AT91_SAMA5D4_USART3 default 0xfcb00000 if DEBUG_HI3620_UART default 0xfd883000 if DEBUG_ALPINE_UART0 default 0xfe800000 if ARCH_IOP32X @@ -1518,6 +1542,8 @@ config DEBUG_UART_PHYS default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2 default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3 default 0xfffe8600 if DEBUG_BCM63XX_UART + default 0xffffee00 if DEBUG_AT91_SAM9263_DBGU + default 0xfffff200 if DEBUG_AT91_RM9200_DBGU default 0xfffff700 if ARCH_IOP33X depends on ARCH_EP93XX || \ DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ @@ -1566,13 +1592,17 @@ config DEBUG_UART_VIRT DEBUG_S3C2410_UART1) default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \ DEBUG_S3C2410_UART2) + default 0xf7020000 if DEBUG_AT91_SAMA5D2_UART1 default 0xf7fc9000 if DEBUG_BERLIN_UART default 0xf8007000 if DEBUG_HIP04_UART default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9 default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 + default 0xf8ffee00 if DEBUG_AT91_SAM9263_DBGU + default 0xf8fff200 if DEBUG_AT91_RM9200_DBGU default 0xfa71e000 if DEBUG_QCOM_UARTDM default 0xfb002000 if DEBUG_CNS3XXX default 0xfb009000 if DEBUG_REALVIEW_STD_PORT + default 0xfb00c000 if DEBUG_AT91_SAMA5D4_USART3 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT default 0xfc40ab00 if DEBUG_BRCMSTB_UART default 0xfc705000 if DEBUG_ZTE_ZX @@ -1627,7 +1657,8 @@ config DEBUG_UART_VIRT DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ DEBUG_S3C64XX_UART || \ DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \ - DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 + DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ + DEBUG_AT91_UART config DEBUG_UART_8250_SHIFT int "Register offset shift for the 8250 debug UART" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 229afaf2058b..56ea5c60b318 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -140,7 +140,6 @@ head-y := arch/arm/kernel/head$(MMUEXT).o # Text offset. This list is sorted numerically by address in order to # provide a means to avoid/resolve conflicts in multi-arch kernels. textofs-y := 0x00008000 -textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 # We don't want the htc bootloader to corrupt kernel during resume textofs-$(CONFIG_PM_H1940) := 0x00108000 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index d4ae3b8e2426..0098401e5aeb 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -9,14 +9,6 @@ * */ -#ifdef CONFIG_MMU -#define AT91_IO_P2V(x) ((x) - 0x01000000) -#else -#define AT91_IO_P2V(x) (x) -#endif - -#define AT91_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) - #define AT91_DBGU_SR (0x14) /* Status Register */ #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ #define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */ @@ -24,7 +16,7 @@ .macro addruart, rp, rv, tmp ldr \rp, =CONFIG_DEBUG_UART_PHYS @ System peripherals (phys address) - ldr \rv, =AT91_DEBUG_UART_VIRT @ System peripherals (virt address) + ldr \rv, =CONFIG_DEBUG_UART_VIRT @ System peripherals (virt address) .endm .macro senduart,rd,rx diff --git a/arch/arm/include/debug/clps711x.S b/arch/arm/include/debug/clps711x.S index abe225436686..c17ac5c9e5f3 100644 --- a/arch/arm/include/debug/clps711x.S +++ b/arch/arm/include/debug/clps711x.S @@ -9,10 +9,10 @@ #ifndef CONFIG_DEBUG_CLPS711X_UART2 #define CLPS711X_UART_PADDR (0x80000000 + 0x0000) -#define CLPS711X_UART_VADDR (0xfeff0000 + 0x0000) +#define CLPS711X_UART_VADDR (0xfeff4000 + 0x0000) #else #define CLPS711X_UART_PADDR (0x80000000 + 0x1000) -#define CLPS711X_UART_VADDR (0xfeff0000 + 0x1000) +#define CLPS711X_UART_VADDR (0xfeff4000 + 0x1000) #endif #define SYSFLG (0x0140) diff --git a/arch/arm/include/debug/exynos.S b/arch/arm/include/debug/exynos.S index b17fdb7fbd34..60bf3c23200d 100644 --- a/arch/arm/include/debug/exynos.S +++ b/arch/arm/include/debug/exynos.S @@ -24,7 +24,11 @@ mrc p15, 0, \tmp, c0, c0, 0 and \tmp, \tmp, #0xf0 teq \tmp, #0xf0 @@ A15 - ldreq \rp, =EXYNOS5_PA_UART + beq 100f + mrc p15, 0, \tmp, c0, c0, 5 + and \tmp, \tmp, #0xf00 + teq \tmp, #0x100 @@ A15 + A7 but boot to A7 +100: ldreq \rp, =EXYNOS5_PA_UART movne \rp, #EXYNOS4_PA_UART @@ EXYNOS4 ldr \rv, =S3C_VA_UART #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S index 8d8d922e5e44..f4eeed2a1981 100644 --- a/arch/arm/include/debug/samsung.S +++ b/arch/arm/include/debug/samsung.S @@ -15,11 +15,13 @@ .macro fifo_level_s5pv210 rd, rx ldr \rd, [\rx, # S3C2410_UFSTAT] +ARM_BE8(rev \rd, \rd) and \rd, \rd, #S5PV210_UFSTAT_TXMASK .endm .macro fifo_full_s5pv210 rd, rx ldr \rd, [\rx, # S3C2410_UFSTAT] +ARM_BE8(rev \rd, \rd) tst \rd, #S5PV210_UFSTAT_TXFULL .endm @@ -28,6 +30,7 @@ .macro fifo_level_s3c2440 rd, rx ldr \rd, [\rx, # S3C2410_UFSTAT] +ARM_BE8(rev \rd, \rd) and \rd, \rd, #S3C2440_UFSTAT_TXMASK .endm @@ -37,6 +40,7 @@ .macro fifo_full_s3c2440 rd, rx ldr \rd, [\rx, # S3C2410_UFSTAT] +ARM_BE8(rev \rd, \rd) tst \rd, #S3C2440_UFSTAT_TXFULL .endm @@ -50,6 +54,7 @@ .macro busyuart, rd, rx ldr \rd, [\rx, # S3C2410_UFCON] +ARM_BE8(rev \rd, \rd) tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? beq 1001f @ @ FIFO enabled... @@ -61,6 +66,7 @@ 1001: @ busy waiting for non fifo ldr \rd, [\rx, # S3C2410_UTRSTAT] +ARM_BE8(rev \rd, \rd) tst \rd, #S3C2410_UTRSTAT_TXFE beq 1001b @@ -69,6 +75,7 @@ .macro waituart,rd,rx ldr \rd, [\rx, # S3C2410_UFCON] +ARM_BE8(rev \rd, \rd) tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? beq 1001f @ @ FIFO enabled... @@ -80,6 +87,7 @@ 1001: @ idle waiting for non fifo ldr \rd, [\rx, # S3C2410_UTRSTAT] +ARM_BE8(rev \rd, \rd) tst \rd, #S3C2410_UTRSTAT_TXFE beq 1001b diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index f06270198bf1..b4332b727e9c 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -22,6 +22,7 @@ #include <linux/of_platform.h> #include <linux/of_address.h> #include <linux/platform_device.h> +#include <linux/platform_data/atmel.h> #include <linux/io.h> #include <linux/clk/at91_pmc.h> @@ -355,7 +356,7 @@ static __init void at91_dt_ramc(void) at91_pm_set_standby(standby); } -void at91rm9200_idle(void) +static void at91rm9200_idle(void) { /* * Disable the processor clock. The processor will be automatically @@ -364,7 +365,7 @@ void at91rm9200_idle(void) writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); } -void at91sam9_idle(void) +static void at91sam9_idle(void) { writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); cpu_do_idle(); diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 5f63f513d9c9..34f0fca0b847 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -112,9 +112,17 @@ config ARCH_BCM_21664 Enable support for the BCM21664 family, which includes BCM21663 and BCM21664 variants. +config ARCH_BCM_23550 + bool "Broadcom BCM23550 SoC" + depends on ARCH_MULTI_V7 + select ARCH_BCM_MOBILE + select HAVE_SMP + help + Enable support for the BCM23550. + config ARCH_BCM_MOBILE_L2_CACHE bool "Broadcom mobile SoC level 2 cache support" - depends on ARCH_BCM_MOBILE + depends on ARCH_BCM_281XX || ARCH_BCM_21664 default y select CACHE_L2X0 select ARCH_BCM_MOBILE_SMC @@ -129,7 +137,7 @@ config ARCH_BCM_MOBILE_SMP select HAVE_ARM_SCU select ARM_ERRATA_764369 help - SMP support for the BCM281XX and BCM21664 SoC families. + SMP support for the BCM281XX, BCM21664 and BCM23550 SoC families. Provided as an option so SMP support for SoCs of this type can be disabled for an SMP-enabled kernel. diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 7d665151c772..980f5850097c 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -26,7 +26,10 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o # BCM21664 obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o -# BCM281XX and BCM21664 SMP support +# BCM23550 +obj-$(CONFIG_ARCH_BCM_23550) += board_bcm23550.o + +# BCM281XX, BCM21664 and BCM23550 SMP support obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o # BCM281XX and BCM21664 L2 cache control diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c index 0d7034c57334..c5bf01641172 100644 --- a/arch/arm/mach-bcm/board_bcm21664.c +++ b/arch/arm/mach-bcm/board_bcm21664.c @@ -11,52 +11,10 @@ * GNU General Public License for more details. */ -#include <linux/of_address.h> -#include <linux/io.h> - #include <asm/mach/arch.h> #include "kona_l2_cache.h" -#define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr" - -#define RSTMGR_REG_WR_ACCESS_OFFSET 0 -#define RSTMGR_REG_CHIP_SOFT_RST_OFFSET 4 - -#define RSTMGR_WR_PASSWORD 0xa5a5 -#define RSTMGR_WR_PASSWORD_SHIFT 8 -#define RSTMGR_WR_ACCESS_ENABLE 1 - -static void bcm21664_restart(enum reboot_mode mode, const char *cmd) -{ - void __iomem *base; - struct device_node *resetmgr; - - resetmgr = of_find_compatible_node(NULL, NULL, RSTMGR_DT_STRING); - if (!resetmgr) { - pr_emerg("Couldn't find " RSTMGR_DT_STRING "\n"); - return; - } - base = of_iomap(resetmgr, 0); - if (!base) { - pr_emerg("Couldn't map " RSTMGR_DT_STRING "\n"); - return; - } - - /* - * A soft reset is triggered by writing a 0 to bit 0 of the soft reset - * register. To write to that register we must first write the password - * and the enable bit in the write access enable register. - */ - writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) | - RSTMGR_WR_ACCESS_ENABLE, - base + RSTMGR_REG_WR_ACCESS_OFFSET); - writel(0, base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET); - - /* Wait for reset */ - while (1); -} - static void __init bcm21664_init(void) { kona_l2_cache_init(); @@ -69,6 +27,5 @@ static const char * const bcm21664_dt_compat[] = { DT_MACHINE_START(BCM21664_DT, "BCM21664 Broadcom Application Processor") .init_machine = bcm21664_init, - .restart = bcm21664_restart, .dt_compat = bcm21664_dt_compat, MACHINE_END diff --git a/arch/arm/mach-bcm/board_bcm23550.c b/arch/arm/mach-bcm/board_bcm23550.c new file mode 100644 index 000000000000..0ac01debd077 --- /dev/null +++ b/arch/arm/mach-bcm/board_bcm23550.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 Broadcom + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/of_platform.h> + +#include <asm/mach/arch.h> + +static const char * const bcm23550_dt_compat[] = { + "brcm,bcm23550", + NULL, +}; + +DT_MACHINE_START(BCM23550_DT, "BCM23550 Broadcom Application Processor") + .dt_compat = bcm23550_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-bcm/kona_l2_cache.c b/arch/arm/mach-bcm/kona_l2_cache.c index b31970377c20..59ad86304092 100644 --- a/arch/arm/mach-bcm/kona_l2_cache.c +++ b/arch/arm/mach-bcm/kona_l2_cache.c @@ -17,6 +17,7 @@ #include <asm/hardware/cache-l2x0.h> #include "bcm_kona_smc.h" +#include "kona_l2_cache.h" void __init kona_l2_cache_init(void) { diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c index cfae9c71fb74..33c4d8349f95 100644 --- a/arch/arm/mach-bcm/platsmp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/jiffies.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/sched.h> #include <linux/smp.h> @@ -255,6 +256,57 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) return -ENXIO; } +/* Cluster Dormant Control command to bring CPU into a running state */ +#define CDC_CMD 6 +#define CDC_CMD_OFFSET 0 +#define CDC_CMD_REG(cpu) (CDC_CMD_OFFSET + 4*(cpu)) + +/* + * BCM23550 has a Cluster Dormant Control block that keeps the core in + * idle state. A command needs to be sent to the block to bring the CPU + * into running state. + */ +static int bcm23550_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + void __iomem *cdc_base; + struct device_node *dn; + char *name; + int ret; + + /* Make sure a CDC node exists before booting the + * secondary core. + */ + name = "brcm,bcm23550-cdc"; + dn = of_find_compatible_node(NULL, NULL, name); + if (!dn) { + pr_err("unable to find cdc node\n"); + return -ENODEV; + } + + cdc_base = of_iomap(dn, 0); + of_node_put(dn); + + if (!cdc_base) { + pr_err("unable to remap cdc base register\n"); + return -ENOMEM; + } + + /* Boot the secondary core */ + ret = kona_boot_secondary(cpu, idle); + if (ret) + goto out; + + /* Bring this CPU to RUN state so that nIRQ nFIQ + * signals are unblocked. + */ + writel_relaxed(CDC_CMD, cdc_base + CDC_CMD_REG(cpu)); + +out: + iounmap(cdc_base); + + return ret; +} + static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) { int ret; @@ -283,6 +335,12 @@ static const struct smp_operations bcm_smp_ops __initconst = { CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); +static const struct smp_operations bcm23550_smp_ops __initconst = { + .smp_boot_secondary = bcm23550_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550", + &bcm23550_smp_ops); + static const struct smp_operations nsp_smp_ops __initconst = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = nsp_boot_secondary, diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index f711498c180c..3b56197ccfd0 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -1,38 +1,15 @@ -if ARCH_CLPS711X - -menu "CLPS711X/EP721X/EP731X Implementations" - -config ARCH_AUTCPU12 - bool "AUTCPU12" - help - Say Y if you intend to run the kernel on the autronix autcpu12 - board. This board is based on a Cirrus Logic CS89712. - -config ARCH_CDB89712 - bool "CDB89712" - help - This is an evaluation board from Cirrus for the CS89712 processor. - The board includes 2 serial ports, Ethernet, IRDA, and expansion - headers. It comes with 16 MB SDRAM and 8 MB flash ROM. - -config ARCH_CLEP7312 - bool "CLEP7312" - help - Boards based on the Cirrus Logic 7212/7312 chips. - -config ARCH_EDB7211 - bool "EDB7211" - select ARCH_HAS_HOLES_MEMORYMODEL - help - Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 - evaluation board. - -config ARCH_P720T - bool "P720T" - help - Say Y here if you intend to run this kernel on the ARM Prospector - 720T. - -endmenu - -endif +menuconfig ARCH_CLPS711X + bool "Cirrus Logic EP721x/EP731x-based" + depends on ARCH_MULTI_V4T + select ARCH_REQUIRE_GPIOLIB + select AUTO_ZRELADDR + select CLKSRC_MMIO + select CLKSRC_OF + select COMMON_CLK + select CPU_ARM720T + select GENERIC_CLOCKEVENTS + select MFD_SYSCON + select OF_IRQ + select USE_OF + help + Select this if you use ARMv4T Cirrus Logic chips. diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile index f04151efd96a..bd0b7b5d6e9d 100644 --- a/arch/arm/mach-clps711x/Makefile +++ b/arch/arm/mach-clps711x/Makefile @@ -1,13 +1 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := common.o devices.o - -obj-$(CONFIG_ARCH_AUTCPU12) += board-autcpu12.o -obj-$(CONFIG_ARCH_CDB89712) += board-cdb89712.o -obj-$(CONFIG_ARCH_CLEP7312) += board-clep7312.o -obj-$(CONFIG_ARCH_EDB7211) += board-edb7211.o -obj-$(CONFIG_ARCH_P720T) += board-p720t.o +obj-y += board-dt.o diff --git a/arch/arm/mach-clps711x/Makefile.boot b/arch/arm/mach-clps711x/Makefile.boot index eba77d35a615..e69de29bb2d1 100644 --- a/arch/arm/mach-clps711x/Makefile.boot +++ b/arch/arm/mach-clps711x/Makefile.boot @@ -1,5 +0,0 @@ -# The standard locations for stuff on CLPS711x type processors -params_phys-y := 0xc0000100 -# Should probably have some agreement on these... -initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000 -initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000 diff --git a/arch/arm/mach-clps711x/board-dt.c b/arch/arm/mach-clps711x/board-dt.c new file mode 100644 index 000000000000..ee1f83b1a332 --- /dev/null +++ b/arch/arm/mach-clps711x/board-dt.c @@ -0,0 +1,82 @@ +/* + * Author: Alexander Shiyan <shc_work@mail.ru>, 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/io.h> +#include <linux/of_fdt.h> +#include <linux/platform_device.h> +#include <linux/random.h> +#include <linux/sizes.h> + +#include <linux/mfd/syscon/clps711x.h> + +#include <asm/system_info.h> +#include <asm/system_misc.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#define CLPS711X_VIRT_BASE IOMEM(0xfeff4000) +#define CLPS711X_PHYS_BASE (0x80000000) +# define SYSFLG1 (0x0140) +# define HALT (0x0800) +# define UNIQID (0x2440) +# define RANDID0 (0x2700) +# define RANDID1 (0x2704) +# define RANDID2 (0x2708) +# define RANDID3 (0x270c) + +static struct map_desc clps711x_io_desc __initdata = { + .virtual = (unsigned long)CLPS711X_VIRT_BASE, + .pfn = __phys_to_pfn(CLPS711X_PHYS_BASE), + .length = 48 * SZ_1K, + .type = MT_DEVICE, +}; + +static void __init clps711x_map_io(void) +{ + iotable_init(&clps711x_io_desc, 1); +} + +static const struct resource clps711x_cpuidle_res = + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + HALT, SZ_128); + +static void __init clps711x_init(void) +{ + u32 id[5]; + + id[0] = readl(CLPS711X_VIRT_BASE + UNIQID); + id[1] = readl(CLPS711X_VIRT_BASE + RANDID0); + id[2] = readl(CLPS711X_VIRT_BASE + RANDID1); + id[3] = readl(CLPS711X_VIRT_BASE + RANDID2); + id[4] = readl(CLPS711X_VIRT_BASE + RANDID3); + system_rev = SYSFLG1_VERID(readl(CLPS711X_VIRT_BASE + SYSFLG1)); + + add_device_randomness(id, sizeof(id)); + + system_serial_low = id[0]; + + platform_device_register_simple("clps711x-cpuidle", PLATFORM_DEVID_NONE, + &clps711x_cpuidle_res, 1); +} + +static void clps711x_restart(enum reboot_mode mode, const char *cmd) +{ + soft_restart(0); +} + +static const char *clps711x_compat[] __initconst = { + "cirrus,ep7209", + NULL +}; + +DT_MACHINE_START(CLPS711X_DT, "Cirrus Logic CLPS711X (Device Tree Support)") + .dt_compat = clps711x_compat, + .map_io = clps711x_map_io, + .init_late = clps711x_init, + .restart = clps711x_restart, +MACHINE_END diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 671acc5a3282..6466da8f3c11 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -37,8 +37,8 @@ static struct map_desc clps711x_io_desc[] __initdata = { { .virtual = (unsigned long)CLPS711X_VIRT_BASE, .pfn = __phys_to_pfn(CLPS711X_PHYS_BASE), - .length = SZ_64K, - .type = MT_DEVICE + .length = 48 * SZ_1K, + .type = MT_DEVICE, } }; diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h deleted file mode 100644 index eb052a11aa9d..000000000000 --- a/arch/arm/mach-clps711x/include/mach/clps711x.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * This file contains the hardware definitions of the Cirrus Logic - * ARM7 CLPS711X internal registers. - * - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __MACH_CLPS711X_H -#define __MACH_CLPS711X_H - -#include <linux/mfd/syscon/clps711x.h> - -#define CLPS711X_PHYS_BASE (0x80000000) - -#define PADR (0x0000) -#define PBDR (0x0001) -#define PCDR (0x0002) -#define PDDR (0x0003) -#define PADDR (0x0040) -#define PBDDR (0x0041) -#define PCDDR (0x0042) -#define PDDDR (0x0043) -#define PEDR (0x0083) -#define PEDDR (0x00c3) -#define SYSCON1 (0x0100) -#define SYSFLG1 (0x0140) -#define MEMCFG1 (0x0180) -#define MEMCFG2 (0x01c0) -#define DRFPR (0x0200) -#define LCDCON (0x02c0) -#define TC1D (0x0300) -#define TC2D (0x0340) -#define RTCDR (0x0380) -#define RTCMR (0x03c0) -#define PMPCON (0x0400) -#define CODR (0x0440) -#define UARTDR1 (0x0480) -#define UBRLCR1 (0x04c0) -#define SYNCIO (0x0500) -#define PALLSW (0x0540) -#define PALMSW (0x0580) -#define STFCLR (0x05c0) -#define HALT (0x0800) -#define STDBY (0x0840) - -#define FBADDR (0x1000) -#define SYSCON2 (0x1100) -#define SYSFLG2 (0x1140) -#define UARTDR2 (0x1480) -#define UBRLCR2 (0x14c0) -#define SS2DR (0x1500) -#define SS2POP (0x16c0) - -#define DAIR (0x2000) -#define DAIDR0 (0x2040) -#define DAIDR1 (0x2080) -#define DAIDR2 (0x20c0) -#define DAISR (0x2100) -#define SYSCON3 (0x2200) -#define LEDFLSH (0x22c0) -#define SDCONF (0x2300) -#define SDRFPR (0x2340) -#define UNIQID (0x2440) -#define DAI64FS (0x2600) -#define PLLW (0x2610) -#define PLLR (0xa5a8) -#define RANDID0 (0x2700) -#define RANDID1 (0x2704) -#define RANDID2 (0x2708) -#define RANDID3 (0x270c) - -#define LCDCON_GSEN (1 << 30) -#define LCDCON_GSMD (1 << 31) - -/* common bits: UARTDR1 / UARTDR2 */ -#define UARTDR_FRMERR (1 << 8) -#define UARTDR_PARERR (1 << 9) -#define UARTDR_OVERR (1 << 10) - -/* common bits: UBRLCR1 / UBRLCR2 */ -#define UBRLCR_BAUD_MASK ((1 << 12) - 1) -#define UBRLCR_BREAK (1 << 12) -#define UBRLCR_PRTEN (1 << 13) -#define UBRLCR_EVENPRT (1 << 14) -#define UBRLCR_XSTOP (1 << 15) -#define UBRLCR_FIFOEN (1 << 16) -#define UBRLCR_WRDLEN5 (0 << 17) -#define UBRLCR_WRDLEN6 (1 << 17) -#define UBRLCR_WRDLEN7 (2 << 17) -#define UBRLCR_WRDLEN8 (3 << 17) -#define UBRLCR_WRDLEN_MASK (3 << 17) - -#define SYNCIO_FRMLEN(x) (((x) & 0x1f) << 8) -#define SYNCIO_SMCKEN (1 << 13) -#define SYNCIO_TXFRMEN (1 << 14) - -#define DAIR_RESERVED (0x0404) -#define DAIR_DAIEN (1 << 16) -#define DAIR_ECS (1 << 17) -#define DAIR_LCTM (1 << 19) -#define DAIR_LCRM (1 << 20) -#define DAIR_RCTM (1 << 21) -#define DAIR_RCRM (1 << 22) -#define DAIR_LBM (1 << 23) - -#define DAIDR2_FIFOEN (1 << 15) -#define DAIDR2_FIFOLEFT (0x0d << 16) -#define DAIDR2_FIFORIGHT (0x11 << 16) - -#define DAISR_RCTS (1 << 0) -#define DAISR_RCRS (1 << 1) -#define DAISR_LCTS (1 << 2) -#define DAISR_LCRS (1 << 3) -#define DAISR_RCTU (1 << 4) -#define DAISR_RCRO (1 << 5) -#define DAISR_LCTU (1 << 6) -#define DAISR_LCRO (1 << 7) -#define DAISR_RCNF (1 << 8) -#define DAISR_RCNE (1 << 9) -#define DAISR_LCNF (1 << 10) -#define DAISR_LCNE (1 << 11) -#define DAISR_FIFO (1 << 12) - -#define DAI64FS_I2SF64 (1 << 0) -#define DAI64FS_AUDIOCLKEN (1 << 1) -#define DAI64FS_AUDIOCLKSRC (1 << 2) -#define DAI64FS_MCLK256EN (1 << 3) -#define DAI64FS_LOOPBACK (1 << 5) - -#define SDCONF_ACTIVE (1 << 10) -#define SDCONF_CLKCTL (1 << 9) -#define SDCONF_WIDTH_4 (0 << 7) -#define SDCONF_WIDTH_8 (1 << 7) -#define SDCONF_WIDTH_16 (2 << 7) -#define SDCONF_WIDTH_32 (3 << 7) -#define SDCONF_SIZE_16 (0 << 5) -#define SDCONF_SIZE_64 (1 << 5) -#define SDCONF_SIZE_128 (2 << 5) -#define SDCONF_SIZE_256 (3 << 5) -#define SDCONF_CASLAT_2 (2) -#define SDCONF_CASLAT_3 (3) - -#define MEMCFG_BUS_WIDTH_32 (1) -#define MEMCFG_BUS_WIDTH_16 (0) -#define MEMCFG_BUS_WIDTH_8 (3) - -#define MEMCFG_SQAEN (1 << 6) -#define MEMCFG_CLKENB (1 << 7) - -#define MEMCFG_WAITSTATE_8_3 (0 << 2) -#define MEMCFG_WAITSTATE_7_3 (1 << 2) -#define MEMCFG_WAITSTATE_6_3 (2 << 2) -#define MEMCFG_WAITSTATE_5_3 (3 << 2) -#define MEMCFG_WAITSTATE_4_2 (4 << 2) -#define MEMCFG_WAITSTATE_3_2 (5 << 2) -#define MEMCFG_WAITSTATE_2_2 (6 << 2) -#define MEMCFG_WAITSTATE_1_2 (7 << 2) -#define MEMCFG_WAITSTATE_8_1 (8 << 2) -#define MEMCFG_WAITSTATE_7_1 (9 << 2) -#define MEMCFG_WAITSTATE_6_1 (10 << 2) -#define MEMCFG_WAITSTATE_5_1 (11 << 2) -#define MEMCFG_WAITSTATE_4_0 (12 << 2) -#define MEMCFG_WAITSTATE_3_0 (13 << 2) -#define MEMCFG_WAITSTATE_2_0 (14 << 2) -#define MEMCFG_WAITSTATE_1_0 (15 << 2) - -/* INTSR1 Interrupts */ -#define IRQ_CSINT (4) -#define IRQ_EINT1 (5) -#define IRQ_EINT2 (6) -#define IRQ_EINT3 (7) -#define IRQ_TC1OI (8) -#define IRQ_TC2OI (9) -#define IRQ_RTCMI (10) -#define IRQ_TINT (11) -#define IRQ_UTXINT1 (12) -#define IRQ_URXINT1 (13) -#define IRQ_UMSINT (14) -#define IRQ_SSEOTI (15) - -/* INTSR2 Interrupts */ -#define IRQ_KBDINT (16 + 0) -#define IRQ_SS2RX (16 + 1) -#define IRQ_SS2TX (16 + 2) -#define IRQ_UTXINT2 (16 + 12) -#define IRQ_URXINT2 (16 + 13) - -/* INTSR3 Interrupts */ -#define IRQ_DAIINT (32 + 0) - -#endif /* __MACH_CLPS711X_H */ diff --git a/arch/arm/mach-clps711x/include/mach/hardware.h b/arch/arm/mach-clps711x/include/mach/hardware.h deleted file mode 100644 index 833129c9f798..000000000000 --- a/arch/arm/mach-clps711x/include/mach/hardware.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/hardware.h - * - * This file contains the hardware definitions of the Prospector P720T. - * - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __MACH_HARDWARE_H -#define __MACH_HARDWARE_H - -#include <mach/clps711x.h> - -#define CLPS711X_VIRT_BASE IOMEM(0xfeff0000) - -#ifndef __ASSEMBLY__ -#define clps_readb(off) readb(CLPS711X_VIRT_BASE + (off)) -#define clps_readw(off) readw(CLPS711X_VIRT_BASE + (off)) -#define clps_readl(off) readl(CLPS711X_VIRT_BASE + (off)) -#define clps_writeb(val,off) writeb(val, CLPS711X_VIRT_BASE + (off)) -#define clps_writew(val,off) writew(val, CLPS711X_VIRT_BASE + (off)) -#define clps_writel(val,off) writel(val, CLPS711X_VIRT_BASE + (off)) -#endif - -#define CS0_PHYS_BASE (0x00000000) -#define CS1_PHYS_BASE (0x10000000) -#define CS2_PHYS_BASE (0x20000000) -#define CS3_PHYS_BASE (0x30000000) -#define CS4_PHYS_BASE (0x40000000) -#define CS5_PHYS_BASE (0x50000000) -#define CS6_PHYS_BASE (0x60000000) -#define CS7_PHYS_BASE (0x70000000) - -#define CLPS711X_SRAM_BASE CS6_PHYS_BASE -#define CLPS711X_SRAM_SIZE (48 * 1024) - -#define CLPS711X_SDRAM0_BASE (0xc0000000) -#define CLPS711X_SDRAM1_BASE (0xd0000000) - -#endif diff --git a/arch/arm/mach-clps711x/include/mach/uncompress.h b/arch/arm/mach-clps711x/include/mach/uncompress.h deleted file mode 100644 index 5f02d06dc655..000000000000 --- a/arch/arm/mach-clps711x/include/mach/uncompress.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/uncompress.h - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <mach/clps711x.h> - -#ifdef CONFIG_DEBUG_CLPS711X_UART2 -#define SYSFLGx SYSFLG2 -#define UARTDRx UARTDR2 -#else -#define SYSFLGx SYSFLG1 -#define UARTDRx UARTDR1 -#endif - -#define phys_reg(x) (*(volatile u32 *)(CLPS711X_PHYS_BASE + (x))) - -/* - * The following code assumes the serial port has already been - * initialized by the bootloader. If you didn't setup a port in - * your bootloader then nothing will appear (which might be desired). - * - * This does not append a newline - */ -static inline void putc(int c) -{ - while (phys_reg(SYSFLGx) & SYSFLG_UTXFF) - barrier(); - phys_reg(UARTDRx) = c; -} - -static inline void flush(void) -{ - while (phys_reg(SYSFLGx) & SYSFLG_UBUSY) - barrier(); -} - -/* - * nothing to do - */ -#define arch_decomp_setup() diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 1844076f6403..18296a99c4d2 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -115,8 +115,6 @@ static struct davinci_i2c_platform_data i2c_pdata = { .scl_pin = 14, }; -static struct snd_platform_data dm355_evm_snd_data; - static int dm355evm_mmc_gpios = -EINVAL; static void dm355evm_mmcsd_gpios(unsigned gpio) @@ -411,7 +409,7 @@ static __init void dm355_evm_init(void) ARRAY_SIZE(dm355_evm_spi_info)); /* DM335 EVM uses ASP1; line-out is a stereo mini-jack */ - dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data); + dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN); } MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index f073518f621a..0464999b7137 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -176,10 +176,6 @@ static struct at24_platform_data eeprom_info = { .context = (void *)0x7f00, }; -static struct snd_platform_data dm365_evm_snd_data __maybe_unused = { - .asp_chan_q = EVENTQ_3, -}; - static struct i2c_board_info i2c_info[] = { { I2C_BOARD_INFO("24c256", 0x50), @@ -763,9 +759,9 @@ static __init void dm365_evm_init(void) evm_init_cpld(); #ifdef CONFIG_SND_DM365_AIC3X_CODEC - dm365_init_asp(&dm365_evm_snd_data); + dm365_init_asp(); #elif defined(CONFIG_SND_DM365_VOICE_CODEC) - dm365_init_vc(&dm365_evm_snd_data); + dm365_init_vc(); #endif dm365_init_rtc(); dm365_init_ks(&dm365evm_ks_data); diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index ab47b8eb1b15..521e40977265 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -264,8 +264,6 @@ static struct platform_device rtc_dev = { .id = -1, }; -static struct snd_platform_data dm644x_evm_snd_data; - /*----------------------------------------------------------------------*/ #ifdef CONFIG_I2C /* @@ -799,7 +797,7 @@ static __init void davinci_evm_init(void) dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg); davinci_serial_init(dm644x_serial_device); - dm644x_init_asp(&dm644x_evm_snd_data); + dm644x_init_asp(); /* irlml6401 switches over 1A, in under 8 msec */ davinci_setup_usb(1000, 8); diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 8fcdcf87c47c..ad10017203c1 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -127,8 +127,6 @@ static struct platform_device davinci_fb_device = { .num_resources = 0, }; -static struct snd_platform_data dm644x_ntosd2_snd_data; - static struct gpio_led ntosd2_leds[] = { { .name = "led1_green", .gpio = GPIO(10), }, { .name = "led1_red", .gpio = GPIO(11), }, @@ -200,7 +198,7 @@ static __init void davinci_ntosd2_init(void) ARRAY_SIZE(davinci_ntosd2_devices)); davinci_serial_init(dm644x_serial_device); - dm644x_init_asp(&dm644x_ntosd2_snd_data); + dm644x_init_asp(); soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID; diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 239886299968..0d046accb35b 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -326,6 +326,20 @@ static struct clk mcasp_clk = { .gpsc = 1, }; +static struct clk mcbsp0_clk = { + .name = "mcbsp0", + .parent = &async3_clk, + .lpsc = DA850_LPSC1_McBSP0, + .gpsc = 1, +}; + +static struct clk mcbsp1_clk = { + .name = "mcbsp1", + .parent = &async3_clk, + .lpsc = DA850_LPSC1_McBSP1, + .gpsc = 1, +}; + static struct clk lcdc_clk = { .name = "lcdc", .parent = &pll0_sysclk2, @@ -482,6 +496,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_emac.1", NULL, &emac_clk), CLK("davinci_mdio.0", "fck", &emac_clk), CLK("davinci-mcasp.0", NULL, &mcasp_clk), + CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk), + CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk), CLK("da8xx_lcdc.0", "fck", &lcdc_clk), CLK("da830-mmc.0", NULL, &mmcsd0_clk), CLK("da830-mmc.1", NULL, &mmcsd1_clk), diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 4ffc37accce0..c62b90c6118a 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -85,14 +85,14 @@ int davinci_init_wdt(void); void dm355_init(void); void dm355_init_spi0(unsigned chipselect_mask, const struct spi_board_info *info, unsigned len); -void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata); +void dm355_init_asp1(u32 evt_enable); int dm355_init_video(struct vpfe_config *, struct vpbe_config *); int dm355_gpio_register(void); /* DM365 function declarations */ void dm365_init(void); -void dm365_init_asp(struct snd_platform_data *pdata); -void dm365_init_vc(struct snd_platform_data *pdata); +void dm365_init_asp(void); +void dm365_init_vc(void); void dm365_init_ks(struct davinci_ks_platform_data *pdata); void dm365_init_rtc(void); void dm365_init_spi0(unsigned chipselect_mask, @@ -102,7 +102,7 @@ int dm365_gpio_register(void); /* DM644x function declarations */ void dm644x_init(void); -void dm644x_init_asp(struct snd_platform_data *pdata); +void dm644x_init_asp(void); int dm644x_init_video(struct vpfe_config *, struct vpbe_config *); int dm644x_gpio_register(void); diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 5a19cca7ed6a..d33322ddedab 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -1035,7 +1035,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .sram_len = SZ_32K, }; -void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) +void __init dm355_init_asp1(u32 evt_enable) { /* we don't use ASP1 IRQs, or we'd need to mux them ... */ if (evt_enable & ASP1_TX_EVT_EN) @@ -1044,7 +1044,6 @@ void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) if (evt_enable & ASP1_RX_EVT_EN) davinci_cfg_reg(DM355_EVT9_ASP1_RX); - dm355_asp1_device.dev.platform_data = pdata; platform_device_register(&dm355_asp1_device); } diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 8aa004b02fe9..ef3add999263 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1138,7 +1138,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .sram_len = SZ_32K, }; -void __init dm365_init_asp(struct snd_platform_data *pdata) +void __init dm365_init_asp(void) { davinci_cfg_reg(DM365_MCBSP0_BDX); davinci_cfg_reg(DM365_MCBSP0_X); @@ -1148,15 +1148,13 @@ void __init dm365_init_asp(struct snd_platform_data *pdata) davinci_cfg_reg(DM365_MCBSP0_BFSR); davinci_cfg_reg(DM365_EVT2_ASP_TX); davinci_cfg_reg(DM365_EVT3_ASP_RX); - dm365_asp_device.dev.platform_data = pdata; platform_device_register(&dm365_asp_device); } -void __init dm365_init_vc(struct snd_platform_data *pdata) +void __init dm365_init_vc(void) { davinci_cfg_reg(DM365_EVT2_VC_TX); davinci_cfg_reg(DM365_EVT3_VC_RX); - dm365_vc_device.dev.platform_data = pdata; platform_device_register(&dm365_vc_device); } diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 0afa279ec460..b437c3730f65 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -921,10 +921,9 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .sram_len = SZ_16K, }; -void __init dm644x_init_asp(struct snd_platform_data *pdata) +void __init dm644x_init_asp(void) { davinci_cfg_reg(DM644X_MCBSP); - dm644x_asp_device.dev.platform_data = pdata; platform_device_register(&dm644x_asp_device); } diff --git a/arch/arm/mach-davinci/psc.h b/arch/arm/mach-davinci/psc.h index 99d47cfa301f..8af9f09fc10c 100644 --- a/arch/arm/mach-davinci/psc.h +++ b/arch/arm/mach-davinci/psc.h @@ -171,6 +171,8 @@ #define DA8XX_LPSC1_I2C 11 #define DA8XX_LPSC1_UART1 12 #define DA8XX_LPSC1_UART2 13 +#define DA850_LPSC1_McBSP0 14 +#define DA850_LPSC1_McBSP1 15 #define DA8XX_LPSC1_LCDC 16 #define DA8XX_LPSC1_PWM 17 #define DA850_LPSC1_MMC_SD1 18 diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 5365bf1f586a..9424a8a9f308 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -166,7 +166,6 @@ extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data; extern void exynos_set_delayed_reset_assertion(bool enable); -extern void s5p_init_cpu(void __iomem *cpuid_addr); extern unsigned int samsung_rev(void); extern void exynos_core_restart(u32 core_id); extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr); @@ -174,12 +173,12 @@ extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr); static inline void pmu_raw_writel(u32 val, u32 offset) { - __raw_writel(val, pmu_base_addr + offset); + writel_relaxed(val, pmu_base_addr + offset); } static inline u32 pmu_raw_readl(u32 offset) { - return __raw_readl(pmu_base_addr + offset); + return readl_relaxed(pmu_base_addr + offset); } #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index dea410adee7e..ecbfa5dd3c54 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -24,6 +24,7 @@ #include <asm/mach/map.h> #include <mach/map.h> +#include <plat/cpu.h> #include "common.h" #include "mfc.h" diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index 1bfd1b0bd9dc..fd6da5419b51 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c @@ -41,9 +41,9 @@ static int exynos_do_idle(unsigned long mode) case FW_DO_IDLE_AFTR: if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) exynos_save_cp15(); - __raw_writel(virt_to_phys(exynos_cpu_resume_ns), - sysram_ns_base_addr + 0x24); - __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); + writel_relaxed(virt_to_phys(exynos_cpu_resume_ns), + sysram_ns_base_addr + 0x24); + writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20); if (soc_is_exynos3250()) { flush_cache_all(); exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE, @@ -97,7 +97,7 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) if (soc_is_exynos4412()) boot_reg += 4 * cpu; - __raw_writel(boot_addr, boot_reg); + writel_relaxed(boot_addr, boot_reg); return 0; } @@ -113,7 +113,7 @@ static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr) if (soc_is_exynos4412()) boot_reg += 4 * cpu; - *boot_addr = __raw_readl(boot_reg); + *boot_addr = readl_relaxed(boot_reg); return 0; } @@ -234,20 +234,20 @@ void exynos_set_boot_flag(unsigned int cpu, unsigned int mode) { unsigned int tmp; - tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4); + tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4); if (mode & BOOT_MODE_MASK) tmp &= ~BOOT_MODE_MASK; tmp |= mode; - __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4); + writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4); } void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode) { unsigned int tmp; - tmp = __raw_readl(REG_CPU_STATE_ADDR + cpu * 4); + tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4); tmp &= ~mode; - __raw_writel(tmp, REG_CPU_STATE_ADDR + cpu * 4); + writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4); } diff --git a/arch/arm/mach-exynos/headsmp.S b/arch/arm/mach-exynos/headsmp.S index b54f9701e421..d3d24ab351ae 100644 --- a/arch/arm/mach-exynos/headsmp.S +++ b/arch/arm/mach-exynos/headsmp.S @@ -12,12 +12,15 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> + /* * exynos4 specific entry point for secondary CPUs. This provides * a "holding pen" into which all secondary cores are held until we're * ready for them to initialise. */ ENTRY(exynos4_secondary_startup) +ARM_BE8(setend be) mrc p15, 0, r0, c0, c0, 5 and r0, r0, #15 adr r4, 1f diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 85c3be63d644..98ffe1e62ad5 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -264,7 +264,7 @@ int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) ret = PTR_ERR(boot_reg); goto fail; } - __raw_writel(boot_addr, boot_reg); + writel_relaxed(boot_addr, boot_reg); ret = 0; } fail: @@ -289,7 +289,7 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr) ret = PTR_ERR(boot_reg); goto fail; } - *boot_addr = __raw_readl(boot_reg); + *boot_addr = readl_relaxed(boot_reg); ret = 0; } fail: diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index c43b776a51a3..487295f4a56b 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -132,9 +132,9 @@ static void exynos_set_wakeupmask(long mask) static void exynos_cpu_set_boot_vector(long flags) { - __raw_writel(virt_to_phys(exynos_cpu_resume), - exynos_boot_vector_addr()); - __raw_writel(flags, exynos_boot_vector_flag()); + writel_relaxed(virt_to_phys(exynos_cpu_resume), + exynos_boot_vector_addr()); + writel_relaxed(flags, exynos_boot_vector_flag()); } static int exynos_aftr_finisher(unsigned long flags) diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 875a2bab64f6..0e075d96ccd4 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -70,12 +70,12 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) } pwr = power_on ? INT_LOCAL_PWR_EN : 0; - __raw_writel(pwr, base); + writel_relaxed(pwr, base); /* Wait max 1ms */ timeout = 10; - while ((__raw_readl(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) { + while ((readl_relaxed(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) { if (!timeout) { op = (power_on) ? "enable" : "disable"; pr_err("Power domain %s %s failed\n", domain->name, op); @@ -185,7 +185,7 @@ static __init int exynos4_pm_init_power_domain(void) clk_put(pd->oscclk); no_clk: - on = __raw_readl(pd->base + 0x4) & INT_LOCAL_PWR_EN; + on = readl_relaxed(pd->base + 0x4) & INT_LOCAL_PWR_EN; pm_genpd_init(&pd->pd, NULL, !on); of_genpd_add_provider_simple(np, &pd->pd); diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index f21690937b7d..3750575c73c5 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -301,7 +301,7 @@ static int exynos5420_cpu_suspend(unsigned long arg) unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - __raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE); + writel_relaxed(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE); if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) { mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume); @@ -373,8 +373,8 @@ static void exynos5420_pm_prepare(void) * needs to restore it back in case, the primary cpu fails to * suspend for any reason. */ - exynos5420_cpu_state = __raw_readl(sysram_base_addr + - EXYNOS5420_CPU_STATE); + exynos5420_cpu_state = readl_relaxed(sysram_base_addr + + EXYNOS5420_CPU_STATE); exynos_pm_enter_sleep_mode(); @@ -504,11 +504,11 @@ static void exynos5420_pm_resume(void) /* Restore the CPU0 low power state register */ tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG); pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN, - EXYNOS5_ARM_CORE0_SYS_PWR_REG); + EXYNOS5_ARM_CORE0_SYS_PWR_REG); /* Restore the sysram cpu state register */ - __raw_writel(exynos5420_cpu_state, - sysram_base_addr + EXYNOS5420_CPU_STATE); + writel_relaxed(exynos5420_cpu_state, + sysram_base_addr + EXYNOS5420_CPU_STATE); pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c index 8cc62150116a..c08c44ec5175 100644 --- a/arch/arm/mach-hisi/hisilicon.c +++ b/arch/arm/mach-hisi/hisilicon.c @@ -53,31 +53,3 @@ DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)") .map_io = hi3620_map_io, .dt_compat = hi3xxx_compat, MACHINE_END - -static const char *const hix5hd2_compat[] __initconst = { - "hisilicon,hix5hd2", - NULL, -}; - -DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)") - .dt_compat = hix5hd2_compat, -MACHINE_END - -static const char *const hip04_compat[] __initconst = { - "hisilicon,hip04-d01", - NULL, -}; - -DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)") - .dt_compat = hip04_compat, -MACHINE_END - -static const char *const hip01_compat[] __initconst = { - "hisilicon,hip01", - "hisilicon,hip01-ca9x2", - NULL, -}; - -DT_MACHINE_START(HIP01, "Hisilicon HIP01 (Flattened Device Tree)") - .dt_compat = hip01_compat, -MACHINE_END diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index 47ed32cf57cc..e1d67648d5d0 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -103,7 +103,7 @@ static void __init hisi_common_smp_prepare_cpus(unsigned int max_cpus) hisi_enable_scu_a9(); } -void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) +static void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) { void __iomem *virt; @@ -139,7 +139,7 @@ static const struct smp_operations hix5hd2_smp_ops __initconst = { #define HIP01_BOOT_ADDRESS 0x80000000 #define REG_SC_CTRL 0x000 -void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) +static void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr) { void __iomem *virt; diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 7fa176e792bd..1afccae0420c 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -55,23 +55,20 @@ static void __iomem *avic_base; static struct irq_domain *domain; #ifdef CONFIG_FIQ -static int avic_set_irq_fiq(unsigned int irq, unsigned int type) +static int avic_set_irq_fiq(unsigned int hwirq, unsigned int type) { - struct irq_data *d = irq_get_irq_data(irq); unsigned int irqt; - irq = d->hwirq; - - if (irq >= AVIC_NUM_IRQS) + if (hwirq >= AVIC_NUM_IRQS) return -EINVAL; - if (irq < AVIC_NUM_IRQS / 2) { - irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); - imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); + if (hwirq < AVIC_NUM_IRQS / 2) { + irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << hwirq); + imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEL); } else { - irq -= AVIC_NUM_IRQS / 2; - irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); - imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); + hwirq -= AVIC_NUM_IRQS / 2; + irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << hwirq); + imx_writel(irqt | (!!type << hwirq), avic_base + AVIC_INTTYPEH); } return 0; diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 353bb8774112..db0f48c4b17e 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -10,6 +10,8 @@ #include <linux/module.h> #include <asm/cpuidle.h> +#include <soc/imx/cpuidle.h> + #include "common.h" #include "cpuidle.h" #include "hardware.h" @@ -62,6 +64,24 @@ static struct cpuidle_driver imx6q_cpuidle_driver = { .safe_state_index = 0, }; +/* + * i.MX6 Q/DL has an erratum (ERR006687) that prevents the FEC from waking the + * CPUs when they are in wait(unclocked) state. As the hardware workaround isn't + * applicable to all boards, disable the deeper idle state when the workaround + * isn't present and the FEC is in use. + */ +void imx6q_cpuidle_fec_irqs_used(void) +{ + imx6q_cpuidle_driver.states[1].disabled = true; +} +EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_used); + +void imx6q_cpuidle_fec_irqs_unused(void) +{ + imx6q_cpuidle_driver.states[1].disabled = false; +} +EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_unused); + int __init imx6q_cpuidle_init(void) { /* Set INT_MEM_CLK_LPM bit to get a reliable WAIT mode support */ diff --git a/arch/arm/mach-imx/devices/devices.c b/arch/arm/mach-imx/devices/devices.c index 8eab5440da28..300451727362 100644 --- a/arch/arm/mach-imx/devices/devices.c +++ b/arch/arm/mach-imx/devices/devices.c @@ -22,6 +22,9 @@ #include <linux/err.h> #include <linux/platform_device.h> +#include "../common.h" +#include "devices-common.h" + struct device mxc_aips_bus = { .init_name = "mxc_aips", }; diff --git a/arch/arm/mach-imx/devices/platform-gpio-mxc.c b/arch/arm/mach-imx/devices/platform-gpio-mxc.c index 26483fa94b75..cd1fe69d8807 100644 --- a/arch/arm/mach-imx/devices/platform-gpio-mxc.c +++ b/arch/arm/mach-imx/devices/platform-gpio-mxc.c @@ -7,6 +7,7 @@ * Free Software Foundation. */ #include "devices-common.h" +#include "../common.h" struct platform_device *__init mxc_register_gpio(char *name, int id, resource_size_t iobase, resource_size_t iosize, int irq, int irq_high) diff --git a/arch/arm/mach-imx/irq-common.c b/arch/arm/mach-imx/irq-common.c index 0a920d184867..210d36eba8f2 100644 --- a/arch/arm/mach-imx/irq-common.c +++ b/arch/arm/mach-imx/irq-common.c @@ -33,8 +33,10 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type) gc = irq_get_chip_data(irq); if (gc && gc->private) { exirq = gc->private; - if (exirq->set_irq_fiq) - ret = exirq->set_irq_fiq(irq, type); + if (exirq->set_irq_fiq) { + struct irq_data *d = irq_get_irq_data(irq); + ret = exirq->set_irq_fiq(irqd_to_hwirq(d), type); + } } return ret; diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c index 40564c9b1226..3835b6a3423c 100644 --- a/arch/arm/mach-imx/mach-imx51.c +++ b/arch/arm/mach-imx/mach-imx51.c @@ -52,6 +52,8 @@ static void __init imx51_dt_init(void) { imx51_ipu_mipi_setup(); imx_src_init(); + + imx_aips_allow_unprivileged_access("fsl,imx51-aipstz"); } static void __init imx51_init_late(void) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 68c16d59b808..97fd25105e2c 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -220,7 +220,7 @@ static void __init imx6q_1588_init(void) IMX6Q_GPR1_ENET_CLK_SEL_MASK, clksel); else - pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n"); + pr_err("failed to find fsl,imx6q-iomuxc-gpr regmap\n"); clk_put(enet_ref); put_ptp_clk: diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c index f388e6bd46ec..26ca744d3e2b 100644 --- a/arch/arm/mach-imx/mach-imx7d.c +++ b/arch/arm/mach-imx/mach-imx7d.c @@ -106,6 +106,7 @@ static void __init imx7d_init_irq(void) static const char *const imx7d_dt_compat[] __initconst = { "fsl,imx7d", + "fsl,imx7s", NULL, }; diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index a53fdc263a37..4ca37c3f1da4 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -55,14 +55,14 @@ static struct irq_domain *domain; #define TZIC_NUM_IRQS 128 #ifdef CONFIG_FIQ -static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) +static int tzic_set_irq_fiq(unsigned int hwirq, unsigned int type) { unsigned int index, mask, value; - index = irq >> 5; + index = hwirq >> 5; if (unlikely(index >= 4)) return -EINVAL; - mask = 1U << (irq & 0x1F); + mask = 1U << (hwirq & 0x1F); value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; if (type) diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c index e283939a216f..8cbb35765a19 100644 --- a/arch/arm/mach-keystone/pm_domain.c +++ b/arch/arm/mach-keystone/pm_domain.c @@ -18,6 +18,8 @@ #include <linux/platform_device.h> #include <linux/of.h> +#include "keystone.h" + static struct dev_pm_domain keystone_pm_domain = { .ops = { USE_PM_CLK_RUNTIME_OPS diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index fbce42d7390f..b6e3acc63e14 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig @@ -7,6 +7,8 @@ menuconfig ARCH_MESON select CACHE_L2X0 select PINCTRL select PINCTRL_MESON + select COMMON_CLK + select COMMON_CLK_AMLOGIC if ARCH_MESON @@ -24,5 +26,6 @@ config MACH_MESON8B bool "Amlogic Meson8b SoCs support" default ARCH_MESON select MESON6_TIMER + select COMMON_CLK_MESON8B endif diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index ec760ae2f917..793a24a53c52 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -137,7 +137,7 @@ void __init ams_delta_init_fiq(void) fiq_buffer[i] = 0; /* - * FIQ mode r9 always points to the fiq_buffer, becauses the FIQ isr + * FIQ mode r9 always points to the fiq_buffer, because the FIQ isr * will run in an unpredictable context. The fiq_buffer is the FIQ isr's * only means of communication with the IRQ level and other kernel * context code. diff --git a/arch/arm/mach-omap1/include/mach/mtd-xip.h b/arch/arm/mach-omap1/include/mach/mtd-xip.h index f82a8dcaad94..d09b2bc4920f 100644 --- a/arch/arm/mach-omap1/include/mach/mtd-xip.h +++ b/arch/arm/mach-omap1/include/mach/mtd-xip.h @@ -39,7 +39,7 @@ static inline unsigned long xip_omap_mpu_timer_read(int nr) #define xip_currtime() (~xip_omap_mpu_timer_read(0)) /* - * It's permitted to do approxmation for xip_elapsed_since macro + * It's permitted to do approximation for xip_elapsed_since macro * (see linux/mtd/xip.h) */ diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 04e276ce8413..a7f2d051f524 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -8,7 +8,7 @@ ccflags-y := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o timer.o pm.o \ common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ - omap_device.o sram.o drm.o + omap_device.o omap-headsmp.o sram.o drm.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o @@ -32,7 +32,7 @@ obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o # SMP support ONLY available for OMAP4 -smp-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o +smp-$(CONFIG_SMP) += omap-smp.o smp-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o omap-4-5-common = omap4-common.o omap-wakeupgen.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common) $(smp-y) sleep44xx.o @@ -78,13 +78,16 @@ obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o endif # Power Management +omap-4-5-pm-common = omap-mpuss-lowpower.o +obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common) +obj-$(CONFIG_ARCH_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 obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o -omap-4-5-pm-common = pm44xx.o omap-mpuss-lowpower.o +omap-4-5-pm-common += pm44xx.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-pm-common) diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index d9c3ffc39329..390795b334c3 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -39,7 +39,7 @@ #include "gpmc.h" #include "gpmc-smsc911x.h" -#include <video/omapdss.h> +#include <linux/platform_data/omapdss.h> #include <video/omap-panel-data.h> #include "board-flash.h" @@ -47,6 +47,7 @@ #include "hsmmc.h" #include "control.h" #include "common-board-devices.h" +#include "display.h" #define LDP_SMSC911X_CS 1 #define LDP_SMSC911X_GPIO 152 diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c index 9cfebc5c7455..180c6aa633bd 100644 --- a/arch/arm/mach-omap2/board-rx51-video.c +++ b/arch/arm/mach-omap2/board-rx51-video.c @@ -15,13 +15,14 @@ #include <linux/spi/spi.h> #include <linux/mm.h> #include <asm/mach-types.h> -#include <video/omapdss.h> +#include <linux/platform_data/omapdss.h> #include <video/omap-panel-data.h> #include <linux/platform_data/spi-omap2-mcspi.h> #include "soc.h" #include "board-rx51.h" +#include "display.h" #include "mux.h" @@ -32,7 +33,6 @@ static struct connector_atv_platform_data rx51_tv_pdata = { .name = "tv", .source = "venc.0", - .connector_type = OMAP_DSS_VENC_TYPE_COMPOSITE, .invert_polarity = false, }; diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 2da3b5ec010c..b79b1ca9aee9 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -465,10 +465,7 @@ int clkdm_complete_init(void) return -EACCES; list_for_each_entry(clkdm, &clkdm_list, node) { - if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) - clkdm_wakeup(clkdm); - else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO) - clkdm_deny_idle(clkdm); + clkdm_deny_idle(clkdm); _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs); clkdm_clear_all_wkdeps(clkdm); @@ -925,11 +922,20 @@ void clkdm_allow_idle_nolock(struct clockdomain *clkdm) if (!clkdm) return; - if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) { - pr_debug("clock: %s: automatic idle transitions cannot be enabled\n", - clkdm->name); + if (!WARN_ON(!clkdm->forcewake_count)) + clkdm->forcewake_count--; + + if (clkdm->forcewake_count) + return; + + if (!clkdm->usecount && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) + clkdm_sleep_nolock(clkdm); + + if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) + return; + + if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) return; - } if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle) return; @@ -974,11 +980,17 @@ void clkdm_deny_idle_nolock(struct clockdomain *clkdm) if (!clkdm) return; - if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) { - pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n", - clkdm->name); + if (clkdm->forcewake_count++) + return; + + if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) + clkdm_wakeup_nolock(clkdm); + + if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) + return; + + if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) return; - } if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle) return; diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 2c398ce1a0f2..24667a5a9dc0 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -114,6 +114,7 @@ struct omap_hwmod; * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact * @usecount: Usecount tracking + * @forcewake_count: Usecount for forcing the domain active * @node: list_head to link all clockdomains together * * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only) @@ -138,6 +139,7 @@ struct clockdomain { struct clkdm_dep *wkdep_srcs; struct clkdm_dep *sleepdep_srcs; int usecount; + int forcewake_count; struct list_head node; }; diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 7b181f929525..c073fb57dd13 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -220,6 +220,9 @@ static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs, { int i = 0; + if (!clkctrl_offs) + return 0; + omap_test_timeout(_is_module_ready(inst, clkctrl_offs), MAX_MODULE_READY_TIME, i); diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 187fa4386718..d91ae8206d1e 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -649,7 +649,7 @@ void omap3_cm_save_scratchpad_contents(u32 *ptr) /* * As per erratum i671, ROM code does not respect the PER DPLL * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. - * Then, in anycase, clear these bits to avoid extra latencies. + * Then, in any case, clear these bits to avoid extra latencies. */ *ptr++ = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & ~OMAP3430_AUTO_PERIPH_DPLL_MASK; diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index f7666b9f3b21..deed42e1dd9c 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -257,18 +257,22 @@ extern void gic_dist_enable(void); extern bool gic_dist_disabled(void); extern void gic_timer_retrigger(void); extern void omap_smc1(u32 fn, u32 arg); +extern void omap4_sar_ram_init(void); extern void __iomem *omap4_get_sar_ram_base(void); +extern void omap4_mpuss_early_init(void); extern void omap_do_wfi(void); -#ifdef CONFIG_SMP -/* Needed for secondary core boot */ extern void omap4_secondary_startup(void); extern void omap4460_secondary_startup(void); + +#ifdef CONFIG_SMP +/* Needed for secondary core boot */ extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); extern u32 omap_read_auxcoreboot0(void); extern void omap4_cpu_die(unsigned int cpu); +extern int omap4_cpu_kill(unsigned int cpu); extern const struct smp_operations omap4_smp_ops; diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 4b8e9f4d59ea..fa138d4032b6 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -140,7 +140,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, mpuss_can_lose_context) gic_dist_disable(); - clkdm_wakeup(cpu_clkdm[1]); + clkdm_deny_idle(cpu_clkdm[1]); omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); clkdm_allow_idle(cpu_clkdm[1]); diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 6ab13d18c636..70b3eaf085e4 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -29,7 +29,7 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> -#include <video/omapdss.h> +#include <linux/platform_data/omapdss.h> #include "omap_hwmod.h" #include "omap_device.h" #include "omap-pm.h" diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h index 7375854b16c7..78f253005279 100644 --- a/arch/arm/mach-omap2/display.h +++ b/arch/arm/mach-omap2/display.h @@ -33,4 +33,9 @@ int omap_init_vout(void); struct device_node * __init omapdss_find_dss_of_node(void); +struct omap_dss_board_info; + +/* Init with the board info */ +int omap_display_init(struct omap_dss_board_info *board_data); + #endif diff --git a/arch/arm/mach-omap2/dss-common.c b/arch/arm/mach-omap2/dss-common.c index ea2be0f5953b..1d583bc0b1a9 100644 --- a/arch/arm/mach-omap2/dss-common.c +++ b/arch/arm/mach-omap2/dss-common.c @@ -27,7 +27,7 @@ #include <linux/gpio.h> #include <linux/platform_device.h> -#include <video/omapdss.h> +#include <linux/platform_data/omapdss.h> #include <video/omap-panel-data.h> #include "soc.h" diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 49de4dd227be..0e9acdd95d70 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -690,6 +690,8 @@ void __init omap4430_init_early(void) omap4xxx_check_revision(); omap4xxx_check_features(); omap2_prcm_base_init(); + omap4_sar_ram_init(); + omap4_mpuss_early_init(); omap4_pm_init_early(); omap44xx_voltagedomains_init(); omap44xx_powerdomains_init(); @@ -718,6 +720,7 @@ void __init omap5_init_early(void) omap4_pm_init_early(); omap2_prcm_base_init(); omap5xxx_check_revision(); + omap4_sar_ram_init(); omap54xx_voltagedomains_init(); omap54xx_powerdomains_init(); omap54xx_clockdomains_init(); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index b4ac3af1160c..fc04be74e064 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -34,18 +34,24 @@ #include "cm3xxx.h" #include "cm-regbits-34xx.h" -static struct clk *mcbsp_iclks[5]; - -static int omap3_enable_st_clock(unsigned int id, bool enable) +static int omap3_mcbsp_force_ick_on(struct clk *clk, bool force_on) { - /* - * Sidetone uses McBSP ICLK - which must not idle when sidetones - * are enabled or sidetones start sounding ugly. - */ - if (enable) - return omap2_clk_deny_idle(mcbsp_iclks[id]); + if (!clk) + return 0; + + if (force_on) + return omap2_clk_deny_idle(clk); else - return omap2_clk_allow_idle(mcbsp_iclks[id]); + return omap2_clk_allow_idle(clk); +} + +void __init omap3_mcbsp_init_pdata_callback( + struct omap_mcbsp_platform_data *pdata) +{ + if (!pdata) + return; + + pdata->force_ick_on = omap3_mcbsp_force_ick_on; } static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) @@ -55,7 +61,6 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) struct omap_hwmod *oh_device[2]; struct omap_mcbsp_platform_data *pdata = NULL; struct platform_device *pdev; - char clk_name[11]; sscanf(oh->name, "mcbsp%d", &id); @@ -96,9 +101,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) if (oh->dev_attr) { oh_device[1] = omap_hwmod_lookup(( (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); - pdata->enable_st_clock = omap3_enable_st_clock; - sprintf(clk_name, "mcbsp%d_ick", id); - mcbsp_iclks[id] = clk_get(NULL, clk_name); + pdata->force_ick_on = omap3_mcbsp_force_ick_on; count++; } pdev = omap_device_build_ss(name, id, oh_device, count, pdata, diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c index be271f1d585b..393e687f99e2 100644 --- a/arch/arm/mach-omap2/mux34xx.c +++ b/arch/arm/mach-omap2/mux34xx.c @@ -1266,7 +1266,7 @@ static struct omap_ball __initdata omap3_cus_ball[] = { #endif /* - * Signals different on CBB package comapared to superset + * Signals different on CBB package compared to superset */ #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB) static struct omap_mux __initdata omap3_cbb_subset[] = { @@ -1597,7 +1597,7 @@ static struct omap_ball __initdata omap3_cbb_ball[] = { #endif /* - * Signals different on 36XX CBP package comapared to 34XX CBC package + * Signals different on 36XX CBP package compared to 34XX CBC package */ #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP) static struct omap_mux __initdata omap36xx_cbp_subset[] = { diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 6d1dffca6c7b..fe36ce2734d4 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -24,6 +24,16 @@ #define AUX_CORE_BOOT0_PA 0x48281800 #define API_HYP_ENTRY 0x102 +ENTRY(omap_secondary_startup) +#ifdef CONFIG_SMP + b secondary_startup +#else +/* Should never get here */ +again: wfi + b again +#endif +#ENDPROC(omap_secondary_startup) + /* * OMAP5 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which @@ -39,7 +49,7 @@ wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 and r4, r4, #0x0f cmp r0, r4 bne wait - b secondary_startup + b omap_secondary_startup ENDPROC(omap5_secondary_startup) /* * Same as omap5_secondary_startup except we call into the ROM to @@ -59,7 +69,7 @@ wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0 adr r0, hyp_boot smc #0 hyp_boot: - b secondary_startup + b omap_secondary_startup ENDPROC(omap5_secondary_hyp_startup) /* * OMAP4 specific entry point for secondary CPU to jump from ROM @@ -82,7 +92,7 @@ hold: ldr r12,=0x103 * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ - b secondary_startup + b omap_secondary_startup ENDPROC(omap4_secondary_startup) ENTRY(omap4460_secondary_startup) @@ -119,5 +129,5 @@ hold_2: ldr r12,=0x103 * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ - b secondary_startup + b omap_secondary_startup ENDPROC(omap4460_secondary_startup) diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 593fec753b28..d3fb5661bb5d 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -64,3 +64,9 @@ void omap4_cpu_die(unsigned int cpu) pr_debug("CPU%u: spurious wakeup call\n", cpu); } } + +/* Needed by kexec and platform_can_cpu_hotplug() */ +int omap4_cpu_kill(unsigned int cpu) +{ + return 1; +} diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 65024af169d3..ad982465efd0 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -62,7 +62,9 @@ #include "prm44xx.h" #include "prm-regbits-44xx.h" -#ifdef CONFIG_SMP +static void __iomem *sar_base; + +#if defined(CONFIG_PM) && defined(CONFIG_SMP) struct omap4_cpu_pm_info { struct powerdomain *pwrdm; @@ -90,7 +92,6 @@ struct cpu_pm_ops { static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); static struct powerdomain *mpuss_pd; -static void __iomem *sar_base; static u32 cpu_context_offset; static int default_finish_suspend(unsigned long cpu_state) @@ -366,9 +367,6 @@ int __init omap4_mpuss_init(void) return -ENODEV; } - if (cpu_is_omap44xx()) - sar_base = omap4_get_sar_ram_base(); - /* Initilaise per CPU PM information */ pm_info = &per_cpu(omap4_pm_info, 0x0); if (sar_base) { @@ -444,3 +442,26 @@ int __init omap4_mpuss_init(void) } #endif + +/* + * For kexec, we must set CPU1_WAKEUP_NS_PA_ADDR to point to + * current kernel's secondary_startup() early before + * clockdomains_init(). Otherwise clockdomain_init() can + * wake CPU1 and cause a hang. + */ +void __init omap4_mpuss_early_init(void) +{ + unsigned long startup_pa; + + if (!cpu_is_omap44xx()) + return; + + sar_base = omap4_get_sar_ram_base(); + + if (cpu_is_omap443x()) + startup_pa = virt_to_phys(omap4_secondary_startup); + else + startup_pa = virt_to_phys(omap4460_secondary_startup); + + writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET); +} diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 8cd1de914ee4..b4de3da6dffa 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -40,14 +40,35 @@ #define OMAP5_CORE_COUNT 0x2 -/* SCU base address */ -static void __iomem *scu_base; +struct omap_smp_config { + unsigned long cpu1_rstctrl_pa; + void __iomem *cpu1_rstctrl_va; + void __iomem *scu_base; + void *startup_addr; +}; + +static struct omap_smp_config cfg; + +static const struct omap_smp_config omap443x_cfg __initconst = { + .cpu1_rstctrl_pa = 0x4824380c, + .startup_addr = omap4_secondary_startup, +}; + +static const struct omap_smp_config omap446x_cfg __initconst = { + .cpu1_rstctrl_pa = 0x4824380c, + .startup_addr = omap4460_secondary_startup, +}; + +static const struct omap_smp_config omap5_cfg __initconst = { + .cpu1_rstctrl_pa = 0x48243810, + .startup_addr = omap5_secondary_startup, +}; static DEFINE_SPINLOCK(boot_lock); void __iomem *omap4_get_scu_base(void) { - return scu_base; + return cfg.scu_base; } #ifdef CONFIG_OMAP5_ERRATA_801819 @@ -93,7 +114,7 @@ static void omap4_secondary_init(unsigned int cpu) * OMAP443X GP devices- SMP bit isn't accessible. * OMAP446X GP devices - SMP bit access is enabled on both CPUs. */ - if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) + if (soc_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, 4, 0, 0, 0, 0, 0); @@ -179,7 +200,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) * Ensure that CPU power state is set to ON to avoid CPU * powerdomain transition on wfi */ - clkdm_wakeup_nolock(cpu1_clkdm); + clkdm_deny_idle_nolock(cpu1_clkdm); pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON); clkdm_allow_idle_nolock(cpu1_clkdm); @@ -222,9 +243,9 @@ static void __init omap4_smp_init_cpus(void) * Currently we can't call ioremap here because * SoC detection won't work until after init_early. */ - scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base()); - BUG_ON(!scu_base); - ncores = scu_get_core_count(scu_base); + cfg.scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base()); + BUG_ON(!cfg.scu_base); + ncores = scu_get_core_count(cfg.scu_base); } else if (cpu_id == CPU_CORTEX_A15) { ncores = OMAP5_CORE_COUNT; } @@ -242,20 +263,51 @@ static void __init omap4_smp_init_cpus(void) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { - void *startup_addr = omap4_secondary_startup; void __iomem *base = omap_get_wakeupgen_base(); + const struct omap_smp_config *c = NULL; + + if (soc_is_omap443x()) + c = &omap443x_cfg; + else if (soc_is_omap446x()) + c = &omap446x_cfg; + else if (soc_is_dra74x() || soc_is_omap54xx()) + c = &omap5_cfg; + + if (!c) { + pr_err("%s Unknown SMP SoC?\n", __func__); + return; + } + + /* Must preserve cfg.scu_base set earlier */ + cfg.cpu1_rstctrl_pa = c->cpu1_rstctrl_pa; + cfg.startup_addr = c->startup_addr; + + if (soc_is_dra74x() || soc_is_omap54xx()) { + if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) + cfg.startup_addr = omap5_secondary_hyp_startup; + omap5_erratum_workaround_801819(); + } + + cfg.cpu1_rstctrl_va = ioremap(cfg.cpu1_rstctrl_pa, 4); + if (!cfg.cpu1_rstctrl_va) + return; /* * Initialise the SCU and wake up the secondary core using * wakeup_secondary(). */ - if (scu_base) - scu_enable(scu_base); + if (cfg.scu_base) + scu_enable(cfg.scu_base); - if (cpu_is_omap446x()) - startup_addr = omap4460_secondary_startup; - if (soc_is_dra74x() || soc_is_omap54xx()) - omap5_erratum_workaround_801819(); + /* + * Reset CPU1 before configuring, otherwise kexec will + * end up trying to use old kernel startup address. + */ + if (cfg.cpu1_rstctrl_va) { + writel_relaxed(1, cfg.cpu1_rstctrl_va); + readl_relaxed(cfg.cpu1_rstctrl_va); + writel_relaxed(0, cfg.cpu1_rstctrl_va); + } /* * Write the address of secondary startup routine into the @@ -264,19 +316,10 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) * A barrier is added to ensure that write buffer is drained */ if (omap_secure_apis_support()) - omap_auxcoreboot_addr(virt_to_phys(startup_addr)); + omap_auxcoreboot_addr(virt_to_phys(cfg.startup_addr)); else - /* - * If the boot CPU is in HYP mode then start secondary - * CPU in HYP mode as well. - */ - if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) - writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup), - base + OMAP_AUX_CORE_BOOT_1); - else - writel_relaxed(virt_to_phys(omap5_secondary_startup), - base + OMAP_AUX_CORE_BOOT_1); - + writel_relaxed(virt_to_phys(cfg.startup_addr), + base + OMAP_AUX_CORE_BOOT_1); } const struct smp_operations omap4_smp_ops __initconst = { @@ -286,5 +329,6 @@ const struct smp_operations omap4_smp_ops __initconst = { .smp_boot_secondary = omap4_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = omap4_cpu_die, + .cpu_kill = omap4_cpu_kill, #endif }; diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 949696b6f17b..cf65ab8bb004 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c @@ -61,7 +61,7 @@ static phys_addr_t dram_sync_paddr; static u32 dram_sync_size; /* - * The OMAP4 bus structure contains asynchrnous bridges which can buffer + * The OMAP4 bus structure contains asynchronous bridges which can buffer * data writes from the MPU. These asynchronous bridges can be found on * paths between the MPU to EMIF, and the MPU to L3 interconnects. * @@ -266,10 +266,11 @@ void __iomem *omap4_get_sar_ram_base(void) } /* - * SAR RAM used to save and restore the HW - * context in low power modes + * SAR RAM used to save and restore the HW context in low power modes. + * Note that we need to initialize this very early for kexec. See + * omap4_mpuss_early_init(). */ -static int __init omap4_sar_ram_init(void) +void __init omap4_sar_ram_init(void) { unsigned long sar_base; @@ -282,16 +283,13 @@ static int __init omap4_sar_ram_init(void) else if (soc_is_omap54xx()) sar_base = OMAP54XX_SAR_RAM_BASE; else - return -ENOMEM; + return; /* Static mapping, never released */ sar_ram_base = ioremap(sar_base, SZ_16K); if (WARN_ON(!sar_ram_base)) - return -ENOMEM; - - return 0; + return; } -omap_early_initcall(omap4_sar_ram_init); static const struct of_device_id intc_match[] = { { .compatible = "ti,omap4-wugen-mpu", }, diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index f7ff3b9dad87..c2626f83e0c2 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -63,7 +63,22 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, return; } - rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), clk_name, NULL); + r = clk_get_sys(NULL, clk_name); + + if (IS_ERR(r) && of_have_populated_dt()) { + struct of_phandle_args clkspec; + + clkspec.np = of_find_node_by_name(NULL, clk_name); + + r = of_clk_get_from_provider(&clkspec); + + rc = clk_register_clkdev(r, clk_alias, + dev_name(&od->pdev->dev)); + } else { + rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), + clk_name, NULL); + } + if (rc) { if (rc == -ENODEV || rc == -ENOMEM) dev_err(&od->pdev->dev, @@ -268,7 +283,7 @@ static int _omap_device_idle_hwmods(struct omap_device *od) * function returns a value different than the value the caller got * the last time it called this function. * - * If any hwmods exist for the omap_device assoiated with @pdev, + * If any hwmods exist for the omap_device associated with @pdev, * return the context loss counter for that hwmod, otherwise return * zero. */ diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 83cb527755a9..5b709383381c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -178,6 +178,11 @@ */ #define OMAP4_RST_CTRL_ST_OFFSET 4 +/* + * Maximum length for module clock handle names + */ +#define MOD_CLK_MAX_NAME_LEN 32 + /** * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations * @enable_module: function to enable a module (via MODULEMODE) @@ -200,6 +205,7 @@ struct omap_hwmod_soc_ops { int (*init_clkdm)(struct omap_hwmod *oh); void (*update_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh); + int (*disable_direct_prcm)(struct omap_hwmod *oh); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -776,17 +782,35 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) * @oh: struct omap_hwmod * * * Called from _init_clocks(). Populates the @oh _clk (main - * functional clock pointer) if a main_clk is present. Returns 0 on - * success or -EINVAL on error. + * functional clock pointer) if a clock matching the hwmod name is found, + * or a main_clk is present. Returns 0 on success or -EINVAL on error. */ static int _init_main_clk(struct omap_hwmod *oh) { int ret = 0; + char name[MOD_CLK_MAX_NAME_LEN]; + struct clk *clk; - if (!oh->main_clk) - return 0; + /* +7 magic comes from '_mod_ck' suffix */ + if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN) + pr_warn("%s: warning: cropping name for %s\n", __func__, + oh->name); + + strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7); + strcat(name, "_mod_ck"); + + clk = clk_get(NULL, name); + if (!IS_ERR(clk)) { + oh->_clk = clk; + soc_ops.disable_direct_prcm(oh); + oh->main_clk = kstrdup(name, GFP_KERNEL); + } else { + if (!oh->main_clk) + return 0; + + oh->_clk = clk_get(NULL, oh->main_clk); + } - oh->_clk = clk_get(NULL, oh->main_clk); if (IS_ERR(oh->_clk)) { pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n", oh->name, oh->main_clk); @@ -1678,7 +1702,6 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) { struct omap_hwmod_rst_info ohri; int ret = -EINVAL; - int hwsup = 0; if (!oh) return -EINVAL; @@ -1696,7 +1719,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) * might not be completed. The clockdomain can be set * in HW_AUTO only when the module become ready. */ - hwsup = clkdm_in_hwsup(oh->clkdm); + clkdm_deny_idle(oh->clkdm); ret = clkdm_hwmod_enable(oh->clkdm, oh); if (ret) { WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n", @@ -1723,8 +1746,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) * Set the clockdomain to HW_AUTO, assuming that the * previous state was HW_AUTO. */ - if (hwsup) - clkdm_allow_idle(oh->clkdm); + clkdm_allow_idle(oh->clkdm); clkdm_hwmod_disable(oh->clkdm, oh); } @@ -2078,7 +2100,6 @@ static int _enable_preprogram(struct omap_hwmod *oh) static int _enable(struct omap_hwmod *oh) { int r; - int hwsup = 0; pr_debug("omap_hwmod: %s: enabling\n", oh->name); @@ -2138,8 +2159,7 @@ static int _enable(struct omap_hwmod *oh) * completely the module. The clockdomain can be set * in HW_AUTO only when the module become ready. */ - hwsup = clkdm_in_hwsup(oh->clkdm) && - !clkdm_missing_idle_reporting(oh->clkdm); + clkdm_deny_idle(oh->clkdm); r = clkdm_hwmod_enable(oh->clkdm, oh); if (r) { WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n", @@ -2159,14 +2179,10 @@ static int _enable(struct omap_hwmod *oh) r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : -EINVAL; - if (!r) { - /* - * Set the clockdomain to HW_AUTO only if the target is ready, - * assuming that the previous state was HW_AUTO - */ - if (oh->clkdm && hwsup) - clkdm_allow_idle(oh->clkdm); + if (oh->clkdm) + clkdm_allow_idle(oh->clkdm); + if (!r) { oh->_state = _HWMOD_STATE_ENABLED; /* Access the sysconfig only if the target is ready */ @@ -2220,6 +2236,9 @@ static int _idle(struct omap_hwmod *oh) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); + if (oh->clkdm) + clkdm_deny_idle(oh->clkdm); + if (oh->flags & HWMOD_BLOCK_WFI) cpu_idle_poll_ctrl(false); if (soc_ops.disable_module) @@ -2232,8 +2251,10 @@ static int _idle(struct omap_hwmod *oh) * transition to complete properly. */ _disable_clocks(oh); - if (oh->clkdm) + if (oh->clkdm) { + clkdm_allow_idle(oh->clkdm); clkdm_hwmod_disable(oh->clkdm, oh); + } /* Mux pins for device idle if populated */ if (oh->mux && oh->mux->pads_dynamic) { @@ -3091,6 +3112,25 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh, } /** + * _omap4_disable_direct_prcm - disable direct PRCM control for hwmod + * @oh: struct omap_hwmod * to disable control for + * + * Disables direct PRCM clkctrl done by hwmod core. Instead, the hwmod + * will be using its main_clk to enable/disable the module. Returns + * 0 if successful. + */ +static int _omap4_disable_direct_prcm(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + oh->prcm.omap4.clkctrl_offs = 0; + oh->prcm.omap4.modulemode = 0; + + return 0; +} + +/** * _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args * @oh: struct omap_hwmod * to deassert hardreset * @ohri: hardreset line data @@ -3913,6 +3953,7 @@ void __init omap_hwmod_init(void) soc_ops.init_clkdm = _init_clkdm; soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; + soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) { soc_ops.enable_module = _omap4_enable_module; @@ -3922,6 +3963,7 @@ void __init omap_hwmod_init(void) soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; soc_ops.init_clkdm = _init_clkdm; + soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; } else { WARN(1, "omap_hwmod: unknown SoC type\n"); } diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h index 7f737965f543..d3e61d1a02d7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -36,17 +36,8 @@ extern struct omap_hwmod_ocp_if am33xx_l4_per__gpio3; extern struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio; extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm; extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0; -extern struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0; -extern struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0; -extern struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0; extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1; -extern struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1; -extern struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1; -extern struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1; extern struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2; -extern struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2; -extern struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2; -extern struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2; extern struct omap_hwmod_ocp_if am33xx_l3_s__gpmc; extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c2; extern struct omap_hwmod_ocp_if am33xx_l4_per__i2c3; @@ -98,17 +89,8 @@ extern struct omap_hwmod am33xx_dcan0_hwmod; extern struct omap_hwmod am33xx_dcan1_hwmod; extern struct omap_hwmod am33xx_elm_hwmod; extern struct omap_hwmod am33xx_epwmss0_hwmod; -extern struct omap_hwmod am33xx_ecap0_hwmod; -extern struct omap_hwmod am33xx_eqep0_hwmod; -extern struct omap_hwmod am33xx_ehrpwm0_hwmod; extern struct omap_hwmod am33xx_epwmss1_hwmod; -extern struct omap_hwmod am33xx_ecap1_hwmod; -extern struct omap_hwmod am33xx_eqep1_hwmod; -extern struct omap_hwmod am33xx_ehrpwm1_hwmod; extern struct omap_hwmod am33xx_epwmss2_hwmod; -extern struct omap_hwmod am33xx_ecap2_hwmod; -extern struct omap_hwmod am33xx_eqep2_hwmod; -extern struct omap_hwmod am33xx_ehrpwm2_hwmod; extern struct omap_hwmod am33xx_gpio1_hwmod; extern struct omap_hwmod am33xx_gpio2_hwmod; extern struct omap_hwmod am33xx_gpio3_hwmod; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c index 1c210cb2b8c1..10dff2f0086a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_interconnect_data.c @@ -176,28 +176,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_ecap0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_eqep0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = { - .master = &am33xx_epwmss0_hwmod, - .slave = &am33xx_ehrpwm0_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - - static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = { { .pa_start = 0x48302000, @@ -215,27 +193,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_ecap1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_eqep1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = { - .master = &am33xx_epwmss1_hwmod, - .slave = &am33xx_ehrpwm1_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = { { .pa_start = 0x48304000, @@ -253,27 +210,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_ecap2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_eqep2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - -struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = { - .master = &am33xx_epwmss2_hwmod, - .slave = &am33xx_ehrpwm2_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - /* l3s cfg -> gpmc */ struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = { .master = &am33xx_l3_s_hwmod, 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 aed33621deeb..55c5878577f4 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 @@ -449,18 +449,6 @@ struct omap_hwmod_class am33xx_epwmss_hwmod_class = { .sysc = &am33xx_epwmss_sysc, }; -static struct omap_hwmod_class am33xx_ecap_hwmod_class = { - .name = "ecap", -}; - -static struct omap_hwmod_class am33xx_eqep_hwmod_class = { - .name = "eqep", -}; - -struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = { - .name = "ehrpwm", -}; - /* epwmss0 */ struct omap_hwmod am33xx_epwmss0_hwmod = { .name = "epwmss0", @@ -474,30 +462,6 @@ struct omap_hwmod am33xx_epwmss0_hwmod = { }, }; -/* ecap0 */ -struct omap_hwmod am33xx_ecap0_hwmod = { - .name = "ecap0", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep0 */ -struct omap_hwmod am33xx_eqep0_hwmod = { - .name = "eqep0", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm0 */ -struct omap_hwmod am33xx_ehrpwm0_hwmod = { - .name = "ehrpwm0", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - /* epwmss1 */ struct omap_hwmod am33xx_epwmss1_hwmod = { .name = "epwmss1", @@ -511,30 +475,6 @@ struct omap_hwmod am33xx_epwmss1_hwmod = { }, }; -/* ecap1 */ -struct omap_hwmod am33xx_ecap1_hwmod = { - .name = "ecap1", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep1 */ -struct omap_hwmod am33xx_eqep1_hwmod = { - .name = "eqep1", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm1 */ -struct omap_hwmod am33xx_ehrpwm1_hwmod = { - .name = "ehrpwm1", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - /* epwmss2 */ struct omap_hwmod am33xx_epwmss2_hwmod = { .name = "epwmss2", @@ -548,30 +488,6 @@ struct omap_hwmod am33xx_epwmss2_hwmod = { }, }; -/* ecap2 */ -struct omap_hwmod am33xx_ecap2_hwmod = { - .name = "ecap2", - .class = &am33xx_ecap_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* eqep2 */ -struct omap_hwmod am33xx_eqep2_hwmod = { - .name = "eqep2", - .class = &am33xx_eqep_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - -/* ehrpwm2 */ -struct omap_hwmod am33xx_ehrpwm2_hwmod = { - .name = "ehrpwm2", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - /* * 'gpio' class: for gpio 0,1,2,3 */ @@ -1476,6 +1392,7 @@ static void omap_hwmod_am43xx_rst(void) { RSTCTRL(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTCTRL_OFFSET); RSTCTRL(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTCTRL_OFFSET); + RSTST(am33xx_pruss_hwmod, AM43XX_RM_PER_RSTST_OFFSET); RSTST(am33xx_gfx_hwmod, AM43XX_RM_GFX_RSTST_OFFSET); } diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index cc0791d9125b..e1c2025d6d3e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -593,17 +593,8 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_ls__spinlock, &am33xx_l4_ls__elm, &am33xx_l4_ls__epwmss0, - &am33xx_epwmss0__ecap0, - &am33xx_epwmss0__eqep0, - &am33xx_epwmss0__ehrpwm0, &am33xx_l4_ls__epwmss1, - &am33xx_epwmss1__ecap1, - &am33xx_epwmss1__eqep1, - &am33xx_epwmss1__ehrpwm1, &am33xx_l4_ls__epwmss2, - &am33xx_epwmss2__ecap2, - &am33xx_epwmss2__eqep2, - &am33xx_epwmss2__ehrpwm2, &am33xx_l3_s__gpmc, &am33xx_l3_main__lcdc, &am33xx_l4_ls__mcspi0, diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 9869a75c5d96..d72ee6185d5e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1322,16 +1322,8 @@ static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = { .name = "mcbsp2_sidetone", .class = &omap3xxx_mcbsp_sidetone_hwmod_class, .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs, - .main_clk = "mcbsp2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, - .module_bit = OMAP3430_EN_MCBSP2_SHIFT, - .module_offs = OMAP3430_PER_MOD, - .idlest_reg_id = 1, - .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, - }, - }, + .main_clk = "mcbsp2_ick", + .flags = HWMOD_NO_IDLEST, }; /* mcbsp3_sidetone */ @@ -1344,16 +1336,8 @@ static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = { .name = "mcbsp3_sidetone", .class = &omap3xxx_mcbsp_sidetone_hwmod_class, .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs, - .main_clk = "mcbsp3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, - .module_bit = OMAP3430_EN_MCBSP3_SHIFT, - .module_offs = OMAP3430_PER_MOD, - .idlest_reg_id = 1, - .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, - }, - }, + .main_clk = "mcbsp3_ick", + .flags = HWMOD_NO_IDLEST, }; /* SR common */ diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index 97fd399202dc..61f2f301d739 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -202,13 +202,6 @@ static struct omap_hwmod am43xx_epwmss3_hwmod = { }, }; -static struct omap_hwmod am43xx_ehrpwm3_hwmod = { - .name = "ehrpwm3", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - static struct omap_hwmod am43xx_epwmss4_hwmod = { .name = "epwmss4", .class = &am33xx_epwmss_hwmod_class, @@ -222,13 +215,6 @@ static struct omap_hwmod am43xx_epwmss4_hwmod = { }, }; -static struct omap_hwmod am43xx_ehrpwm4_hwmod = { - .name = "ehrpwm4", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - static struct omap_hwmod am43xx_epwmss5_hwmod = { .name = "epwmss5", .class = &am33xx_epwmss_hwmod_class, @@ -242,13 +228,6 @@ static struct omap_hwmod am43xx_epwmss5_hwmod = { }, }; -static struct omap_hwmod am43xx_ehrpwm5_hwmod = { - .name = "ehrpwm5", - .class = &am33xx_ehrpwm_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .main_clk = "l4ls_gclk", -}; - static struct omap_hwmod am43xx_spi2_hwmod = { .name = "spi2", .class = &am33xx_spi_hwmod_class, @@ -744,13 +723,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_ocp_if am43xx_epwmss3__ehrpwm3 = { - .master = &am43xx_epwmss3_hwmod, - .slave = &am43xx_ehrpwm3_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = { .master = &am33xx_l4_ls_hwmod, .slave = &am43xx_epwmss4_hwmod, @@ -758,13 +730,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_ocp_if am43xx_epwmss4__ehrpwm4 = { - .master = &am43xx_epwmss4_hwmod, - .slave = &am43xx_ehrpwm4_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = { .master = &am33xx_l4_ls_hwmod, .slave = &am43xx_epwmss5_hwmod, @@ -772,13 +737,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_ocp_if am43xx_epwmss5__ehrpwm5 = { - .master = &am43xx_epwmss5_hwmod, - .slave = &am43xx_ehrpwm5_hwmod, - .clk = "l4ls_gclk", - .user = OCP_USER_MPU, -}; - static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = { .master = &am33xx_l4_ls_hwmod, .slave = &am43xx_spi2_hwmod, @@ -919,11 +877,8 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am43xx_l4_ls__timer10, &am43xx_l4_ls__timer11, &am43xx_l4_ls__epwmss3, - &am43xx_epwmss3__ehrpwm3, &am43xx_l4_ls__epwmss4, - &am43xx_epwmss4__ehrpwm4, &am43xx_l4_ls__epwmss5, - &am43xx_epwmss5__ehrpwm5, &am43xx_l4_ls__mcspi2, &am43xx_l4_ls__mcspi3, &am43xx_l4_ls__mcspi4, @@ -982,17 +937,8 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_ls__spinlock, &am33xx_l4_ls__elm, &am33xx_l4_ls__epwmss0, - &am33xx_epwmss0__ecap0, - &am33xx_epwmss0__eqep0, - &am33xx_epwmss0__ehrpwm0, &am33xx_l4_ls__epwmss1, - &am33xx_epwmss1__ecap1, - &am33xx_epwmss1__eqep1, - &am33xx_epwmss1__ehrpwm1, &am33xx_l4_ls__epwmss2, - &am33xx_epwmss2__ecap2, - &am33xx_epwmss2__eqep2, - &am33xx_epwmss2__ehrpwm2, &am33xx_l3_s__gpmc, &am33xx_l4_ls__mcspi0, &am33xx_l4_ls__mcspi1, diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index d0e7e5259ec3..1ab7096af8e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -2905,58 +2905,27 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc1 = { .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = { - { - .name = "family", - .pa_start = 0x58000000, - .pa_end = 0x5800007f, - .flags = ADDR_TYPE_RT - }, -}; - /* l3_main_1 -> dss */ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dss = { .master = &dra7xx_l3_main_1_hwmod, .slave = &dra7xx_dss_hwmod, .clk = "l3_iclk_div", - .addr = dra7xx_dss_addrs, .user = OCP_USER_MPU | OCP_USER_SDMA, }; -static struct omap_hwmod_addr_space dra7xx_dss_dispc_addrs[] = { - { - .name = "dispc", - .pa_start = 0x58001000, - .pa_end = 0x58001fff, - .flags = ADDR_TYPE_RT - }, -}; - /* l3_main_1 -> dispc */ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__dispc = { .master = &dra7xx_l3_main_1_hwmod, .slave = &dra7xx_dss_dispc_hwmod, .clk = "l3_iclk_div", - .addr = dra7xx_dss_dispc_addrs, .user = OCP_USER_MPU | OCP_USER_SDMA, }; -static struct omap_hwmod_addr_space dra7xx_dss_hdmi_addrs[] = { - { - .name = "hdmi_wp", - .pa_start = 0x58040000, - .pa_end = 0x580400ff, - .flags = ADDR_TYPE_RT - }, - { } -}; - /* l3_main_1 -> dispc */ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = { .master = &dra7xx_l3_main_1_hwmod, .slave = &dra7xx_dss_hdmi_hwmod, .clk = "l3_iclk_div", - .addr = dra7xx_dss_hdmi_addrs, .user = OCP_USER_MPU | OCP_USER_SDMA, }; @@ -3410,21 +3379,11 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; -static struct omap_hwmod_addr_space dra7xx_qspi_addrs[] = { - { - .pa_start = 0x4b300000, - .pa_end = 0x4b30007f, - .flags = ADDR_TYPE_RT - }, - { } -}; - /* l3_main_1 -> qspi */ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__qspi = { .master = &dra7xx_l3_main_1_hwmod, .slave = &dra7xx_qspi_hwmod, .clk = "l3_iclk_div", - .addr = dra7xx_qspi_addrs, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index df8327713d06..b82b77cff24c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -243,7 +243,7 @@ static struct omap_hwmod_class ti81xx_rtc_hwmod_class = { .sysc = &ti81xx_rtc_sysc, }; -struct omap_hwmod ti81xx_rtc_hwmod = { +static struct omap_hwmod ti81xx_rtc_hwmod = { .name = "rtc", .class = &ti81xx_rtc_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 6571ad959908..ab2b2b2b90e5 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -26,6 +26,7 @@ #include <linux/platform_data/wkup_m3.h> #include <linux/platform_data/pwm_omap_dmtimer.h> #include <linux/platform_data/media/ir-rx51.h> +#include <linux/platform_data/asoc-ti-mcbsp.h> #include <plat/dmtimer.h> #include "common.h" @@ -505,6 +506,16 @@ static struct platform_device __maybe_unused rx51_lirc_device = { }, }; +#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP) +static struct omap_mcbsp_platform_data mcbsp_pdata; +static void __init omap3_mcbsp_init(void) +{ + omap3_mcbsp_init_pdata_callback(&mcbsp_pdata); +} +#else +static void __init omap3_mcbsp_init(void) {} +#endif + /* * Few boards still need auxdata populated before we populate * the dev entries in of_platform_populate(). @@ -536,6 +547,11 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", &am35xx_emac_pdata), + /* McBSP modules with sidetone core */ +#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP) + OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49022000, "49022000.mcbsp", &mcbsp_pdata), + OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49024000, "49024000.mcbsp", &mcbsp_pdata), +#endif #endif #ifdef CONFIG_SOC_AM33XX OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3", @@ -608,6 +624,8 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table) of_machine_is_compatible("ti,omap3")) omap_sdrc_init(NULL, NULL); + if (of_machine_is_compatible("ti,omap3")) + omap3_mcbsp_init(); pdata_quirks_check(auxdata_quirks); of_platform_populate(NULL, omap_dt_match_table, omap_auxdata_lookup, NULL); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 2f7b11da7d5d..678d2a31dcb8 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -110,13 +110,7 @@ static void __init omap2_init_processor_devices(void) int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) { - /* XXX The usecount test is racy */ - if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && - !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) - clkdm_allow_idle(clkdm); - else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && - clkdm->usecount == 0) - clkdm_sleep(clkdm); + clkdm_allow_idle(clkdm); return 0; } diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index daf2753de7aa..76eb6ec5f157 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -223,7 +223,6 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) * @pwrdm: struct powerdomain * to operate on * @curr_pwrst: current power state of @pwrdm * @pwrst: power state to switch to - * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised * * Determine whether the powerdomain needs to be turned on before * attempting to switch power states. Called by @@ -234,8 +233,7 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) * "Types of sleep_switch" comment above). */ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, - u8 curr_pwrst, u8 pwrst, - bool *hwsup) + u8 curr_pwrst, u8 pwrst) { u8 sleep_switch; @@ -245,8 +243,7 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, arch_pwrdm->pwrdm_set_lowpwrstchange) { sleep_switch = LOWPOWERSTATE_SWITCH; } else { - *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); - clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]); + clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]); sleep_switch = FORCEWAKEUP_SWITCH; } } else { @@ -260,7 +257,6 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change * @pwrdm: struct powerdomain * to operate on * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate() - * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode? * * Restore the clockdomain state perturbed by * _pwrdm_save_clkdm_state_and_activate(), and call the power state @@ -271,14 +267,11 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, * software-supervised sleep. No return value. */ static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, - u8 sleep_switch, bool hwsup) + u8 sleep_switch) { switch (sleep_switch) { case FORCEWAKEUP_SWITCH: - if (hwsup) - clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); - else - clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]); + clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); break; case LOWPOWERSTATE_SWITCH: if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && @@ -1093,7 +1086,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) u8 next_pwrst, sleep_switch; int curr_pwrst; int ret = 0; - bool hwsup = false; if (!pwrdm || IS_ERR(pwrdm)) return -EINVAL; @@ -1117,14 +1109,14 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) goto osps_out; sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, - pwrst, &hwsup); + pwrst); ret = pwrdm_set_next_pwrst(pwrdm, pwrst); if (ret) pr_err("%s: unable to set power state of powerdomain: %s\n", __func__, pwrdm->name); - _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup); + _pwrdm_restore_clkdm_state(pwrdm, sleep_switch); osps_out: pwrdm_unlock(pwrdm); diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h index 7c34c44eb0ae..babb5db5a3a4 100644 --- a/arch/arm/mach-omap2/prcm43xx.h +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -39,6 +39,7 @@ /* RM RSTST offsets */ #define AM43XX_RM_GFX_RSTST_OFFSET 0x0014 +#define AM43XX_RM_PER_RSTST_OFFSET 0x0014 #define AM43XX_RM_WKUP_RSTST_OFFSET 0x0014 /* CM instances */ diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 2bc4ec52ba78..66302c6aba61 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h @@ -52,8 +52,6 @@ /* PRM.PER_PRM register offsets */ #define AM33XX_RM_PER_RSTCTRL_OFFSET 0x0000 #define AM33XX_RM_PER_RSTCTRL AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0000) -#define AM33XX_RM_PER_RSTST_OFFSET 0x0004 -#define AM33XX_RM_PER_RSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0004) #define AM33XX_PM_PER_PWRSTST_OFFSET 0x0008 #define AM33XX_PM_PER_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_PER_MOD, 0x0008) #define AM33XX_PM_PER_PWRSTCTRL_OFFSET 0x000c diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index 645a2a46b213..f11500612983 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h @@ -175,8 +175,8 @@ u32 omap2xxx_sdrc_reprogram(u32 level, u32 force); * don't adjust it down as your clock period increases the refresh interval * will not be met. Setting all parameters for complete worst case may work, * but may cut memory performance by 2x. Due to errata the DLLs need to be - * unlocked and their value needs run time calibration. A dynamic call is - * need for that as no single right value exists acorss production samples. + * unlocked and their value needs run time calibration. A dynamic call is + * need for that as no single right value exists across production samples. * * Only the FULL speed values are given. Current code is such that rate * changes must be made at DPLLoutx2. The actual value adjustment for low diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index cb9497a20fb3..5e2e2218a402 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -289,6 +289,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (!timer->io_base) return -ENXIO; + omap_hwmod_setup_one(oh_name); + /* After the dmtimer is using hwmod these clocks won't be needed */ timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) @@ -303,7 +305,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, clk_put(src); - omap_hwmod_setup_one(oh_name); omap_hwmod_enable(oh); __omap_dm_timer_init_regs(timer); diff --git a/arch/arm/mach-oxnas/Kconfig b/arch/arm/mach-oxnas/Kconfig index 2dde0acf01fd..567496bd250a 100644 --- a/arch/arm/mach-oxnas/Kconfig +++ b/arch/arm/mach-oxnas/Kconfig @@ -11,10 +11,10 @@ if ARCH_OXNAS config MACH_OX810SE bool "Support OX810SE Based Products" - select ARM_TIMER_SP804 select COMMON_CLK_OXNAS select CPU_ARM926T select MFD_SYSCON + select OXNAS_RPS_TIMER select PINCTRL_OXNAS select RESET_OXNAS select VERSATILE_FPGA_IRQ diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index 73494500b51c..46ed10a807f0 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -23,4 +23,8 @@ config ARCH_MSM8974 bool "Enable support for MSM8974" select HAVE_ARM_ARCH_TIMER +config ARCH_MDM9615 + bool "Enable support for MDM9615" + select CLKSRC_QCOM + endif diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c index 6d8bbf7d39d8..d8060dfd1a21 100644 --- a/arch/arm/mach-qcom/board.c +++ b/arch/arm/mach-qcom/board.c @@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = { "qcom,ipq8064", "qcom,msm8660-surf", "qcom,msm8960-cdp", + "qcom,mdm9615", NULL }; diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 936a63fc68d5..e0e1a729ef98 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -43,6 +43,7 @@ #include <plat/samsung-time.h> #include "common.h" +#include "mach-smartq.h" #include "regs-modem.h" #define UCON S3C2410_UCON_DEFAULT diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 108ae2b41819..4a48c9f5f725 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -86,6 +86,10 @@ config ARCH_R8A7791 select ARCH_RCAR_GEN2 select I2C +config ARCH_R8A7792 + bool "R-Car V2H (R8A77920)" + select ARCH_RCAR_GEN2 + config ARCH_R8A7793 bool "R-Car M2-N (R8A7793)" select ARCH_RCAR_GEN2 diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index fc95f7bd2dd9..3fc48b02eb4f 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o +obj-$(CONFIG_ARCH_R8A7792) += setup-r8a7792.o obj-$(CONFIG_ARCH_R8A7793) += setup-r8a7793.o obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 3b562d87826d..1a8f7b3ab449 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -10,6 +10,7 @@ extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); extern bool shmobile_smp_cpu_can_disable(unsigned int cpu); +extern bool shmobile_smp_init_fallback_ops(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys, unsigned int max_cpus); diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index aba75c89f9c1..0c6bb458b7a4 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -24,6 +24,7 @@ #include <asm/suspend.h> #include "common.h" #include "platsmp-apmu.h" +#include "rcar-gen2.h" static struct { void __iomem *iomem; @@ -74,6 +75,7 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu) return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; } +#ifdef CONFIG_SMP static void apmu_init_cpu(struct resource *res, int cpu, int bit) { if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem) @@ -117,18 +119,69 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit), } } -void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, - struct rcar_apmu_config *apmu_config, - int num) +static const struct of_device_id apmu_ids[] = { + { .compatible = "renesas,apmu" }, + { /*sentinel*/ } +}; + +static void apmu_parse_dt(void (*fn)(struct resource *res, int cpu, int bit)) +{ + struct device_node *np_apmu, *np_cpu; + struct resource res; + int bit, index; + u32 id; + + for_each_matching_node(np_apmu, apmu_ids) { + /* only enable the cluster that includes the boot CPU */ + bool is_allowed = false; + + for (bit = 0; bit < CONFIG_NR_CPUS; bit++) { + np_cpu = of_parse_phandle(np_apmu, "cpus", bit); + if (np_cpu) { + if (!of_property_read_u32(np_cpu, "reg", &id)) { + if (id == cpu_logical_map(0)) { + is_allowed = true; + of_node_put(np_cpu); + break; + } + + } + of_node_put(np_cpu); + } + } + if (!is_allowed) + continue; + + for (bit = 0; bit < CONFIG_NR_CPUS; bit++) { + np_cpu = of_parse_phandle(np_apmu, "cpus", bit); + if (np_cpu) { + if (!of_property_read_u32(np_cpu, "reg", &id)) { + index = get_logical_index(id); + if ((index >= 0) && + !of_address_to_resource(np_apmu, + 0, &res)) + fn(&res, index, bit); + } + of_node_put(np_cpu); + } + } + } +} + +static void __init shmobile_smp_apmu_setup_boot(void) { /* install boot code shared by all CPUs */ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); +} - /* perform per-cpu setup */ +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, + struct rcar_apmu_config *apmu_config, + int num) +{ + shmobile_smp_apmu_setup_boot(); apmu_parse_cfg(apmu_init_cpu, apmu_config, num); } -#ifdef CONFIG_SMP int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) { /* For this particular CPU register boot vector */ @@ -136,7 +189,38 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) return apmu_wrap(cpu, apmu_power_on); } + +static void __init shmobile_smp_apmu_prepare_cpus_dt(unsigned int max_cpus) +{ + shmobile_smp_apmu_setup_boot(); + apmu_parse_dt(apmu_init_cpu); + rcar_gen2_pm_init(); +} + +static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu, + struct task_struct *idle) +{ + /* Error out when hardware debug mode is enabled */ + if (rcar_gen2_read_mode_pins() & BIT(21)) { + pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu); + return -ENOTSUPP; + } + + return shmobile_smp_apmu_boot_secondary(cpu, idle); +} + +static struct smp_operations apmu_smp_ops __initdata = { + .smp_prepare_cpus = shmobile_smp_apmu_prepare_cpus_dt, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary_md21, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_can_disable = shmobile_smp_cpu_can_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, #endif +}; + +CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops); +#endif /* CONFIG_SMP */ #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND) /* nicked from arch/arm/mach-exynos/hotplug.c */ diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index b23378f3d7e1..f3dba6f356e2 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -36,3 +36,9 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu) return true; /* Hotplug of any CPU is supported */ } #endif + +bool __init shmobile_smp_init_fallback_ops(void) +{ + /* fallback on PSCI/smp_ops if no other DT based method is detected */ + return platform_can_secondary_boot() ? true : false; +} diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index 4174cbcbc467..5c9a93f5e650 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -23,11 +23,7 @@ static void __init r8a7779_sysc_init(void) { - void __iomem *base = rcar_sysc_init(0xffd85000); - - /* enable all interrupt sources, but do not use interrupt handler */ - iowrite32(0x0131000e, base + SYSCIER); - iowrite32(0, base + SYSCIMR); + rcar_sysc_init(0xffd85000, 0x0131000e); } #else /* CONFIG_PM || CONFIG_SMP */ diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index 691ac166a277..dd9ac366868f 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -26,8 +26,7 @@ #define CA7RESCNT 0x0044 /* On-chip RAM */ -#define MERAM 0xe8080000 -#define RAM 0xe6300000 +#define ICRAM1 0xe63c0000 /* Inter Connect RAM1 (4 KiB) */ /* SYSC */ #define SYSCIER 0x0c @@ -37,11 +36,7 @@ static void __init rcar_gen2_sysc_init(u32 syscier) { - void __iomem *base = rcar_sysc_init(0xe6180000); - - /* enable all interrupt sources, but do not use interrupt handler */ - iowrite32(syscier, base + SYSCIER); - iowrite32(0, base + SYSCIMR); + rcar_sysc_init(0xe6180000, syscier); } #else /* CONFIG_SMP */ @@ -58,7 +53,7 @@ void __init rcar_gen2_pm_init(void) struct device_node *np, *cpus; bool has_a7 = false; bool has_a15 = false; - phys_addr_t boot_vector_addr = 0; + phys_addr_t boot_vector_addr = ICRAM1; u32 syscier = 0; if (once++) @@ -75,14 +70,10 @@ void __init rcar_gen2_pm_init(void) has_a7 = true; } - if (of_machine_is_compatible("renesas,r8a7790")) { - boot_vector_addr = MERAM; + if (of_machine_is_compatible("renesas,r8a7790")) syscier = 0x013111ef; - - } else if (of_machine_is_compatible("renesas,r8a7791")) { - boot_vector_addr = RAM; + else if (of_machine_is_compatible("renesas,r8a7791")) syscier = 0x00111003; - } /* RAM for jump stub, because BAR requires 256KB aligned address */ p = ioremap_nocache(boot_vector_addr, shmobile_boot_size); diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index c0b05e9e6442..45a195501b78 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -131,13 +131,13 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) struct dev_power_governor *gov = rmobile_pd->gov; genpd->flags = GENPD_FLAG_PM_CLK; - pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; genpd->power_off = rmobile_pd_power_down; genpd->power_on = rmobile_pd_power_up; genpd->attach_dev = cpg_mstp_attach_dev; genpd->detach_dev = cpg_mstp_detach_dev; __rmobile_pd_power_up(rmobile_pd, false); + pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); } static int rmobile_pd_suspend_busy(void) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 3a18af4922b4..3506327e0bed 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -28,6 +28,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") + .smp_init = shmobile_smp_init_fallback_ops, .smp = smp_ops(r8a7790_smp_ops), .init_early = shmobile_init_delay, .init_time = rcar_gen2_timer_init, diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index 3b8dbaf07777..110e8b588e56 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -29,6 +29,7 @@ static const char *const r8a7791_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .smp_init = shmobile_smp_init_fallback_ops, .smp = smp_ops(r8a7791_smp_ops), .init_early = shmobile_init_delay, .init_time = rcar_gen2_timer_init, diff --git a/arch/arm/mach-shmobile/setup-r8a7792.c b/arch/arm/mach-shmobile/setup-r8a7792.c new file mode 100644 index 000000000000..a0910395da09 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7792.c @@ -0,0 +1,35 @@ +/* + * r8a7792 processor support + * + * Copyright (C) 2014 Renesas Electronics Corporation + * Copyright (C) 2016 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/of_platform.h> + +#include <asm/mach/arch.h> + +#include "common.h" +#include "rcar-gen2.h" + +static const char * const r8a7792_boards_compat_dt[] __initconst = { + "renesas,r8a7792", + NULL, +}; + +DT_MACHINE_START(R8A7792_DT, "Generic R8A7792 (Flattened Device Tree)") + .init_early = shmobile_init_delay, + .init_late = shmobile_init_late, + .init_time = rcar_gen2_timer_init, + .reserve = rcar_gen2_reserve, + .dt_compat = r8a7792_boards_compat_dt, +MACHINE_END diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 1c6fd11c2f82..afb9fdcd3d90 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -46,6 +46,26 @@ u32 rcar_gen2_read_mode_pins(void) return mode; } +static unsigned int __init get_extal_freq(void) +{ + struct device_node *cpg, *extal; + u32 freq = 20000000; + + cpg = of_find_compatible_node(NULL, NULL, + "renesas,rcar-gen2-cpg-clocks"); + if (!cpg) + return freq; + + extal = of_parse_phandle(cpg, "clocks", 0); + of_node_put(cpg); + if (!extal) + return freq; + + of_property_read_u32(extal, "clock-frequency", &freq); + of_node_put(extal); + return freq; +} + #define CNTCR 0 #define CNTFID0 0x20 @@ -54,10 +74,10 @@ void __init rcar_gen2_timer_init(void) u32 mode = rcar_gen2_read_mode_pins(); #ifdef CONFIG_ARM_ARCH_TIMER void __iomem *base; - int extal_mhz = 0; u32 freq; - if (of_machine_is_compatible("renesas,r8a7794")) { + if (of_machine_is_compatible("renesas,r8a7792") || + of_machine_is_compatible("renesas,r8a7794")) { freq = 260000000 / 8; /* ZS / 8 */ /* CNTVOFF has to be initialized either from non-secure * Hypervisor mode or secure Monitor mode with SCR.NS==1. @@ -82,26 +102,9 @@ void __init rcar_gen2_timer_init(void) * with the counter disabled. Moreover, it may also report * a potentially incorrect fixed 13 MHz frequency. To be * correct these registers need to be updated to use the - * frequency EXTAL / 2 which can be determined by the MD pins. + * frequency EXTAL / 2. */ - - switch (mode & (MD(14) | MD(13))) { - case 0: - extal_mhz = 15; - break; - case MD(13): - extal_mhz = 20; - break; - case MD(14): - extal_mhz = 26; - break; - case MD(13) | MD(14): - extal_mhz = 30; - break; - } - - /* The arch timer frequency equals EXTAL / 2 */ - freq = extal_mhz * (1000000 / 2); + freq = get_extal_freq() / 2; } /* Remap "armgcnt address map" space */ diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c index ae10fb280a78..e04cd1b201bb 100644 --- a/arch/arm/mach-sti/board-dt.c +++ b/arch/arm/mach-sti/board-dt.c @@ -23,7 +23,15 @@ static const char *const stih41x_dt_match[] __initconst = { NULL }; -DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree") +static void sti_l2_write_sec(unsigned long val, unsigned reg) +{ + /* + * We can't write to secure registers as we are in non-secure + * mode, until we have some SMI service available. + */ +} + +DT_MACHINE_START(STM, "STi SoC with Flattened Device Tree") .dt_compat = stih41x_dt_match, .l2c_aux_val = L2C_AUX_CTRL_SHARED_OVERRIDE | L310_AUX_CTRL_DATA_PREFETCH | @@ -31,4 +39,5 @@ DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree") L2C_AUX_CTRL_WAY_SIZE(4), .l2c_aux_mask = 0xc0000fff, .smp = smp_ops(sti_smp_ops), + .l2c_write_sec = sti_l2_write_sec, MACHINE_END diff --git a/arch/arm/mach-tango/Makefile b/arch/arm/mach-tango/Makefile index f33935e42e77..204fcd9fe180 100644 --- a/arch/arm/mach-tango/Makefile +++ b/arch/arm/mach-tango/Makefile @@ -3,3 +3,4 @@ AFLAGS_smc.o := -Wa,-march=armv7-a$(plus_sec) obj-y += setup.o smc.o obj-$(CONFIG_SMP) += platsmp.o +obj-$(CONFIG_SUSPEND) += pm.o diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c index a21f55e000d2..98c62a4a8623 100644 --- a/arch/arm/mach-tango/platsmp.c +++ b/arch/arm/mach-tango/platsmp.c @@ -1,3 +1,4 @@ +#include <linux/delay.h> #include <linux/init.h> #include <linux/smp.h> #include "smc.h" @@ -9,8 +10,42 @@ static int tango_boot_secondary(unsigned int cpu, struct task_struct *idle) return 0; } +#ifdef CONFIG_HOTPLUG_CPU +/* + * cpu_kill() and cpu_die() run concurrently on different cores. + * Firmware will only "kill" a core once it has properly "died". + * Try a few times to kill a core before giving up, and sleep + * between tries to give that core enough time to die. + */ +static int tango_cpu_kill(unsigned int cpu) +{ + int i, err; + + for (i = 0; i < 10; ++i) { + msleep(10); + err = tango_aux_core_kill(cpu); + if (!err) + return true; + } + + return false; +} + +static void tango_cpu_die(unsigned int cpu) +{ + while (tango_aux_core_die(cpu) < 0) + cpu_relax(); + + panic("cpu %d failed to die\n", cpu); +} +#endif + static const struct smp_operations tango_smp_ops __initconst = { .smp_boot_secondary = tango_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_kill = tango_cpu_kill, + .cpu_die = tango_cpu_die, +#endif }; CPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango_smp_ops); diff --git a/arch/arm/mach-tango/pm.c b/arch/arm/mach-tango/pm.c new file mode 100644 index 000000000000..b05c6d6f99d0 --- /dev/null +++ b/arch/arm/mach-tango/pm.c @@ -0,0 +1,32 @@ +#include <linux/init.h> +#include <linux/suspend.h> +#include <asm/suspend.h> +#include "smc.h" + +static int tango_pm_powerdown(unsigned long arg) +{ + tango_suspend(virt_to_phys(cpu_resume)); + + return -EIO; /* tango_suspend has failed */ +} + +static int tango_pm_enter(suspend_state_t state) +{ + if (state == PM_SUSPEND_MEM) + return cpu_suspend(0, tango_pm_powerdown); + + return -EINVAL; +} + +static const struct platform_suspend_ops tango_pm_ops = { + .enter = tango_pm_enter, + .valid = suspend_valid_only_mem, +}; + +static int __init tango_pm_init(void) +{ + suspend_set_ops(&tango_pm_ops); + return 0; +} + +late_initcall(tango_pm_init); diff --git a/arch/arm/mach-tango/smc.h b/arch/arm/mach-tango/smc.h index 7a4af35cc390..57919539da1b 100644 --- a/arch/arm/mach-tango/smc.h +++ b/arch/arm/mach-tango/smc.h @@ -2,4 +2,7 @@ extern int tango_smc(unsigned int val, unsigned int service); #define tango_set_l2_control(val) tango_smc(val, 0x102) #define tango_start_aux_core(val) tango_smc(val, 0x104) -#define tango_set_aux_boot_addr(val) tango_smc((unsigned int)val, 0x105) +#define tango_set_aux_boot_addr(val) tango_smc(val, 0x105) +#define tango_suspend(val) tango_smc(val, 0x120) +#define tango_aux_core_die(val) tango_smc(val, 0x121) +#define tango_aux_core_kill(val) tango_smc(val, 0x122) diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile index 1233f9b610bc..396afe109e67 100644 --- a/arch/arm/mach-uniphier/Makefile +++ b/arch/arm/mach-uniphier/Makefile @@ -1,2 +1 @@ -obj-y := uniphier.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/arch/arm/mach-uniphier/uniphier.c b/arch/arm/mach-uniphier/uniphier.c deleted file mode 100644 index 9be10efacb7d..000000000000 --- a/arch/arm/mach-uniphier/uniphier.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <asm/mach/arch.h> - -static const char * const uniphier_dt_compat[] __initconst = { - "socionext,ph1-sld3", - "socionext,ph1-ld4", - "socionext,ph1-pro4", - "socionext,ph1-sld8", - "socionext,ph1-pro5", - "socionext,proxstream2", - "socionext,ph1-ld6b", - NULL, -}; - -DT_MACHINE_START(UNIPHIER, "Socionext UniPhier") - .dt_compat = uniphier_dt_compat, -MACHINE_END diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c index 71333bb61013..a107b3a0b095 100644 --- a/arch/arm/plat-samsung/cpu.c +++ b/arch/arm/plat-samsung/cpu.c @@ -29,14 +29,14 @@ EXPORT_SYMBOL(samsung_rev); void __init s3c64xx_init_cpu(void) { - samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118); + samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118); if (!samsung_cpu_id) { /* * S3C6400 has the ID register in a different place, * and needs a write before it can be read. */ - __raw_writel(0x0, S3C_VA_SYS + 0xA1C); - samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C); + writel_relaxed(0x0, S3C_VA_SYS + 0xA1C); + samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0xA1C); } samsung_cpu_rev = 0; @@ -44,9 +44,9 @@ void __init s3c64xx_init_cpu(void) pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id); } -void __init s5p_init_cpu(void __iomem *cpuid_addr) +void __init s5p_init_cpu(const void __iomem *cpuid_addr) { - samsung_cpu_id = __raw_readl(cpuid_addr); + samsung_cpu_id = readl_relaxed(cpuid_addr); samsung_cpu_rev = samsung_cpu_id & 0xFF; pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id); diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 61d14f3a0426..b7b702a72cac 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -113,6 +113,7 @@ extern void s3c_init_cpu(unsigned long idcode, extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); extern void s3c64xx_init_cpu(void); +extern void s5p_init_cpu(const void __iomem *cpuid_addr); extern unsigned int samsung_rev(void); diff --git a/arch/arm/plat-samsung/pm-common.c b/arch/arm/plat-samsung/pm-common.c index 515cd53372bd..6534c3ff9fe2 100644 --- a/arch/arm/plat-samsung/pm-common.c +++ b/arch/arm/plat-samsung/pm-common.c @@ -31,7 +31,7 @@ void s3c_pm_do_save(struct sleep_save *ptr, int count) { for (; count > 0; count--, ptr++) { - ptr->val = __raw_readl(ptr->reg); + ptr->val = readl_relaxed(ptr->reg); S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); } } @@ -51,9 +51,9 @@ void s3c_pm_do_restore(const struct sleep_save *ptr, int count) { for (; count > 0; count--, ptr++) { pr_debug("restore %p (restore %08lx, was %08x)\n", - ptr->reg, ptr->val, __raw_readl(ptr->reg)); + ptr->reg, ptr->val, readl_relaxed(ptr->reg)); - __raw_writel(ptr->val, ptr->reg); + writel_relaxed(ptr->val, ptr->reg); } } @@ -71,5 +71,5 @@ void s3c_pm_do_restore(const struct sleep_save *ptr, int count) void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) { for (; count > 0; count--, ptr++) - __raw_writel(ptr->val, ptr->reg); + writel_relaxed(ptr->val, ptr->reg); } |