Skip to contentSkip to conversation

ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

PATCH Superseded Daniel Lezcano 8 participants 48 messages Apr 11, 2014 – Jun 27, 2014

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Changelog:

V5:
* Removed patch : "Move clock setup to pm.c"
* Added patch : "Move arm core power down clock to exynos5250 common code"
V4:
* Took into account Tomasz's comments
* Fixed missing call in for central suspend
* Passed parameter to the wakeup mask function
* Moved wakeup mask, boot vector and aftr state into a single function
* Used this function as callback for platform data
* Moved S5P_CHECK_AFTR/S5P_CHECK_SLEEP into pm.c
* Set boot vector only one time
* Splitted some patches to make them more readable
V3:
* Added patch : "ARM: exynos: cpuidle: Disable cpuidle for 5440"
* Removed patch : "ARM: exynos: config: Enable cpuidle"
* Removed default ARM_EXYNOS4210_CPUIDLE=y
* Added comment about bug fix side effect 'for_each_possible_cpu'
V2:
* Added comment in changelog for calls order (5/17)
* Call the powerdown only for cpu0 in the pm notifier
* Set the pm notifier for all boards

V1: initial post

This patchset relies on the cpm_pm notifier to initiate the powerdown sequence operations from pm.c instead cpuidle.c. Thus the cpuidle driver is no longer dependent from arch specific code as everything is called from the pm.c file.

The patchset applies on top of linux-samsung/for-next.

Tested on exynos4: 4210
Tested on exynos5: 5250 (without AFTR)

Amit Daniel Kachhap (1):
ARM: EXYNOS: Move arm core power down clock to exynos5250 common
clock

Daniel Lezcano (19):
ARM: exynos: cpuidle: Prevent forward declaration
ARM: exynos: cpuidle: Use cpuidle_register
ARM: exynos: cpuidle: Change function name prefix
ARM: exynos: cpuidle: Encapsulate register access inside a function
ARM: exynos: cpuidle: Move some code inside the idle_finisher
ARM: exynos: cpuidle: Fix S5P_WAKEUP_STAT call
ARM: exynos: cpuidle: Use the cpu_pm notifier
ARM: exynos: cpuidle: Move scu_enable in the cpu_pm notifier
ARM: exynos: cpuidle: Remove ifdef for scu_enable
ARM: exynos: cpuidle: Pass wakeup mask parameter to function
ARM: exynos: cpuidle: Encapsulate boot vector code into a function
ARM: exynos: cpuidle: Disable cpuidle for 5440
ARM: exynos: cpuidle: Encapsulate the AFTR code into a function
ARM: exynos: cpuidle: Move the AFTR state function into pm.c
ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm
notifier
ARM: exynos: cpuidle: Move S5P_CHECK_SLEEP into pm.c
ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data
ARM: exynos: cpuidle: Cleanup all unneeded headers from cpuidle.c
ARM: exynos: cpuidle: Move the driver to drivers/cpuidle directory

 arch/arm/mach-exynos/Makefile        |    1 -
 arch/arm/mach-exynos/common.h        |    1 +
 arch/arm/mach-exynos/cpuidle.c       |  255 ----------------------------------
 arch/arm/mach-exynos/exynos.c        |    8 +-
 arch/arm/mach-exynos/pm.c            |  152 ++++++++++++++++----
 arch/arm/mach-exynos/regs-pmu.h      |    2 -
 drivers/clk/samsung/clk-exynos5250.c |   42 ++++++
 drivers/cpuidle/Kconfig.arm          |    6 +
 drivers/cpuidle/Makefile             |    1 +
 drivers/cpuidle/cpuidle-exynos.c     |   98 +++++++++++++
 10 files changed, 277 insertions(+), 289 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/cpuidle.c
 create mode 100644 drivers/cpuidle/cpuidle-exynos.c
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v5 1/20 ARM: EXYNOS: Move arm core power down clock to exynos5250 common clock

From: Amit Daniel Kachhap <[email protected]>

Now with common clock support added for exynos5250 it is necessary to move this code to exynos5250 common clock driver as clock registers should be handled there. This change is tested in exynos5250 based arndale platform.

Cc Abhilash Kesavan <[email protected]>
Cc Thomas Abraham <[email protected]>
[t.figa: Rebased onto current kernel sources.]
---
 arch/arm/mach-exynos/cpuidle.c       |   54 ----------------------------------
 drivers/clk/samsung/clk-exynos5250.c |   42 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 54 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -54
index b530231..3e260ba 100644
@@ -40,25 +40,6 @@
 
 #define S5P_CHECK_AFTR		0xFCBA0D10
 
-#define EXYNOS5_PWR_CTRL1			(S5P_VA_CMU + 0x01020)
-#define EXYNOS5_PWR_CTRL2			(S5P_VA_CMU + 0x01024)
-
-#define PWR_CTRL1_CORE2_DOWN_RATIO		(7 << 28)
-#define PWR_CTRL1_CORE1_DOWN_RATIO		(7 << 16)
-#define PWR_CTRL1_DIV2_DOWN_EN			(1 << 9)
-#define PWR_CTRL1_DIV1_DOWN_EN			(1 << 8)
-#define PWR_CTRL1_USE_CORE1_WFE			(1 << 5)
-#define PWR_CTRL1_USE_CORE0_WFE			(1 << 4)
-#define PWR_CTRL1_USE_CORE1_WFI			(1 << 1)
-#define PWR_CTRL1_USE_CORE0_WFI			(1 << 0)
-
-#define PWR_CTRL2_DIV2_UP_EN			(1 << 25)
-#define PWR_CTRL2_DIV1_UP_EN			(1 << 24)
-#define PWR_CTRL2_DUR_STANDBY2_VAL		(1 << 16)
-#define PWR_CTRL2_DUR_STANDBY1_VAL		(1 << 8)
-#define PWR_CTRL2_CORE2_UP_RATIO		(1 << 4)
-#define PWR_CTRL2_CORE1_UP_RATIO		(1 << 0)
-
 static int exynos4_enter_lowpower(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
 				int index);
@@ -181,46 +162,11 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,
 		return exynos4_enter_core0_aftr(dev, drv, new_index);
 }
 
-static void __init exynos5_core_down_clk(void)
-{
-	unsigned int tmp;
-
-	/*
-	 * Enable arm clock down (in idle) and set arm divider
-	 * ratios in WFI/WFE state.
-	 */
-	tmp = PWR_CTRL1_CORE2_DOWN_RATIO | \
-	      PWR_CTRL1_CORE1_DOWN_RATIO | \
-	      PWR_CTRL1_DIV2_DOWN_EN	 | \
-	      PWR_CTRL1_DIV1_DOWN_EN	 | \
-	      PWR_CTRL1_USE_CORE1_WFE	 | \
-	      PWR_CTRL1_USE_CORE0_WFE	 | \
-	      PWR_CTRL1_USE_CORE1_WFI	 | \
-	      PWR_CTRL1_USE_CORE0_WFI;
-	__raw_writel(tmp, EXYNOS5_PWR_CTRL1);
-
-	/*
-	 * Enable arm clock up (on exiting idle). Set arm divider
-	 * ratios when not in idle along with the standby duration
-	 * ratios.
-	 */
-	tmp = PWR_CTRL2_DIV2_UP_EN	 | \
-	      PWR_CTRL2_DIV1_UP_EN	 | \
-	      PWR_CTRL2_DUR_STANDBY2_VAL | \
-	      PWR_CTRL2_DUR_STANDBY1_VAL | \
-	      PWR_CTRL2_CORE2_UP_RATIO	 | \
-	      PWR_CTRL2_CORE1_UP_RATIO;
-	__raw_writel(tmp, EXYNOS5_PWR_CTRL2);
-}
-
 static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int cpu_id, ret;
 	struct cpuidle_device *device;
 
-	if (soc_is_exynos5250())
-		exynos5_core_down_clk();
-
 	if (soc_is_exynos5440())
 		exynos4_idle_driver.state_count = 1;
 
drivers/clk/samsung/clk-exynos5250.c +42 -0

72 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v5 2/20 ARM: exynos: cpuidle: Prevent forward declaration

In reply to Daniel Lezcano

Move the structure below the 'exynos4_enter_lowpower' function so no more need of forward declaration.

---
 arch/arm/mach-exynos/cpuidle.c |   40 ++++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 22 deletions(-)
arch/arm/mach-exynos/cpuidle.c +18 -22
index 3e260ba..17df0d8 100644
@@ -40,30 +40,8 @@
 
 #define S5P_CHECK_AFTR		0xFCBA0D10
 
-static int exynos4_enter_lowpower(struct cpuidle_device *dev,
-				struct cpuidle_driver *drv,
-				int index);
-
 static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
 
-static struct cpuidle_driver exynos4_idle_driver = {
-	.name			= "exynos4_idle",
-	.owner			= THIS_MODULE,
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE,
-		[1] = {
-			.enter			= exynos4_enter_lowpower,
-			.exit_latency		= 300,
-			.target_residency	= 100000,
-			.flags			= CPUIDLE_FLAG_TIME_VALID,
-			.name			= "C1",
-			.desc			= "ARM power down",
-		},
-	},
-	.state_count = 2,
-	.safe_state_index = 0,
-};
-
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
 static void exynos4_set_wakeupmask(void)
 {
@@ -162,6 +140,24 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,
 		return exynos4_enter_core0_aftr(dev, drv, new_index);
 }
 
+static struct cpuidle_driver exynos4_idle_driver = {
+	.name			= "exynos4_idle",
+	.owner			= THIS_MODULE,
+	.states = {
+		[0] = ARM_CPUIDLE_WFI_STATE,
+		[1] = {
+			.enter			= exynos4_enter_lowpower,
+			.exit_latency		= 300,
+			.target_residency	= 100000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "C1",
+			.desc			= "ARM power down",
+		},
+	},
+	.state_count = 2,
+	.safe_state_index = 0,
+};
+
 static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int cpu_id, ret;
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH v5 3/20 ARM: exynos: cpuidle: Use cpuidle_register

In reply to Daniel Lezcano

Use the cpuidle generic function 'cpuidle_register'. That saves us from some extra lines of code and unneeded variables.

A side effect of this change is a bug fix where before the cpuidle driver was registered for each_online_cpu and now it is for each_possible_cpu.

---
 arch/arm/mach-exynos/cpuidle.c |   18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)
arch/arm/mach-exynos/cpuidle.c +2 -16
index 17df0d8..61e1481 100644
@@ -40,8 +40,6 @@
 
 #define S5P_CHECK_AFTR		0xFCBA0D10
 
-static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
-
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
 static void exynos4_set_wakeupmask(void)
 {
@@ -160,29 +158,17 @@ static struct cpuidle_driver exynos4_idle_driver = {
 
 static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
-	int cpu_id, ret;
-	struct cpuidle_device *device;
+	int ret;
 
 	if (soc_is_exynos5440())
 		exynos4_idle_driver.state_count = 1;
 
-	ret = cpuidle_register_driver(&exynos4_idle_driver);
+	ret = cpuidle_register(&exynos4_idle_driver, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
 		return ret;
 	}
 
-	for_each_online_cpu(cpu_id) {
-		device = &per_cpu(exynos4_cpuidle_device, cpu_id);
-		device->cpu = cpu_id;
-
-		ret = cpuidle_register_device(device);
-		if (ret) {
-			dev_err(&pdev->dev, "failed to register cpuidle device\n");
-			return ret;
-		}
-	}
-
 	return 0;
 }
 
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH v5 4/20 ARM: exynos: cpuidle: Change function name prefix

In reply to Daniel Lezcano

The driver was initially written for exynos4 but the driver is used also for exynos5.

Change the function prefix name exynos4 -> exynos

---
 arch/arm/mach-exynos/cpuidle.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
arch/arm/mach-exynos/cpuidle.c +11 -11
index 61e1481..f565186 100644
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/cpuidle.c
+/* linux/arch/arm/mach-exynos/cpuidle.c
  *
  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
@@ -41,7 +41,7 @@
 #define S5P_CHECK_AFTR		0xFCBA0D10
 
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
-static void exynos4_set_wakeupmask(void)
+static void exynos_set_wakeupmask(void)
 {
 	__raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
 }
@@ -72,13 +72,13 @@ static int idle_finisher(unsigned long flags)
 	return 1;
 }
 
-static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
+static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
 				int index)
 {
 	unsigned long tmp;
 
-	exynos4_set_wakeupmask();
+	exynos_set_wakeupmask();
 
 	/* Set value of power down register for aftr mode */
 	exynos_sys_powerdown_conf(SYS_AFTR);
@@ -122,7 +122,7 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
 	return index;
 }
 
-static int exynos4_enter_lowpower(struct cpuidle_device *dev,
+static int exynos_enter_lowpower(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
 				int index)
 {
@@ -135,16 +135,16 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,
 	if (new_index == 0)
 		return arm_cpuidle_simple_enter(dev, drv, new_index);
 	else
-		return exynos4_enter_core0_aftr(dev, drv, new_index);
+		return exynos_enter_core0_aftr(dev, drv, new_index);
 }
 
-static struct cpuidle_driver exynos4_idle_driver = {
-	.name			= "exynos4_idle",
+static struct cpuidle_driver exynos_idle_driver = {
+	.name			= "exynos_idle",
 	.owner			= THIS_MODULE,
 	.states = {
 		[0] = ARM_CPUIDLE_WFI_STATE,
 		[1] = {
-			.enter			= exynos4_enter_lowpower,
+			.enter			= exynos_enter_lowpower,
 			.exit_latency		= 300,
 			.target_residency	= 100000,
 			.flags			= CPUIDLE_FLAG_TIME_VALID,
@@ -161,9 +161,9 @@ static int exynos_cpuidle_probe(struct platform_device *pdev)
 	int ret;
 
 	if (soc_is_exynos5440())
-		exynos4_idle_driver.state_count = 1;
+		exynos_idle_driver.state_count = 1;
 
-	ret = cpuidle_register(&exynos4_idle_driver, NULL);
+	ret = cpuidle_register(&exynos_idle_driver, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
 		return ret;
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v5 5/20 ARM: exynos: cpuidle: Encapsulate register access inside a function

In reply to Daniel Lezcano

That makes the code cleaner and encapsulted. The function will be reused in the next patch.

---
 arch/arm/mach-exynos/pm.c |   65 ++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 24 deletions(-)
arch/arm/mach-exynos/pm.c +41 -24
index 15af0ce..adfdf4b 100644
@@ -103,6 +103,42 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
 /* For Cortex-A9 Diagnostic and Power control register */
 static unsigned int save_arm_register[2];
 
+static void exynos_cpu_save_register(void)
+{
+	unsigned long tmp;
+
+	/* Save Power control register */
+	asm ("mrc p15, 0, %0, c15, c0, 0"
+	     : "=r" (tmp) : : "cc");
+
+	save_arm_register[0] = tmp;
+
+	/* Save Diagnostic register */
+	asm ("mrc p15, 0, %0, c15, c0, 1"
+	     : "=r" (tmp) : : "cc");
+
+	save_arm_register[1] = tmp;
+}
+
+static void exynos_cpu_restore_register(void)
+{
+	unsigned long tmp;
+
+	/* Restore Power control register */
+	tmp = save_arm_register[0];
+
+	asm volatile ("mcr p15, 0, %0, c15, c0, 0"
+		      : : "r" (tmp)
+		      : "cc");
+
+	/* Restore Diagnostic register */
+	tmp = save_arm_register[1];
+
+	asm volatile ("mcr p15, 0, %0, c15, c0, 1"
+		      : : "r" (tmp)
+		      : "cc");
+}
+
 static int exynos_cpu_suspend(unsigned long arg)
 {
 #ifdef CONFIG_CACHE_L2X0
@@ -162,17 +198,8 @@ static int exynos_pm_suspend(void)
 	tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
 	__raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
 
-	if (!soc_is_exynos5250()) {
-		/* Save Power control register */
-		asm ("mrc p15, 0, %0, c15, c0, 0"
-		     : "=r" (tmp) : : "cc");
-		save_arm_register[0] = tmp;
-
-		/* Save Diagnostic register */
-		asm ("mrc p15, 0, %0, c15, c0, 1"
-		     : "=r" (tmp) : : "cc");
-		save_arm_register[1] = tmp;
-	}
+	if (!soc_is_exynos5250())
+		exynos_cpu_save_register();
 
 	return 0;
 }
@@ -196,19 +223,9 @@ static void exynos_pm_resume(void)
 		/* No need to perform below restore code */
 		goto early_wakeup;
 	}
-	if (!soc_is_exynos5250()) {
-		/* Restore Power control register */
-		tmp = save_arm_register[0];
-		asm volatile ("mcr p15, 0, %0, c15, c0, 0"
-			      : : "r" (tmp)
-			      : "cc");
-
-		/* Restore Diagnostic register */
-		tmp = save_arm_register[1];
-		asm volatile ("mcr p15, 0, %0, c15, c0, 1"
-			      : : "r" (tmp)
-			      : "cc");
-	}
+
+	if (!soc_is_exynos5250())
+		exynos_cpu_restore_register();
 
 	/* For release retention */
 
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH v5 6/20 ARM: exynos: cpuidle: Move some code inside the idle_finisher

In reply to Daniel Lezcano

Move the code around to differentiate different section of code and prepare it to be factored out in the next patches.

The call order changed but hat doesn't have a side effect because they are independent. The important call is cpu_do_idle() which must be done the last.

---
 arch/arm/mach-exynos/cpuidle.c |   17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
arch/arm/mach-exynos/cpuidle.c +9 -8
index f565186..4d8bcfd 100644
@@ -68,7 +68,16 @@ static void restore_cpu_arch_register(void)
 
 static int idle_finisher(unsigned long flags)
 {
+	exynos_set_wakeupmask();
+
+	__raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
+	__raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
+
+	/* Set value of power down register for aftr mode */
+	exynos_sys_powerdown_conf(SYS_AFTR);
+
 	cpu_do_idle();
+
 	return 1;
 }
 
@@ -78,14 +87,6 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 {
 	unsigned long tmp;
 
-	exynos_set_wakeupmask();
-
-	/* Set value of power down register for aftr mode */
-	exynos_sys_powerdown_conf(SYS_AFTR);
-
-	__raw_writel(virt_to_phys(exynos_cpu_resume), REG_DIRECTGO_ADDR);
-	__raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
-
 	save_cpu_arch_register();
 
 	/* Setting Central Sequence Register for power down mode */
Signature · 1 line
1.7.9.5
#7 lore raw

PATCH v5 7/20 ARM: exynos: cpuidle: Fix S5P_WAKEUP_STAT call

In reply to Daniel Lezcano

This function should be called only when the powerdown sequence fails.

Even if the current code does not hurt, by moving this line, we have the same code than the one in pm.c.

---
 arch/arm/mach-exynos/cpuidle.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/cpuidle.c +2 -3
index 4d8bcfd..346c2d0 100644
@@ -115,11 +115,10 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 	if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
 		tmp |= S5P_CENTRAL_LOWPWR_CFG;
 		__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+		/* Clear wakeup state register */
+		__raw_writel(0x0, S5P_WAKEUP_STAT);
 	}
 
-	/* Clear wakeup state register */
-	__raw_writel(0x0, S5P_WAKEUP_STAT);
-
 	return index;
 }
 
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v5 8/20 ARM: exynos: cpuidle: Use the cpu_pm notifier

In reply to Daniel Lezcano

Use the cpu_pm_enter/exit notifier to group some pm code inside the pm file.

The save and restore code is duplicated across pm.c and cpuidle.c. By using the cpu_pm notifier, we can factor out the routine.

---
 arch/arm/mach-exynos/cpuidle.c |   24 ------------------------
 arch/arm/mach-exynos/pm.c      |   29 +++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 24 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -24
index 346c2d0..aa8ab1b 100644
@@ -46,26 +46,6 @@ static void exynos_set_wakeupmask(void)
 	__raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
 }
 
-static unsigned int g_pwr_ctrl, g_diag_reg;
-
-static void save_cpu_arch_register(void)
-{
-	/*read power control register*/
-	asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
-	/*read diagnostic register*/
-	asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
-	return;
-}
-
-static void restore_cpu_arch_register(void)
-{
-	/*write power control register*/
-	asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc");
-	/*write diagnostic register*/
-	asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
-	return;
-}
-
 static int idle_finisher(unsigned long flags)
 {
 	exynos_set_wakeupmask();
@@ -87,8 +67,6 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 {
 	unsigned long tmp;
 
-	save_cpu_arch_register();
-
 	/* Setting Central Sequence Register for power down mode */
 	tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
 	tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
@@ -103,8 +81,6 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 #endif
 	cpu_pm_exit();
 
-	restore_cpu_arch_register();
-
 	/*
 	 * If PMU failed while entering sleep mode, WFI will be
 	 * ignored by PMU and then exiting cpu_do_idle().
arch/arm/mach-exynos/pm.c +29 -0
index adfdf4b..67d75fe 100644
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
+#include <linux/cpu_pm.h>
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/err.h>
@@ -321,10 +322,38 @@ static const struct platform_suspend_ops exynos_suspend_ops = {
 	.valid		= suspend_valid_only_mem,
 };
 
+static int exynos_cpu_pm_notifier(struct notifier_block *self,
+				  unsigned long cmd, void *v)
+{
+	int cpu = smp_processor_id();
+
+	switch (cmd) {
+	case CPU_PM_ENTER:
+		if (cpu == 0) {
+			exynos_cpu_save_register();
+		}
+		break;
+
+	case CPU_PM_EXIT:
+		if (cpu == 0) {
+			exynos_cpu_restore_register();
+		}
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block exynos_cpu_pm_notifier_block = {
+	.notifier_call = exynos_cpu_pm_notifier,
+};
+
 void __init exynos_pm_init(void)
 {
 	u32 tmp;
 
+	cpu_pm_register_notifier(&exynos_cpu_pm_notifier_block);
+
 	/* Platform-specific GIC callback */
 	gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
 
Signature · 1 line
1.7.9.5
#9 lore raw

PATCH v5 9/20 ARM: exynos: cpuidle: Move scu_enable in the cpu_pm notifier

In reply to Daniel Lezcano

We make the cpuidle code less arch dependent.

---
 arch/arm/mach-exynos/cpuidle.c |    6 ------
 arch/arm/mach-exynos/pm.c      |    4 ++++
 2 files changed, 4 insertions(+), 6 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -6
index aa8ab1b..95826c6 100644
@@ -18,7 +18,6 @@
 #include <linux/platform_device.h>
 
 #include <asm/proc-fns.h>
-#include <asm/smp_scu.h>
 #include <asm/suspend.h>
 #include <asm/unified.h>
 #include <asm/cpuidle.h>
@@ -74,11 +73,6 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 
 	cpu_pm_enter();
 	cpu_suspend(0, idle_finisher);
-
-#ifdef CONFIG_SMP
-	if (!soc_is_exynos5250())
-		scu_enable(S5P_VA_SCU);
-#endif
 	cpu_pm_exit();
 
 	/*
arch/arm/mach-exynos/pm.c +4 -0
index 67d75fe..aba577f 100644
@@ -336,6 +336,10 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
 
 	case CPU_PM_EXIT:
 		if (cpu == 0) {
+#ifdef CONFIG_SMP
+			if (!soc_is_exynos5250())
+				scu_enable(S5P_VA_SCU);
+#endif
 			exynos_cpu_restore_register();
 		}
 		break;
Signature · 1 line
1.7.9.5
#10 lore raw

PATCH v5 10/20 ARM: exynos: cpuidle: Remove ifdef for scu_enable

In reply to Daniel Lezcano

The scu_enable function is already a noop in the scu's header file is CONFIG_SMP=n, so no need to use these macros in the code.

---
 arch/arm/mach-exynos/pm.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
arch/arm/mach-exynos/pm.c +1 -3
index aba577f..9773a00 100644
@@ -244,7 +244,7 @@ static void exynos_pm_resume(void)
 
 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
 
-	if (IS_ENABLED(CONFIG_SMP) && !soc_is_exynos5250())
+	if (!soc_is_exynos5250())
 		scu_enable(S5P_VA_SCU);
 
 early_wakeup:
@@ -336,10 +336,8 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
 
 	case CPU_PM_EXIT:
 		if (cpu == 0) {
-#ifdef CONFIG_SMP
 			if (!soc_is_exynos5250())
 				scu_enable(S5P_VA_SCU);
-#endif
 			exynos_cpu_restore_register();
 		}
 		break;
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH v5 11/20 ARM: exynos: cpuidle: Pass wakeup mask parameter to function

In reply to Daniel Lezcano

Pass the wakeup mask to 'exynos_set_wakeupmask' as this function could be used for different idle states with different mask.

---
 arch/arm/mach-exynos/cpuidle.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/cpuidle.c +3 -3
index 95826c6..169db74 100644
@@ -40,14 +40,14 @@
 #define S5P_CHECK_AFTR		0xFCBA0D10
 
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
-static void exynos_set_wakeupmask(void)
+static void exynos_set_wakeupmask(long mask)
 {
-	__raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
+	__raw_writel(mask, S5P_WAKEUP_MASK);
 }
 
 static int idle_finisher(unsigned long flags)
 {
-	exynos_set_wakeupmask();
+	exynos_set_wakeupmask(0x0000ff3e);
 
 	__raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
 	__raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
Signature · 1 line
1.7.9.5
#12 lore raw

PATCH v5 12/20 ARM: exynos: cpuidle: Encapsulate boot vector code into a function

In reply to Daniel Lezcano
---
 arch/arm/mach-exynos/cpuidle.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
arch/arm/mach-exynos/cpuidle.c +7 -4
index 169db74..f66ee4d 100644
@@ -45,13 +45,16 @@ static void exynos_set_wakeupmask(long mask)
 	__raw_writel(mask, S5P_WAKEUP_MASK);
 }
 
+static void exynos_cpu_set_boot_vector(long flags)
+{
+	__raw_writel(virt_to_phys(exynos_cpu_resume), REG_DIRECTGO_ADDR);
+	__raw_writel(flags, REG_DIRECTGO_FLAG);
+}
+
 static int idle_finisher(unsigned long flags)
 {
 	exynos_set_wakeupmask(0x0000ff3e);
-
-	__raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
-	__raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
-
+	exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
 	/* Set value of power down register for aftr mode */
 	exynos_sys_powerdown_conf(SYS_AFTR);
 
Signature · 1 line
1.7.9.5
#13 lore raw

PATCH v5 13/20 ARM: exynos: cpuidle: Disable cpuidle for 5440

In reply to Daniel Lezcano

There is no point to register the cpuidle driver for the 5440 as it has only one WFI state which is the default idle function when the cpuidle driver is disabled.

By disabling cpuidle we prevent to enter to the governor computation for nothing, thus saving a lot of processing time.

The only drawback is the statistic via sysfs on this state which is lost but it is meaningless and it could be retrieved from the ftrace easily.

---
 arch/arm/mach-exynos/cpuidle.c |    3 ---
 arch/arm/mach-exynos/exynos.c  |    3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -3
index f66ee4d..95313ea 100644
@@ -133,9 +133,6 @@ static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	if (soc_is_exynos5440())
-		exynos_idle_driver.state_count = 1;
-
 	ret = cpuidle_register(&exynos_idle_driver, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
arch/arm/mach-exynos/exynos.c +3 -0
index b567361..fe8dac8 100644
@@ -227,6 +227,9 @@ static struct platform_device exynos_cpuidle = {
 
 void __init exynos_cpuidle_init(void)
 {
+	if (soc_is_exynos5440())
+		return;
+
 	platform_device_register(&exynos_cpuidle);
 }
 
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH v5 14/20 ARM: exynos: cpuidle: Encapsulate the AFTR code into a function

In reply to Daniel Lezcano

Let's encapsulate the AFTR state specific call into a single function.

---
 arch/arm/mach-exynos/cpuidle.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-exynos/cpuidle.c +5 -1
index 95313ea..fe35fba 100644
@@ -51,13 +51,17 @@ static void exynos_cpu_set_boot_vector(long flags)
 	__raw_writel(flags, REG_DIRECTGO_FLAG);
 }
 
-static int idle_finisher(unsigned long flags)
+static void exynos_enter_aftr(void)
 {
 	exynos_set_wakeupmask(0x0000ff3e);
 	exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
 	/* Set value of power down register for aftr mode */
 	exynos_sys_powerdown_conf(SYS_AFTR);
+}
 
+static int idle_finisher(unsigned long flags)
+{
+	exynos_enter_aftr();
 	cpu_do_idle();
 
 	return 1;
Signature · 1 line
1.7.9.5
#15 lore raw

PATCH v5 15/20 ARM: exynos: cpuidle: Move the AFTR state function into pm.c

In reply to Daniel Lezcano

In order to remove depedency on pm code, let's move the 'exynos_enter_aftr' function into the pm.c file as well as the other helper functions.

---
 arch/arm/mach-exynos/common.h  |    1 +
 arch/arm/mach-exynos/cpuidle.c |   29 -----------------------------
 arch/arm/mach-exynos/pm.c      |   29 +++++++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 29 deletions(-)
arch/arm/mach-exynos/common.h +1 -0
index 9ef3f83..30123a0 100644
@@ -62,5 +62,6 @@ struct exynos_pmu_conf {
 };
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
+extern void exynos_enter_aftr(void);
 
 #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
arch/arm/mach-exynos/cpuidle.c +0 -29
index fe35fba..e6d813d 100644
@@ -30,35 +30,6 @@
 #include "common.h"
 #include "regs-pmu.h"
 
-#define REG_DIRECTGO_ADDR	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
-			S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
-#define REG_DIRECTGO_FLAG	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
-			S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
-
-#define S5P_CHECK_AFTR		0xFCBA0D10
-
-/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
-static void exynos_set_wakeupmask(long mask)
-{
-	__raw_writel(mask, S5P_WAKEUP_MASK);
-}
-
-static void exynos_cpu_set_boot_vector(long flags)
-{
-	__raw_writel(virt_to_phys(exynos_cpu_resume), REG_DIRECTGO_ADDR);
-	__raw_writel(flags, REG_DIRECTGO_FLAG);
-}
-
-static void exynos_enter_aftr(void)
-{
-	exynos_set_wakeupmask(0x0000ff3e);
-	exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
-	/* Set value of power down register for aftr mode */
-	exynos_sys_powerdown_conf(SYS_AFTR);
-}
-
 static int idle_finisher(unsigned long flags)
 {
 	exynos_enter_aftr();
arch/arm/mach-exynos/pm.c +29 -0
index 9773a00..50b6b4d 100644
@@ -101,6 +101,35 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
 	return -ENOENT;
 }
 
+#define EXYNOS_BOOT_VECTOR_ADDR	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
+			S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
+			(S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
+#define EXYNOS_BOOT_VECTOR_FLAG	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
+			S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
+			(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
+
+#define S5P_CHECK_AFTR 0xFCBA0D10
+
+/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
+static void exynos_set_wakeupmask(long mask)
+{
+	__raw_writel(mask, S5P_WAKEUP_MASK);
+}
+
+static void exynos_cpu_set_boot_vector(long flags)
+{
+	__raw_writel(virt_to_phys(exynos_cpu_resume), EXYNOS_BOOT_VECTOR_ADDR);
+	__raw_writel(flags, EXYNOS_BOOT_VECTOR_FLAG);
+}
+
+void exynos_enter_aftr(void)
+{
+	exynos_set_wakeupmask(0x0000ff3e);
+	exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
+	/* Set value of power down register for aftr mode */
+	exynos_sys_powerdown_conf(SYS_AFTR);
+}
+
 /* For Cortex-A9 Diagnostic and Power control register */
 static unsigned int save_arm_register[2];
 
Signature · 1 line
1.7.9.5
#16 lore raw

PATCH v5 16/20 ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm notifier

In reply to Daniel Lezcano

The code to initiate and exit the powerdown sequence is the same in pm.c and cpuidle.c.

Let's split the common part in the pm.c and reuse it from the cpu_pm notifier.

That is one more step forward to make the cpuidle driver arch indenpendant.

---
 arch/arm/mach-exynos/cpuidle.c |   22 ----------------------
 arch/arm/mach-exynos/pm.c      |   24 ++++++++++++++++++++----
 2 files changed, 20 insertions(+), 26 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -22
index e6d813d..02609ac 100644
@@ -28,7 +28,6 @@
 #include <mach/map.h>
 
 #include "common.h"
-#include "regs-pmu.h"
 
 static int idle_finisher(unsigned long flags)
 {
@@ -42,31 +41,10 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
 				int index)
 {
-	unsigned long tmp;
-
-	/* Setting Central Sequence Register for power down mode */
-	tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-	tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
-	__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-
 	cpu_pm_enter();
 	cpu_suspend(0, idle_finisher);
 	cpu_pm_exit();
 
-	/*
-	 * If PMU failed while entering sleep mode, WFI will be
-	 * ignored by PMU and then exiting cpu_do_idle().
-	 * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
-	 * in this situation.
-	 */
-	tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-	if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
-		tmp |= S5P_CENTRAL_LOWPWR_CFG;
-		__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-		/* Clear wakeup state register */
-		__raw_writel(0x0, S5P_WAKEUP_STAT);
-	}
-
 	return index;
 }
 
arch/arm/mach-exynos/pm.c +20 -4
index 50b6b4d..6d9ef69 100644
@@ -213,15 +213,21 @@ static void exynos_pm_prepare(void)
 	__raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
 }
 
-static int exynos_pm_suspend(void)
+static void exynos_pm_central_suspend(void)
 {
 	unsigned long tmp;
 
 	/* Setting Central Sequence Register for power down mode */
-
 	tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
 	tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
 	__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+}
+
+static int exynos_pm_suspend(void)
+{
+	unsigned long tmp;
+
+	exynos_pm_central_suspend();
 
 	/* Setting SEQ_OPTION register */
 
@@ -234,7 +240,7 @@ static int exynos_pm_suspend(void)
 	return 0;
 }
 
-static void exynos_pm_resume(void)
+static int exynos_pm_central_resume(void)
 {
 	unsigned long tmp;
 
@@ -251,9 +257,17 @@ static void exynos_pm_resume(void)
 		/* clear the wakeup state register */
 		__raw_writel(0x0, S5P_WAKEUP_STAT);
 		/* No need to perform below restore code */
-		goto early_wakeup;
+		return -1;
 	}
 
+	return 0;
+}
+
+static void exynos_pm_resume(void)
+{
+	if (exynos_pm_central_resume())
+		goto early_wakeup;
+
 	if (!soc_is_exynos5250())
 		exynos_cpu_restore_register();
 
@@ -359,6 +373,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
 	switch (cmd) {
 	case CPU_PM_ENTER:
 		if (cpu == 0) {
+			exynos_pm_central_suspend();
 			exynos_cpu_save_register();
 		}
 		break;
@@ -368,6 +383,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
 			if (!soc_is_exynos5250())
 				scu_enable(S5P_VA_SCU);
 			exynos_cpu_restore_register();
+			exynos_pm_central_resume();
 		}
 		break;
 	}
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH v5 16/20 ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm notifier

Quoted 124 lines · Daniel Lezcano

The code to initiate and exit the powerdown sequence is the same in pm.c and cpuidle.c.

Let's split the common part in the pm.c and reuse it from the cpu_pm notifier.

That is one more step forward to make the cpuidle driver arch indenpendant.

---
 arch/arm/mach-exynos/cpuidle.c |   22 ----------------------
 arch/arm/mach-exynos/pm.c      |   24 ++++++++++++++++++++----
 2 files changed, 20 insertions(+), 26 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -22
index e6d813d..02609ac 100644
@@ -28,7 +28,6 @@
 #include <mach/map.h>
 
 #include "common.h"
-#include "regs-pmu.h"
 
 static int idle_finisher(unsigned long flags)
 {
@@ -42,31 +41,10 @@ static int exynos_enter_core0_aftr(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv,
                                int index)
 {
-       unsigned long tmp;
-
-       /* Setting Central Sequence Register for power down mode */
-       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-       tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
-       __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-
        cpu_pm_enter();
        cpu_suspend(0, idle_finisher);
        cpu_pm_exit();
 
-       /*
-        * If PMU failed while entering sleep mode, WFI will be
-        * ignored by PMU and then exiting cpu_do_idle().
-        * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
-        * in this situation.
-        */
-       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-       if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
-               tmp |= S5P_CENTRAL_LOWPWR_CFG;
-               __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-               /* Clear wakeup state register */
-               __raw_writel(0x0, S5P_WAKEUP_STAT);
-       }
-
        return index;
 }
 
arch/arm/mach-exynos/pm.c +19 -4
index 50b6b4d..6d9ef69 100644
@@ -213,15 +213,21 @@ static void exynos_pm_prepare(void)
        __raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
 }
 
-static int exynos_pm_suspend(void)
+static void exynos_pm_central_suspend(void)
 {
        unsigned long tmp;
 
        /* Setting Central Sequence Register for power down mode */
-
        tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
        tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
        __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+}
+
+static int exynos_pm_suspend(void)
+{
+       unsigned long tmp;
+
+       exynos_pm_central_suspend();
 
        /* Setting SEQ_OPTION register */
 
@@ -234,7 +240,7 @@ static int exynos_pm_suspend(void)
        return 0;
 }
 
-static void exynos_pm_resume(void)
+static int exynos_pm_central_resume(void)
 {
        unsigned long tmp;
 
@@ -251,9 +257,17 @@ static void exynos_pm_resume(void)
                /* clear the wakeup state register */
                __raw_writel(0x0, S5P_WAKEUP_STAT);
                /* No need to perform below restore code */
-               goto early_wakeup;
+               return -1;
        }
 
+       return 0;
+}
+
+static void exynos_pm_resume(void)
+{
+       if (exynos_pm_central_resume())
+               goto early_wakeup;
+
        if (!soc_is_exynos5250())
                exynos_cpu_restore_register();
 
@@ -359,6 +373,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
        switch (cmd) {
        case CPU_PM_ENTER:
                if (cpu == 0) {
+                       exynos_pm_central_suspend();
                        exynos_cpu_save_register();
                }
                break;

arch/arm/mach-exynos/pm.c static int exynos_cpu_pm_notifier(struct notifier_block *self, · line 386

Quoted 4 lines
arch/arm/mach-exynos/pm.c +1 -0
@@ -368,6 +383,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
                        if (!soc_is_exynos5250())
                                scu_enable(S5P_VA_SCU);
                        exynos_cpu_restore_register();
+                       exynos_pm_central_resume();

This notifier is called for system wide suspend and cpuidle.

In case of Exynos cpuidle only AFTR and LPA state need to program central_sequencer and store/restore the registers.

But in 5420 (core-power-down), this is not required, and causing the regression.

Hence need to remove this notifier, or need to find a way to differentiate the cpuidle state.

Quoted 10 lines
arch/arm/mach-exynos/pm.c +0 -1
                }
                break;
        }
--

1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#18 lore raw

PATCH v5 16/20 ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm notifier

Hi Chander,

Quoted 2 lines · Chander Kashyap

On Fri, Apr 11, 2014 at 4:10 PM, Daniel Lezcano
<[email protected]> wrote:

[snip]

Quoted 16 lines

arch/arm/mach-exynos/pm.c static int exynos_cpu_pm_notifier(struct notifier_block *self, · line 386

Quoted 13 lines
arch/arm/mach-exynos/pm.c +2 -0
@@ -359,6 +373,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
        switch (cmd) {
        case CPU_PM_ENTER:
                if (cpu == 0) {
+                       exynos_pm_central_suspend();
                        exynos_cpu_save_register();
                }
                break;
@@ -368,6 +383,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
                        if (!soc_is_exynos5250())
                                scu_enable(S5P_VA_SCU);
                        exynos_cpu_restore_register();
+                       exynos_pm_central_resume();

This notifier is called for system wide suspend and cpuidle.

Quoted 7 lines

In case of Exynos cpuidle only AFTR and LPA state need to program central_sequencer and store/restore the registers.

But in 5420 (core-power-down), this is not required, and causing the regression.

Hence need to remove this notifier, or need to find a way to differentiate the cpuidle state.

This patch is already present in v3.16. Moreover, Exynos5420 cpuidle has not been merged yet. This means that this issue is not a regression and I believe any further work on this should be carried out as further patches on top of this change.

Anyway, this change has introduced a regression, though, but in another area - it broke suspend, at least on Exynos4-based devices, because now certain steps are performed twice. I've sent a patch for 3.16-rc3 to fix this by dropping custom suspend-specific syscore ops, effectively moving most of the handling to CPU PM notifier, which also matches requirements of AFTR and lower power states. See [1].

[1]
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg32935.html

However, in this case, moving back to suspend-specific syscore_ops and simply duplicating some code for lower cpuidle states might be a better option. Care to send a patch (fix for 3.16, replacing mine) or I should do it?

Best regards,
Tomasz

#19 lore raw

PATCH v5 16/20 ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm notifier

Quoted 44 lines · Tomasz Figa

Hi Chander,

Quoted 2 lines · Chander Kashyap

On Fri, Apr 11, 2014 at 4:10 PM, Daniel Lezcano
<[email protected]> wrote:

[snip]

Quoted 16 lines

arch/arm/mach-exynos/pm.c static int exynos_cpu_pm_notifier(struct notifier_block *self, · line 386

Quoted 13 lines
arch/arm/mach-exynos/pm.c +2 -0
@@ -359,6 +373,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
        switch (cmd) {
        case CPU_PM_ENTER:
                if (cpu == 0) {
+                       exynos_pm_central_suspend();
                        exynos_cpu_save_register();
                }
                break;
@@ -368,6 +383,7 @@ static int exynos_cpu_pm_notifier(struct notifier_block *self,
                        if (!soc_is_exynos5250())
                                scu_enable(S5P_VA_SCU);
                        exynos_cpu_restore_register();
+                       exynos_pm_central_resume();

This notifier is called for system wide suspend and cpuidle.

Quoted 7 lines

In case of Exynos cpuidle only AFTR and LPA state need to program central_sequencer and store/restore the registers.

But in 5420 (core-power-down), this is not required, and causing the regression.

Hence need to remove this notifier, or need to find a way to differentiate the cpuidle state.

This patch is already present in v3.16. Moreover, Exynos5420 cpuidle has not been merged yet. This means that this issue is not a regression and I believe any further work on this should be carried out as further patches on top of this change.

Anyway, this change has introduced a regression, though, but in another area - it broke suspend, at least on Exynos4-based devices, because now certain steps are performed twice. I've sent a patch for 3.16-rc3 to fix this by dropping custom suspend-specific syscore ops, effectively moving most of the handling to CPU PM notifier, which also matches requirements of AFTR and lower power states. See [1].

Quoted 7 lines

[1]
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg32935.html

However, in this case, moving back to suspend-specific syscore_ops and simply duplicating some code for lower cpuidle states might be a better option. Care to send a patch (fix for 3.16, replacing mine) or I should do it?

Yes need to move the common code to lower cpuildle implementation and removing the notifier all together.
I will do it and send the patch.

Quoted 7 lines

Best regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#20 lore raw

PATCH v5 17/20 ARM: exynos: cpuidle: Move S5P_CHECK_SLEEP into pm.c

In reply to Daniel Lezcano

This macro is only used there.

---
 arch/arm/mach-exynos/pm.c       |    3 ++-
 arch/arm/mach-exynos/regs-pmu.h |    2 --
 2 files changed, 2 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/pm.c +2 -1
index 6d9ef69..b380d48 100644
@@ -108,7 +108,8 @@ static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
 			S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
 			(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
 
-#define S5P_CHECK_AFTR 0xFCBA0D10
+#define S5P_CHECK_AFTR  0xFCBA0D10
+#define S5P_CHECK_SLEEP 0x00000BAD
 
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
 static void exynos_set_wakeupmask(long mask)
arch/arm/mach-exynos/regs-pmu.h +0 -2
index 4f6a256..6c1d2db 100644
@@ -119,8 +119,6 @@
 #define S5P_CORE_LOCAL_PWR_EN			0x3
 #define S5P_INT_LOCAL_PWR_EN			0x7
 
-#define S5P_CHECK_SLEEP				0x00000BAD
-
 /* Only for EXYNOS4210 */
 #define S5P_CMU_CLKSTOP_LCD1_LOWPWR	S5P_PMUREG(0x1154)
 #define S5P_CMU_RESET_LCD1_LOWPWR	S5P_PMUREG(0x1174)
Signature · 1 line
1.7.9.5
#21 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

In reply to Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

---
 arch/arm/mach-exynos/cpuidle.c |    4 +++-
 arch/arm/mach-exynos/exynos.c  |    5 +++--
 2 files changed, 6 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/cpuidle.c +3 -1
index 02609ac..1d1222e 100644
@@ -27,7 +27,7 @@
 
 #include <mach/map.h>
 
-#include "common.h"
+static void (*exynos_enter_aftr)(void);
 
 static int idle_finisher(unsigned long flags)
 {
@@ -86,6 +86,8 @@ static int exynos_cpuidle_probe(struct platform_device *pdev)
 {
 	int ret;
 
+	exynos_enter_aftr = (void *)(pdev->dev.platform_data);
+
 	ret = cpuidle_register(&exynos_idle_driver, NULL);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register cpuidle driver\n");
arch/arm/mach-exynos/exynos.c +3 -2
index fe8dac8..d22f0e4 100644
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct platform_device exynos_cpuidle = {
-	.name		= "exynos_cpuidle",
-	.id		= -1,
+	.name              = "exynos_cpuidle",
+	.dev.platform_data = exynos_enter_aftr,
+	.id                = -1,
 };
 
 void __init exynos_cpuidle_init(void)
Signature · 1 line
1.7.9.5
#22 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
 };
 

This is wrong on many levels, can we please do this properly?

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.
* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().
* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

Daniel, you should really know better than this. Why are you still adding code to drivers/cpuidle that uses legacy platform devices rather than DT probing?

Arnd

#23 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Hi Arnd,

Quoted 28 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
 };
 

This is wrong on many levels, can we please do this properly?

Quoted 2 lines

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.

+1

Quoted 3 lines

* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().

+0.5

The missing 0.5 is because you can't pass platform data using platform_device_register_simple(). There is platform_device_register_resndata(), though.

Quoted 3 lines

* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

-1

Exynos cpuidle is not a device on the SoC, so I don't think there is any way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

Best regards,
Tomasz

#24 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Hi,

Quoted 12 lines · Tomasz Figa

Hi Arnd,

Quoted 9 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Could you please give some more details about these issues?

If this is a build breakage for CONFIG_PM_SLEEP=n && CONFIG_CPU_IDLE=y configuration then this is not a new problem introduced by the current patchset (please see below).

Quoted 18 lines
Quoted 18 lines
Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
 }
 
 static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
 };
 

This is wrong on many levels, can we please do this properly?

Quoted 4 lines
Quoted 2 lines

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.

+1

Even without Daniel's patchset we are getting a link error for CONFIG_PM_SLEEP=n && CONFIG_CPU_IDLE=y configuration.

In arch/arm/mach-exynos/Makefile we have:

...
obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
...
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
...

and since cpuidle.c is referencing exynos_cpu_resume() from sleep.S the build results in:

arch/arm/kernel/return_address.c:63:2: warning: #warning "TODO: return_address should use unwind tables" [-Wcpp] arch/arm/mach-exynos/built-in.o: In function `exynos4_enter_core0_aftr':
/home/bzolnier/linux-sprc/arch/arm/mach-exynos/cpuidle.c:141: undefined reference to cpu_suspend' arch/arm/mach-exynos/built-in.o: In function exynos4_enter_lowpower':
/home/bzolnier/linux-sprc/arch/arm/mach-exynos/cpuidle.c:176: undefined reference to `exynos_cpu_resume'
make: *** [vmlinux] Error 1

linkage errors.

[ The other error for the current code is for cpu_suspend() which is
also (indirectly) dependent on CONFIG_PM_SLEEP. ]

Quoted 9 lines
Quoted 3 lines

* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().

+0.5

The missing 0.5 is because you can't pass platform data using platform_device_register_simple(). There is platform_device_register_resndata(), though.

Agreed but this can be fixed trivially (even in in the incremental patch).

Quoted 11 lines
Quoted 3 lines

* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

-1

Exynos cpuidle is not a device on the SoC, so I don't think there is any way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

Moreover this code is not going to be shared between arm32 and arm64 in the near future (if ever) and doing things by using platform device has such benefit that the current code can be changed without a problem when the need arise. With DT there is no such flexibility and it also takes some time to design DT bindings properly.

The build problems should be fixed but if indeed they are not a new ones then the patchset should be brought back (Kukjin has dropped it entirely for now). This is important work which serves as a base for more cpuidle improvements from both Daniel and me therefore it would be great to have it merged in v3.16 and not delay it unnecessarily.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

#25 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

In reply to Tomasz Figa
Quoted 31 lines · Tomasz Figa

Hi Arnd,

Quoted 28 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
  }
 
  static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
  };
 

This is wrong on many levels, can we please do this properly?

Quoted 4 lines
Quoted 2 lines

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.

+1

That is true but still we have a link error without this patch. We shouldn't register and declare this structure if CONFIG_PM / CONFIG_CPU_IDLE are not set.

Quoted 14 lines
Quoted 3 lines

* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().

+0.5

The missing 0.5 is because you can't pass platform data using platform_device_register_simple(). There is platform_device_register_resndata(), though.

Quoted 3 lines

* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

Quoted 7 lines

-1

Exynos cpuidle is not a device on the SoC, so I don't think there is any way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

Thanks
-- Daniel

[1] http://www.spinics.net/lists/arm-kernel/msg328747.html

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#26 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Arnd, Kukjin, Daniel,

Quoted 72 lines · Daniel Lezcano
Quoted 31 lines · Tomasz Figa

Hi Arnd,

Quoted 28 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
  }
 
  static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
  };
 

This is wrong on many levels, can we please do this properly?

Quoted 4 lines
Quoted 2 lines

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.

+1

That is true but still we have a link error without this patch. We shouldn't register and declare this structure if CONFIG_PM / CONFIG_CPU_IDLE are not set.

Quoted 14 lines
Quoted 3 lines

* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().

+0.5

The missing 0.5 is because you can't pass platform data using platform_device_register_simple(). There is platform_device_register_resndata(), though.

Quoted 3 lines

* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

Quoted 7 lines

-1

Exynos cpuidle is not a device on the SoC, so I don't think there is any way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Quoted 8 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

In general, it would be nice to have everything done properly, but I'd consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

Best regards,
Tomasz

#27 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Quoted 84 lines · Tomasz Figa

Arnd, Kukjin, Daniel,

Quoted 72 lines · Daniel Lezcano
Quoted 31 lines · Tomasz Figa

Hi Arnd,

Quoted 28 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Quoted 5 lines
arch/arm/mach-exynos/exynos.c +0 -0
index fe8dac8..d22f0e4 100644

arch/arm/mach-exynos/exynos.c void exynos_restart(enum reboot_mode mode, const char *cmd) · line 228

Quoted 10 lines
arch/arm/mach-exynos/exynos.c +3 -2
@@ -221,8 +221,9 @@ void exynos_restart(enum reboot_mode mode, const char *cmd)
   }
 
   static struct platform_device exynos_cpuidle = {
-       .name           = "exynos_cpuidle",
-       .id             = -1,
+       .name              = "exynos_cpuidle",
+       .dev.platform_data = exynos_enter_aftr,
+       .id                = -1,
   };
 

This is wrong on many levels, can we please do this properly?

Quoted 4 lines
Quoted 2 lines

* The exynos_enter_aftr function is compiled conditionally, so you can't just reference it from generic code, or you get a link error.

+1

That is true but still we have a link error without this patch. We shouldn't register and declare this structure if CONFIG_PM / CONFIG_CPU_IDLE are not set.

Quoted 14 lines
Quoted 3 lines

* 'static struct platform_device ...' has been deprecated for at least a decade, stop doing that. For any platform devices that get registered, there is platform_device_register_simple().

+0.5

The missing 0.5 is because you can't pass platform data using platform_device_register_simple(). There is platform_device_register_resndata(), though.

Quoted 3 lines

* There shouldn't need to be a platform_device to start with, this should all come from DT. We can't do this on arm64 anyway, so any code that may be shared between arm32 and arm64 should have proper abstractions.

Quoted 7 lines

-1

Exynos cpuidle is not a device on the SoC, so I don't think there is any way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Quoted 8 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

Quoted 7 lines

In general, it would be nice to have everything done properly, but I'd consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

I'm fine.

Arnd, how about you?

- Kukjin

#28 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

On 05/15/2014 10:40 PM, Kukjin Kim wrote:

[ ... ]

Quoted 29 lines
Quoted 29 lines
Quoted 16 lines
Quoted 6 lines

Exynos cpuidle is not a device on the SoC, so I don't think there is any
way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Quoted 8 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

In general, it would be nice to have everything done properly, but I'd consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

Quoted 8 lines
Quoted 3 lines

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

I'm fine.

Arnd, how about you?

- Kukjin

Arnd ?

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#29 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Quoted 19 lines · On Wednesday 21 May 2014 09:15:34 Daniel Lezcano wrote:

On 05/15/2014 10:40 PM, Kukjin Kim wrote:

[ ... ]

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 6 lines

Exynos cpuidle is not a device on the SoC, so I don't think there is any
way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Yes, that would be great. I only looked briefly at the series now, doesn't that require the use of psci? That's not a bad idea of course, but it doesn't solve the problem I raised here.

Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 8 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

In general, it would be nice to have everything done properly, but I'd consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

Quoted 7 lines
Quoted 5 lines

I'm fine.

Arnd, how about you?

- Kukjin

Arnd ?

Sorry for the delay. Yes, let's do it this way once more, but please come up with something better for the future that doesn't tie the cpuidle method to the root compatible string as this does.

Arnd

#30 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Quoted 17 lines · Arnd Bergmann
Quoted 16 lines · On Wednesday 21 May 2014 09:15:34 Daniel Lezcano wrote:

On 05/15/2014 10:40 PM, Kukjin Kim wrote:

[ ... ]

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 6 lines

Exynos cpuidle is not a device on the SoC, so I don't think there is any
way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Yes, that would be great. I only looked briefly at the series now, doesn't that require the use of psci?

No, because PSCI is for some specific platform (eg. calxeda), all the other drivers are legacy and manually handling the PM via some low level callbacks. This is why all drivers were implemented all over the place making so difficult to maintain them. Little by little, we split the PM callbacks from the idle algorithm so reducing the platform dependency with the generic code.

The PSCI implements such PM callbacks in the firmware directly and are accessed through an API. PSCI is, let's say some kindof nextgen cpuidle. It is similar than mwait on Intel. But if a new platform does not have such firmware, then the cpuidle driver will have the legacy format.

Quoted 21 lines

That's not a bad idea of course, but it
doesn't solve the problem I raised here.

Quoted 18 lines
Quoted 18 lines
Quoted 9 lines
Quoted 8 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too. That will be easier if we have them grouped in a single directory (this is what does this patchset at the end).

As there are some more work based on this patchset and the link error could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

Quoted 7 lines

In general, it would be nice to have everything done properly, but I'd consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

I'm fine.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

Arnd, how about you?

- Kukjin

Arnd ?

Sorry for the delay.

No problem.

Quoted 3 lines

Yes, let's do it this way once more, but please
come up with something better for the future that doesn't tie the cpuidle method to the root compatible string as this does.

ok.

Thanks

-- Daniel

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#31 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

Quoted 32 lines · On Wednesday 21 May 2014 11:02:29 Daniel Lezcano wrote:
Quoted 17 lines · Arnd Bergmann
Quoted 16 lines · On Wednesday 21 May 2014 09:15:34 Daniel Lezcano wrote:

On 05/15/2014 10:40 PM, Kukjin Kim wrote:

[ ... ]

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 6 lines

Exynos cpuidle is not a device on the SoC, so I don't think there is any
way to represent it in DT. The only thing I could see this is matching root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any available infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the code across the different drivers and separate the PM / cpuidle code.

Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

By this way, we can move the different drivers to drivers/cpuidle and store them in a single place. That make easier the tracking, the review and the maintenance.

Yes, that would be great. I only looked briefly at the series now, doesn't that require the use of psci?

No, because PSCI is for some specific platform (eg. calxeda), all the other drivers are legacy and manually handling the PM via some low level callbacks. This is why all drivers were implemented all over the place making so difficult to maintain them. Little by little, we split the PM callbacks from the idle algorithm so reducing the platform dependency with the generic code.

Quoted 4 lines

The PSCI implements such PM callbacks in the firmware directly and are accessed through an API. PSCI is, let's say some kindof nextgen cpuidle. It is similar than mwait on Intel. But if a new platform does not have such firmware, then the cpuidle driver will have the legacy format.

Ok, thanks for the exlanation.

Arnd

#32 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

In reply to Arnd Bergmann
Quoted 56 lines · Arnd Bergmann
Quoted 5 lines · On Wednesday 21 May 2014 09:15:34 Daniel Lezcano wrote:

On 05/15/2014 10:40 PM, Kukjin Kim wrote:

[ ... ]

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

Exynos cpuidle is not a device on the SoC, so I don't think there

is

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

any
way to represent it in DT. The only thing I could see this is

matching

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

root node with a central SoC driver that instantiates specific subdevices, such as cpufreq and cpuidle, but I don't see any

available

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 1 line

infrastructure for this.

There is a RFC for defining generic idle states [1].

The idea behind using the platform driver framework is to unify the

code

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

across the different drivers and separate the PM / cpuidle code.

By this way, we can move the different drivers to drivers/cpuidle

and

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

store them in a single place. That make easier the tracking, the

review

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

and the maintenance.

Yes, that would be great. I only looked briefly at the series now, doesn't that require the use of psci? That's not a bad idea of course, but it doesn't solve the problem I raised here.

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

I am ok to by using platform_device_register_resndata() but I would prefer to do that a bit later by converting the other drivers too.

That

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

will be easier if we have them grouped in a single directory (this

is

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

what does this patchset at the end).

As there are some more work based on this patchset and the link

error

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

could be fixed as an independent patch, I would recommend to re-integrate it in the tree as asked by Bartlomiej.

In general, it would be nice to have everything done properly, but

I'd

Quoted 10 lines
Quoted 10 lines
Quoted 6 lines

consider Daniel's series as a huge improvement already and a nice intermediate step towards further clean-up.

So based on the comments quoted above, instead of stalling the development, I'd suggest to accept this series and then move forward.

I'm fine.

Arnd, how about you?

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

- Kukjin

Arnd ?

Sorry for the delay. Yes, let's do it this way once more, but please come up with something better for the future that doesn't tie the cpuidle method to the root compatible string as this does.

Good!

I will include this series into for-next and 2nd round of samsung pull-request for 3.16.

Thanks,
Kukjin

#33 lore raw

PATCH v5 18/20 ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data

In reply to Arnd Bergmann
Quoted 10 lines · Arnd Bergmann
Quoted 6 lines · Daniel Lezcano

No more dependency on the arch code. The platform_data field is used to set the PM callback as the other cpuidle drivers.

This has just shown up in linux-next and broken randconfig builds.

Hi Arnd,

Hmm...I just reverted this series in for-next of samsung tree and will hold on until solving the randconfig build breakage. I need to look at this again and think about your suggestion...

Thanks,
Kukjin

#34 lore raw

PATCH v5 19/20 ARM: exynos: cpuidle: Cleanup all unneeded headers from cpuidle.c

In reply to Daniel Lezcano
---
 arch/arm/mach-exynos/cpuidle.c |   10 ----------
 1 file changed, 10 deletions(-)
arch/arm/mach-exynos/cpuidle.c +0 -10
index 1d1222e..1d09ebd 100644
@@ -8,25 +8,15 @@
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
-#include <linux/io.h>
 #include <linux/export.h>
-#include <linux/time.h>
 #include <linux/platform_device.h>
 
 #include <asm/proc-fns.h>
 #include <asm/suspend.h>
-#include <asm/unified.h>
 #include <asm/cpuidle.h>
 
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-
 static void (*exynos_enter_aftr)(void);
 
 static int idle_finisher(unsigned long flags)
Signature · 1 line
1.7.9.5
#35 lore raw

PATCH v5 20/20 ARM: exynos: cpuidle: Move the driver to drivers/cpuidle directory

In reply to Daniel Lezcano
---
 arch/arm/mach-exynos/Makefile                      |    1 -
 drivers/cpuidle/Kconfig.arm                        |    6 ++++++
 drivers/cpuidle/Makefile                           |    1 +
 .../cpuidle.c => drivers/cpuidle/cpuidle-exynos.c  |    0
 4 files changed, 7 insertions(+), 1 deletion(-)
 rename arch/arm/mach-exynos/cpuidle.c => drivers/cpuidle/cpuidle-exynos.c (100%)
arch/arm/mach-exynos/Makefile +0 -1
index a656dbe..21bd364 100644
@@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_EXYNOS)	+= exynos.o
 
 obj-$(CONFIG_PM_SLEEP)		+= pm.o sleep.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 obj-$(CONFIG_ARCH_EXYNOS)	+= pmu.o
 
drivers/cpuidle/Kconfig.arm +6 -0
index d988948..364c984 100644
@@ -44,3 +44,9 @@ config ARM_AT91_CPUIDLE
 	depends on ARCH_AT91
 	help
 	  Select this to enable cpuidle for AT91 processors
+
+config ARM_EXYNOS_CPUIDLE
+	bool "Cpu Idle Driver for the Exynos processors"
+	depends on ARCH_EXYNOS
+	help
+	  Select this to enable cpuidle for Exynos processors
drivers/cpuidle/Makefile +1 -0
index f71ae1b..0d1540a 100644
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE)	+= cpuidle-kirkwood.o
 obj-$(CONFIG_ARM_ZYNQ_CPUIDLE)		+= cpuidle-zynq.o
 obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
+obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 
 ###############################################################################
 # POWERPC drivers
drivers/cpuidle/cpuidle-exynos.c renamed from arch/arm/mach-exynos/cpuidle.c +0 -0
similarity index 100%
rename from arch/arm/mach-exynos/cpuidle.c
rename to drivers/cpuidle/cpuidle-exynos.c
Signature · 1 line
1.7.9.5
#36 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

In reply to Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Regards

-- Daniel

Quoted 76 lines · Daniel Lezcano

Changelog:

V5:
* Removed patch : "Move clock setup to pm.c"
* Added patch : "Move arm core power down clock to exynos5250 common code"
V4:
* Took into account Tomasz's comments
* Fixed missing call in for central suspend
* Passed parameter to the wakeup mask function
* Moved wakeup mask, boot vector and aftr state into a single function
* Used this function as callback for platform data
* Moved S5P_CHECK_AFTR/S5P_CHECK_SLEEP into pm.c
* Set boot vector only one time
* Splitted some patches to make them more readable
V3:
* Added patch : "ARM: exynos: cpuidle: Disable cpuidle for 5440"
* Removed patch : "ARM: exynos: config: Enable cpuidle"
* Removed default ARM_EXYNOS4210_CPUIDLE=y
* Added comment about bug fix side effect 'for_each_possible_cpu'
V2:
* Added comment in changelog for calls order (5/17)
* Call the powerdown only for cpu0 in the pm notifier
* Set the pm notifier for all boards

V1: initial post

This patchset relies on the cpm_pm notifier to initiate the powerdown sequence operations from pm.c instead cpuidle.c. Thus the cpuidle driver is no longer dependent from arch specific code as everything is called from the pm.c file.

The patchset applies on top of linux-samsung/for-next.

Tested on exynos4: 4210
Tested on exynos5: 5250 (without AFTR)

Amit Daniel Kachhap (1):
ARM: EXYNOS: Move arm core power down clock to exynos5250 common
clock

Daniel Lezcano (19):
ARM: exynos: cpuidle: Prevent forward declaration
ARM: exynos: cpuidle: Use cpuidle_register
ARM: exynos: cpuidle: Change function name prefix
ARM: exynos: cpuidle: Encapsulate register access inside a function
ARM: exynos: cpuidle: Move some code inside the idle_finisher
ARM: exynos: cpuidle: Fix S5P_WAKEUP_STAT call
ARM: exynos: cpuidle: Use the cpu_pm notifier
ARM: exynos: cpuidle: Move scu_enable in the cpu_pm notifier
ARM: exynos: cpuidle: Remove ifdef for scu_enable
ARM: exynos: cpuidle: Pass wakeup mask parameter to function
ARM: exynos: cpuidle: Encapsulate boot vector code into a function
ARM: exynos: cpuidle: Disable cpuidle for 5440
ARM: exynos: cpuidle: Encapsulate the AFTR code into a function
ARM: exynos: cpuidle: Move the AFTR state function into pm.c
ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm
notifier
ARM: exynos: cpuidle: Move S5P_CHECK_SLEEP into pm.c
ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data
ARM: exynos: cpuidle: Cleanup all unneeded headers from cpuidle.c
ARM: exynos: cpuidle: Move the driver to drivers/cpuidle directory

  arch/arm/mach-exynos/Makefile        |    1 -
  arch/arm/mach-exynos/common.h        |    1 +
  arch/arm/mach-exynos/cpuidle.c       |  255 ----------------------------------
  arch/arm/mach-exynos/exynos.c        |    8 +-
  arch/arm/mach-exynos/pm.c            |  152 ++++++++++++++++----
  arch/arm/mach-exynos/regs-pmu.h      |    2 -
  drivers/clk/samsung/clk-exynos5250.c |   42 ++++++
  drivers/cpuidle/Kconfig.arm          |    6 +
  drivers/cpuidle/Makefile             |    1 +
  drivers/cpuidle/cpuidle-exynos.c     |   98 +++++++++++++
  10 files changed, 277 insertions(+), 289 deletions(-)

delete mode 100644 arch/arm/mach-exynos/cpuidle.c create mode 100644 drivers/cpuidle/cpuidle-exynos.c

Signature · 5 lines
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#37 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

+1.

Also when applying you might add

to any patches that don't have it yet.

Best regards,
Tomasz

#38 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 8 lines

+1.

Also when applying you might add

to any patches that don't have it yet.

Tomasz, thanks for your review.

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Thanks,
Kukjin

#39 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Quoted 15 lines · Kukjin Kim
Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 4 lines

+1.

Also when applying you might add

Quoted 8 lines
Quoted 4 lines

to any patches that don't have it yet.

Tomasz, thanks for your review.

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Daniel,

Can you please check/test the functionality your series with using my for-next because there were merge conflicts with mcpm-exynos stuff...?

Thanks,
Kukjin

#40 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Quoted 22 lines · Kukjin Kim
Quoted 21 lines · Kukjin Kim
Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 8 lines

+1.

Also when applying you might add

to any patches that don't have it yet.

Tomasz, thanks for your review.

Quoted 7 lines
Quoted 3 lines

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Daniel,

Can you please check/test the functionality your series with using my for-next because there were merge conflicts with mcpm-exynos stuff...?

Sure, will do that tomorrow.

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#41 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

In reply to Kukjin Kim
Quoted 22 lines · Kukjin Kim
Quoted 21 lines · Kukjin Kim
Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 8 lines

+1.

Also when applying you might add

to any patches that don't have it yet.

Tomasz, thanks for your review.

Quoted 7 lines
Quoted 3 lines

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Daniel,

Can you please check/test the functionality your series with using my for-next because there were merge conflicts with mcpm-exynos stuff...?

Hi Kukjin,

I tested the latest tree. Unfortunately it panics when unplugging cpu1:

[    3.124189] Unable to handle kernel paging request at virtual address f8400024
[    3.129950] pgd = c0004000
[    3.132626] [f8400024] *pgd=6f7f7841, *pte=00000000, *ppte=00000000
[    3.138877] Internal error: Oops: 827 [#1] PREEMPT SMP ARM
[    3.192782] r3 : f8400024  r2 : f8180800  r1 : ee836e44  r0 : f8400024
[    3.199293] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM Segment kernel
[    3.206673] Control: 10c5387d  Table: 6e37c04a  DAC: 00000015
[    3.212398] Process swapper/0 (pid: 0, stack limit = 0xc0510240)
[    3.218388] Stack: (0xc0511ef4 to 0xc0512000)
[    3.222728] 1ee0: 00000030 c02b20f8 ee836e40
[    3.230894] 1f00: c001234c 6e880000 c0511f34 40018a80 00000000 00000000 00000000 00000015
[    3.239053] 1f20: 4000404a 10c5387d 00000041 00f00000 00000000 00000000 c02b20e4 edc4a540
[    3.247212] 1f40: c038dacc eefc5cf8 c050ecf0 c0543210 00000000 c0012460 00000001 c0543210
[    3.255371] 1f60: eefc5cf8 c02b2148 b9f92927 00000000 c054326c c02b0968 b9f92927 00000000
[    3.263530] 1f80: c0510000 c0518480 c038dacc c0510000 c0510000 c0518480 c038dacc eefc5cf8
[    3.271689] 1fa0: c0543210 c004e990 c0511fb4 c03873b8 00000000 c04f90c8 00000000 c04d4b18
[    3.279848] 1fc0: ffffffff ffffffff c04d457c 00000000 00000000 c04f90c8 00000000 10c5387d
[    3.288007] 1fe0: c0518410 c04f90c4 c051bd5c 4000406a 00000000 40008074 00000000 00000000
[    3.296184] [<c0019c5c>] (exynos_enter_aftr) from [<c02b20f8>] (idle_finisher+0x14/0x20)
[    3.304247] [<c02b20f8>] (idle_finisher) from [<c001234c>] (cpu_suspend_abort+0x0/0x14)
[    3.312226] [<c001234c>] (cpu_suspend_abort) from [<00000000>] (  (null))
[    3.318994] Code: e34f3840 e3500010 11a00002 01a00003 (e5804000)
[    3.325069] ---[ end trace fca911f75a18c040 ]---

After git bisecting I falls on this commit:

commit b3205dea8fbf6db9b1e46a0dad19a0712fdff44f

Author: Sachin Kamat <[email protected]>
Date:   Tue May 13 07:13:44 2014 +0900

ARM: EXYNOS: Map SYSRAM through generic DT bindings

Instead of hardcoding the SYSRAM details for each SoC, pass this information through device tree (DT) and make the code SoC agnostic. Generic DT SRAM bindings are used for achieving this.

... which is before my series is applied.

So I am not able to tell yet if my series is correctly rebased or not.

And before someone asks me, yes I updated the dtb :)

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#42 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Hi Daniel,

Quoted 93 lines · Daniel Lezcano
Quoted 22 lines · Kukjin Kim
Quoted 21 lines · Kukjin Kim
Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 8 lines

+1.

Also when applying you might add

to any patches that don't have it yet.

Tomasz, thanks for your review.

Quoted 7 lines
Quoted 3 lines

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Daniel,

Can you please check/test the functionality your series with using my for-next because there were merge conflicts with mcpm-exynos stuff...?

Hi Kukjin,

I tested the latest tree. Unfortunately it panics when unplugging cpu1:

[    3.124189] Unable to handle kernel paging request at virtual address
f8400024
[    3.129950] pgd = c0004000
[    3.132626] [f8400024] *pgd=6f7f7841, *pte=00000000, *ppte=00000000
[    3.138877] Internal error: Oops: 827 [#1] PREEMPT SMP ARM
[    3.192782] r3 : f8400024  r2 : f8180800  r1 : ee836e44  r0 : f8400024
[    3.199293] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[    3.206673] Control: 10c5387d  Table: 6e37c04a  DAC: 00000015
[    3.212398] Process swapper/0 (pid: 0, stack limit = 0xc0510240)
[    3.218388] Stack: (0xc0511ef4 to 0xc0512000)
[    3.222728] 1ee0: 00000030 c02b20f8 ee836e40
[    3.230894] 1f00: c001234c 6e880000 c0511f34 40018a80 00000000
00000000 00000000 00000015
[    3.239053] 1f20: 4000404a 10c5387d 00000041 00f00000 00000000
00000000 c02b20e4 edc4a540
[    3.247212] 1f40: c038dacc eefc5cf8 c050ecf0 c0543210 00000000
c0012460 00000001 c0543210
[    3.255371] 1f60: eefc5cf8 c02b2148 b9f92927 00000000 c054326c
c02b0968 b9f92927 00000000
[    3.263530] 1f80: c0510000 c0518480 c038dacc c0510000 c0510000
c0518480 c038dacc eefc5cf8
[    3.271689] 1fa0: c0543210 c004e990 c0511fb4 c03873b8 00000000
c04f90c8 00000000 c04d4b18
[    3.279848] 1fc0: ffffffff ffffffff c04d457c 00000000 00000000
c04f90c8 00000000 10c5387d
[    3.288007] 1fe0: c0518410 c04f90c4 c051bd5c 4000406a 00000000
40008074 00000000 00000000
[    3.296184] [<c0019c5c>] (exynos_enter_aftr) from [<c02b20f8>]
(idle_finisher+0x14/0x20)
[    3.304247] [<c02b20f8>] (idle_finisher) from [<c001234c>]
(cpu_suspend_abort+0x0/0x14)
[    3.312226] [<c001234c>] (cpu_suspend_abort) from [<00000000>] ( 
(null))
[    3.318994] Code: e34f3840 e3500010 11a00002 01a00003 (e5804000)
[    3.325069] ---[ end trace fca911f75a18c040 ]---

After git bisecting I falls on this commit:

commit b3205dea8fbf6db9b1e46a0dad19a0712fdff44f

Author: Sachin Kamat <[email protected]>
Date:   Tue May 13 07:13:44 2014 +0900

ARM: EXYNOS: Map SYSRAM through generic DT bindings

Instead of hardcoding the SYSRAM details for each SoC, pass this information through device tree (DT) and make the code SoC agnostic. Generic DT SRAM bindings are used for achieving this.

Quoted 5 lines

... which is before my series is applied.

So I am not able to tell yet if my series is correctly rebased or not.

And before someone asks me, yes I updated the dtb :)

The driver seemed to be working fine for me on Exynos4210-TRATS board (with right bootloader, which supports AFTR).

Still, a quick look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC revisions, which is not valid any longer, after SYSRAM started to be mapped dynamically. As you can see in platsmp.c, the new dynamic mapping is stored in sysram_base_addr variable, which is static right now.

My proposed fix would be to make it non-static, declare it in one of existing private headers (common.h probably) and use it in pm.c instead of S5P_VA_SYSRAM.

Best regards,
Tomasz

#43 lore raw

v5 cover ARM: exynos: cpuidle: Move the driver to drivers/cpuidle

Quoted 111 lines · Tomasz Figa

Hi Daniel,

Quoted 93 lines · Daniel Lezcano
Quoted 22 lines · Kukjin Kim
Quoted 21 lines · Kukjin Kim
Quoted 8 lines · Tomasz Figa
Quoted 5 lines · Daniel Lezcano

Hi Kukjin,

I believe I addressed all the comments. Is it possible to take this patchset for next ?

Sure ;-)

Quoted 8 lines

+1.

Also when applying you might add

to any patches that don't have it yet.

Tomasz, thanks for your review.

Quoted 7 lines
Quoted 3 lines

I will take this series, "moving exynos-cpuidle into drivers/cpuidle" into samsung tree if Rafael is OK on that.

Daniel,

Can you please check/test the functionality your series with using my for-next because there were merge conflicts with mcpm-exynos stuff...?

Hi Kukjin,

I tested the latest tree. Unfortunately it panics when unplugging cpu1:

[    3.124189] Unable to handle kernel paging request at virtual address
f8400024
[    3.129950] pgd = c0004000
[    3.132626] [f8400024] *pgd=6f7f7841, *pte=00000000, *ppte=00000000
[    3.138877] Internal error: Oops: 827 [#1] PREEMPT SMP ARM
[    3.192782] r3 : f8400024  r2 : f8180800  r1 : ee836e44  r0 : f8400024
[    3.199293] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[    3.206673] Control: 10c5387d  Table: 6e37c04a  DAC: 00000015
[    3.212398] Process swapper/0 (pid: 0, stack limit = 0xc0510240)
[    3.218388] Stack: (0xc0511ef4 to 0xc0512000)
[    3.222728] 1ee0: 00000030 c02b20f8 ee836e40
[    3.230894] 1f00: c001234c 6e880000 c0511f34 40018a80 00000000
00000000 00000000 00000015
[    3.239053] 1f20: 4000404a 10c5387d 00000041 00f00000 00000000
00000000 c02b20e4 edc4a540
[    3.247212] 1f40: c038dacc eefc5cf8 c050ecf0 c0543210 00000000
c0012460 00000001 c0543210
[    3.255371] 1f60: eefc5cf8 c02b2148 b9f92927 00000000 c054326c
c02b0968 b9f92927 00000000
[    3.263530] 1f80: c0510000 c0518480 c038dacc c0510000 c0510000
c0518480 c038dacc eefc5cf8
[    3.271689] 1fa0: c0543210 c004e990 c0511fb4 c03873b8 00000000
c04f90c8 00000000 c04d4b18
[    3.279848] 1fc0: ffffffff ffffffff c04d457c 00000000 00000000
c04f90c8 00000000 10c5387d
[    3.288007] 1fe0: c0518410 c04f90c4 c051bd5c 4000406a 00000000
40008074 00000000 00000000
[    3.296184] [<c0019c5c>] (exynos_enter_aftr) from [<c02b20f8>]
(idle_finisher+0x14/0x20)
[    3.304247] [<c02b20f8>] (idle_finisher) from [<c001234c>]
(cpu_suspend_abort+0x0/0x14)
[    3.312226] [<c001234c>] (cpu_suspend_abort) from [<00000000>] (
(null))
[    3.318994] Code: e34f3840 e3500010 11a00002 01a00003 (e5804000)
[    3.325069] ---[ end trace fca911f75a18c040 ]---

After git bisecting I falls on this commit:

commit b3205dea8fbf6db9b1e46a0dad19a0712fdff44f

Author: Sachin Kamat <[email protected]>
Date:   Tue May 13 07:13:44 2014 +0900

ARM: EXYNOS: Map SYSRAM through generic DT bindings

Instead of hardcoding the SYSRAM details for each SoC, pass this information through device tree (DT) and make the code SoC agnostic. Generic DT SRAM bindings are used for achieving this.

Quoted 5 lines

... which is before my series is applied.

So I am not able to tell yet if my series is correctly rebased or not.

And before someone asks me, yes I updated the dtb :)

The driver seemed to be working fine for me on Exynos4210-TRATS board (with right bootloader, which supports AFTR).

Still, a quick look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC revisions, which is not valid any longer, after SYSRAM started to be mapped dynamically. As you can see in platsmp.c, the new dynamic mapping is stored in sysram_base_addr variable, which is static right now.

Quoted 3 lines

My proposed fix would be to make it non-static, declare it in one of existing private headers (common.h probably) and use it in pm.c instead of S5P_VA_SYSRAM.

Yes, that is right. Just like the way it is done for sysram_ns_base_addr in common.h

Signature · 2 lines
With warm regards,
Sachin
#44 lore raw

PATCH 1/1 ARM: exynos: Fix kernel panic when unplugging CPU1 on 4210

In reply to Tomasz Figa

A look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC revisions, which is not valid any longer, after SYSRAM started to be mapped dynamically. The new dynamic mapping is stored in sysram_base_addr variable, which is declared static in platsmp.c

This fix makes sysram_base_addr non-static, declared it in common.h and used in pm.c instead of S5P_VA_SYSRAM.

---
 arch/arm/mach-exynos/common.h  |    1 +
 arch/arm/mach-exynos/platsmp.c |    2 +-
 arch/arm/mach-exynos/pm.c      |    4 ++--
 3 files changed, 4 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/common.h +1 -0
index e2d0954..a012bc1 100644
@@ -88,6 +88,7 @@ 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_base_addr;
 void exynos_init_io(void);
 void exynos_restart(enum reboot_mode mode, const char *cmd);
 void exynos_cpuidle_init(void);
arch/arm/mach-exynos/platsmp.c +1 -1
index 9c16da2..f2bea78 100644
@@ -32,7 +32,7 @@
 
 extern void exynos4_secondary_startup(void);
 
-static void __iomem *sysram_base_addr;
+void __iomem *sysram_base_addr;
 void __iomem *sysram_ns_base_addr;
 
 static void __init exynos_smp_prepare_sysram(void)
arch/arm/mach-exynos/pm.c +2 -2
index d10c351..87c0d34 100644
@@ -168,10 +168,10 @@ int exynos_cluster_power_state(int cluster)
 
 #define EXYNOS_BOOT_VECTOR_ADDR	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
 			S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
+			(sysram_base_addr + 0x24) : S5P_INFORM0))
 #define EXYNOS_BOOT_VECTOR_FLAG	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
 			S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
+			(sysram_base_addr + 0x20) : S5P_INFORM1))
 
 #define S5P_CHECK_AFTR  0xFCBA0D10
 #define S5P_CHECK_SLEEP 0x00000BAD
Signature · 1 line
1.7.9.5
#45 lore raw

PATCH 1/1 ARM: exynos: Fix kernel panic when unplugging CPU1 on 4210

Quoted 10 lines · Daniel Lezcano

A look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC revisions, which is not valid any longer, after SYSRAM started to be mapped dynamically. The new dynamic mapping is stored in sysram_base_addr variable, which is declared static in platsmp.c

This fix makes sysram_base_addr non-static, declared it in common.h and used in pm.c instead of S5P_VA_SYSRAM.

Hi Kukjin,

with this fix I confirm cpuidle is working well with the AFTR state on the exynos 4210.

Regards
-- Daniel

Quoted 49 lines
---
  arch/arm/mach-exynos/common.h  |    1 +
  arch/arm/mach-exynos/platsmp.c |    2 +-
  arch/arm/mach-exynos/pm.c      |    4 ++--
  3 files changed, 4 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/common.h +1 -0
index e2d0954..a012bc1 100644
@@ -88,6 +88,7 @@ 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_base_addr;
  void exynos_init_io(void);
  void exynos_restart(enum reboot_mode mode, const char *cmd);
  void exynos_cpuidle_init(void);
arch/arm/mach-exynos/platsmp.c +1 -1
index 9c16da2..f2bea78 100644
@@ -32,7 +32,7 @@
 
  extern void exynos4_secondary_startup(void);
 
-static void __iomem *sysram_base_addr;
+void __iomem *sysram_base_addr;
  void __iomem *sysram_ns_base_addr;
 
  static void __init exynos_smp_prepare_sysram(void)
arch/arm/mach-exynos/pm.c +2 -2
index d10c351..87c0d34 100644
@@ -168,10 +168,10 @@ int exynos_cluster_power_state(int cluster)
 
  #define EXYNOS_BOOT_VECTOR_ADDR	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
  			S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
+			(sysram_base_addr + 0x24) : S5P_INFORM0))
  #define EXYNOS_BOOT_VECTOR_FLAG	(samsung_rev() == EXYNOS4210_REV_1_1 ? \
  			S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
-			(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
+			(sysram_base_addr + 0x20) : S5P_INFORM1))
 
  #define S5P_CHECK_AFTR  0xFCBA0D10
  #define S5P_CHECK_SLEEP 0x00000BAD
Signature · 5 lines
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
#46 lore raw

PATCH 1/1 ARM: exynos: Fix kernel panic when unplugging CPU1 on 4210

Quoted 13 lines · Daniel Lezcano
Quoted 12 lines · Daniel Lezcano

A look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC
revisions, which is not valid any longer, after SYSRAM started to be mapped
dynamically. The new dynamic mapping is stored in sysram_base_addr variable,
which is declared static in platsmp.c

This fix makes sysram_base_addr non-static, declared it in common.h and used
in pm.c instead of S5P_VA_SYSRAM.

Quoted 8 lines
Quoted 2 lines

Hi Kukjin,

with this fix I confirm cpuidle is working well with the AFTR state on the exynos 4210.

Thanks a lot.

I've applied this fix on top of cpuidle-exynos branch.

- Kukjin

#47 lore raw

PATCH 1/1 ARM: exynos: Fix kernel panic when unplugging CPU1 on 4210

In reply to Daniel Lezcano

Hi Daniel,

Quoted 8 lines · Daniel Lezcano

A look at the code reveals use of S5P_VA_SYSRAM macro, in case of certain SoC revisions, which is not valid any longer, after SYSRAM started to be mapped dynamically. The new dynamic mapping is stored in sysram_base_addr variable, which is declared static in platsmp.c

This fix makes sysram_base_addr non-static, declared it in common.h and used in pm.c instead of S5P_VA_SYSRAM.

Quoted 8 lines
---
 arch/arm/mach-exynos/common.h  |    1 +
 arch/arm/mach-exynos/platsmp.c |    2 +-
 arch/arm/mach-exynos/pm.c      |    4 ++--
 3 files changed, 4 insertions(+), 3 deletions(-)

Looks good to me.

Best regards,
Tomasz