提交 8850e0ba 编写于 作者: O Olof Johansson

Merge tag 'samsung-dt-2' of...

Merge tag 'samsung-dt-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/dt

Merge "Samsung DT 2nd updates for v3.17" from Kukjin Kim:

This is based on tags/exynos-power because this DT changes
are depending PMU cleanup.

Fixes boot for exynos5260 and exynos5410,
- Since exynos cannot boot without obtaining PMU address via
  DT from now on, add PMU node for exynos5260 and exynos5410

For preparing exynos5250-spring,
- move max77686 and cypress,cyapa trackpad from exynos5250-
  cros-common to exynos5250-snow DT file
(Note exynos5250-spring is not included in this branch yet)

For exynos3250,
- add TMU node and remove duplicated interrupt-parent
- add missing pinctrl property for uart0 and uart1

For exynos5250-smdk5250 board
- add max77686 pmic interrupt property which is connected to
  gpx3

* tag 'samsung-dt-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: (28 commits)
  ARM: dts: Add missing pinctrl for uart0/1 for exynos3250
  ARM: dts: Remove duplicate 'interrput-parent' property for exynos3250
  ARM: dts: Add TMU dt node to monitor the temperature for exynos3250
  ARM: dts: Specify MAX77686 pmic interrupt for exynos5250-smdk5250
  ARM: dts: cypress,cyapa trackpad is exynos5250-Snow only
  ARM: dts: max77686 is exynos5250-snow only
  ARM: EXYNOS: Add exynos5260 PMU compatible string to DT match table
  ARM: dts: Add PMU DT node for exynos5260 SoC
  ARM: EXYNOS: Add support for Exynos5410 PMU
  ARM: dts: Add PMU to exynos5410
  ARM: dts: Document exynos5410 PMU
  ARM: EXYNOS: Move cpufreq and cpuidle device registration to init_machine
  ARM: EXYNOS: Refactored code for using PMU address via DT
  ARM: EXYNOS: Support cluster power off on exynos5420/5800
  ARM: EXYNOS: populate suspend and powered_up callbacks for mcpm
  ARM: EXYNOS: do not allow cpuidle registration for exynos5420
  cpuidle: big.LITTLE: init driver for exynos5420
  cpuidle: big.LITTLE: Add ARCH_EXYNOS entry in config
  ARM: EXYNOS: add generic function to calculate cpu number
  cpuidle: big.LITTLE: add of_device_id structure
  ...
Signed-off-by: NOlof Johansson <olof@lixom.net>
...@@ -7,6 +7,8 @@ Properties: ...@@ -7,6 +7,8 @@ Properties:
- "samsung,exynos4212-pmu" - for Exynos4212 SoC, - "samsung,exynos4212-pmu" - for Exynos4212 SoC,
- "samsung,exynos4412-pmu" - for Exynos4412 SoC, - "samsung,exynos4412-pmu" - for Exynos4412 SoC,
- "samsung,exynos5250-pmu" - for Exynos5250 SoC, - "samsung,exynos5250-pmu" - for Exynos5250 SoC,
- "samsung,exynos5260-pmu" - for Exynos5260 SoC.
- "samsung,exynos5410-pmu" - for Exynos5410 SoC,
- "samsung,exynos5420-pmu" - for Exynos5420 SoC. - "samsung,exynos5420-pmu" - for Exynos5420 SoC.
second value must be always "syscon". second value must be always "syscon".
......
...@@ -625,53 +625,41 @@ choice ...@@ -625,53 +625,41 @@ choice
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C24XX_UART if ARCH_S3C24XX
bool "Use S3C UART 0 for low-level debug" bool "Use Samsung S3C UART 0 for low-level debug"
help help
Say Y here if you want the debug print routines to direct Say Y here if you want the debug print routines to direct
their output to UART 0. The port must have been initialised their output to UART 0. The port must have been initialised
by the boot-loader before use. by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C_UART1 config DEBUG_S3C_UART1
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C24XX_UART if ARCH_S3C24XX
bool "Use S3C UART 1 for low-level debug" bool "Use Samsung S3C UART 1 for low-level debug"
help help
Say Y here if you want the debug print routines to direct Say Y here if you want the debug print routines to direct
their output to UART 1. The port must have been initialised their output to UART 1. The port must have been initialised
by the boot-loader before use. by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C_UART2 config DEBUG_S3C_UART2
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS select DEBUG_EXYNOS_UART if ARCH_EXYNOS
select DEBUG_S3C24XX_UART if ARCH_S3C24XX select DEBUG_S3C24XX_UART if ARCH_S3C24XX
bool "Use S3C UART 2 for low-level debug" bool "Use Samsung S3C UART 2 for low-level debug"
help help
Say Y here if you want the debug print routines to direct Say Y here if you want the debug print routines to direct
their output to UART 2. The port must have been initialised their output to UART 2. The port must have been initialised
by the boot-loader before use. by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C_UART3 config DEBUG_S3C_UART3
depends on PLAT_SAMSUNG && ARCH_EXYNOS depends on PLAT_SAMSUNG && ARCH_EXYNOS
select DEBUG_EXYNOS_UART select DEBUG_EXYNOS_UART
bool "Use S3C UART 3 for low-level debug" bool "Use Samsung S3C UART 3 for low-level debug"
help help
Say Y here if you want the debug print routines to direct Say Y here if you want the debug print routines to direct
their output to UART 3. The port must have been initialised their output to UART 3. The port must have been initialised
by the boot-loader before use. by the boot-loader before use.
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
config DEBUG_S3C2410_UART0 config DEBUG_S3C2410_UART0
depends on ARCH_S3C24XX depends on ARCH_S3C24XX
select DEBUG_S3C2410_UART select DEBUG_S3C2410_UART
......
...@@ -168,6 +168,15 @@ ...@@ -168,6 +168,15 @@
status = "disabled"; status = "disabled";
}; };
tmu: tmu@100C0000 {
compatible = "samsung,exynos3250-tmu";
reg = <0x100C0000 0x100>;
interrupts = <0 216 0>;
clocks = <&cmu CLK_TMU_APBIF>;
clock-names = "tmu_apbif";
status = "disabled";
};
gic: interrupt-controller@10481000 { gic: interrupt-controller@10481000 {
compatible = "arm,cortex-a15-gic"; compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>; #interrupt-cells = <3>;
...@@ -195,7 +204,6 @@ ...@@ -195,7 +204,6 @@
wakeup-interrupt-controller { wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint"; compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
interrupts = <0 48 0>; interrupts = <0 48 0>;
}; };
}; };
...@@ -234,7 +242,6 @@ ...@@ -234,7 +242,6 @@
compatible = "arm,amba-bus"; compatible = "arm,amba-bus";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
interrupt-parent = <&gic>;
ranges; ranges;
pdma0: pdma@12680000 { pdma0: pdma@12680000 {
...@@ -277,6 +284,8 @@ ...@@ -277,6 +284,8 @@
interrupts = <0 109 0>; interrupts = <0 109 0>;
clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>; clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0"; clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
pinctrl-0 = <&uart0_data &uart0_fctl>;
status = "disabled"; status = "disabled";
}; };
...@@ -286,6 +295,8 @@ ...@@ -286,6 +295,8 @@
interrupts = <0 110 0>; interrupts = <0 110 0>;
clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>; clocks = <&cmu CLK_UART1>, <&cmu CLK_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0"; clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
pinctrl-0 = <&uart1_data>;
status = "disabled"; status = "disabled";
}; };
......
...@@ -27,177 +27,18 @@ ...@@ -27,177 +27,18 @@
i2c2_bus: i2c2-bus { i2c2_bus: i2c2-bus {
samsung,pin-pud = <0>; samsung,pin-pud = <0>;
}; };
max77686_irq: max77686-irq {
samsung,pins = "gpx3-2";
samsung,pin-function = <0>;
samsung,pin-pud = <0>;
samsung,pin-drv = <0>;
};
}; };
i2c@12C60000 { i2c@12C60000 {
status = "okay"; status = "okay";
samsung,i2c-sda-delay = <100>; samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <378000>; samsung,i2c-max-bus-freq = <378000>;
max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&gpx3>;
interrupts = <2 0>;
pinctrl-names = "default";
pinctrl-0 = <&max77686_irq>;
wakeup-source;
reg = <0x09>;
#clock-cells = <1>;
voltage-regulators {
ldo1_reg: LDO1 {
regulator-name = "P1.0V_LDO_OUT1";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo2_reg: LDO2 {
regulator-name = "P1.8V_LDO_OUT2";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo3_reg: LDO3 {
regulator-name = "P1.8V_LDO_OUT3";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo7_reg: LDO7 {
regulator-name = "P1.1V_LDO_OUT7";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
ldo8_reg: LDO8 {
regulator-name = "P1.0V_LDO_OUT8";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo10_reg: LDO10 {
regulator-name = "P1.8V_LDO_OUT10";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo12_reg: LDO12 {
regulator-name = "P3.0V_LDO_OUT12";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo14_reg: LDO14 {
regulator-name = "P1.8V_LDO_OUT14";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo15_reg: LDO15 {
regulator-name = "P1.0V_LDO_OUT15";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo16_reg: LDO16 {
regulator-name = "P1.8V_LDO_OUT16";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck3_reg: BUCK3 {
regulator-name = "vdd_int";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
buck4_reg: BUCK4 {
regulator-name = "vdd_g3d";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
buck5_reg: BUCK5 {
regulator-name = "P1.8V_BUCK_OUT5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
buck6_reg: BUCK6 {
regulator-name = "P1.35V_BUCK_OUT6";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
};
buck7_reg: BUCK7 {
regulator-name = "P2.0V_BUCK_OUT7";
regulator-min-microvolt = <2000000>;
regulator-max-microvolt = <2000000>;
regulator-always-on;
};
buck8_reg: BUCK8 {
regulator-name = "P2.85V_BUCK_OUT8";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
regulator-always-on;
};
};
};
}; };
i2c@12C70000 { i2c@12C70000 {
status = "okay"; status = "okay";
samsung,i2c-sda-delay = <100>; samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <378000>; samsung,i2c-max-bus-freq = <378000>;
trackpad {
reg = <0x67>;
compatible = "cypress,cyapa";
interrupts = <2 0>;
interrupt-parent = <&gpx1>;
wakeup-source;
};
}; };
i2c@12C80000 { i2c@12C80000 {
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
max77686@09 { max77686@09 {
compatible = "maxim,max77686"; compatible = "maxim,max77686";
reg = <0x09>; reg = <0x09>;
interrupt-parent = <&gpx3>;
interrupts = <2 0>;
voltage-regulators { voltage-regulators {
ldo1_reg: LDO1 { ldo1_reg: LDO1 {
......
...@@ -344,4 +344,169 @@ ...@@ -344,4 +344,169 @@
}; };
}; };
&i2c_0 {
max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&gpx3>;
interrupts = <2 0>;
pinctrl-names = "default";
pinctrl-0 = <&max77686_irq>;
wakeup-source;
reg = <0x09>;
#clock-cells = <1>;
voltage-regulators {
ldo1_reg: LDO1 {
regulator-name = "P1.0V_LDO_OUT1";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo2_reg: LDO2 {
regulator-name = "P1.8V_LDO_OUT2";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo3_reg: LDO3 {
regulator-name = "P1.8V_LDO_OUT3";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo7_reg: LDO7 {
regulator-name = "P1.1V_LDO_OUT7";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
ldo8_reg: LDO8 {
regulator-name = "P1.0V_LDO_OUT8";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo10_reg: LDO10 {
regulator-name = "P1.8V_LDO_OUT10";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo12_reg: LDO12 {
regulator-name = "P3.0V_LDO_OUT12";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
ldo14_reg: LDO14 {
regulator-name = "P1.8V_LDO_OUT14";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
ldo15_reg: LDO15 {
regulator-name = "P1.0V_LDO_OUT15";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-always-on;
};
ldo16_reg: LDO16 {
regulator-name = "P1.8V_LDO_OUT16";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck3_reg: BUCK3 {
regulator-name = "vdd_int";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
buck4_reg: BUCK4 {
regulator-name = "vdd_g3d";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
buck5_reg: BUCK5 {
regulator-name = "P1.8V_BUCK_OUT5";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
buck6_reg: BUCK6 {
regulator-name = "P1.35V_BUCK_OUT6";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
};
buck7_reg: BUCK7 {
regulator-name = "P2.0V_BUCK_OUT7";
regulator-min-microvolt = <2000000>;
regulator-max-microvolt = <2000000>;
regulator-always-on;
};
buck8_reg: BUCK8 {
regulator-name = "P2.85V_BUCK_OUT8";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
regulator-always-on;
};
};
};
};
&i2c_1 {
trackpad {
reg = <0x67>;
compatible = "cypress,cyapa";
interrupts = <2 0>;
interrupt-parent = <&gpx1>;
wakeup-source;
};
};
&pinctrl_0 {
max77686_irq: max77686-irq {
samsung,pins = "gpx3-2";
samsung,pin-function = <0>;
samsung,pin-pud = <0>;
samsung,pin-drv = <0>;
};
};
#include "cros-ec-keyboard.dtsi" #include "cros-ec-keyboard.dtsi"
...@@ -227,6 +227,11 @@ ...@@ -227,6 +227,11 @@
interrupts = <0 243 0>; interrupts = <0 243 0>;
}; };
pmu_system_controller: system-controller@10D50000 {
compatible = "samsung,exynos5260-pmu", "syscon";
reg = <0x10D50000 0x10000>;
};
uart0: serial@12C00000 { uart0: serial@12C00000 {
compatible = "samsung,exynos4210-uart"; compatible = "samsung,exynos4210-uart";
reg = <0x12C00000 0x100>; reg = <0x12C00000 0x100>;
......
...@@ -91,6 +91,11 @@ ...@@ -91,6 +91,11 @@
reg = <0x10000000 0x100>; reg = <0x10000000 0x100>;
}; };
pmu_system_controller: system-controller@10040000 {
compatible = "samsung,exynos5410-pmu", "syscon";
reg = <0x10040000 0x5000>;
};
mct: mct@101C0000 { mct: mct@101C0000 {
compatible = "samsung,exynos4210-mct"; compatible = "samsung,exynos4210-mct";
reg = <0x101C0000 0xB00>; reg = <0x101C0000 0xB00>;
......
...@@ -111,25 +111,14 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK) ...@@ -111,25 +111,14 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \ #define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
soc_is_exynos5420() || soc_is_exynos5800()) soc_is_exynos5420() || soc_is_exynos5800())
void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
struct map_desc;
extern void __iomem *sysram_ns_base_addr; extern void __iomem *sysram_ns_base_addr;
extern void __iomem *sysram_base_addr; extern void __iomem *sysram_base_addr;
void exynos_init_io(void); extern void __iomem *pmu_base_addr;
void exynos_restart(enum reboot_mode mode, const char *cmd);
void exynos_sysram_init(void); void exynos_sysram_init(void);
void exynos_cpuidle_init(void);
void exynos_cpufreq_init(void);
void exynos_init_late(void);
void exynos_firmware_init(void); void exynos_firmware_init(void);
#ifdef CONFIG_PINCTRL_EXYNOS
extern u32 exynos_get_eint_wake_mask(void); extern u32 exynos_get_eint_wake_mask(void);
#else
static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
#endif
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
extern void __init exynos_pm_init(void); extern void __init exynos_pm_init(void);
...@@ -145,7 +134,7 @@ extern void exynos_cpu_die(unsigned int cpu); ...@@ -145,7 +134,7 @@ extern void exynos_cpu_die(unsigned int cpu);
/* PMU(Power Management Unit) support */ /* PMU(Power Management Unit) support */
#define PMU_TABLE_END NULL #define PMU_TABLE_END (-1U)
enum sys_powerdown { enum sys_powerdown {
SYS_AFTR, SYS_AFTR,
...@@ -155,7 +144,7 @@ enum sys_powerdown { ...@@ -155,7 +144,7 @@ enum sys_powerdown {
}; };
struct exynos_pmu_conf { struct exynos_pmu_conf {
void __iomem *reg; unsigned int offset;
unsigned int val[NUM_SYS_POWERDOWN]; unsigned int val[NUM_SYS_POWERDOWN];
}; };
...@@ -171,4 +160,14 @@ extern void exynos_enter_aftr(void); ...@@ -171,4 +160,14 @@ extern void exynos_enter_aftr(void);
extern void s5p_init_cpu(void __iomem *cpuid_addr); extern void s5p_init_cpu(void __iomem *cpuid_addr);
extern unsigned int samsung_rev(void); extern unsigned int samsung_rev(void);
static inline void pmu_raw_writel(u32 val, u32 offset)
{
__raw_writel(val, pmu_base_addr + offset);
}
static inline u32 pmu_raw_readl(u32 offset)
{
return __raw_readl(pmu_base_addr + offset);
}
#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
#include <linux/irqchip.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/cache-l2x0.h>
...@@ -29,6 +30,9 @@ ...@@ -29,6 +30,9 @@
#include "common.h" #include "common.h"
#include "mfc.h" #include "mfc.h"
#include "regs-pmu.h" #include "regs-pmu.h"
#include "regs-sys.h"
void __iomem *pmu_base_addr;
static struct map_desc exynos4_iodesc[] __initdata = { static struct map_desc exynos4_iodesc[] __initdata = {
{ {
...@@ -56,11 +60,6 @@ static struct map_desc exynos4_iodesc[] __initdata = { ...@@ -56,11 +60,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
.pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_PMU,
.pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
.length = SZ_64K,
.type = MT_DEVICE,
}, { }, {
.virtual = (unsigned long)S5P_VA_COMBINER_BASE, .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
.pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER), .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
...@@ -135,19 +134,14 @@ static struct map_desc exynos5_iodesc[] __initdata = { ...@@ -135,19 +134,14 @@ static struct map_desc exynos5_iodesc[] __initdata = {
.pfn = __phys_to_pfn(EXYNOS5_PA_CMU), .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
.length = 144 * SZ_1K, .length = 144 * SZ_1K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_PMU,
.pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
.length = SZ_64K,
.type = MT_DEVICE,
}, },
}; };
void exynos_restart(enum reboot_mode mode, const char *cmd) static void exynos_restart(enum reboot_mode mode, const char *cmd)
{ {
struct device_node *np; struct device_node *np;
u32 val = 0x1; u32 val = 0x1;
void __iomem *addr = EXYNOS_SWRESET; void __iomem *addr = pmu_base_addr + EXYNOS_SWRESET;
if (of_machine_is_compatible("samsung,exynos5440")) { if (of_machine_is_compatible("samsung,exynos5440")) {
u32 status; u32 status;
...@@ -171,17 +165,6 @@ static struct platform_device exynos_cpuidle = { ...@@ -171,17 +165,6 @@ static struct platform_device exynos_cpuidle = {
.id = -1, .id = -1,
}; };
void __init exynos_cpuidle_init(void)
{
if (soc_is_exynos4210() || soc_is_exynos5250())
platform_device_register(&exynos_cpuidle);
}
void __init exynos_cpufreq_init(void)
{
platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
}
void __iomem *sysram_base_addr; void __iomem *sysram_base_addr;
void __iomem *sysram_ns_base_addr; void __iomem *sysram_ns_base_addr;
...@@ -204,7 +187,7 @@ void __init exynos_sysram_init(void) ...@@ -204,7 +187,7 @@ void __init exynos_sysram_init(void)
} }
} }
void __init exynos_init_late(void) static void __init exynos_init_late(void)
{ {
if (of_machine_is_compatible("samsung,exynos5440")) if (of_machine_is_compatible("samsung,exynos5440"))
/* to be supported later */ /* to be supported later */
...@@ -251,7 +234,7 @@ static void __init exynos_map_io(void) ...@@ -251,7 +234,7 @@ static void __init exynos_map_io(void)
iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc)); iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
} }
void __init exynos_init_io(void) static void __init exynos_init_io(void)
{ {
debug_ll_io_init(); debug_ll_io_init();
...@@ -263,6 +246,41 @@ void __init exynos_init_io(void) ...@@ -263,6 +246,41 @@ void __init exynos_init_io(void)
exynos_map_io(); exynos_map_io();
} }
static const struct of_device_id exynos_dt_pmu_match[] = {
{ .compatible = "samsung,exynos3250-pmu" },
{ .compatible = "samsung,exynos4210-pmu" },
{ .compatible = "samsung,exynos4212-pmu" },
{ .compatible = "samsung,exynos4412-pmu" },
{ .compatible = "samsung,exynos5250-pmu" },
{ .compatible = "samsung,exynos5260-pmu" },
{ .compatible = "samsung,exynos5410-pmu" },
{ .compatible = "samsung,exynos5420-pmu" },
{ /*sentinel*/ },
};
static void exynos_map_pmu(void)
{
struct device_node *np;
np = of_find_matching_node(NULL, exynos_dt_pmu_match);
if (np)
pmu_base_addr = of_iomap(np, 0);
if (!pmu_base_addr)
panic("failed to find exynos pmu register\n");
}
static void __init exynos_init_irq(void)
{
irqchip_init();
/*
* Since platsmp.c needs pmu base address by the time
* DT is not unflatten so we can't use DT APIs before
* init_irq
*/
exynos_map_pmu();
}
static void __init exynos_dt_machine_init(void) static void __init exynos_dt_machine_init(void)
{ {
struct device_node *i2c_np; struct device_node *i2c_np;
...@@ -298,8 +316,11 @@ static void __init exynos_dt_machine_init(void) ...@@ -298,8 +316,11 @@ static void __init exynos_dt_machine_init(void)
if (!IS_ENABLED(CONFIG_SMP)) if (!IS_ENABLED(CONFIG_SMP))
exynos_sysram_init(); exynos_sysram_init();
exynos_cpuidle_init(); if (of_machine_is_compatible("samsung,exynos4210") ||
exynos_cpufreq_init(); of_machine_is_compatible("samsung,exynos5250"))
platform_device_register(&exynos_cpuidle);
platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
...@@ -343,6 +364,7 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)") ...@@ -343,6 +364,7 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
.smp = smp_ops(exynos_smp_ops), .smp = smp_ops(exynos_smp_ops),
.map_io = exynos_init_io, .map_io = exynos_init_io,
.init_early = exynos_firmware_init, .init_early = exynos_firmware_init,
.init_irq = exynos_init_irq,
.init_machine = exynos_dt_machine_init, .init_machine = exynos_dt_machine_init,
.init_late = exynos_init_late, .init_late = exynos_init_late,
.dt_compat = exynos_dt_compat, .dt_compat = exynos_dt_compat,
......
/* /*
* linux/arch/arm/mach-exynos4/headsmp.S
* *
* Cloned from linux/arch/arm/mach-realview/headsmp.S * Cloned from linux/arch/arm/mach-realview/headsmp.S
* *
......
/* linux arch/arm/mach-exynos4/hotplug.c /*
*
* Cloned from linux/arch/arm/mach-realview/hotplug.c * Cloned from linux/arch/arm/mach-realview/hotplug.c
* *
* Copyright (C) 2002 ARM Ltd. * Copyright (C) 2002 ARM Ltd.
......
/* linux/arch/arm/mach-exynos/include/mach/map.h /*
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/ * http://www.samsung.com/
* *
...@@ -28,9 +27,6 @@ ...@@ -28,9 +27,6 @@
#define EXYNOS4_PA_SYSCON 0x10010000 #define EXYNOS4_PA_SYSCON 0x10010000
#define EXYNOS5_PA_SYSCON 0x10050100 #define EXYNOS5_PA_SYSCON 0x10050100
#define EXYNOS4_PA_PMU 0x10020000
#define EXYNOS5_PA_PMU 0x10040000
#define EXYNOS4_PA_CMU 0x10030000 #define EXYNOS4_PA_CMU 0x10030000
#define EXYNOS5_PA_CMU 0x10010000 #define EXYNOS5_PA_CMU 0x10010000
......
/* linux/arch/arm/mach-exynos4/include/mach/memory.h /*
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
......
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
#define EXYNOS5420_CPUS_PER_CLUSTER 4 #define EXYNOS5420_CPUS_PER_CLUSTER 4
#define EXYNOS5420_NR_CLUSTERS 2 #define EXYNOS5420_NR_CLUSTERS 2
#define EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN BIT(9)
#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
/* /*
* The common v7_exit_coherency_flush API could not be used because of the * The common v7_exit_coherency_flush API could not be used because of the
* Erratum 799270 workaround. This macro is the same as the common one (in * Erratum 799270 workaround. This macro is the same as the common one (in
...@@ -51,7 +55,7 @@ ...@@ -51,7 +55,7 @@
"dsb\n\t" \ "dsb\n\t" \
"ldmfd sp!, {fp, ip}" \ "ldmfd sp!, {fp, ip}" \
: \ : \
: "Ir" (S5P_INFORM0) \ : "Ir" (pmu_base_addr + S5P_INFORM0) \
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r9", "r10", "lr", "memory") "r9", "r10", "lr", "memory")
...@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS]; ...@@ -73,36 +77,9 @@ cpu_use_count[EXYNOS5420_CPUS_PER_CLUSTER][EXYNOS5420_NR_CLUSTERS];
#define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster) #define exynos_cluster_unused(cluster) !exynos_cluster_usecnt(cluster)
static int exynos_cluster_power_control(unsigned int cluster, int enable)
{
unsigned int tries = 100;
unsigned int val;
if (enable) {
exynos_cluster_power_up(cluster);
val = S5P_CORE_LOCAL_PWR_EN;
} else {
exynos_cluster_power_down(cluster);
val = 0;
}
/* Wait until cluster power control is applied */
while (tries--) {
if (exynos_cluster_power_state(cluster) == val)
return 0;
cpu_relax();
}
pr_debug("timed out waiting for cluster %u to power %s\n", cluster,
enable ? "on" : "off");
return -ETIMEDOUT;
}
static int exynos_power_up(unsigned int cpu, unsigned int cluster) static int exynos_power_up(unsigned int cpu, unsigned int cluster)
{ {
unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER); unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER);
int err = 0;
pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER || if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER ||
...@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster) ...@@ -126,12 +103,9 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
* cores. * cores.
*/ */
if (was_cluster_down) if (was_cluster_down)
err = exynos_cluster_power_control(cluster, 1); exynos_cluster_power_up(cluster);
if (!err)
exynos_cpu_power_up(cpunr); exynos_cpu_power_up(cpunr);
else
exynos_cluster_power_control(cluster, 0);
} else if (cpu_use_count[cpu][cluster] != 2) { } else if (cpu_use_count[cpu][cluster] != 2) {
/* /*
* The only possible values are: * The only possible values are:
...@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster) ...@@ -147,7 +121,7 @@ static int exynos_power_up(unsigned int cpu, unsigned int cluster)
arch_spin_unlock(&exynos_mcpm_lock); arch_spin_unlock(&exynos_mcpm_lock);
local_irq_enable(); local_irq_enable();
return err; return 0;
} }
/* /*
...@@ -178,9 +152,10 @@ static void exynos_power_down(void) ...@@ -178,9 +152,10 @@ static void exynos_power_down(void)
if (cpu_use_count[cpu][cluster] == 0) { if (cpu_use_count[cpu][cluster] == 0) {
exynos_cpu_power_down(cpunr); exynos_cpu_power_down(cpunr);
if (exynos_cluster_unused(cluster)) if (exynos_cluster_unused(cluster)) {
/* TODO: Turn off the cluster here to save power. */ exynos_cluster_power_down(cluster);
last_man = true; last_man = true;
}
} else if (cpu_use_count[cpu][cluster] == 1) { } else if (cpu_use_count[cpu][cluster] == 1) {
/* /*
* A power_up request went ahead of us. * A power_up request went ahead of us.
...@@ -257,10 +232,46 @@ static int exynos_wait_for_powerdown(unsigned int cpu, unsigned int cluster) ...@@ -257,10 +232,46 @@ static int exynos_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
return -ETIMEDOUT; /* timeout */ return -ETIMEDOUT; /* timeout */
} }
static void exynos_powered_up(void)
{
unsigned int mpidr, cpu, cluster;
mpidr = read_cpuid_mpidr();
cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
arch_spin_lock(&exynos_mcpm_lock);
if (cpu_use_count[cpu][cluster] == 0)
cpu_use_count[cpu][cluster] = 1;
arch_spin_unlock(&exynos_mcpm_lock);
}
static void exynos_suspend(u64 residency)
{
unsigned int mpidr, cpunr;
exynos_power_down();
/*
* Execution reaches here only if cpu did not power down.
* Hence roll back the changes done in exynos_power_down function.
*
* CAUTION: "This function requires the stack data to be visible through
* power down and can only be executed on processors like A15 and A7
* that hit the cache with the C bit clear in the SCTLR register."
*/
mpidr = read_cpuid_mpidr();
cpunr = exynos_pmu_cpunr(mpidr);
exynos_cpu_power_up(cpunr);
}
static const struct mcpm_platform_ops exynos_power_ops = { static const struct mcpm_platform_ops exynos_power_ops = {
.power_up = exynos_power_up, .power_up = exynos_power_up,
.power_down = exynos_power_down, .power_down = exynos_power_down,
.wait_for_powerdown = exynos_wait_for_powerdown, .wait_for_powerdown = exynos_wait_for_powerdown,
.suspend = exynos_suspend,
.powered_up = exynos_powered_up,
}; };
static void __init exynos_mcpm_usage_count_init(void) static void __init exynos_mcpm_usage_count_init(void)
...@@ -299,6 +310,7 @@ static int __init exynos_mcpm_init(void) ...@@ -299,6 +310,7 @@ static int __init exynos_mcpm_init(void)
{ {
struct device_node *node; struct device_node *node;
void __iomem *ns_sram_base_addr; void __iomem *ns_sram_base_addr;
unsigned int value, i;
int ret; int ret;
node = of_find_matching_node(NULL, exynos_dt_mcpm_match); node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
...@@ -325,7 +337,7 @@ static int __init exynos_mcpm_init(void) ...@@ -325,7 +337,7 @@ static int __init exynos_mcpm_init(void)
* To increase the stability of KFC reset we need to program * To increase the stability of KFC reset we need to program
* the PMU SPARE3 register * the PMU SPARE3 register
*/ */
__raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3); pmu_raw_writel(EXYNOS5420_SWRESET_KFC_SEL, S5P_PMU_SPARE3);
exynos_mcpm_usage_count_init(); exynos_mcpm_usage_count_init();
...@@ -341,6 +353,26 @@ static int __init exynos_mcpm_init(void) ...@@ -341,6 +353,26 @@ static int __init exynos_mcpm_init(void)
pr_info("Exynos MCPM support installed\n"); pr_info("Exynos MCPM support installed\n");
/*
* On Exynos5420/5800 for the A15 and A7 clusters:
*
* EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN ensures that all the cores
* in a cluster are turned off before turning off the cluster L2.
*
* EXYNOS5420_USE_ARM_CORE_DOWN_STATE ensures that a cores is powered
* off before waking it up.
*
* EXYNOS5420_USE_L2_COMMON_UP_STATE ensures that cluster L2 will be
* turned on before the first man is powered up.
*/
for (i = 0; i < EXYNOS5420_NR_CLUSTERS; i++) {
value = pmu_raw_readl(EXYNOS_COMMON_OPTION(i));
value |= EXYNOS5420_ENABLE_AUTOMATIC_CORE_DOWN |
EXYNOS5420_USE_ARM_CORE_DOWN_STATE |
EXYNOS5420_USE_L2_COMMON_UP_STATE;
pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i));
}
/* /*
* U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
* as part of secondary_cpu_start(). Let's redirect it to the * as part of secondary_cpu_start(). Let's redirect it to the
......
/* linux/arch/arm/mach-exynos4/platsmp.c /*
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
...@@ -27,6 +26,8 @@ ...@@ -27,6 +26,8 @@
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <mach/map.h>
#include "common.h" #include "common.h"
#include "regs-pmu.h" #include "regs-pmu.h"
...@@ -35,7 +36,7 @@ extern void exynos4_secondary_startup(void); ...@@ -35,7 +36,7 @@ extern void exynos4_secondary_startup(void);
static inline void __iomem *cpu_boot_reg_base(void) static inline void __iomem *cpu_boot_reg_base(void)
{ {
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1) if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
return S5P_INFORM5; return pmu_base_addr + S5P_INFORM5;
return sysram_base_addr; return sysram_base_addr;
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "common.h" #include "common.h"
#include "regs-pmu.h" #include "regs-pmu.h"
#include "regs-sys.h"
/** /**
* struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
...@@ -110,7 +111,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) ...@@ -110,7 +111,7 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
*/ */
void exynos_cpu_power_down(int cpu) void exynos_cpu_power_down(int cpu)
{ {
__raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
} }
/** /**
...@@ -121,7 +122,7 @@ void exynos_cpu_power_down(int cpu) ...@@ -121,7 +122,7 @@ void exynos_cpu_power_down(int cpu)
*/ */
void exynos_cpu_power_up(int cpu) void exynos_cpu_power_up(int cpu)
{ {
__raw_writel(S5P_CORE_LOCAL_PWR_EN, pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN,
EXYNOS_ARM_CORE_CONFIGURATION(cpu)); EXYNOS_ARM_CORE_CONFIGURATION(cpu));
} }
...@@ -132,7 +133,7 @@ void exynos_cpu_power_up(int cpu) ...@@ -132,7 +133,7 @@ void exynos_cpu_power_up(int cpu)
*/ */
int exynos_cpu_power_state(int cpu) int exynos_cpu_power_state(int cpu)
{ {
return (__raw_readl(EXYNOS_ARM_CORE_STATUS(cpu)) & return (pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(cpu)) &
S5P_CORE_LOCAL_PWR_EN); S5P_CORE_LOCAL_PWR_EN);
} }
...@@ -142,7 +143,7 @@ int exynos_cpu_power_state(int cpu) ...@@ -142,7 +143,7 @@ int exynos_cpu_power_state(int cpu)
*/ */
void exynos_cluster_power_down(int cluster) void exynos_cluster_power_down(int cluster)
{ {
__raw_writel(0, EXYNOS_COMMON_CONFIGURATION(cluster)); pmu_raw_writel(0, EXYNOS_COMMON_CONFIGURATION(cluster));
} }
/** /**
...@@ -151,7 +152,7 @@ void exynos_cluster_power_down(int cluster) ...@@ -151,7 +152,7 @@ void exynos_cluster_power_down(int cluster)
*/ */
void exynos_cluster_power_up(int cluster) void exynos_cluster_power_up(int cluster)
{ {
__raw_writel(S5P_CORE_LOCAL_PWR_EN, pmu_raw_writel(S5P_CORE_LOCAL_PWR_EN,
EXYNOS_COMMON_CONFIGURATION(cluster)); EXYNOS_COMMON_CONFIGURATION(cluster));
} }
...@@ -162,16 +163,20 @@ void exynos_cluster_power_up(int cluster) ...@@ -162,16 +163,20 @@ void exynos_cluster_power_up(int cluster)
*/ */
int exynos_cluster_power_state(int cluster) int exynos_cluster_power_state(int cluster)
{ {
return (__raw_readl(EXYNOS_COMMON_STATUS(cluster)) & return (pmu_raw_readl(EXYNOS_COMMON_STATUS(cluster)) &
S5P_CORE_LOCAL_PWR_EN); S5P_CORE_LOCAL_PWR_EN);
} }
#define EXYNOS_BOOT_VECTOR_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ #define EXYNOS_BOOT_VECTOR_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \
S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ pmu_base_addr + S5P_INFORM7 : \
(sysram_base_addr + 0x24) : S5P_INFORM0)) (samsung_rev() == EXYNOS4210_REV_1_0 ? \
(sysram_base_addr + 0x24) : \
pmu_base_addr + S5P_INFORM0))
#define EXYNOS_BOOT_VECTOR_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ #define EXYNOS_BOOT_VECTOR_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ pmu_base_addr + S5P_INFORM6 : \
(sysram_base_addr + 0x20) : S5P_INFORM1)) (samsung_rev() == EXYNOS4210_REV_1_0 ? \
(sysram_base_addr + 0x20) : \
pmu_base_addr + S5P_INFORM1))
#define S5P_CHECK_AFTR 0xFCBA0D10 #define S5P_CHECK_AFTR 0xFCBA0D10
#define S5P_CHECK_SLEEP 0x00000BAD #define S5P_CHECK_SLEEP 0x00000BAD
...@@ -179,7 +184,7 @@ int exynos_cluster_power_state(int cluster) ...@@ -179,7 +184,7 @@ int exynos_cluster_power_state(int cluster)
/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
static void exynos_set_wakeupmask(long mask) static void exynos_set_wakeupmask(long mask)
{ {
__raw_writel(mask, S5P_WAKEUP_MASK); pmu_raw_writel(mask, S5P_WAKEUP_MASK);
} }
static void exynos_cpu_set_boot_vector(long flags) static void exynos_cpu_set_boot_vector(long flags)
...@@ -256,27 +261,27 @@ static void exynos_pm_prepare(void) ...@@ -256,27 +261,27 @@ static void exynos_pm_prepare(void)
unsigned int tmp; unsigned int tmp;
/* Set wake-up mask registers */ /* Set wake-up mask registers */
__raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK); pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
__raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK); pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
if (soc_is_exynos5250()) { if (soc_is_exynos5250()) {
s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
/* Disable USE_RETENTION of JPEG_MEM_OPTION */ /* Disable USE_RETENTION of JPEG_MEM_OPTION */
tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); tmp = pmu_raw_readl(EXYNOS5_JPEG_MEM_OPTION);
tmp &= ~EXYNOS5_OPTION_USE_RETENTION; tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
__raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION);
} }
/* Set value of power down register for sleep mode */ /* Set value of power down register for sleep mode */
exynos_sys_powerdown_conf(SYS_SLEEP); exynos_sys_powerdown_conf(SYS_SLEEP);
__raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
/* ensure at least INFORM0 has the resume address */ /* ensure at least INFORM0 has the resume address */
__raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0); pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
} }
static void exynos_pm_central_suspend(void) static void exynos_pm_central_suspend(void)
...@@ -284,9 +289,9 @@ static void exynos_pm_central_suspend(void) ...@@ -284,9 +289,9 @@ static void exynos_pm_central_suspend(void)
unsigned long tmp; unsigned long tmp;
/* Setting Central Sequence Register for power down mode */ /* Setting Central Sequence Register for power down mode */
tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
tmp &= ~S5P_CENTRAL_LOWPWR_CFG; tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
} }
static int exynos_pm_suspend(void) static int exynos_pm_suspend(void)
...@@ -298,7 +303,7 @@ static int exynos_pm_suspend(void) ...@@ -298,7 +303,7 @@ static int exynos_pm_suspend(void)
/* Setting SEQ_OPTION register */ /* Setting SEQ_OPTION register */
tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
exynos_cpu_save_register(); exynos_cpu_save_register();
...@@ -316,12 +321,12 @@ static int exynos_pm_central_resume(void) ...@@ -316,12 +321,12 @@ static int exynos_pm_central_resume(void)
* S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
* in this situation. * in this situation.
*/ */
tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
tmp |= S5P_CENTRAL_LOWPWR_CFG; tmp |= S5P_CENTRAL_LOWPWR_CFG;
__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
/* clear the wakeup state register */ /* clear the wakeup state register */
__raw_writel(0x0, S5P_WAKEUP_STAT); pmu_raw_writel(0x0, S5P_WAKEUP_STAT);
/* No need to perform below restore code */ /* No need to perform below restore code */
return -1; return -1;
} }
...@@ -339,13 +344,13 @@ static void exynos_pm_resume(void) ...@@ -339,13 +344,13 @@ static void exynos_pm_resume(void)
/* For release retention */ /* For release retention */
__raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
__raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
if (soc_is_exynos5250()) if (soc_is_exynos5250())
s3c_pm_do_restore(exynos5_sys_save, s3c_pm_do_restore(exynos5_sys_save,
...@@ -359,7 +364,7 @@ static void exynos_pm_resume(void) ...@@ -359,7 +364,7 @@ static void exynos_pm_resume(void)
early_wakeup: early_wakeup:
/* Clear SLEEP mode set in INFORM1 */ /* Clear SLEEP mode set in INFORM1 */
__raw_writel(0x0, S5P_INFORM1); pmu_raw_writel(0x0, S5P_INFORM1);
return; return;
} }
...@@ -403,7 +408,7 @@ static int exynos_suspend_enter(suspend_state_t state) ...@@ -403,7 +408,7 @@ static int exynos_suspend_enter(suspend_state_t state)
s3c_pm_restore_uarts(); s3c_pm_restore_uarts();
S3C_PMDBG("%s: wakeup stat: %08x\n", __func__, S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
__raw_readl(S5P_WAKEUP_STAT)); pmu_raw_readl(S5P_WAKEUP_STAT));
s3c_pm_check_restore(); s3c_pm_check_restore();
...@@ -474,9 +479,9 @@ void __init exynos_pm_init(void) ...@@ -474,9 +479,9 @@ void __init exynos_pm_init(void)
gic_arch_extn.irq_set_wake = exynos_irq_set_wake; gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
/* All wakeup disable */ /* All wakeup disable */
tmp = __raw_readl(S5P_WAKEUP_MASK); tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
tmp |= ((0xFF << 8) | (0x1F << 1)); tmp |= ((0xFF << 8) | (0x1F << 1));
__raw_writel(tmp, S5P_WAKEUP_MASK); pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
register_syscore_ops(&exynos_pm_syscore_ops); register_syscore_ops(&exynos_pm_syscore_ops);
suspend_set_ops(&exynos_suspend_ops); suspend_set_ops(&exynos_suspend_ops);
......
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/sched.h> #include <linux/sched.h>
#include "regs-pmu.h" #define INT_LOCAL_PWR_EN 0x7
#define MAX_CLK_PER_DOMAIN 4 #define MAX_CLK_PER_DOMAIN 4
/* /*
...@@ -63,13 +62,13 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) ...@@ -63,13 +62,13 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
} }
} }
pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0; pwr = power_on ? INT_LOCAL_PWR_EN : 0;
__raw_writel(pwr, base); __raw_writel(pwr, base);
/* Wait max 1ms */ /* Wait max 1ms */
timeout = 10; timeout = 10;
while ((__raw_readl(base + 0x4) & S5P_INT_LOCAL_PWR_EN) != pwr) { while ((__raw_readl(base + 0x4) & INT_LOCAL_PWR_EN) != pwr) {
if (!timeout) { if (!timeout) {
op = (power_on) ? "enable" : "disable"; op = (power_on) ? "enable" : "disable";
pr_err("Power domain %s %s failed\n", domain->name, op); pr_err("Power domain %s %s failed\n", domain->name, op);
...@@ -231,7 +230,7 @@ static __init int exynos4_pm_init_power_domain(void) ...@@ -231,7 +230,7 @@ static __init int exynos4_pm_init_power_domain(void)
no_clk: no_clk:
platform_set_drvdata(pdev, pd); platform_set_drvdata(pdev, pd);
on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN; on = __raw_readl(pd->base + 0x4) & INT_LOCAL_PWR_EN;
pm_genpd_init(&pd->pd, NULL, !on); pm_genpd_init(&pd->pd, NULL, !on);
} }
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bug.h>
#include "common.h" #include "common.h"
#include "regs-pmu.h" #include "regs-pmu.h"
...@@ -19,7 +18,7 @@ ...@@ -19,7 +18,7 @@
static const struct exynos_pmu_conf *exynos_pmu_config; static const struct exynos_pmu_conf *exynos_pmu_config;
static const struct exynos_pmu_conf exynos4210_pmu_config[] = { static const struct exynos_pmu_conf exynos4210_pmu_config[] = {
/* { .reg = address, .val = { AFTR, LPA, SLEEP } */ /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
{ S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
{ S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
{ S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
...@@ -213,7 +212,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = { ...@@ -213,7 +212,7 @@ static const struct exynos_pmu_conf exynos4412_pmu_config[] = {
}; };
static const struct exynos_pmu_conf exynos5250_pmu_config[] = { static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
/* { .reg = address, .val = { AFTR, LPA, SLEEP } */ /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
{ EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
{ EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
{ EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
...@@ -316,7 +315,7 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = { ...@@ -316,7 +315,7 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
{ PMU_TABLE_END,}, { PMU_TABLE_END,},
}; };
static void __iomem * const exynos5_list_both_cnt_feed[] = { static unsigned int const exynos5_list_both_cnt_feed[] = {
EXYNOS5_ARM_CORE0_OPTION, EXYNOS5_ARM_CORE0_OPTION,
EXYNOS5_ARM_CORE1_OPTION, EXYNOS5_ARM_CORE1_OPTION,
EXYNOS5_ARM_COMMON_OPTION, EXYNOS5_ARM_COMMON_OPTION,
...@@ -330,7 +329,7 @@ static void __iomem * const exynos5_list_both_cnt_feed[] = { ...@@ -330,7 +329,7 @@ static void __iomem * const exynos5_list_both_cnt_feed[] = {
EXYNOS5_TOP_PWR_SYSMEM_OPTION, EXYNOS5_TOP_PWR_SYSMEM_OPTION,
}; };
static void __iomem * const exynos5_list_diable_wfi_wfe[] = { static unsigned int const exynos5_list_diable_wfi_wfe[] = {
EXYNOS5_ARM_CORE1_OPTION, EXYNOS5_ARM_CORE1_OPTION,
EXYNOS5_FSYS_ARM_OPTION, EXYNOS5_FSYS_ARM_OPTION,
EXYNOS5_ISP_ARM_OPTION, EXYNOS5_ISP_ARM_OPTION,
...@@ -345,27 +344,27 @@ static void exynos5_init_pmu(void) ...@@ -345,27 +344,27 @@ static void exynos5_init_pmu(void)
* Enable both SC_FEEDBACK and SC_COUNTER * Enable both SC_FEEDBACK and SC_COUNTER
*/ */
for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) {
tmp = __raw_readl(exynos5_list_both_cnt_feed[i]); tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]);
tmp |= (EXYNOS5_USE_SC_FEEDBACK | tmp |= (EXYNOS5_USE_SC_FEEDBACK |
EXYNOS5_USE_SC_COUNTER); EXYNOS5_USE_SC_COUNTER);
__raw_writel(tmp, exynos5_list_both_cnt_feed[i]); pmu_raw_writel(tmp, exynos5_list_both_cnt_feed[i]);
} }
/* /*
* SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable
*/ */
tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION); tmp = pmu_raw_readl(EXYNOS5_ARM_COMMON_OPTION);
tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
__raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); pmu_raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION);
/* /*
* Disable WFI/WFE on XXX_OPTION * Disable WFI/WFE on XXX_OPTION
*/ */
for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) {
tmp = __raw_readl(exynos5_list_diable_wfi_wfe[i]); tmp = pmu_raw_readl(exynos5_list_diable_wfi_wfe[i]);
tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE |
EXYNOS5_OPTION_USE_STANDBYWFI); EXYNOS5_OPTION_USE_STANDBYWFI);
__raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]); pmu_raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]);
} }
} }
...@@ -376,14 +375,14 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) ...@@ -376,14 +375,14 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
if (soc_is_exynos5250()) if (soc_is_exynos5250())
exynos5_init_pmu(); exynos5_init_pmu();
for (i = 0; (exynos_pmu_config[i].reg != PMU_TABLE_END) ; i++) for (i = 0; (exynos_pmu_config[i].offset != PMU_TABLE_END) ; i++)
__raw_writel(exynos_pmu_config[i].val[mode], pmu_raw_writel(exynos_pmu_config[i].val[mode],
exynos_pmu_config[i].reg); exynos_pmu_config[i].offset);
if (soc_is_exynos4412()) { if (soc_is_exynos4412()) {
for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++) for (i = 0; exynos4412_pmu_config[i].offset != PMU_TABLE_END ; i++)
__raw_writel(exynos4412_pmu_config[i].val[mode], pmu_raw_writel(exynos4412_pmu_config[i].val[mode],
exynos4412_pmu_config[i].reg); exynos4412_pmu_config[i].offset);
} }
} }
...@@ -404,13 +403,13 @@ static int __init exynos_pmu_init(void) ...@@ -404,13 +403,13 @@ static int __init exynos_pmu_init(void)
* When SYS_WDTRESET is set, watchdog timer reset request * When SYS_WDTRESET is set, watchdog timer reset request
* is ignored by power management unit. * is ignored by power management unit.
*/ */
value = __raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE);
value &= ~EXYNOS5_SYS_WDTRESET; value &= ~EXYNOS5_SYS_WDTRESET;
__raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE);
value = __raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST);
value &= ~EXYNOS5_SYS_WDTRESET; value &= ~EXYNOS5_SYS_WDTRESET;
__raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST);
exynos_pmu_config = exynos5250_pmu_config; exynos_pmu_config = exynos5250_pmu_config;
pr_info("EXYNOS5250 PMU Initialize\n"); pr_info("EXYNOS5250 PMU Initialize\n");
......
此差异已折叠。
/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* EXYNOS - system register definition
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_REGS_SYS_H
#define __ASM_ARCH_REGS_SYS_H __FILE__
#include <mach/map.h>
#define S5P_SYSREG(x) (S3C_VA_SYS + (x))
/* For EXYNOS5 */
#define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234)
#endif /* __ASM_ARCH_REGS_SYS_H */
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#define S5P_VA_CHIPID S3C_ADDR(0x02000000) #define S5P_VA_CHIPID S3C_ADDR(0x02000000)
#define S5P_VA_CMU S3C_ADDR(0x02100000) #define S5P_VA_CMU S3C_ADDR(0x02100000)
#define S5P_VA_PMU S3C_ADDR(0x02180000)
#define S5P_VA_GPIO S3C_ADDR(0x02200000) #define S5P_VA_GPIO S3C_ADDR(0x02200000)
#define S5P_VA_GPIO1 S5P_VA_GPIO #define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_GPIO2 S3C_ADDR(0x02240000) #define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
......
...@@ -9,7 +9,7 @@ config ARM_ARMADA_370_XP_CPUIDLE ...@@ -9,7 +9,7 @@ config ARM_ARMADA_370_XP_CPUIDLE
config ARM_BIG_LITTLE_CPUIDLE config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors" bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
select ARM_CPU_SUSPEND select ARM_CPU_SUSPEND
select CPU_IDLE_MULTIPLE_DRIVERS select CPU_IDLE_MULTIPLE_DRIVERS
help help
......
...@@ -163,14 +163,24 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id) ...@@ -163,14 +163,24 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id)
return 0; return 0;
} }
static const struct of_device_id compatible_machine_match[] = {
{ .compatible = "arm,vexpress,v2p-ca15_a7" },
{ .compatible = "samsung,exynos5420" },
{},
};
static int __init bl_idle_init(void) static int __init bl_idle_init(void)
{ {
int ret; int ret;
struct device_node *root = of_find_node_by_path("/");
if (!root)
return -ENODEV;
/* /*
* Initialize the driver just for a compliant set of machines * Initialize the driver just for a compliant set of machines
*/ */
if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7")) if (!of_match_node(compatible_machine_match, root))
return -ENODEV; return -ENODEV;
/* /*
* For now the differentiation between little and big cores * For now the differentiation between little and big cores
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册