diff options
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | arch/arm/include/debug/brcmstb.S | 30 | ||||
-rw-r--r-- | arch/arm/mach-bcm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-exynos/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/hardware.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6ul.c | 25 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c/irq-s3c24xx-fiq.S | 9 | ||||
-rw-r--r-- | arch/arm/mach-s3c/irq-s3c24xx.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra20.S | 38 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra30.S | 94 | ||||
-rw-r--r-- | arch/arm64/Kconfig.platforms | 1 | ||||
-rw-r--r-- | drivers/soc/renesas/rcar-sysc.c | 37 | ||||
-rw-r--r-- | drivers/soc/samsung/Kconfig | 12 | ||||
-rw-r--r-- | drivers/soc/samsung/Makefile | 3 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-asv.c | 57 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-asv.h | 2 | ||||
-rw-r--r-- | drivers/soc/samsung/exynos-chipid.c | 71 | ||||
-rw-r--r-- | drivers/soc/samsung/pm_domains.c | 97 |
19 files changed, 286 insertions, 213 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2f9b0678b31d..e6b425a5cb33 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1511,6 +1511,7 @@ ARM/ACTIONS SEMI ARCHITECTURE M: Andreas Färber <afaerber@suse.de> M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-actions@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/actions.yaml F: Documentation/devicetree/bindings/clock/actions,owl-cmu.txt @@ -2382,6 +2383,8 @@ F: drivers/*/*s5pv210* F: drivers/memory/samsung/ F: drivers/soc/samsung/ F: drivers/tty/serial/samsung* +F: include/linux/platform_data/*s3c* +F: include/linux/serial_s3c.h F: include/linux/soc/samsung/ N: exynos N: s3c2410 @@ -12843,7 +12846,7 @@ S: Orphan F: drivers/video/fbdev/omap/ OMAP GENERAL PURPOSE MEMORY CONTROLLER SUPPORT -M: Roger Quadros <rogerq@ti.com> +M: Roger Quadros <rogerq@kernel.org> M: Tony Lindgren <tony@atomide.com> L: linux-omap@vger.kernel.org S: Maintained diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S index 0ff32ffc610c..f684e3a815f6 100644 --- a/arch/arm/include/debug/brcmstb.S +++ b/arch/arm/include/debug/brcmstb.S @@ -25,6 +25,7 @@ #define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000) #define UARTA_3390 REG_PHYS_ADDR(0x40a900) +#define UARTA_72116 UARTA_7255 #define UARTA_7250 REG_PHYS_ADDR(0x40b400) #define UARTA_7255 REG_PHYS_ADDR(0x40c000) #define UARTA_7260 UARTA_7255 @@ -85,20 +86,21 @@ ARM_BE8( rev \rv, \rv ) /* Chip specific detection starts here */ 20: checkuart(\rp, \rv, 0x33900000, 3390) -21: checkuart(\rp, \rv, 0x72160000, 7216) -22: checkuart(\rp, \rv, 0x07216400, 72164) -23: checkuart(\rp, \rv, 0x07216500, 72165) -24: checkuart(\rp, \rv, 0x72500000, 7250) -25: checkuart(\rp, \rv, 0x72550000, 7255) -26: checkuart(\rp, \rv, 0x72600000, 7260) -27: checkuart(\rp, \rv, 0x72680000, 7268) -28: checkuart(\rp, \rv, 0x72710000, 7271) -29: checkuart(\rp, \rv, 0x72780000, 7278) -30: checkuart(\rp, \rv, 0x73640000, 7364) -31: checkuart(\rp, \rv, 0x73660000, 7366) -32: checkuart(\rp, \rv, 0x07437100, 74371) -33: checkuart(\rp, \rv, 0x74390000, 7439) -34: checkuart(\rp, \rv, 0x74450000, 7445) +21: checkuart(\rp, \rv, 0x07211600, 72116) +22: checkuart(\rp, \rv, 0x72160000, 7216) +23: checkuart(\rp, \rv, 0x07216400, 72164) +24: checkuart(\rp, \rv, 0x07216500, 72165) +25: checkuart(\rp, \rv, 0x72500000, 7250) +26: checkuart(\rp, \rv, 0x72550000, 7255) +27: checkuart(\rp, \rv, 0x72600000, 7260) +28: checkuart(\rp, \rv, 0x72680000, 7268) +29: checkuart(\rp, \rv, 0x72710000, 7271) +30: checkuart(\rp, \rv, 0x72780000, 7278) +31: checkuart(\rp, \rv, 0x73640000, 7364) +32: checkuart(\rp, \rv, 0x73660000, 7366) +33: checkuart(\rp, \rv, 0x07437100, 74371) +34: checkuart(\rp, \rv, 0x74390000, 7439) +35: checkuart(\rp, \rv, 0x74450000, 7445) /* No valid UART found */ 90: mov \rp, #0 diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 9b594ae98153..2890e61b2b46 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -161,6 +161,7 @@ config ARCH_BCM2835 select ARM_TIMER_SP804 select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select BCM2835_TIMER + select BRCMSTB_L2_IRQ select PINCTRL select PINCTRL_BCM2835 select MFD_CORE diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 56d272967fc0..5a48abac6af4 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -13,7 +13,6 @@ menuconfig ARCH_EXYNOS select ARM_GIC select EXYNOS_IRQ_COMBINER select COMMON_CLK_SAMSUNG - select EXYNOS_ASV select EXYNOS_CHIPID select EXYNOS_THERMAL select EXYNOS_PMU diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 7acf7ce467ed..0760fff39a0b 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -106,8 +106,4 @@ .type = _type, \ } -/* There's an off-by-one between the gpio bank number and the gpiochip */ -/* range e.g. GPIO_1_5 is gpio 5 under linux */ -#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) - #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c index e018e716735f..35e81201cb5d 100644 --- a/arch/arm/mach-imx/mach-imx6ul.c +++ b/arch/arm/mach-imx/mach-imx6ul.c @@ -14,6 +14,7 @@ #include "common.h" #include "cpuidle.h" +#include "hardware.h" static void __init imx6ul_enet_clk_init(void) { @@ -27,34 +28,16 @@ static void __init imx6ul_enet_clk_init(void) pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n"); } -static int ksz8081_phy_fixup(struct phy_device *dev) -{ - if (dev && dev->interface == PHY_INTERFACE_MODE_MII) { - phy_write(dev, 0x1f, 0x8110); - phy_write(dev, 0x16, 0x201); - } else if (dev && dev->interface == PHY_INTERFACE_MODE_RMII) { - phy_write(dev, 0x1f, 0x8190); - phy_write(dev, 0x16, 0x202); - } - - return 0; -} - -static void __init imx6ul_enet_phy_init(void) -{ - if (IS_BUILTIN(CONFIG_PHYLIB)) - phy_register_fixup_for_uid(PHY_ID_KSZ8081, MICREL_PHY_ID_MASK, - ksz8081_phy_fixup); -} - static inline void imx6ul_enet_init(void) { imx6ul_enet_clk_init(); - imx6ul_enet_phy_init(); } static void __init imx6ul_init_machine(void) { + imx_print_silicon_rev(cpu_is_imx6ull() ? "i.MX6ULL" : "i.MX6UL", + imx_get_soc_revision()); + of_platform_default_populate(NULL, NULL, NULL); imx6ul_enet_init(); imx_anatop_init(); diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index dedd47e30b98..1feb0098705e 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -1299,7 +1299,7 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) * Due to a suspend or hibernation operation, the state of the registers * controlling this clkdm will be lost, save their context. */ -static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed) +static int _clkdm_save_context(struct clockdomain *clkdm, void *unused) { if (!arch_clkdm || !arch_clkdm->clkdm_save_context) return -EINVAL; @@ -1312,7 +1312,7 @@ static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed) * * Restore the register values for this clockdomain. */ -static int _clkdm_restore_context(struct clockdomain *clkdm, void *ununsed) +static int _clkdm_restore_context(struct clockdomain *clkdm, void *unused) { if (!arch_clkdm || !arch_clkdm->clkdm_restore_context) return -EINVAL; diff --git a/arch/arm/mach-s3c/irq-s3c24xx-fiq.S b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S index b54cbd012241..5d238d9a798e 100644 --- a/arch/arm/mach-s3c/irq-s3c24xx-fiq.S +++ b/arch/arm/mach-s3c/irq-s3c24xx-fiq.S @@ -35,7 +35,6 @@ @ and an offset to the irq acknowledgment word ENTRY(s3c24xx_spi_fiq_rx) -s3c24xx_spi_fix_rx: .word fiq_rx_end - fiq_rx_start .word fiq_rx_irq_ack - fiq_rx_start fiq_rx_start: @@ -49,7 +48,7 @@ fiq_rx_start: strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do @@ set IRQ controller so that next op will trigger IRQ mov fiq_rtmp, #0 @@ -61,7 +60,6 @@ fiq_rx_irq_ack: fiq_rx_end: ENTRY(s3c24xx_spi_fiq_txrx) -s3c24xx_spi_fiq_txrx: .word fiq_txrx_end - fiq_txrx_start .word fiq_txrx_irq_ack - fiq_txrx_start fiq_txrx_start: @@ -76,7 +74,7 @@ fiq_txrx_start: strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do mov fiq_rtmp, #0 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] @@ -88,7 +86,6 @@ fiq_txrx_irq_ack: fiq_txrx_end: ENTRY(s3c24xx_spi_fiq_tx) -s3c24xx_spi_fix_tx: .word fiq_tx_end - fiq_tx_start .word fiq_tx_irq_ack - fiq_tx_start fiq_tx_start: @@ -101,7 +98,7 @@ fiq_tx_start: strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do mov fiq_rtmp, #0 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c index 79b5f19af7a5..0c631c14a817 100644 --- a/arch/arm/mach-s3c/irq-s3c24xx.c +++ b/arch/arm/mach-s3c/irq-s3c24xx.c @@ -21,6 +21,7 @@ #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_address.h> +#include <linux/spi/s3c24xx.h> #include <asm/exception.h> #include <asm/mach/irq.h> @@ -32,6 +33,7 @@ #include "cpu.h" #include "regs-irqtype.h" #include "pm.h" +#include "s3c24xx.h" #define S3C_IRQTYPE_NONE 0 #define S3C_IRQTYPE_EINT 1 @@ -357,7 +359,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, return true; } -asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) +static asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) { do { if (likely(s3c_intc[0])) @@ -1305,7 +1307,7 @@ static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = { } }; -int __init s3c2410_init_intc_of(struct device_node *np, +static int __init s3c2410_init_intc_of(struct device_node *np, struct device_node *interrupt_parent) { return s3c_init_intc_of(np, interrupt_parent, @@ -1327,7 +1329,7 @@ static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = { } }; -int __init s3c2416_init_intc_of(struct device_node *np, +static int __init s3c2416_init_intc_of(struct device_node *np, struct device_node *interrupt_parent) { return s3c_init_intc_of(np, interrupt_parent, diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S index 0e00ba8cf646..a5a36cce142a 100644 --- a/arch/arm/mach-tegra/sleep-tegra20.S +++ b/arch/arm/mach-tegra/sleep-tegra20.S @@ -43,11 +43,34 @@ #define APB_MISC_XM2CFGCPADCTRL2 0x8e4 #define APB_MISC_XM2CFGDPADCTRL2 0x8e8 -.macro pll_enable, rd, r_car_base, pll_base +#define PLLC_STORE_MASK (1 << 0) +#define PLLM_STORE_MASK (1 << 1) +#define PLLP_STORE_MASK (1 << 2) + +.macro test_pll_state, rd, test_mask + ldr \rd, tegra_pll_state + tst \rd, #\test_mask +.endm + +.macro store_pll_state, rd, tmp, r_car_base, pll_base, pll_mask + ldr \rd, [\r_car_base, #\pll_base] + tst \rd, #(1 << 30) + ldr \rd, tegra_pll_state + biceq \rd, \rd, #\pll_mask + orrne \rd, \rd, #\pll_mask + adr \tmp, tegra_pll_state + str \rd, [\tmp] +.endm + +.macro pll_enable, rd, r_car_base, pll_base, test_mask + test_pll_state \rd, \test_mask + beq 1f + ldr \rd, [\r_car_base, #\pll_base] tst \rd, #(1 << 30) orreq \rd, \rd, #(1 << 30) streq \rd, [\r_car_base, #\pll_base] +1: .endm .macro emc_device_mask, rd, base @@ -177,9 +200,9 @@ ENTRY(tegra20_lp1_reset) str r1, [r0, #CLK_RESET_CCLK_DIVIDER] str r1, [r0, #CLK_RESET_SCLK_DIVIDER] - pll_enable r1, r0, CLK_RESET_PLLM_BASE - pll_enable r1, r0, CLK_RESET_PLLP_BASE - pll_enable r1, r0, CLK_RESET_PLLC_BASE + pll_enable r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK adr r2, tegra20_sdram_pad_address adr r4, tegra20_sdram_pad_save @@ -270,6 +293,10 @@ tegra20_switch_cpu_to_clk32k: add r1, r1, #2 wait_until r1, r7, r9 + store_pll_state r0, r1, r5, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK + /* disable PLLM, PLLP and PLLC */ ldr r0, [r5, #CLK_RESET_PLLM_BASE] bic r0, r0, #(1 << 30) @@ -396,6 +423,9 @@ tegra20_sdram_pad_save: .long 0 .endr +tegra_pll_state: + .word 0x0 + .ltorg /* dummy symbol for end of IRAM */ .align L1_CACHE_SHIFT diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index 2667bcdb5dc6..0cc40b6b2ba3 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S @@ -71,6 +71,13 @@ #define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */ +#define PLLA_STORE_MASK (1 << 0) +#define PLLC_STORE_MASK (1 << 1) +#define PLLM_STORE_MASK (1 << 2) +#define PLLP_STORE_MASK (1 << 3) +#define PLLX_STORE_MASK (1 << 4) +#define PLLM_PMC_STORE_MASK (1 << 5) + .macro emc_device_mask, rd, base ldr \rd, [\base, #EMC_ADR_CFG] tst \rd, #0x1 @@ -87,7 +94,43 @@ bne 1001b .endm -.macro pll_enable, rd, r_car_base, pll_base, pll_misc +.macro test_pll_state, rd, test_mask + ldr \rd, tegra_pll_state + tst \rd, #\test_mask +.endm + +.macro store_pll_state, rd, tmp, r_car_base, pll_base, pll_mask + ldr \rd, [\r_car_base, #\pll_base] + tst \rd, #(1 << 30) + ldr \rd, tegra_pll_state + biceq \rd, \rd, #\pll_mask + orrne \rd, \rd, #\pll_mask + adr \tmp, tegra_pll_state + str \rd, [\tmp] +.endm + +.macro store_pllm_pmc_state, rd, tmp, pmc_base + ldr \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE] + tst \rd, #(1 << 12) + ldr \rd, tegra_pll_state + biceq \rd, \rd, #PLLM_PMC_STORE_MASK + orrne \rd, \rd, #PLLM_PMC_STORE_MASK + adr \tmp, tegra_pll_state + str \rd, [\tmp] +.endm + +.macro pllm_pmc_enable, rd, pmc_base + test_pll_state \rd, PLLM_PMC_STORE_MASK + + ldrne \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE] + orrne \rd, \rd, #(1 << 12) + strne \rd, [\pmc_base, #PMC_PLLP_WB0_OVERRIDE] +.endm + +.macro pll_enable, rd, r_car_base, pll_base, pll_misc, test_mask + test_pll_state \rd, \test_mask + beq 1f + ldr \rd, [\r_car_base, #\pll_base] tst \rd, #(1 << 30) orreq \rd, \rd, #(1 << 30) @@ -102,13 +145,17 @@ orr \rd, \rd, #(1 << 18) str \rd, [\r_car_base, #\pll_misc] .endif +1: .endm -.macro pll_locked, rd, r_car_base, pll_base +.macro pll_locked, rd, r_car_base, pll_base, test_mask + test_pll_state \rd, \test_mask + beq 2f 1: ldr \rd, [\r_car_base, #\pll_base] tst \rd, #(1 << 27) beq 1b +2: .endm .macro pll_iddq_exit, rd, car, iddq, iddq_bit @@ -342,34 +389,30 @@ ENTRY(tegra30_lp1_reset) /* enable PLLM via PMC */ mov32 r2, TEGRA_PMC_BASE - ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE] - orr r1, r1, #(1 << 12) - str r1, [r2, #PMC_PLLP_WB0_OVERRIDE] + pllm_pmc_enable r1, r2 - pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0 - pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0 - pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0 + pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0, PLLM_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0, PLLC_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0, PLLX_STORE_MASK b _pll_m_c_x_done _no_pll_iddq_exit: /* enable PLLM via PMC */ mov32 r2, TEGRA_PMC_BASE - ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE] - orr r1, r1, #(1 << 12) - str r1, [r2, #PMC_PLLP_WB0_OVERRIDE] + pllm_pmc_enable r1, r2 - pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC - pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC + pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_MISC, PLLM_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC, PLLC_STORE_MASK _pll_m_c_x_done: - pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC - pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC + pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_MISC, PLLP_STORE_MASK + pll_enable r1, r0, CLK_RESET_PLLA_BASE, CLK_RESET_PLLA_MISC, PLLA_STORE_MASK - pll_locked r1, r0, CLK_RESET_PLLM_BASE - pll_locked r1, r0, CLK_RESET_PLLP_BASE - pll_locked r1, r0, CLK_RESET_PLLA_BASE - pll_locked r1, r0, CLK_RESET_PLLC_BASE + pll_locked r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK + pll_locked r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK + pll_locked r1, r0, CLK_RESET_PLLA_BASE, PLLA_STORE_MASK + pll_locked r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK /* * CPUFreq driver could select other PLL for CPU. PLLX will be @@ -380,7 +423,7 @@ _pll_m_c_x_done: cmp r1, #TEGRA30 beq 1f - pll_locked r1, r0, CLK_RESET_PLLX_BASE + pll_locked r1, r0, CLK_RESET_PLLX_BASE, PLLX_STORE_MASK ldr r1, [r0, #CLK_RESET_PLLP_BASE] bic r1, r1, #(1<<31) @ disable PllP bypass @@ -593,6 +636,9 @@ tegra_sdram_pad_save: .long 0 .endr +tegra_pll_state: + .word 0x0 + /* * tegra30_tear_down_core * @@ -641,6 +687,14 @@ tegra30_switch_cpu_to_clk32k: add r1, r1, #2 wait_until r1, r7, r9 + /* store enable-state of PLLs */ + store_pll_state r0, r1, r5, CLK_RESET_PLLA_BASE, PLLA_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK + store_pll_state r0, r1, r5, CLK_RESET_PLLX_BASE, PLLX_STORE_MASK + store_pllm_pmc_state r0, r1, r4 + /* disable PLLM via PMC in LP1 */ ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE] bic r0, r0, #(1 << 12) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index ec3c0cb27d1e..88fdf6fc7569 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -39,6 +39,7 @@ config ARCH_BCM2835 select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 + select BRCMSTB_L2_IRQ help This enables support for the Broadcom BCM2837 and BCM2711 SoC. These SoCs are used in the Raspberry Pi 3 and 4 devices. diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 9b235fc90027..53387a72ca00 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/soc/renesas/rcar-sysc.h> #include "rcar-sysc.h" @@ -44,13 +45,13 @@ #define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */ -#define SYSCSR_RETRIES 100 +#define SYSCSR_TIMEOUT 100 #define SYSCSR_DELAY_US 1 #define PWRER_RETRIES 100 #define PWRER_DELAY_US 1 -#define SYSCISR_RETRIES 1000 +#define SYSCISR_TIMEOUT 1000 #define SYSCISR_DELAY_US 1 #define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */ @@ -68,7 +69,8 @@ static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val; static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) { unsigned int sr_bit, reg_offs; - int k; + u32 val; + int ret; if (on) { sr_bit = SYSCSR_PONENB; @@ -79,13 +81,10 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) } /* Wait until SYSC is ready to accept a power request */ - for (k = 0; k < SYSCSR_RETRIES; k++) { - if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit)) - break; - udelay(SYSCSR_DELAY_US); - } - - if (k == SYSCSR_RETRIES) + ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCSR, val, + val & BIT(sr_bit), SYSCSR_DELAY_US, + SYSCSR_TIMEOUT); + if (ret) return -EAGAIN; /* Submit power shutoff or power resume request */ @@ -99,10 +98,9 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) { unsigned int isr_mask = BIT(sysc_ch->isr_bit); unsigned int chan_mask = BIT(sysc_ch->chan_bit); - unsigned int status; + unsigned int status, k; unsigned long flags; - int ret = 0; - int k; + int ret; spin_lock_irqsave(&rcar_sysc_lock, flags); @@ -145,13 +143,10 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on) } /* Wait until the power shutoff or resume request has completed * */ - for (k = 0; k < SYSCISR_RETRIES; k++) { - if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask) - break; - udelay(SYSCISR_DELAY_US); - } - - if (k == SYSCISR_RETRIES) + ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCISR, status, + status & isr_mask, SYSCISR_DELAY_US, + SYSCISR_TIMEOUT); + if (ret) ret = -EIO; iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); @@ -439,6 +434,8 @@ static int __init rcar_sysc_pd_init(void) } error = of_genpd_add_provider_onecell(np, &domains->onecell_data); + if (!error) + of_node_set_flag(np, OF_POPULATED); out_put: of_node_put(np); diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig index fc7f48a92288..5745d7e5908e 100644 --- a/drivers/soc/samsung/Kconfig +++ b/drivers/soc/samsung/Kconfig @@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG if SOC_SAMSUNG -config EXYNOS_ASV - bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST - depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST - select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS - # There is no need to enable these drivers for ARMv8 config EXYNOS_ASV_ARM bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST - depends on EXYNOS_ASV + depends on EXYNOS_CHIPID config EXYNOS_CHIPID - bool "Exynos Chipid controller driver" if COMPILE_TEST + bool "Exynos ChipID controller and ASV driver" if COMPILE_TEST depends on ARCH_EXYNOS || COMPILE_TEST + select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS select MFD_SYSCON select SOC_BUS + help + Support for Samsung Exynos SoC ChipID and Adaptive Supply Voltage. config EXYNOS_PMU bool "Exynos PMU controller driver" if COMPILE_TEST diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile index 59e8e9453f27..0c523a8de4eb 100644 --- a/drivers/soc/samsung/Makefile +++ b/drivers/soc/samsung/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_EXYNOS_ASV) += exynos-asv.o obj-$(CONFIG_EXYNOS_ASV_ARM) += exynos5422-asv.o -obj-$(CONFIG_EXYNOS_CHIPID) += exynos-chipid.o +obj-$(CONFIG_EXYNOS_CHIPID) += exynos-chipid.o exynos-asv.o obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c index 8abf4dfaa5c5..d60af8acc391 100644 --- a/drivers/soc/samsung/exynos-asv.c +++ b/drivers/soc/samsung/exynos-asv.c @@ -2,7 +2,9 @@ /* * Copyright (c) 2019 Samsung Electronics Co., Ltd. * http://www.samsung.com/ + * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> * Author: Sylwester Nawrocki <s.nawrocki@samsung.com> + * Author: Krzysztof Kozlowski <krzk@kernel.org> * * Samsung Exynos SoC Adaptive Supply Voltage support */ @@ -10,12 +12,7 @@ #include <linux/cpu.h> #include <linux/device.h> #include <linux/errno.h> -#include <linux/init.h> -#include <linux/mfd/syscon.h> -#include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> -#include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/regmap.h> #include <linux/soc/samsung/exynos-chipid.h> @@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv) return 0; } -static int exynos_asv_probe(struct platform_device *pdev) +int exynos_asv_init(struct device *dev, struct regmap *regmap) { int (*probe_func)(struct exynos_asv *asv); struct exynos_asv *asv; @@ -119,39 +116,39 @@ static int exynos_asv_probe(struct platform_device *pdev) u32 product_id = 0; int ret, i; - cpu_dev = get_cpu_device(0); - ret = dev_pm_opp_get_opp_count(cpu_dev); - if (ret < 0) - return -EPROBE_DEFER; - - asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL); + asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL); if (!asv) return -ENOMEM; - asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node); - if (IS_ERR(asv->chipid_regmap)) { - dev_err(&pdev->dev, "Could not find syscon regmap\n"); - return PTR_ERR(asv->chipid_regmap); + asv->chipid_regmap = regmap; + asv->dev = dev; + ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, + &product_id); + if (ret < 0) { + dev_err(dev, "Cannot read revision from ChipID: %d\n", ret); + return -ENODEV; } - regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id); - switch (product_id & EXYNOS_MASK) { case 0xE5422000: probe_func = exynos5422_asv_init; break; default: - return -ENODEV; + dev_dbg(dev, "No ASV support for this SoC\n"); + devm_kfree(dev, asv); + return 0; } - ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin", + cpu_dev = get_cpu_device(0); + ret = dev_pm_opp_get_opp_count(cpu_dev); + if (ret < 0) + return -EPROBE_DEFER; + + ret = of_property_read_u32(dev->of_node, "samsung,asv-bin", &asv->of_bin); if (ret < 0) asv->of_bin = -EINVAL; - asv->dev = &pdev->dev; - dev_set_drvdata(&pdev->dev, asv); - for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) asv->subsys[i].asv = asv; @@ -161,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev) return exynos_asv_update_opps(asv); } - -static const struct of_device_id exynos_asv_of_device_ids[] = { - { .compatible = "samsung,exynos4210-chipid" }, - {} -}; - -static struct platform_driver exynos_asv_driver = { - .driver = { - .name = "exynos-asv", - .of_match_table = exynos_asv_of_device_ids, - }, - .probe = exynos_asv_probe, -}; -module_platform_driver(exynos_asv_driver); diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h index 3fd1f2acd999..dcbe154db31e 100644 --- a/drivers/soc/samsung/exynos-asv.h +++ b/drivers/soc/samsung/exynos-asv.h @@ -68,4 +68,6 @@ static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *s return __asv_get_table_entry(&subsys->table, level, 0); } +int exynos_asv_init(struct device *dev, struct regmap *regmap); + #endif /* __LINUX_SOC_EXYNOS_ASV_H */ diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 1a76eade2ed6..5c1d0f97f766 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -2,20 +2,28 @@ /* * Copyright (c) 2019 Samsung Electronics Co., Ltd. * http://www.samsung.com/ + * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> * * Exynos - CHIP ID support * Author: Pankaj Dubey <pankaj.dubey@samsung.com> * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> + * Author: Krzysztof Kozlowski <krzk@kernel.org> + * + * Samsung Exynos SoC Adaptive Supply Voltage and Chip ID support */ -#include <linux/io.h> +#include <linux/device.h> +#include <linux/errno.h> #include <linux/mfd/syscon.h> #include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/soc/samsung/exynos-chipid.h> #include <linux/sys_soc.h> +#include "exynos-asv.h" + static const struct exynos_soc_id { const char *name; unsigned int id; @@ -36,7 +44,7 @@ static const struct exynos_soc_id { { "EXYNOS7420", 0xE7420000 }, }; -static const char * __init product_id_to_soc_id(unsigned int product_id) +static const char *product_id_to_soc_id(unsigned int product_id) { int i; @@ -46,25 +54,17 @@ static const char * __init product_id_to_soc_id(unsigned int product_id) return NULL; } -static int __init exynos_chipid_early_init(void) +static int exynos_chipid_probe(struct platform_device *pdev) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; struct device_node *root; - struct device_node *syscon; struct regmap *regmap; u32 product_id; u32 revision; int ret; - syscon = of_find_compatible_node(NULL, NULL, - "samsung,exynos4210-chipid"); - if (!syscon) - return -ENODEV; - - regmap = device_node_to_regmap(syscon); - of_node_put(syscon); - + regmap = device_node_to_regmap(pdev->dev.of_node); if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -74,7 +74,8 @@ static int __init exynos_chipid_early_init(void) revision = product_id & EXYNOS_REV_MASK; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), + GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; @@ -84,20 +85,24 @@ static int __init exynos_chipid_early_init(void) of_property_read_string(root, "model", &soc_dev_attr->machine); of_node_put(root); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision); + soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "%x", revision); soc_dev_attr->soc_id = product_id_to_soc_id(product_id); if (!soc_dev_attr->soc_id) { pr_err("Unknown SoC\n"); - ret = -ENODEV; - goto err; + return -ENODEV; } /* please note that the actual registration will be deferred */ soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - ret = PTR_ERR(soc_dev); + if (IS_ERR(soc_dev)) + return PTR_ERR(soc_dev); + + ret = exynos_asv_init(&pdev->dev, regmap); + if (ret) goto err; - } + + platform_set_drvdata(pdev, soc_dev); dev_info(soc_device_to_device(soc_dev), "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n", @@ -106,9 +111,31 @@ static int __init exynos_chipid_early_init(void) return 0; err: - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr); + soc_device_unregister(soc_dev); + return ret; } -arch_initcall(exynos_chipid_early_init); +static int exynos_chipid_remove(struct platform_device *pdev) +{ + struct soc_device *soc_dev = platform_get_drvdata(pdev); + + soc_device_unregister(soc_dev); + + return 0; +} + +static const struct of_device_id exynos_chipid_of_device_ids[] = { + { .compatible = "samsung,exynos4210-chipid" }, + {} +}; + +static struct platform_driver exynos_chipid_driver = { + .driver = { + .name = "exynos-chipid", + .of_match_table = exynos_chipid_of_device_ids, + }, + .probe = exynos_chipid_probe, + .remove = exynos_chipid_remove, +}; +builtin_platform_driver(exynos_chipid_driver); diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index ab8582971bfc..5ec0c13f0aaf 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -16,7 +16,7 @@ #include <linux/delay.h> #include <linux/of_address.h> #include <linux/of_platform.h> -#include <linux/sched.h> +#include <linux/pm_runtime.h> struct exynos_pm_domain_config { /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ @@ -73,15 +73,15 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain) return exynos_pd_power(domain, false); } -static const struct exynos_pm_domain_config exynos4210_cfg __initconst = { +static const struct exynos_pm_domain_config exynos4210_cfg = { .local_pwr_cfg = 0x7, }; -static const struct exynos_pm_domain_config exynos5433_cfg __initconst = { +static const struct exynos_pm_domain_config exynos5433_cfg = { .local_pwr_cfg = 0xf, }; -static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { +static const struct of_device_id exynos_pm_domain_of_match[] = { { .compatible = "samsung,exynos4210-pd", .data = &exynos4210_cfg, @@ -92,7 +92,7 @@ static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { { }, }; -static __init const char *exynos_get_domain_name(struct device_node *node) +static const char *exynos_get_domain_name(struct device_node *node) { const char *name; @@ -101,60 +101,44 @@ static __init const char *exynos_get_domain_name(struct device_node *node) return kstrdup_const(name, GFP_KERNEL); } -static __init int exynos4_pm_init_power_domain(void) +static int exynos_pd_probe(struct platform_device *pdev) { - struct device_node *np; - const struct of_device_id *match; - - for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { - const struct exynos_pm_domain_config *pm_domain_cfg; - struct exynos_pm_domain *pd; - int on; + const struct exynos_pm_domain_config *pm_domain_cfg; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct of_phandle_args child, parent; + struct exynos_pm_domain *pd; + int on, ret; - pm_domain_cfg = match->data; + pm_domain_cfg = of_device_get_match_data(dev); + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) { - of_node_put(np); - return -ENOMEM; - } - pd->pd.name = exynos_get_domain_name(np); - if (!pd->pd.name) { - kfree(pd); - of_node_put(np); - return -ENOMEM; - } + pd->pd.name = exynos_get_domain_name(np); + if (!pd->pd.name) + return -ENOMEM; - pd->base = of_iomap(np, 0); - if (!pd->base) { - pr_warn("%s: failed to map memory\n", __func__); - kfree_const(pd->pd.name); - kfree(pd); - continue; - } - - pd->pd.power_off = exynos_pd_power_off; - pd->pd.power_on = exynos_pd_power_on; - pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; + pd->base = of_iomap(np, 0); + if (!pd->base) { + kfree_const(pd->pd.name); + return -ENODEV; + } - on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; + pd->pd.power_off = exynos_pd_power_off; + pd->pd.power_on = exynos_pd_power_on; + pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; - pm_genpd_init(&pd->pd, NULL, !on); - of_genpd_add_provider_simple(np, &pd->pd); - } + on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; - /* Assign the child power domains to their parents */ - for_each_matching_node(np, exynos_pm_domain_of_match) { - struct of_phandle_args child, parent; + pm_genpd_init(&pd->pd, NULL, !on); + ret = of_genpd_add_provider_simple(np, &pd->pd); + if (ret == 0 && of_parse_phandle_with_args(np, "power-domains", + "#power-domain-cells", 0, &parent) == 0) { child.np = np; child.args_count = 0; - if (of_parse_phandle_with_args(np, "power-domains", - "#power-domain-cells", 0, - &parent) != 0) - continue; - if (of_genpd_add_subdomain(&parent, &child)) pr_warn("%pOF failed to add subdomain: %pOF\n", parent.np, child.np); @@ -163,6 +147,21 @@ static __init int exynos4_pm_init_power_domain(void) parent.np, child.np); } - return 0; + pm_runtime_enable(dev); + return ret; +} + +static struct platform_driver exynos_pd_driver = { + .probe = exynos_pd_probe, + .driver = { + .name = "exynos-pd", + .of_match_table = exynos_pm_domain_of_match, + .suppress_bind_attrs = true, + } +}; + +static __init int exynos4_pm_init_power_domain(void) +{ + return platform_driver_register(&exynos_pd_driver); } core_initcall(exynos4_pm_init_power_domain); |