Commit 5011bb9f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm-soc-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM SoC updates from Arnd Bergmann:
 "This is mostly 32-bit code for SoC platforms, and looks smaller than
  any such branch I remember from previous kernels, as most of this is
  now handled in other subsystems for modern platforms:

   - Minor bugfixes and Kconfig updates for Tegra, Broadcom, i.MX,
     Renesas, and Samsung

   - Updates to the MAINTAINERS listing for Actions, OMAP, and Samsung

   - Samsung SoC driver updates to make them loadable modules"

* tag 'arm-soc-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc:
  MAINTAINERS: arm: samsung: include S3C headers in platform entry
  MAINTAINERS: Add linux-actions ML for Actions Semi Arch
  ARM: s3c: irq-s3c24xx: staticize local functions
  ARM: s3c: irq-s3c24xx: include headers for missing declarations
  ARM: s3c: fix fiq for clang IAS
  ARM: imx: Remove unused IMX_GPIO_NR() macro
  soc: renesas: rcar-sysc: Mark device node OF_POPULATED after init
  ARM: OMAP2+: fix spellint typo
  MAINTAINERS: Update address for OMAP GPMC driver
  soc: renesas: rcar-sysc: Use readl_poll_timeout_atomic()
  ARM: bcm: Select BRCMSTB_L2_IRQ for bcm2835
  ARM: brcmstb: Add debug UART entry for 72116
  ARM: tegra: Don't enable unused PLLs on resume from suspend
  soc: samsung: pm_domains: Convert to regular platform driver
  soc: samsung: exynos-chipid: correct helpers __init annotation
  ARM: mach-imx: imx6ul: Print SOC revision on boot
  ARM: imx: mach-imx6ul: remove 14x14 EVK specific PHY fixup
  soc: samsung: exynos-chipid: convert to driver and merge exynos-asv
  soc: samsung: exynos-asv: handle reading revision register error
  soc: samsung: exynos-asv: don't defer early on not-supported SoCs
parents 584ce3c9 c2bd78de
...@@ -1511,6 +1511,7 @@ ARM/ACTIONS SEMI ARCHITECTURE ...@@ -1511,6 +1511,7 @@ ARM/ACTIONS SEMI ARCHITECTURE
M: Andreas Färber <afaerber@suse.de> M: Andreas Färber <afaerber@suse.de>
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-actions@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/arm/actions.yaml F: Documentation/devicetree/bindings/arm/actions.yaml
F: Documentation/devicetree/bindings/clock/actions,owl-cmu.txt F: Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
...@@ -2382,6 +2383,8 @@ F: drivers/*/*s5pv210* ...@@ -2382,6 +2383,8 @@ F: drivers/*/*s5pv210*
F: drivers/memory/samsung/ F: drivers/memory/samsung/
F: drivers/soc/samsung/ F: drivers/soc/samsung/
F: drivers/tty/serial/samsung* F: drivers/tty/serial/samsung*
F: include/linux/platform_data/*s3c*
F: include/linux/serial_s3c.h
F: include/linux/soc/samsung/ F: include/linux/soc/samsung/
N: exynos N: exynos
N: s3c2410 N: s3c2410
...@@ -12843,7 +12846,7 @@ S: Orphan ...@@ -12843,7 +12846,7 @@ S: Orphan
F: drivers/video/fbdev/omap/ F: drivers/video/fbdev/omap/
OMAP GENERAL PURPOSE MEMORY CONTROLLER SUPPORT OMAP GENERAL PURPOSE MEMORY CONTROLLER SUPPORT
M: Roger Quadros <rogerq@ti.com> M: Roger Quadros <rogerq@kernel.org>
M: Tony Lindgren <tony@atomide.com> M: Tony Lindgren <tony@atomide.com>
L: linux-omap@vger.kernel.org L: linux-omap@vger.kernel.org
S: Maintained S: Maintained
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000) #define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000)
#define UARTA_3390 REG_PHYS_ADDR(0x40a900) #define UARTA_3390 REG_PHYS_ADDR(0x40a900)
#define UARTA_72116 UARTA_7255
#define UARTA_7250 REG_PHYS_ADDR(0x40b400) #define UARTA_7250 REG_PHYS_ADDR(0x40b400)
#define UARTA_7255 REG_PHYS_ADDR(0x40c000) #define UARTA_7255 REG_PHYS_ADDR(0x40c000)
#define UARTA_7260 UARTA_7255 #define UARTA_7260 UARTA_7255
...@@ -85,20 +86,21 @@ ARM_BE8( rev \rv, \rv ) ...@@ -85,20 +86,21 @@ ARM_BE8( rev \rv, \rv )
/* Chip specific detection starts here */ /* Chip specific detection starts here */
20: checkuart(\rp, \rv, 0x33900000, 3390) 20: checkuart(\rp, \rv, 0x33900000, 3390)
21: checkuart(\rp, \rv, 0x72160000, 7216) 21: checkuart(\rp, \rv, 0x07211600, 72116)
22: checkuart(\rp, \rv, 0x07216400, 72164) 22: checkuart(\rp, \rv, 0x72160000, 7216)
23: checkuart(\rp, \rv, 0x07216500, 72165) 23: checkuart(\rp, \rv, 0x07216400, 72164)
24: checkuart(\rp, \rv, 0x72500000, 7250) 24: checkuart(\rp, \rv, 0x07216500, 72165)
25: checkuart(\rp, \rv, 0x72550000, 7255) 25: checkuart(\rp, \rv, 0x72500000, 7250)
26: checkuart(\rp, \rv, 0x72600000, 7260) 26: checkuart(\rp, \rv, 0x72550000, 7255)
27: checkuart(\rp, \rv, 0x72680000, 7268) 27: checkuart(\rp, \rv, 0x72600000, 7260)
28: checkuart(\rp, \rv, 0x72710000, 7271) 28: checkuart(\rp, \rv, 0x72680000, 7268)
29: checkuart(\rp, \rv, 0x72780000, 7278) 29: checkuart(\rp, \rv, 0x72710000, 7271)
30: checkuart(\rp, \rv, 0x73640000, 7364) 30: checkuart(\rp, \rv, 0x72780000, 7278)
31: checkuart(\rp, \rv, 0x73660000, 7366) 31: checkuart(\rp, \rv, 0x73640000, 7364)
32: checkuart(\rp, \rv, 0x07437100, 74371) 32: checkuart(\rp, \rv, 0x73660000, 7366)
33: checkuart(\rp, \rv, 0x74390000, 7439) 33: checkuart(\rp, \rv, 0x07437100, 74371)
34: checkuart(\rp, \rv, 0x74450000, 7445) 34: checkuart(\rp, \rv, 0x74390000, 7439)
35: checkuart(\rp, \rv, 0x74450000, 7445)
/* No valid UART found */ /* No valid UART found */
90: mov \rp, #0 90: mov \rp, #0
......
...@@ -161,6 +161,7 @@ config ARCH_BCM2835 ...@@ -161,6 +161,7 @@ config ARCH_BCM2835
select ARM_TIMER_SP804 select ARM_TIMER_SP804
select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
select BCM2835_TIMER select BCM2835_TIMER
select BRCMSTB_L2_IRQ
select PINCTRL select PINCTRL
select PINCTRL_BCM2835 select PINCTRL_BCM2835
select MFD_CORE select MFD_CORE
......
...@@ -13,7 +13,6 @@ menuconfig ARCH_EXYNOS ...@@ -13,7 +13,6 @@ menuconfig ARCH_EXYNOS
select ARM_GIC select ARM_GIC
select EXYNOS_IRQ_COMBINER select EXYNOS_IRQ_COMBINER
select COMMON_CLK_SAMSUNG select COMMON_CLK_SAMSUNG
select EXYNOS_ASV
select EXYNOS_CHIPID select EXYNOS_CHIPID
select EXYNOS_THERMAL select EXYNOS_THERMAL
select EXYNOS_PMU select EXYNOS_PMU
......
...@@ -106,8 +106,4 @@ ...@@ -106,8 +106,4 @@
.type = _type, \ .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__ */ #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common.h" #include "common.h"
#include "cpuidle.h" #include "cpuidle.h"
#include "hardware.h"
static void __init imx6ul_enet_clk_init(void) static void __init imx6ul_enet_clk_init(void)
{ {
...@@ -27,34 +28,16 @@ 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"); 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) static inline void imx6ul_enet_init(void)
{ {
imx6ul_enet_clk_init(); imx6ul_enet_clk_init();
imx6ul_enet_phy_init();
} }
static void __init imx6ul_init_machine(void) 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); of_platform_default_populate(NULL, NULL, NULL);
imx6ul_enet_init(); imx6ul_enet_init();
imx_anatop_init(); imx_anatop_init();
......
...@@ -1299,7 +1299,7 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) ...@@ -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 * Due to a suspend or hibernation operation, the state of the registers
* controlling this clkdm will be lost, save their context. * 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) if (!arch_clkdm || !arch_clkdm->clkdm_save_context)
return -EINVAL; return -EINVAL;
...@@ -1312,7 +1312,7 @@ static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed) ...@@ -1312,7 +1312,7 @@ static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed)
* *
* Restore the register values for this clockdomain. * 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) if (!arch_clkdm || !arch_clkdm->clkdm_restore_context)
return -EINVAL; return -EINVAL;
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
@ and an offset to the irq acknowledgment word @ and an offset to the irq acknowledgment word
ENTRY(s3c24xx_spi_fiq_rx) ENTRY(s3c24xx_spi_fiq_rx)
s3c24xx_spi_fix_rx:
.word fiq_rx_end - fiq_rx_start .word fiq_rx_end - fiq_rx_start
.word fiq_rx_irq_ack - fiq_rx_start .word fiq_rx_irq_ack - fiq_rx_start
fiq_rx_start: fiq_rx_start:
...@@ -49,7 +48,7 @@ fiq_rx_start: ...@@ -49,7 +48,7 @@ fiq_rx_start:
strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
subs fiq_rcount, fiq_rcount, #1 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 @@ set IRQ controller so that next op will trigger IRQ
mov fiq_rtmp, #0 mov fiq_rtmp, #0
...@@ -61,7 +60,6 @@ fiq_rx_irq_ack: ...@@ -61,7 +60,6 @@ fiq_rx_irq_ack:
fiq_rx_end: fiq_rx_end:
ENTRY(s3c24xx_spi_fiq_txrx) ENTRY(s3c24xx_spi_fiq_txrx)
s3c24xx_spi_fiq_txrx:
.word fiq_txrx_end - fiq_txrx_start .word fiq_txrx_end - fiq_txrx_start
.word fiq_txrx_irq_ack - fiq_txrx_start .word fiq_txrx_irq_ack - fiq_txrx_start
fiq_txrx_start: fiq_txrx_start:
...@@ -76,7 +74,7 @@ fiq_txrx_start: ...@@ -76,7 +74,7 @@ fiq_txrx_start:
strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
subs fiq_rcount, fiq_rcount, #1 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 mov fiq_rtmp, #0
str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ]
...@@ -88,7 +86,6 @@ fiq_txrx_irq_ack: ...@@ -88,7 +86,6 @@ fiq_txrx_irq_ack:
fiq_txrx_end: fiq_txrx_end:
ENTRY(s3c24xx_spi_fiq_tx) ENTRY(s3c24xx_spi_fiq_tx)
s3c24xx_spi_fix_tx:
.word fiq_tx_end - fiq_tx_start .word fiq_tx_end - fiq_tx_start
.word fiq_tx_irq_ack - fiq_tx_start .word fiq_tx_irq_ack - fiq_tx_start
fiq_tx_start: fiq_tx_start:
...@@ -101,7 +98,7 @@ fiq_tx_start: ...@@ -101,7 +98,7 @@ fiq_tx_start:
strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ]
subs fiq_rcount, fiq_rcount, #1 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 mov fiq_rtmp, #0
str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ]
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/spi/s3c24xx.h>
#include <asm/exception.h> #include <asm/exception.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
#include "cpu.h" #include "cpu.h"
#include "regs-irqtype.h" #include "regs-irqtype.h"
#include "pm.h" #include "pm.h"
#include "s3c24xx.h"
#define S3C_IRQTYPE_NONE 0 #define S3C_IRQTYPE_NONE 0
#define S3C_IRQTYPE_EINT 1 #define S3C_IRQTYPE_EINT 1
...@@ -357,7 +359,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, ...@@ -357,7 +359,7 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
return true; 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 { do {
if (likely(s3c_intc[0])) if (likely(s3c_intc[0]))
...@@ -1305,7 +1307,7 @@ static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = { ...@@ -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) struct device_node *interrupt_parent)
{ {
return s3c_init_intc_of(np, interrupt_parent, return s3c_init_intc_of(np, interrupt_parent,
...@@ -1327,7 +1329,7 @@ static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = { ...@@ -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) struct device_node *interrupt_parent)
{ {
return s3c_init_intc_of(np, interrupt_parent, return s3c_init_intc_of(np, interrupt_parent,
......
...@@ -43,11 +43,34 @@ ...@@ -43,11 +43,34 @@
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4 #define APB_MISC_XM2CFGCPADCTRL2 0x8e4
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8 #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] ldr \rd, [\r_car_base, #\pll_base]
tst \rd, #(1 << 30) tst \rd, #(1 << 30)
orreq \rd, \rd, #(1 << 30) orreq \rd, \rd, #(1 << 30)
streq \rd, [\r_car_base, #\pll_base] streq \rd, [\r_car_base, #\pll_base]
1:
.endm .endm
.macro emc_device_mask, rd, base .macro emc_device_mask, rd, base
...@@ -177,9 +200,9 @@ ENTRY(tegra20_lp1_reset) ...@@ -177,9 +200,9 @@ ENTRY(tegra20_lp1_reset)
str r1, [r0, #CLK_RESET_CCLK_DIVIDER] str r1, [r0, #CLK_RESET_CCLK_DIVIDER]
str r1, [r0, #CLK_RESET_SCLK_DIVIDER] str r1, [r0, #CLK_RESET_SCLK_DIVIDER]
pll_enable r1, r0, CLK_RESET_PLLM_BASE pll_enable r1, r0, CLK_RESET_PLLM_BASE, PLLM_STORE_MASK
pll_enable r1, r0, CLK_RESET_PLLP_BASE pll_enable r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
pll_enable r1, r0, CLK_RESET_PLLC_BASE pll_enable r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
adr r2, tegra20_sdram_pad_address adr r2, tegra20_sdram_pad_address
adr r4, tegra20_sdram_pad_save adr r4, tegra20_sdram_pad_save
...@@ -270,6 +293,10 @@ tegra20_switch_cpu_to_clk32k: ...@@ -270,6 +293,10 @@ tegra20_switch_cpu_to_clk32k:
add r1, r1, #2 add r1, r1, #2
wait_until r1, r7, r9 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 */ /* disable PLLM, PLLP and PLLC */
ldr r0, [r5, #CLK_RESET_PLLM_BASE] ldr r0, [r5, #CLK_RESET_PLLM_BASE]
bic r0, r0, #(1 << 30) bic r0, r0, #(1 << 30)
...@@ -396,6 +423,9 @@ tegra20_sdram_pad_save: ...@@ -396,6 +423,9 @@ tegra20_sdram_pad_save:
.long 0 .long 0
.endr .endr
tegra_pll_state:
.word 0x0
.ltorg .ltorg
/* dummy symbol for end of IRAM */ /* dummy symbol for end of IRAM */
.align L1_CACHE_SHIFT .align L1_CACHE_SHIFT
......
...@@ -71,6 +71,13 @@ ...@@ -71,6 +71,13 @@
#define TEGRA30_POWER_HOTPLUG_SHUTDOWN (1 << 27) /* Hotplug shutdown */ #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 .macro emc_device_mask, rd, base
ldr \rd, [\base, #EMC_ADR_CFG] ldr \rd, [\base, #EMC_ADR_CFG]
tst \rd, #0x1 tst \rd, #0x1
...@@ -87,7 +94,43 @@ ...@@ -87,7 +94,43 @@
bne 1001b bne 1001b
.endm .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] ldr \rd, [\r_car_base, #\pll_base]
tst \rd, #(1 << 30) tst \rd, #(1 << 30)
orreq \rd, \rd, #(1 << 30) orreq \rd, \rd, #(1 << 30)
...@@ -102,13 +145,17 @@ ...@@ -102,13 +145,17 @@
orr \rd, \rd, #(1 << 18) orr \rd, \rd, #(1 << 18)
str \rd, [\r_car_base, #\pll_misc] str \rd, [\r_car_base, #\pll_misc]
.endif .endif
1:
.endm .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: 1:
ldr \rd, [\r_car_base, #\pll_base] ldr \rd, [\r_car_base, #\pll_base]
tst \rd, #(1 << 27) tst \rd, #(1 << 27)
beq 1b beq 1b
2:
.endm .endm
.macro pll_iddq_exit, rd, car, iddq, iddq_bit .macro pll_iddq_exit, rd, car, iddq, iddq_bit
...@@ -342,34 +389,30 @@ ENTRY(tegra30_lp1_reset) ...@@ -342,34 +389,30 @@ ENTRY(tegra30_lp1_reset)
/* enable PLLM via PMC */ /* enable PLLM via PMC */
mov32 r2, TEGRA_PMC_BASE mov32 r2, TEGRA_PMC_BASE
ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE] pllm_pmc_enable r1, r2
orr r1, r1, #(1 << 12)
str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0 pll_enable r1, r0, CLK_RESET_PLLM_BASE, 0, PLLM_STORE_MASK
pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0 pll_enable r1, r0, CLK_RESET_PLLC_BASE, 0, PLLC_STORE_MASK
pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0 pll_enable r1, r0, CLK_RESET_PLLX_BASE, 0, PLLX_STORE_MASK
b _pll_m_c_x_done b _pll_m_c_x_done
_no_pll_iddq_exit: _no_pll_iddq_exit:
/* enable PLLM via PMC */ /* enable PLLM via PMC */
mov32 r2, TEGRA_PMC_BASE mov32 r2, TEGRA_PMC_BASE
ldr r1, [r2, #PMC_PLLP_WB0_OVERRIDE] pllm_pmc_enable r1, r2
orr r1, r1, #(1 << 12)
str r1, [r2, #PMC_PLLP_WB0_OVERRIDE]
pll_enable r1, r0, CLK_RESET_PLLM_BASE, CLK_RESET_PLLM_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 pll_enable r1, r0, CLK_RESET_PLLC_BASE, CLK_RESET_PLLC_MISC, PLLC_STORE_MASK
_pll_m_c_x_done: _pll_m_c_x_done:
pll_enable r1, r0, CLK_RESET_PLLP_BASE, CLK_RESET_PLLP_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 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_PLLM_BASE, PLLM_STORE_MASK
pll_locked r1, r0, CLK_RESET_PLLP_BASE pll_locked r1, r0, CLK_RESET_PLLP_BASE, PLLP_STORE_MASK
pll_locked r1, r0, CLK_RESET_PLLA_BASE pll_locked r1, r0, CLK_RESET_PLLA_BASE, PLLA_STORE_MASK
pll_locked r1, r0, CLK_RESET_PLLC_BASE pll_locked r1, r0, CLK_RESET_PLLC_BASE, PLLC_STORE_MASK
/* /*
* CPUFreq driver could select other PLL for CPU. PLLX will be * CPUFreq driver could select other PLL for CPU. PLLX will be
...@@ -380,7 +423,7 @@ _pll_m_c_x_done: ...@@ -380,7 +423,7 @@ _pll_m_c_x_done:
cmp r1, #TEGRA30 cmp r1, #TEGRA30
beq 1f 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] ldr r1, [r0, #CLK_RESET_PLLP_BASE]
bic r1, r1, #(1<<31) @ disable PllP bypass bic r1, r1, #(1<<31) @ disable PllP bypass
...@@ -593,6 +636,9 @@ tegra_sdram_pad_save: ...@@ -593,6 +636,9 @@ tegra_sdram_pad_save:
.long 0 .long 0
.endr .endr
tegra_pll_state:
.word 0x0
/* /*
* tegra30_tear_down_core * tegra30_tear_down_core
* *
...@@ -641,6 +687,14 @@ tegra30_switch_cpu_to_clk32k: ...@@ -641,6 +687,14 @@ tegra30_switch_cpu_to_clk32k:
add r1, r1, #2 add r1, r1, #2
wait_until r1, r7, r9 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 */ /* disable PLLM via PMC in LP1 */
ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE] ldr r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
bic r0, r0, #(1 << 12) bic r0, r0, #(1 << 12)
......
...@@ -39,6 +39,7 @@ config ARCH_BCM2835 ...@@ -39,6 +39,7 @@ config ARCH_BCM2835
select ARM_AMBA select ARM_AMBA
select ARM_GIC select ARM_GIC
select ARM_TIMER_SP804 select ARM_TIMER_SP804
select BRCMSTB_L2_IRQ
help help
This enables support for the Broadcom BCM2837 and BCM2711 SoC. This enables support for the Broadcom BCM2837 and BCM2711 SoC.
These SoCs are used in the Raspberry Pi 3 and 4 devices. These SoCs are used in the Raspberry Pi 3 and 4 devices.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/soc/renesas/rcar-sysc.h> #include <linux/soc/renesas/rcar-sysc.h>
#include "rcar-sysc.h" #include "rcar-sysc.h"
...@@ -44,13 +45,13 @@ ...@@ -44,13 +45,13 @@
#define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */ #define PWRER_OFFS 0x14 /* Power Shutoff/Resume Error */
#define SYSCSR_RETRIES 100 #define SYSCSR_TIMEOUT 100
#define SYSCSR_DELAY_US 1 #define SYSCSR_DELAY_US 1
#define PWRER_RETRIES 100 #define PWRER_RETRIES 100
#define PWRER_DELAY_US 1 #define PWRER_DELAY_US 1
#define SYSCISR_RETRIES 1000 #define SYSCISR_TIMEOUT 1000
#define SYSCISR_DELAY_US 1 #define SYSCISR_DELAY_US 1
#define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */ #define RCAR_PD_ALWAYS_ON 32 /* Always-on power area */
...@@ -68,7 +69,8 @@ static u32 rcar_sysc_extmask_offs, rcar_sysc_extmask_val; ...@@ -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) static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
{ {
unsigned int sr_bit, reg_offs; unsigned int sr_bit, reg_offs;
int k; u32 val;
int ret;
if (on) { if (on) {
sr_bit = SYSCSR_PONENB; sr_bit = SYSCSR_PONENB;
...@@ -79,13 +81,10 @@ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on) ...@@ -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 */ /* Wait until SYSC is ready to accept a power request */
for (k = 0; k < SYSCSR_RETRIES; k++) { ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCSR, val,
if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit)) val & BIT(sr_bit), SYSCSR_DELAY_US,
break; SYSCSR_TIMEOUT);
udelay(SYSCSR_DELAY_US); if (ret)
}
if (k == SYSCSR_RETRIES)
return -EAGAIN; return -EAGAIN;
/* Submit power shutoff or power resume request */ /* 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) ...@@ -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 isr_mask = BIT(sysc_ch->isr_bit);
unsigned int chan_mask = BIT(sysc_ch->chan_bit); unsigned int chan_mask = BIT(sysc_ch->chan_bit);
unsigned int status; unsigned int status, k;
unsigned long flags; unsigned long flags;
int ret = 0; int ret;
int k;
spin_lock_irqsave(&rcar_sysc_lock, flags); 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) ...@@ -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 * */ /* Wait until the power shutoff or resume request has completed * */
for (k = 0; k < SYSCISR_RETRIES; k++) { ret = readl_poll_timeout_atomic(rcar_sysc_base + SYSCISR, status,
if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask) status & isr_mask, SYSCISR_DELAY_US,
break; SYSCISR_TIMEOUT);
udelay(SYSCISR_DELAY_US); if (ret)
}
if (k == SYSCISR_RETRIES)
ret = -EIO; ret = -EIO;
iowrite32(isr_mask, rcar_sysc_base + SYSCISCR); iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
...@@ -439,6 +434,8 @@ static int __init rcar_sysc_pd_init(void) ...@@ -439,6 +434,8 @@ static int __init rcar_sysc_pd_init(void)
} }
error = of_genpd_add_provider_onecell(np, &domains->onecell_data); error = of_genpd_add_provider_onecell(np, &domains->onecell_data);
if (!error)
of_node_set_flag(np, OF_POPULATED);
out_put: out_put:
of_node_put(np); of_node_put(np);
......
...@@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG ...@@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG
if 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 # There is no need to enable these drivers for ARMv8
config EXYNOS_ASV_ARM config EXYNOS_ASV_ARM
bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
depends on EXYNOS_ASV depends on EXYNOS_CHIPID
config 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 depends on ARCH_EXYNOS || COMPILE_TEST
select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
select MFD_SYSCON select MFD_SYSCON
select SOC_BUS select SOC_BUS
help
Support for Samsung Exynos SoC ChipID and Adaptive Supply Voltage.
config EXYNOS_PMU config EXYNOS_PMU
bool "Exynos PMU controller driver" if COMPILE_TEST bool "Exynos PMU controller driver" if COMPILE_TEST
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_EXYNOS_ASV) += exynos-asv.o
obj-$(CONFIG_EXYNOS_ASV_ARM) += exynos5422-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) += exynos-pmu.o
obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
/* /*
* Copyright (c) 2019 Samsung Electronics Co., Ltd. * Copyright (c) 2019 Samsung Electronics Co., Ltd.
* http://www.samsung.com/ * http://www.samsung.com/
* Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org>
* Author: Sylwester Nawrocki <s.nawrocki@samsung.com> * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
* Author: Krzysztof Kozlowski <krzk@kernel.org>
* *
* Samsung Exynos SoC Adaptive Supply Voltage support * Samsung Exynos SoC Adaptive Supply Voltage support
*/ */
...@@ -10,12 +12,7 @@ ...@@ -10,12 +12,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.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.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h> #include <linux/pm_opp.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/soc/samsung/exynos-chipid.h> #include <linux/soc/samsung/exynos-chipid.h>
...@@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv) ...@@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
return 0; 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); int (*probe_func)(struct exynos_asv *asv);
struct exynos_asv *asv; struct exynos_asv *asv;
...@@ -119,39 +116,39 @@ static int exynos_asv_probe(struct platform_device *pdev) ...@@ -119,39 +116,39 @@ static int exynos_asv_probe(struct platform_device *pdev)
u32 product_id = 0; u32 product_id = 0;
int ret, i; int ret, i;
cpu_dev = get_cpu_device(0); asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL);
ret = dev_pm_opp_get_opp_count(cpu_dev);
if (ret < 0)
return -EPROBE_DEFER;
asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
if (!asv) if (!asv)
return -ENOMEM; return -ENOMEM;
asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node); asv->chipid_regmap = regmap;
if (IS_ERR(asv->chipid_regmap)) { asv->dev = dev;
dev_err(&pdev->dev, "Could not find syscon regmap\n"); ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID,
return PTR_ERR(asv->chipid_regmap); &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) { switch (product_id & EXYNOS_MASK) {
case 0xE5422000: case 0xE5422000:
probe_func = exynos5422_asv_init; probe_func = exynos5422_asv_init;
break; break;
default: 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); &asv->of_bin);
if (ret < 0) if (ret < 0)
asv->of_bin = -EINVAL; asv->of_bin = -EINVAL;
asv->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, asv);
for (i = 0; i < ARRAY_SIZE(asv->subsys); i++) for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
asv->subsys[i].asv = asv; asv->subsys[i].asv = asv;
...@@ -161,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev) ...@@ -161,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev)
return exynos_asv_update_opps(asv); 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);
...@@ -68,4 +68,6 @@ static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *s ...@@ -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); 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 */ #endif /* __LINUX_SOC_EXYNOS_ASV_H */
...@@ -2,20 +2,28 @@ ...@@ -2,20 +2,28 @@
/* /*
* Copyright (c) 2019 Samsung Electronics Co., Ltd. * Copyright (c) 2019 Samsung Electronics Co., Ltd.
* http://www.samsung.com/ * http://www.samsung.com/
* Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org>
* *
* Exynos - CHIP ID support * Exynos - CHIP ID support
* Author: Pankaj Dubey <pankaj.dubey@samsung.com> * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
* Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@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/mfd/syscon.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/soc/samsung/exynos-chipid.h> #include <linux/soc/samsung/exynos-chipid.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include "exynos-asv.h"
static const struct exynos_soc_id { static const struct exynos_soc_id {
const char *name; const char *name;
unsigned int id; unsigned int id;
...@@ -36,7 +44,7 @@ static const struct exynos_soc_id { ...@@ -36,7 +44,7 @@ static const struct exynos_soc_id {
{ "EXYNOS7420", 0xE7420000 }, { "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; int i;
...@@ -46,25 +54,17 @@ static const char * __init product_id_to_soc_id(unsigned int product_id) ...@@ -46,25 +54,17 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
return NULL; 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_attribute *soc_dev_attr;
struct soc_device *soc_dev; struct soc_device *soc_dev;
struct device_node *root; struct device_node *root;
struct device_node *syscon;
struct regmap *regmap; struct regmap *regmap;
u32 product_id; u32 product_id;
u32 revision; u32 revision;
int ret; int ret;
syscon = of_find_compatible_node(NULL, NULL, regmap = device_node_to_regmap(pdev->dev.of_node);
"samsung,exynos4210-chipid");
if (!syscon)
return -ENODEV;
regmap = device_node_to_regmap(syscon);
of_node_put(syscon);
if (IS_ERR(regmap)) if (IS_ERR(regmap))
return PTR_ERR(regmap); return PTR_ERR(regmap);
...@@ -74,7 +74,8 @@ static int __init exynos_chipid_early_init(void) ...@@ -74,7 +74,8 @@ static int __init exynos_chipid_early_init(void)
revision = product_id & EXYNOS_REV_MASK; 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) if (!soc_dev_attr)
return -ENOMEM; return -ENOMEM;
...@@ -84,20 +85,24 @@ static int __init exynos_chipid_early_init(void) ...@@ -84,20 +85,24 @@ static int __init exynos_chipid_early_init(void)
of_property_read_string(root, "model", &soc_dev_attr->machine); of_property_read_string(root, "model", &soc_dev_attr->machine);
of_node_put(root); 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); soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
if (!soc_dev_attr->soc_id) { if (!soc_dev_attr->soc_id) {
pr_err("Unknown SoC\n"); pr_err("Unknown SoC\n");
ret = -ENODEV; return -ENODEV;
goto err;
} }
/* please note that the actual registration will be deferred */ /* please note that the actual registration will be deferred */
soc_dev = soc_device_register(soc_dev_attr); soc_dev = soc_device_register(soc_dev_attr);
if (IS_ERR(soc_dev)) { if (IS_ERR(soc_dev))
ret = PTR_ERR(soc_dev); return PTR_ERR(soc_dev);
ret = exynos_asv_init(&pdev->dev, regmap);
if (ret)
goto err; goto err;
}
platform_set_drvdata(pdev, soc_dev);
dev_info(soc_device_to_device(soc_dev), dev_info(soc_device_to_device(soc_dev),
"Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n", "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
...@@ -106,9 +111,31 @@ static int __init exynos_chipid_early_init(void) ...@@ -106,9 +111,31 @@ static int __init exynos_chipid_early_init(void)
return 0; return 0;
err: err:
kfree(soc_dev_attr->revision); soc_device_unregister(soc_dev);
kfree(soc_dev_attr);
return ret; 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);
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/sched.h> #include <linux/pm_runtime.h>
struct exynos_pm_domain_config { struct exynos_pm_domain_config {
/* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ /* 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) ...@@ -73,15 +73,15 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
return exynos_pd_power(domain, false); 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, .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, .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", .compatible = "samsung,exynos4210-pd",
.data = &exynos4210_cfg, .data = &exynos4210_cfg,
...@@ -92,7 +92,7 @@ static const struct of_device_id exynos_pm_domain_of_match[] __initconst = { ...@@ -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; const char *name;
...@@ -101,60 +101,44 @@ static __init const char *exynos_get_domain_name(struct device_node *node) ...@@ -101,60 +101,44 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
return kstrdup_const(name, GFP_KERNEL); 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 exynos_pm_domain_config *pm_domain_cfg;
const struct of_device_id *match; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { struct of_phandle_args child, parent;
const struct exynos_pm_domain_config *pm_domain_cfg; struct exynos_pm_domain *pd;
struct exynos_pm_domain *pd; int on, ret;
int on;
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); pd->pd.name = exynos_get_domain_name(np);
if (!pd) { if (!pd->pd.name)
of_node_put(np); return -ENOMEM;
return -ENOMEM;
}
pd->pd.name = exynos_get_domain_name(np);
if (!pd->pd.name) {
kfree(pd);
of_node_put(np);
return -ENOMEM;
}
pd->base = of_iomap(np, 0); pd->base = of_iomap(np, 0);
if (!pd->base) { if (!pd->base) {
pr_warn("%s: failed to map memory\n", __func__); kfree_const(pd->pd.name);
kfree_const(pd->pd.name); return -ENODEV;
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;
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); on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
of_genpd_add_provider_simple(np, &pd->pd);
}
/* Assign the child power domains to their parents */ pm_genpd_init(&pd->pd, NULL, !on);
for_each_matching_node(np, exynos_pm_domain_of_match) { ret = of_genpd_add_provider_simple(np, &pd->pd);
struct of_phandle_args child, parent;
if (ret == 0 && of_parse_phandle_with_args(np, "power-domains",
"#power-domain-cells", 0, &parent) == 0) {
child.np = np; child.np = np;
child.args_count = 0; 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)) if (of_genpd_add_subdomain(&parent, &child))
pr_warn("%pOF failed to add subdomain: %pOF\n", pr_warn("%pOF failed to add subdomain: %pOF\n",
parent.np, child.np); parent.np, child.np);
...@@ -163,6 +147,21 @@ static __init int exynos4_pm_init_power_domain(void) ...@@ -163,6 +147,21 @@ static __init int exynos4_pm_init_power_domain(void)
parent.np, child.np); 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); core_initcall(exynos4_pm_init_power_domain);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment