mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
ARM: SoC changes for v5.12
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 Signed-off-by: Arnd Bergmann <arnd@arndb.de> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmApkHsACgkQYKtH/8kJ UidKTRAA4nFode+U/cvcfDoA4HoUseDTzEHL7WmEjnQk48lEbNI3B2rONFkzXtFC Wa8dvZw8EQ/bx/Sfe2WHUCVPEK6iVzb8AaaYPx06Xg6yFQjSEc4qdeeBtWFaRZoC tmGQWMNjB3IzxhrKGwCwhbuUuVdIWN7DlKcyx+5sMjg9oPO7Ptb557VtR5f1vjQC UR1KB1IBag2hNuE2BRPpmbOn/Jhq0ADQRrIm0sjvWN9CmArL7Og9WiuU0pwkmbqn AGnzsylJ8+kR70F4O+s20SOC+NkAK1uA80+QeNDX9IeCyI2mz5ubg1tkXLb9nIQQ qLYoMI7tUWTnROhcO10nSLz4wqcWWLKgf+6Wsod6lhUS8DNSYC5/bDf13UYHzGu0 fQZZxp7hEabKcD/Ub8IpY4hUfeUfpWts/h0iUVkpQfCYAreRxUG8C7ZHjIWycdg9 cOl6GyPLe397ONfX4XER0htICjUSrSCB09EpmoFfdBDBlbw/E1eZoKjTI0emEu2J bvA1x7orDdlCJcQn5dPpP1L2HTh1gLC8/LFFuAHtMozuxGqp7f5pHXn+6OhiHLcA l5+T/+53iVGxvfC4g3/Pk+SQAEjF0RpL/cA8EZ5kA0MmxuwQPt35yo2RobCTEfRi 7yC0dD4HavvDK1gfAJ7Af7v4lBtX3MidvY5el+dNjuGKvBJTqGg= =2ehx -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
5011bb9fbb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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 ]
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
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;
|
||||
|
||||
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;
|
||||
pm_domain_cfg = of_device_get_match_data(dev);
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
pm_domain_cfg = match->data;
|
||||
pd->pd.name = exynos_get_domain_name(np);
|
||||
if (!pd->pd.name)
|
||||
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->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;
|
||||
|
||||
on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
|
||||
|
||||
pm_genpd_init(&pd->pd, NULL, !on);
|
||||
of_genpd_add_provider_simple(np, &pd->pd);
|
||||
pd->base = of_iomap(np, 0);
|
||||
if (!pd->base) {
|
||||
kfree_const(pd->pd.name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Assign the child power domains to their parents */
|
||||
for_each_matching_node(np, exynos_pm_domain_of_match) {
|
||||
struct of_phandle_args child, parent;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user